Struct rustc_ast_lowering::LoweringContext[][src]

pub(crate) struct LoweringContext<'a, 'hir: 'a> {
Show 26 fields pub(crate) sess: &'a Session, pub(crate) resolver: &'a mut dyn ResolverAstLowering, pub(crate) nt_to_tokenstream: NtToTokenstream, pub(crate) arena: &'hir Arena<'hir>, pub(crate) owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>, pub(crate) bodies: Vec<(ItemLocalId, &'hir Body<'hir>)>, pub(crate) attrs: SortedMap<ItemLocalId, &'hir [Attribute]>, pub(crate) generator_kind: Option<GeneratorKind>, pub(crate) task_context: Option<HirId>, pub(crate) current_item: Option<Span>, pub(crate) catch_scope: Option<NodeId>, pub(crate) loop_scope: Option<NodeId>, pub(crate) is_in_loop_condition: bool, pub(crate) is_in_trait_impl: bool, pub(crate) is_in_dyn_type: bool, pub(crate) anonymous_lifetime_mode: AnonymousLifetimeMode, pub(crate) lifetimes_to_define: Vec<(Span, ParamName)>, pub(crate) is_collecting_in_band_lifetimes: bool, pub(crate) in_scope_lifetimes: Vec<ParamName>, pub(crate) current_hir_id_owner: LocalDefId, pub(crate) item_local_id_counter: ItemLocalId, pub(crate) node_id_to_hir_id: IndexVec<NodeId, Option<HirId>>, pub(crate) local_node_ids: Vec<NodeId>, pub(crate) allow_try_trait: Option<Lrc<[Symbol]>>, pub(crate) allow_gen_future: Option<Lrc<[Symbol]>>, pub(crate) allow_into_future: Option<Lrc<[Symbol]>>,
}

Fields

sess: &'a Session

Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.

resolver: &'a mut dyn ResolverAstLoweringnt_to_tokenstream: NtToTokenstream

HACK(Centril): there is a cyclic dependency between the parser and lowering if we don’t have this function pointer. To avoid that dependency so that rustc_middle is independent of the parser, we use dynamic dispatch here.

arena: &'hir Arena<'hir>

Used to allocate HIR nodes.

owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>

The items being lowered are collected here.

bodies: Vec<(ItemLocalId, &'hir Body<'hir>)>

Bodies inside the owner being lowered.

attrs: SortedMap<ItemLocalId, &'hir [Attribute]>

Attributes inside the owner being lowered.

generator_kind: Option<GeneratorKind>task_context: Option<HirId>

When inside an async context, this is the HirId of the task_context local bound to the resume argument of the generator.

current_item: Option<Span>

Used to get the current fn’s def span to point to when using await outside of an async fn.

catch_scope: Option<NodeId>loop_scope: Option<NodeId>is_in_loop_condition: boolis_in_trait_impl: boolis_in_dyn_type: boolanonymous_lifetime_mode: AnonymousLifetimeMode

What to do when we encounter an “anonymous lifetime reference”. The term “anonymous” is meant to encompass both '_ lifetimes as well as fully elided cases where nothing is written at all (e.g., &T or std::cell::Ref<T>).

lifetimes_to_define: Vec<(Span, ParamName)>

Used to create lifetime definitions from in-band lifetime usages. e.g., fn foo(x: &'x u8) -> &'x u8 to fn foo<'x>(x: &'x u8) -> &'x u8 When a named lifetime is encountered in a function or impl header and has not been defined (i.e., it doesn’t appear in the in_scope_lifetimes list), it is added to this list. The results of this list are then added to the list of lifetime definitions in the corresponding impl or function generics.

is_collecting_in_band_lifetimes: bool

true if in-band lifetimes are being collected. This is used to indicate whether or not we’re in a place where new lifetimes will result in in-band lifetime definitions, such a function or an impl header, including implicit lifetimes from impl_header_lifetime_elision.

in_scope_lifetimes: Vec<ParamName>

Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB. When is_collecting_in_band_lifetimes is true, each lifetime is checked against this list to see if it is already in-scope, or if a definition needs to be created for it.

We always store a normalize_to_macros_2_0() version of the param-name in this vector.

current_hir_id_owner: LocalDefIditem_local_id_counter: ItemLocalIdnode_id_to_hir_id: IndexVec<NodeId, Option<HirId>>local_node_ids: Vec<NodeId>

NodeIds that are lowered inside the current HIR owner.

allow_try_trait: Option<Lrc<[Symbol]>>allow_gen_future: Option<Lrc<[Symbol]>>allow_into_future: Option<Lrc<[Symbol]>>

Implementations

Desugar try { <stmts>; <expr> } into { <stmts>; ::std::ops::Try::from_output(<expr>) }, try { <stmts>; } into { <stmts>; ::std::ops::Try::from_output(()) } and save the block id to use it as a break target for desugaring of the ? operator.

Lower an async construct to a generator that is then wrapped so it implements Future.

This results in:

std::future::from_generator(static move? |_task_context| -> <ret_ty> {
    <body>
})

Desugar <expr>.await into:

match ::std::future::IntoFuture::into_future(<expr>) {
    mut pinned => loop {
        match unsafe { ::std::future::Future::poll(
            <::std::pin::Pin>::new_unchecked(&mut pinned),
            ::std::future::get_context(task_context),
        ) } {
            ::std::task::Poll::Ready(result) => break result,
            ::std::task::Poll::Pending => {}
        }
        task_context = yield ();
    }
}

Destructure the LHS of complex assignments. For instance, lower (a, b) = t to { let (lhs1, lhs2) = t; a = lhs1; b = lhs2; }.

If the given expression is a path to a tuple struct, returns that path. It is not a complete check, but just tries to reject most paths early if they are not tuple structs. Type checking will take care of the full validation later.

Convert the LHS of a destructuring assignment to a pattern. Each sub-assignment is recorded in assignments.

Destructure a sequence of expressions occurring on the LHS of an assignment. Such a sequence occurs in a tuple (struct)/slice. Return a sequence of corresponding patterns, and the index and the span of .. if it exists. Each sub-assignment is recorded in assignments.

Desugar <start>..=<end> into std::ops::RangeInclusive::new(<start>, <end>).

Desugar ExprForLoop from: [opt_ident]: for <pat> in <head> <body> into:

{
    let result = match IntoIterator::into_iter(<head>) {
        mut iter => {
            [opt_ident]: loop {
                match Iterator::next(&mut iter) {
                    None => break,
                    Some(<pat>) => <body>,
                };
            }
        }
    };
    result
}

Desugar ExprKind::Try from: <expr>? into:

match Try::branch(<expr>) {
    ControlFlow::Continue(val) => #[allow(unreachable_code)] val,,
    ControlFlow::Break(residual) =>
        #[allow(unreachable_code)]
        // If there is an enclosing `try {...}`:
        break 'catch_target Try::from_residual(residual),
        // Otherwise:
        return Try::from_residual(residual),
}

Wrap the given expr in a terminating scope using hir::ExprKind::DropTemps.

In terms of drop order, it has the same effect as wrapping expr in { let _t = $expr; _t } but should provide better compile-time performance.

The drop order can be important in e.g. if expr { .. }.

Paths like the visibility path in pub(super) use foo::{bar, baz} are repeated many times in the HIR tree; for each occurrence, we need to assign distinct NodeIds. (See, e.g., #56128.)

Construct ExprKind::Err for the given span.

If an explicit_owner is given, this method allocates the HirId in the address space of that item instead of the item currently being lowered. This can happen during lower_impl_item_ref() where we need to lower a Visibility value although we haven’t lowered the owning ImplItem in question yet.

Lower a slice pattern of form [pat_0, ..., pat_n] into hir::PatKind::Slice(before, slice, after).

When encountering ($binding_mode $ident @)? .. (slice), this is interpreted as a sub-slice pattern semantically. Patterns that follow, which are not like slice – or an error occurs, are in after.

Construct a Pat with the HirId of p.id lowered.

Emit a friendly error for extra .. patterns in a tuple/tuple struct/slice pattern.

Used to ban the .. pattern in places it shouldn’t be semantically.

An associated type binding Output = $ty.

Compute the hash for the HIR of the full crate. This hash will then be part of the crate_hash which is stored in the metadata.

Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate queries which depend on the full HIR tree and those which only depend on the item signature.

This method allocates a new HirId for the given NodeId and stores it in the LoweringContext’s NodeId => HirId map. Take care not to call this method if the resulting HirId is then not actually used in the HIR, as that would trigger an assertion in the HirIdValidator later on, which makes sure that all NodeIds got mapped properly. Calling the method twice with the same NodeId is fine though.

Reuses the span but adds information like the kind of the desugaring and features that are allowed inside this span.

Intercept all spans entering HIR. Mark a span as relative to the current owning item.

Creates a new hir::GenericParam for every new lifetime and type parameter encountered while evaluating f. Definitions are created with the parent provided. If no parent_id is provided, no definitions will be returned.

Presuming that in-band lifetimes are enabled, then self.anonymous_lifetime_mode will be updated to match the parameter while f is running (and restored afterwards).

Converts a lifetime into a new generic parameter.

When there is a reference to some lifetime 'a, and in-band lifetimes are enabled, then we want to push that lifetime into the vector of names to define later. In that case, it will get added to the appropriate generics.

When we have either an elided or '_ lifetime in an impl header, we convert it to an in-band lifetime.

Appends in-band lifetime defs and argument-position impl Trait defs to the existing set of generics.

Presuming that in-band lifetimes are enabled, then self.anonymous_lifetime_mode will be updated to match the parameter while f is running (and restored afterwards).

Given an associated type constraint like one of these:

T: Iterator<Item: Debug>
            ^^^^^^^^^^^
T: Iterator<Item = Debug>
            ^^^^^^^^^^^^

returns a hir::TypeBinding representing Item.

Registers a new opaque type with the proper NodeIds and returns the lowered node-ID for the opaque type.

Transforms -> T into Future<Output = T>.

Lowers a block directly to an expression, presuming that it has no attributes and is not targeted by a break.

Invoked to create the lifetime argument for a type &T with no explicit lifetime.

Report an error on illegal use of '_ or a &T with no explicit lifetime; return an “error lifetime”.

Invoked to create the lifetime argument(s) for a path like std::cell::Ref<T>; note that implicit lifetimes in these sorts of cases are deprecated. This may therefore report a warning or an error, depending on the mode.

Invoked to create the lifetime argument(s) for an elided trait object bound, like the bound in Box<dyn Debug>. This method is not invoked when the bound is written, even if it is written with '_ like in Box<dyn Debug + '_>. In those cases, lower_lifetime is invoked.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

Layout

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference’s “Type Layout” chapter for details on type layout guarantees.

Size: 304 bytes