Expand description
Run-time “linear types”
They panic in the Drop implementation in debug builds,
optionally only warning in release builds (depending on fatal
runtime value in the type).
Attempts at using the idea of panicking in const context does not
work in practice (it appears that drop templates are instantiated
before being optimized away, hence e.g. returning them in
Result::Ok is not possible since it apparently unconditionally
instantiates the drop for Result which instantiates the drop for
the Ok value even if never used, but I did not manage to analyze
the binary to detect drop use after the optimizer either).
Only token types are supported: embedding such a token type inside
a larger data structure makes the larger data structure run-time
checked for linearity, too. That type then has to provide a moving
method or function that throws away the linear token by calling
bury() on it. With that approach, no wrapper around the
containing data structure is needed, which might be cleaner?
Original idea and partially code came from
https://jack.wrenn.fyi/blog/undroppable/ and
https://geo-ant.github.io/blog/2024/rust-linear-types-use-once/,
but again, doesn’t appear to work in practice. There are also some
other crates going the runtime route, maybe the most-used one
being https://crates.io/crates/drop_bomb.
Calling std::mem::leak (even on a containing data structure)
by-passes the linearity. It is recommended to only ever use the
bury() method to get rid of a linear token, and reserve the use
of std::mem::forget for other purposes, so that searching the
code base for it will still just show up actual potential memory
leaks as well as potential improper bypasses of the linearity:
forget on an enclosing data structure bypasses the check and can
be done for any data type; whereas bury() is only available to
the code declaring the linear token type, hence under the control
of the library.
Structs§
- Undroppable
Within - A type that cannot be dropped.