Something Secret This Way Comes

24 April 2016

On the Rust Lint Workshop, I started coding on a “secret” project (Actually I hinted at the possibility during our 100 clippy lints celebration). Now that I’ve built a prototype, it’s time to spill the beans: I wrote a new lint. One might even say a new type of lint. One of the interesting things about this lint is that it doesn’t report anything. Ever.

Instead, it collects metadata from the crates compiled with it. Notably: Which types contain what other types and which methods call which. So it basically compiles a network of types and functions that lets us find some interesting properties without obviously violating privacy. To faithfully describe those properties, I named this new lint

'nsa'

metacollect’. (Edit: It appears some people were uneasy with the old name).

Now what are those properties we want to find out? For example, with the collected metadata, we may check if a method can panic, because those that do have an unwind call somewhere in their call graph. This is obviously a very useful property to know e.g. for interrupt handlers or custom panic handlers.

Another example is the property of purity of a method – if a method is pure, we can replace multiple calls with the same parameters by one call. We simply define pure methods as methods that take only immutable borrows to types that are themselves not internally mutable (though we may want to carve out exceptions for Rc<T> and Arc<T> , considering their internal mutability is limited to the ref count).

We can also easily find out if a method is recursive, which would preclude compiling it to GPU code. Or if a type stores something on the heap. We may even be able to find out what methods can allocate something on the heap (and an alloc lint that could be #[deny(_)] d could be useful for embedded programming or high performance work.

However, we don’t use the data yet, nsa only collects it. To make it useful (especially in other lints), we’ll have to run it via a build script (calling rustc -L/path/to/nsa.rlib -Z extra-plugins=nsa -Z no-trans on the crate and all its dependencies). In the long run, I personally think the compiler should make this information available to lints (perhaps in some kind of serialized map format and an API to query it), but I don’t have a say in that so here we are.

Anyway, this is just a prototype for now – there’s a lot of work to do: Create the build script, change the output (to database, add generics), add code to analyze the output so we can actually do something useful with it.

If you’d like to help, join me on github.