This is written informally because imho this should only be added if it can be explained trivially and informally. It is possible I've overlooked a simple thing which could be added in to fix, but the important part is that a beginner should be able to get a basic explanation of 'unsafe
and what it is / why it's used that is at least as good as with *const T
, without making normal named lifetimes more complicated.
TL;DR
Add a keyword lifetime, 'unsafe
. 'unsafe
is a stand-in for a lifetime which is not compiler enforced. Any use of a type including the 'unsafe
lifetime requires an unsafe
block. Said usage is only allowed if there exists some dynamic lifetime which is valid from creation to last use; in other words: you're the borrow checker now.
Why not pointers?
For a number of reasons:
-
&'unsafe T
has all of the benefits[1] of references other than safe dereferencing, such as the fact it is known aligned an non-null. As such, it can be niche optimized. - Access to method calls, autoref/autoderef, and functions which take references without converting pointer to reference.
-
'unsafe
can be used in struct lifetime generics. Doing so is wildlyunsafe
, but sometimes beneficial (e.g. for encapsulation of lifetimes).
Pointers are still very useful! 'unsafe
serves a distinct but related purpose. If in doubt, use pointers instead; they're the safer option due to being more permissive with what you can do.
Define "signatures that mention 'unsafe
"
If the fully expanded type signature contains the token 'unsafe
, the type mentions 'unsafe
and faces the consequences. This includes types which contain the 'unsafe
in positions which do not represent actual stored data, such as ::std::marker::PhantomData<&'unsafe ()>
and impl ::std::ops::Fn(&'unsafe ())
.
At runtime, the 'unsafe
lifetime is erased like any other. It only impacts what operations are considered unsafe
, not runtime semantics in any way.
What about Drop
?
Dropping types that include 'unsafe
is unsafe
. As such, any type that mentions 'unsafe
has its drop glue suppressed, and must be manually dropped[3].
Types which have multiple fields, only some of which mention 'unsafe
, have drop glue that drop all fields that do not mention 'unsafe
.
The one semiformal bit: Patching Stacked Borrows
is trivial[4]: don't ever retag or emit protectors for a reference with the 'unsafe
keyword lifetime.
Bonus
This is emulated today by lying (...kinda; 'static
is complicated) and using 'static
and just being really careful, especially about exposing that false 'static
to external code. 'unsafe
encodes existing practice and makes it, well... not safer, but more obvious the extent of the unsafe
. (Dis?)Honorable mention goes to yoke for making 'unsafe
properly safe. You might also know owning_ref and/or rental.
-
And drawbacks[2], like subobject slicing (still contentious) and shared XOR mutable! ↩︎
-
Drawbacks are just benefits to the compiler, not to you ↩︎
-
This gives us a way to define
ManuallyDrop
:(PhantomData<&'unsafe ()>, T)
. ↩︎ -
And if it isn't, this proposal should be rejected immediately. ↩︎