Enum rustc_resolve::late::lifetimes::Scope [−][src]
enum Scope<'a> {
Binder {
lifetimes: FxHashMap<ParamName, Region>,
next_early_index: u32,
track_lifetime_uses: bool,
opaque_type_parent: bool,
from_poly_trait_ref: bool,
hir_id: HirId,
s: &'a Scope<'a>,
},
Body {
id: BodyId,
s: &'a Scope<'a>,
},
Elision {
elide: Elide,
s: &'a Scope<'a>,
},
ObjectLifetimeDefault {
lifetime: Option<Region>,
s: &'a Scope<'a>,
},
TraitRefHackInner {
hir_id: HirId,
s: &'a Scope<'a>,
},
Supertrait {
lifetimes: Vec<BoundVariableKind>,
s: &'a Scope<'a>,
},
TraitRefBoundary {
s: &'a Scope<'a>,
},
Root,
}Variants
Declares lifetimes, and each can be early-bound or late-bound.
The DebruijnIndex of late-bound lifetimes starts at 1 and
it should be shifted by the number of Binders in between the
declaration Binder and the location it’s referenced from.
Fields of Binder
lifetimes: FxHashMap<ParamName, Region>next_early_index: u32if we extend this scope with another scope, what is the next index we should use for an early-bound region?
track_lifetime_uses: boolFlag is set to true if, in this binder, '_ would be
equivalent to a “single-use region”. This is true on
impls, but not other kinds of items.
opaque_type_parent: boolWhether or not this binder would serve as the parent binder for opaque types introduced within. For example:
fn foo<'a>() -> impl for<'b> Trait<Item = impl Trait2<'a>>
Here, the opaque types we create for the impl Trait
and impl Trait2 references will both have the foo item
as their parent. When we get to impl Trait2, we find
that it is nested within the for<> binder – this flag
allows us to skip that when looking for the parent binder
of the resulting opaque type.
from_poly_trait_ref: boolTrue only if this Binder scope is from the quantifiers on a
PolyTraitRef. This is necessary for assocated_type_bounds, which
requires binders of nested trait refs to be merged.
hir_id: HirIdThe late bound vars for a given item are stored by HirId to be
queried later. However, if we enter an elision scope, we have to
later append the elided bound vars to the list and need to know what
to append to.
s: &'a Scope<'a>Lifetimes introduced by a fn are scoped to the call-site for that fn,
if this is a fn body, otherwise the original definitions are used.
Unspecified lifetimes are inferred, unless an elision scope is nested,
e.g., (&T, fn(&T) -> &T); becomes (&'_ T, for<'a> fn(&'a T) -> &'a T).
A scope which either determines unspecified lifetimes or errors
on them (e.g., due to ambiguity). For more details, see Elide.
Use a specific lifetime (if Some) or leave it unset (to be
inferred in a function body or potentially error outside one),
for the default choice of lifetime in a trait object type.
This is a particularly interesting consequence of how we handle poly
trait refs. See trait_ref_hack for additional info. This bit is
important w.r.t. querying late-bound vars.
To completely understand why this is necessary, first it’s important to
realize that T: for<'a> U + for<'a, 'b> V is actually two separate
trait refs: T: for<'a> U and T: for<'b> V and as such, the late
bound vars on each needs to be tracked separately. Also, in this case,
are three relevant HirIds: one for the entire bound and one
for each separate one.
Next, imagine three different poly trait refs:
for<'a, 'b> T: U<'a, 'b>T: for<'a, 'b> U<'a, 'b>for<'a> T: for<'b> U<'a, 'b>
First, note that the third example is semantically invalid and an error,
but we must handle it as valid, since type checking isn’t bailed out
of. Other than that, if ask for bound vars for each, we expect
['a, 'b]. If we didn’t allow binders before T, then we would
always introduce a binder scope at the inner trait ref. This is great,
becauase later on during type-checking, we will ask “what are the late
bound vars on this trait ref”. However, because we allow bound vars on
the bound itself, we have to have some way of keeping track of the fact
that we actually want to store the late bound vars as being associated
with the trait ref; this is that.
One alternative way to handle this would be to just introduce a new
Binder scope, but that’s semantically a bit different, since bound
vars from both for<...>s do share the same binder level.
When we have nested trait refs, we concanetate late bound vars for inner trait refs from outer ones. But we also need to include any HRTB lifetimes encountered when identifying the trait that an associated type is declared on.
Fields of Supertrait
lifetimes: Vec<BoundVariableKind>s: &'a Scope<'a>Fields of TraitRefBoundary
s: &'a Scope<'a>Trait Implementations
Auto Trait Implementations
impl<'a> !RefUnwindSafe for Scope<'a>
impl<'a> !Send for Scope<'a>
impl<'a> !Sync for Scope<'a>
impl<'a> Unpin for Scope<'a>
impl<'a> !UnwindSafe for Scope<'a>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized, [src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized, [src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized, [src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T[src]
impl<T> From<T> for T[src]
impl<T, U> Into<U> for T where
U: From<T>, [src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>, [src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>, [src]
U: TryFrom<T>,