Motivation
In the course of writing unsafe code, the need can sometimes arise to store a value with an unknowable or inexpressible lifetime. In such cases, the value is insulated from the outside world and exposed through a safe interface. This is all well and good, but we must still hold the value internally somehow, and if it demands lifetime parameters, we must provide them.
In many such cases, it may suffice to simply use 'static
as a surrogate lifetime and coerce the value as appropriate. This approach is workable, but has two major problems.
-
First, the intent is unclear and must be expressed as a comment. The claim that the value is valid for
'static
is a lie and one must keep in mind what the actual true lifetime is. Later audits of the code may overlook this detail and accidentally misuse the value. -
Second,
'static
is not flexible enough. While in many cases it will work,'static
has meaningful semantic implications of its own and cannot act as a stand-in for any possible lifetime. Case in point:
Ref<'static, i32> // This is acceptable to the compiler
Ref<'static, MyType<'a>> // This is not
In the second case, we’re forced to provide a stand-in lifetime that meets the requirements imposed by the signature of Ref
, but doing so may not be possible without exposing an additional, meaningless input parameter.
A Solution
In cases such as this, what we could really use is a lifetime that’s more general than 'static
, and more clearly indicates our intent. For this purpose I propose 'unsafe
. This lifetime would satisfy any constraint, with the caveat that it can only be instantiated within an unsafe
context. “Instantiated” is key, in that after creation, it can be freely consumed as any other lifetime, without unsafe qualifications. This is important for parametricity.
The semantics of 'unsafe
would be akin to the semantics described for “unbounded lifetimes” in the nomicon; this merely allows such a lifetime to be named and used in other contexts.
Alternatives
- Do nothing. In some cases,
'static
still suffices as a stand-in, and in others, the problem can be worked around by introducing a new lifetime parameter. This additional parameter, however, leaks out to externally facing API and is difficult to explain to users.
Unanswered Questions
- How many use cases are there for this. rental is one, are there more?
- What are the implications of implementing this? Is the notion reconcilable with borrowck?
- Does this cause unintended “spooky action at a distance” if an
'unsafe
value is allowed to mingle with external, otherwise safe code?