[Making a quick post about this and I can explain more in response to questions, but just wanted to share something from an experiment I did over the past couple weeks. I’ll do a writeup or video explaining more of this soon in context of my C workflow.] I wrote a borrow checker for C that uses libclang. You can see an example test case with the resulting checker output in the linked gist (this post’s title is the link). Below the checker output in the gist is the code for the borrow checker itself. The <code>main</code> function code quality is ¯(ツ)/¯ because it has some copypasta to read ‘compile_commands.json’ with libclang, and you should probably ignore that, I’ll be cleaning that up. The ‘Visit’ section is where the core of the checker lives. There’s a lot of statically-sized arrays and linear searches and repeat function calls but … it runs pretty fast and is far from the bottleneck in the build pipeline of project(s) I’m testing it on (checking takes 0.04 sec while the actual compile+link takes about 1 sec). The code is definitely still in a proof-of-concept state. It’s meant to pair with a codegen system I have that also generates <code>TArray</code> types and functions like <code>TDealloc</code> and <code>TClone</code> etc. that recurse through struct fields, and the codegen also generates other useful things like json serialization – that I use in my own projects. The codegen and checker currently work on a little game project I wrote as a pragmatic test for all this with Raylib. You can see what the codegen logic looks like here – <a href=“https://gist.github.com/nikki93/5752dff93fa4cb78c4750548cc588b64#file-00-generate-c-L318” rel=“ugc”>https://gist.github.com/nikki93/5752dff93fa4cb78c4750548cc588b64#file-00-generate-c-L318</a> (big dump of my game’s code, not about the details as much as the structure) – there’s a simple ‘quasiquotation’ going on there, and you can see the game code in ‘game.c’ with ‘generated.{h,c}’ below showing the generated API given the types in ‘game.c’. The codegen is from before I started using libclang so it uses a … homemade and incomplete … ‘parser’. The target use case is on app / game ‘business logic’ code written in a style that uses a bunch of arrays or other data structures and accesses things through ids or iteration, but has short-lived local pointers from those accesses and benefits from checking for invalidation of those pointers, and also of accidental copies or missed deallocs etc. of the data structures themselves. There can be a lot of this code that grows and churns with demands on project feature set and having automatic checking helps. I also always have asan+lsan running in development mode on my projects in addition to this. It’s not as catered right now towards, for example, the internal code of an allocator or something like that where you probably want some other system of checking correctness (lots of testing, fuzzing, proofs, thinking, …). [For people familiar with Rust borrow check semantics / ‘linear types’ stuff generally: It avoids a lot of the complexities the Rust borrow checker deals with by not allowing structs to have pointers in them with (multiple) generic lifetime parameters, not needing to do much inference if at all, not dealing with escaping closures, etc. In the future it could have structs that just have one inferred lifetime parameter by analyzing them the same way as pointers currently. It also assumes the first parameter of a function is the one a returning pointer borrows from (eg. in <code>FooArrayPush</code> in the example), so you don’t need to annotate that.] [This might miss some entire set of cases I didn’t think of yet, so there’s that…] Comments