I had a random 3am idea about
unsafe code blocks. Unlike most of my such ideas, it might just not be terrible, so I’m sharing here.
The basic purpose of
unsafe is that the compiler can’t prove what’s inside is safe, but we as programmers can promise that it’s safe, based on additional reasoning. I think it would be good to have a structured annotation in which the programmer can describe their reasoning as to why they believe it’s safe.
This morning, I read The Secure Code WG’s 2019 goals post. Under the “Use of unsafe code” heading, a very important point is made:
Many widely used libraries use
unsafecode where it’s not strictly necessary. Typically this is done for performance reasons, i.e. there are currently no safe abstractions to achieve the goal safely and efficiently.
The goal here is to reduce or eliminate the use of unsafe code throughout the ecosystem where it is not strictly necessary without regressing correctness or performance. The action items for that include:
- Investigate why exactly people resort to unsafe code on a case-by-case basis. Compile a list of case studies so that we can identify missing safe abstractions or idioms.
This is a good goal, and made for a timely collision of ideas.
By “structured”, above, I mean:
- something that allows describing the human reasoning why the author believes the block is safe,
- with enough convention and structure that, it can capture and classify code blocks as above, and support this effort, ideally with some statistical data collection
- I was thinking of something like regular doc comments, as an annotation on the unsafe block, with a template and suitable headings, tags, and keywords - much like there are conventions already for describing when a function panics.
- However these are probably not user-facing documentation, so there might need to be some additional tweak to make the comments hidden by default in rustdoc output, at least when the docs are generated for public consumption.
- It could also be a mix of comments and other attributes for the more structured data (similar to the way deprecations and feature gates are annotated).
The initial goal (as in the blog post above) is discovery and classification:
- Once an author (or reviewer) has looked at an unsafe block and made some kind of decision about why it’s there or whether it’s of concern, we should be able to remember that
- An annotation and classification gets added, by the author or via PR
- Everyone can then spend effort on either analysing others, or prioritise fixing/removing ones more likely to be problematic.
- Once some conventions, classification tags/nomenclature, etc are established we could consider a lint that warns authors about
unsafeblocks lacking the relevant annotations, to prompt additional distributed work to aid the effort and tracking.
- If this whole effort is wildly successful and reduces the number of unnecessary or unknown unsafe blocks, the remainder might be worth some extra visibility and we can think about presentation and discovery for end users about what kinds of unsafe is in their dependency tree.
Note: this is not the same as
unsafe fn, where the author should already be describing why the function is publicly unsafe, but that case might borrow some of the same annotation conventions.