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

Binder

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: u32

if we extend this scope with another scope, what is the next index we should use for an early-bound region?

track_lifetime_uses: bool

Flag 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: bool

Whether 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: bool

True 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: HirId

The 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>
Body

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).

Fields of Body

id: BodyIds: &'a Scope<'a>
Elision

A scope which either determines unspecified lifetimes or errors on them (e.g., due to ambiguity). For more details, see Elide.

Fields of Elision

elide: Elides: &'a Scope<'a>
ObjectLifetimeDefault

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.

Fields of ObjectLifetimeDefault

lifetime: Option<Region>s: &'a Scope<'a>
TraitRefHackInner

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:

  1. for<'a, 'b> T: U<'a, 'b>
  2. T: for<'a, 'b> U<'a, 'b>
  3. 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.

Fields of TraitRefHackInner

hir_id: HirIds: &'a Scope<'a>
Supertrait

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>
TraitRefBoundary

Fields of TraitRefBoundary

s: &'a Scope<'a>
Root

Trait Implementations

impl<'a> Debug for Scope<'a>[src]

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]

impl<T> Borrow<T> for T where
    T: ?Sized, 
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized, 
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.