Something Secret This Way Comes
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
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.