[This proposal is withdrawn.]
Summary:
Following the discussions about RFC PR 210, I propose that we introduce marker traits ScopedLt
and InferredLt
, instead of NoisyDrop
and QuietDrop
, and we implement a variant of RFC PR 210.
This does not strictly follow the RFC format.
Motivation:
I think we can have a more flexible and easier to understand variant of RFC PR 210.
“Detailed” Design:
ScopedLt
, “Scoped Lifetime”, is for types whose lifetimes we care about a lot. We must make sure that they are dropped/made unavailable exactly at certain places, and we want to clearly see the drop points. Often, that is because the drops have side effects.
InferredLt
, “Inferred Lifetime”, is for types whose lifetimes we don’t quite care about. They can be dropped/made unavailable as soon as possible, or at scope boundaries, or anywhere in-between, without changing program semantics. The only observable difference should be performance.
ScopedLt
object semantics:
When stored in local variables, or used as temporaries, their lifetimes are guaranteed by the compiler to be exactly as long as the enclosing scope dictates.
When owned by owning containers (Box, Vec, etc), they make the containers themselves to have ScopedLt
.
When owned by structs/enum variants, the structs/enums would have ScopedLt
, even when other members have InferredLt
.
They cannot be pointed to by Rc/Arc/Gc.
(We care too much about their lifetimes to allow them to be put into Rc/Arc/Gc.)
InferredLt
object semantics:
When stored in local variables, or used as temporaries, their lifetime are guaranteed by the compiler to be at most as long as the enclosing scope dictates.
When owned by owning containers, they make the containers themselves to have InferredLt
.
Struct/enums would have InferredLt
iff. all their fields have InferredLt
.
When pointed to by Rc/Arc/Gc, their lifetimes are “dynamically inferred” following Rc/Arc/Gc’s semantics.
Rc/Arc/Gc pointers themselves have InferredLt
.
Note: ScopedLt
and InferredLt
don’t require the type to have Drop
. Every type in Rust will have either ScopedLt
or InferredLt
.
Variation to RFC PR 210:
In my variant of RFC PR 210, when the compiler determines that it cannot fulfill the drop obligations with “explicit scope boundary drops”, it can insert implicit drops when the offenders are InferredLt
objects, but must report compile errors for ScopedLt
objects.
And in a function with unsafe blocks, all objects are considered to have scoped lifetimes, because the compiler almost cannot make any guarantee about what the unsafe code would do. That means the programmer must deal with drop obligation unfulfillment completely manually there.
Lifetime Pinning:
A#[lifetime(scoped)]
attribute can be used to “pin” InferredLt
objects to the scoped lifetimes, on a per-object/function/module/crate basis. (Is this possible?)
A #[lifetime(inferred)]
attribute does the opposite to ScopedLt
objects. (Hope I know what I am proposing.)
Advantages:
-
Generalizes the
NoisyDrop
/QuietDrop
concepts to non-Drop
objects, and make it possible to unify lifetime handling of references and non-reference objects in the future. (We are implementing non-lexical reference lifetimes now, right?) -
With the guarantees that the compiler makes for
InferredLt
objects, it is possible to support very aggressive early dropping behavior (maybe as an optional optimization, allInferredLt
objects get dropped ASAP), or revert to “out-of-band drop flags” easily in the future. -
I think
ScopedLt
/InferredLt
names are more “direct” and “objective” thanNoisyDrop
/QuietDrop
. -
We issue compile errors.
Why do we want an early drop of NoisyDrop
objects to be “noisy”? Because we think that this early drop may have unexpected behavior, and making it happen at scope boundary can make the intention clear.
If so, why don’t we force the programmer to do it, instead of just a warning?
I suspect there are not many types that should have NoisyDrop
/ScopedLt
after all. But I may well be wrong.
Drawbacks:
We issue compile errors.
Alternatives:
- Go with RFC PR 210 unaltered (but the part about
unsafe
should still be considered). - Use the new names (
ScopedLt
forNoisyDrop
,InferredLt
forQuietDrop
), andunsafe
treatments, but otherwise go with RFC PR 210.
Note:
If this get accepted, I hope the design would be merged into RFC PR 210.
EDIT: Grammar and clarification.