1//! Lowers the AST to the HIR.2//!3//! Since the AST and HIR are fairly similar, this is mostly a simple procedure,4//! much like a fold. Where lowering involves a bit more work things get more5//! interesting and there are some invariants you should know about. These mostly6//! concern spans and IDs.7//!8//! Spans are assigned to AST nodes during parsing and then are modified during9//! expansion to indicate the origin of a node and the process it went through10//! being expanded. IDs are assigned to AST nodes just before lowering.11//!12//! For the simpler lowering steps, IDs and spans should be preserved. Unlike13//! expansion we do not preserve the process of lowering in the spans, so spans14//! should not be modified here. When creating a new node (as opposed to15//! "folding" an existing one), create a new ID using `next_id()`.16//!17//! You must ensure that IDs are unique. That means that you should only use the18//! ID from an AST node in a single HIR node (you can assume that AST node-IDs19//! are unique). Every new node must have a unique ID. Avoid cloning HIR nodes.20//! If you do, you must then set the new node's ID to a fresh one.21//!22//! Spans are used for error messages and for tools to map semantics back to23//! source code. It is therefore not as important with spans as IDs to be strict24//! about use (you can't break the compiler by screwing up a span). Obviously, a25//! HIR node can only have a single span. But multiple nodes can have the same26//! span and spans don't need to be kept in order, etc. Where code is preserved27//! by lowering, it should have the same span as in the AST. Where HIR nodes are28//! new it is probably best to give a span for the whole AST node being lowered.29//! All nodes should have real spans; don't use dummy spans. Tools are likely to30//! get confused if the spans from leaf AST nodes occur in multiple places31//! in the HIR, especially for multiple identifiers.3233// tidy-alphabetical-start34#![feature(box_patterns)]35#![recursion_limit = "256"]36// tidy-alphabetical-end3738use std::mem;39use std::sync::Arc;4041use rustc_ast::node_id::NodeMap;42use rustc_ast::visit::Visitor;43use rustc_ast::{self as ast, *};44use rustc_attr_parsing::{AttributeParser, OmitDoc, Recovery, ShouldEmit};45use rustc_data_structures::fingerprint::Fingerprint;46use rustc_data_structures::fx::FxIndexSet;47use rustc_data_structures::sorted_map::SortedMap;48use rustc_data_structures::stable_hasher::{StableHash, StableHasher};49use rustc_data_structures::steal::Steal;50use rustc_data_structures::tagged_ptr::TaggedRef;51use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle};52use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};53use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE, LocalDefId};54use rustc_hir::definitions::PerParentDisambiguatorState;55use rustc_hir::lints::DelayedLint;56use rustc_hir::{57 self as hir, AngleBrackets, ConstArg, GenericArg, HirId, ItemLocalMap, LifetimeSource,58 LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr,59};60use rustc_index::{Idx, IndexSlice, IndexVec};61use rustc_macros::extension;62use rustc_middle::hir::{self as mid_hir};63use rustc_middle::span_bug;64use rustc_middle::ty::{DelegationInfo, ResolverAstLowering, TyCtxt};65use rustc_session::errors::add_feature_diagnostics;66use rustc_span::symbol::{Ident, Symbol, kw, sym};67use rustc_span::{DUMMY_SP, DesugaringKind, Span};68use smallvec::SmallVec;69use thin_vec::ThinVec;70use tracing::{debug, instrument, trace};7172use crate::errors::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait};73use crate::item::Owners;7475macro_rules! arena_vec {76 ($this:expr; $($x:expr),*) => (77 $this.arena.alloc_from_iter([$($x),*])78 );79}8081mod asm;82mod block;83mod contract;84mod delegation;85mod errors;86mod expr;87mod format;88mod index;89mod item;90mod pat;91mod path;92pub mod stability;9394struct LoweringContext<'a, 'hir> {95 tcx: TyCtxt<'hir>,96 resolver: &'a ResolverAstLowering<'hir>,97 current_disambiguator: PerParentDisambiguatorState,9899 /// Used to allocate HIR nodes.100 arena: &'hir hir::Arena<'hir>,101102 /// Bodies inside the owner being lowered.103 bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,104 /// `#[define_opaque]` attributes105 define_opaque: Option<&'hir [(Span, LocalDefId)]>,106 /// Attributes inside the owner being lowered.107 attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,108 /// Collect items that were created by lowering the current owner.109 children: Vec<(LocalDefId, hir::MaybeOwner<'hir>)>,110111 contract_ensures: Option<(Span, Ident, HirId)>,112113 coroutine_kind: Option<hir::CoroutineKind>,114115 /// When inside an `async` context, this is the `HirId` of the116 /// `task_context` local bound to the resume argument of the coroutine.117 task_context: Option<HirId>,118119 /// Used to get the current `fn`'s def span to point to when using `await`120 /// outside of an `async fn`.121 current_item: Option<Span>,122123 try_block_scope: TryBlockScope,124 loop_scope: Option<HirId>,125 is_in_loop_condition: bool,126 is_in_dyn_type: bool,127128 current_hir_id_owner: hir::OwnerId,129 item_local_id_counter: hir::ItemLocalId,130 trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>,131132 impl_trait_defs: Vec<hir::GenericParam<'hir>>,133 impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,134135 /// NodeIds of pattern identifiers and labelled nodes that are lowered inside the current HIR owner.136 ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,137 /// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering check.138 #[cfg(debug_assertions)]139 node_id_to_local_id: NodeMap<hir::ItemLocalId>,140 /// The `NodeId` space is split in two.141 /// `0..resolver.next_node_id` are created by the resolver on the AST.142 /// The higher part `resolver.next_node_id..next_node_id` are created during lowering.143 next_node_id: NodeId,144 /// Maps the `NodeId`s created during lowering to `LocalDefId`s.145 node_id_to_def_id: NodeMap<LocalDefId>,146 /// Overlay over resolver's `partial_res_map` used by delegation.147 /// This only contains `PartialRes::new(Res::Local(self_param_id))`,148 /// so we only store `self_param_id`.149 partial_res_overrides: NodeMap<NodeId>,150151 allow_contracts: Arc<[Symbol]>,152 allow_try_trait: Arc<[Symbol]>,153 allow_gen_future: Arc<[Symbol]>,154 allow_pattern_type: Arc<[Symbol]>,155 allow_async_gen: Arc<[Symbol]>,156 allow_async_iterator: Arc<[Symbol]>,157 allow_for_await: Arc<[Symbol]>,158 allow_async_fn_traits: Arc<[Symbol]>,159160 delayed_lints: Vec<DelayedLint>,161162 attribute_parser: AttributeParser<'hir>,163}164165impl<'a, 'hir> LoweringContext<'a, 'hir> {166 fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>) -> Self {167 Self {168 tcx,169 resolver,170 current_disambiguator: Default::default(),171 arena: tcx.hir_arena,172173 // HirId handling.174 bodies: Vec::new(),175 define_opaque: None,176 attrs: SortedMap::default(),177 children: Vec::default(),178 contract_ensures: None,179 current_hir_id_owner: hir::CRATE_OWNER_ID,180 item_local_id_counter: hir::ItemLocalId::ZERO,181 ident_and_label_to_local_id: Default::default(),182 #[cfg(debug_assertions)]183 node_id_to_local_id: Default::default(),184 trait_map: Default::default(),185 next_node_id: resolver.next_node_id,186 node_id_to_def_id: NodeMap::default(),187 partial_res_overrides: NodeMap::default(),188189 // Lowering state.190 try_block_scope: TryBlockScope::Function,191 loop_scope: None,192 is_in_loop_condition: false,193 is_in_dyn_type: false,194 coroutine_kind: None,195 task_context: None,196 current_item: None,197 impl_trait_defs: Vec::new(),198 impl_trait_bounds: Vec::new(),199 allow_contracts: [sym::contracts_internals].into(),200 allow_try_trait: [201 sym::try_trait_v2,202 sym::try_trait_v2_residual,203 sym::yeet_desugar_details,204 ]205 .into(),206 allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),207 allow_gen_future: if tcx.features().async_fn_track_caller() {208 [sym::gen_future, sym::closure_track_caller].into()209 } else {210 [sym::gen_future].into()211 },212 allow_for_await: [sym::async_gen_internals, sym::async_iterator].into(),213 allow_async_fn_traits: [sym::async_fn_traits].into(),214 allow_async_gen: [sym::async_gen_internals].into(),215 // FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller`216 // interact with `gen`/`async gen` blocks217 allow_async_iterator: [sym::gen_future, sym::async_iterator].into(),218219 attribute_parser: AttributeParser::new(220 tcx.sess,221 tcx.features(),222 tcx.registered_tools(()),223 ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed },224 ),225 delayed_lints: Vec::new(),226 }227 }228229 pub(crate) fn dcx(&self) -> DiagCtxtHandle<'hir> {230 self.tcx.dcx()231 }232}233234struct SpanLowerer {235 is_incremental: bool,236 def_id: LocalDefId,237}238239impl SpanLowerer {240 fn lower(&self, span: Span) -> Span {241 if self.is_incremental {242 span.with_parent(Some(self.def_id))243 } else {244 // Do not make spans relative when not using incremental compilation.245 span246 }247 }248}249250#[extension(trait ResolverAstLoweringExt<'tcx>)]251impl<'tcx> ResolverAstLowering<'tcx> {252 fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'tcx>) -> Option<Vec<usize>> {253 let ExprKind::Path(None, path) = &expr.kind else {254 return None;255 };256257 // Don't perform legacy const generics rewriting if the path already258 // has generic arguments.259 if path.segments.last().unwrap().args.is_some() {260 return None;261 }262263 // We do not need to look at `partial_res_overrides`. That map only contains overrides for264 // `self_param` locals. And here we are looking for the function definition that `expr`265 // resolves to.266 let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?;267268 // We only support cross-crate argument rewriting. Uses269 // within the same crate should be updated to use the new270 // const generics style.271 if def_id.is_local() {272 return None;273 }274275 // we can use parsed attrs here since for other crates they're already available276 find_attr!(277 tcx, def_id,278 RustcLegacyConstGenerics{fn_indexes,..} => fn_indexes279 )280 .map(|fn_indexes| fn_indexes.iter().map(|(num, _)| *num).collect())281 }282283 /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.284 fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>> {285 self.import_res_map.get(&id).copied().unwrap_or_default()286 }287288 /// Obtains resolution for a label with the given `NodeId`.289 fn get_label_res(&self, id: NodeId) -> Option<NodeId> {290 self.label_res_map.get(&id).copied()291 }292293 /// Obtains resolution for a lifetime with the given `NodeId`.294 fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes> {295 self.lifetimes_res_map.get(&id).copied()296 }297298 /// Obtain the list of lifetimes parameters to add to an item.299 ///300 /// Extra lifetime parameters should only be added in places that can appear301 /// as a `binder` in `LifetimeRes`.302 ///303 /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring304 /// should appear at the enclosing `PolyTraitRef`.305 fn extra_lifetime_params(&self, id: NodeId) -> &[(Ident, NodeId, LifetimeRes)] {306 self.extra_lifetime_params_map.get(&id).map_or(&[], |v| &v[..])307 }308309 fn delegation_info(&self, id: LocalDefId) -> Option<&DelegationInfo> {310 self.delegation_infos.get(&id)311 }312313 fn opt_local_def_id(&self, id: NodeId) -> Option<LocalDefId> {314 self.node_id_to_def_id.get(&id).copied()315 }316317 fn local_def_id(&self, id: NodeId) -> LocalDefId {318 self.opt_local_def_id(id).expect("must have def_id")319 }320321 fn lifetime_elision_allowed(&self, id: NodeId) -> bool {322 self.lifetime_elision_allowed.contains(&id)323 }324}325326/// How relaxed bounds `?Trait` should be treated.327///328/// Relaxed bounds should only be allowed in places where we later329/// (namely during HIR ty lowering) perform *sized elaboration*.330#[derive(Clone, Copy, Debug)]331enum RelaxedBoundPolicy<'a> {332 Allowed,333 AllowedIfOnTyParam(NodeId, &'a [ast::GenericParam]),334 Forbidden(RelaxedBoundForbiddenReason),335}336337#[derive(Clone, Copy, Debug)]338enum RelaxedBoundForbiddenReason {339 TraitObjectTy,340 SuperTrait,341 TraitAlias,342 AssocTyBounds,343 LateBoundVarsInScope,344}345346/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,347/// and if so, what meaning it has.348#[derive(Debug, Copy, Clone, PartialEq, Eq)]349enum ImplTraitContext {350 /// Treat `impl Trait` as shorthand for a new universal generic parameter.351 /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually352 /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.353 ///354 /// Newly generated parameters should be inserted into the given `Vec`.355 Universal,356357 /// Treat `impl Trait` as shorthand for a new opaque type.358 /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually359 /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.360 ///361 OpaqueTy { origin: hir::OpaqueTyOrigin<LocalDefId> },362363 /// Treat `impl Trait` as a "trait ascription", which is like a type364 /// variable but that also enforces that a set of trait goals hold.365 ///366 /// This is useful to guide inference for unnameable types.367 InBinding,368369 /// `impl Trait` is unstably accepted in this position.370 FeatureGated(ImplTraitPosition, Symbol),371 /// `impl Trait` is not accepted in this position.372 Disallowed(ImplTraitPosition),373}374375/// Position in which `impl Trait` is disallowed.376#[derive(Debug, Copy, Clone, PartialEq, Eq)]377enum ImplTraitPosition {378 Path,379 Variable,380 Trait,381 Bound,382 Generic,383 ExternFnParam,384 ClosureParam,385 PointerParam,386 FnTraitParam,387 ExternFnReturn,388 ClosureReturn,389 PointerReturn,390 FnTraitReturn,391 GenericDefault,392 ConstTy,393 StaticTy,394 AssocTy,395 FieldTy,396 Cast,397 ImplSelf,398 OffsetOf,399}400401impl std::fmt::Display for ImplTraitPosition {402 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {403 let name = match self {404 ImplTraitPosition::Path => "paths",405 ImplTraitPosition::Variable => "the type of variable bindings",406 ImplTraitPosition::Trait => "traits",407 ImplTraitPosition::Bound => "bounds",408 ImplTraitPosition::Generic => "generics",409 ImplTraitPosition::ExternFnParam => "`extern fn` parameters",410 ImplTraitPosition::ClosureParam => "closure parameters",411 ImplTraitPosition::PointerParam => "`fn` pointer parameters",412 ImplTraitPosition::FnTraitParam => "the parameters of `Fn` trait bounds",413 ImplTraitPosition::ExternFnReturn => "`extern fn` return types",414 ImplTraitPosition::ClosureReturn => "closure return types",415 ImplTraitPosition::PointerReturn => "`fn` pointer return types",416 ImplTraitPosition::FnTraitReturn => "the return type of `Fn` trait bounds",417 ImplTraitPosition::GenericDefault => "generic parameter defaults",418 ImplTraitPosition::ConstTy => "const types",419 ImplTraitPosition::StaticTy => "static types",420 ImplTraitPosition::AssocTy => "associated types",421 ImplTraitPosition::FieldTy => "field types",422 ImplTraitPosition::Cast => "cast expression types",423 ImplTraitPosition::ImplSelf => "impl headers",424 ImplTraitPosition::OffsetOf => "`offset_of!` parameters",425 };426427 write!(f, "{name}")428 }429}430431#[derive(Copy, Clone, Debug, PartialEq, Eq)]432enum FnDeclKind {433 Fn,434 Inherent,435 ExternFn,436 Closure,437 Pointer,438 Trait,439 Impl,440}441442#[derive(Copy, Clone)]443enum AstOwner<'a> {444 NonOwner,445 Crate(&'a ast::Crate),446 Item(&'a ast::Item),447 AssocItem(&'a ast::AssocItem, visit::AssocCtxt),448 ForeignItem(&'a ast::ForeignItem),449}450451#[derive(Copy, Clone, Debug)]452enum TryBlockScope {453 /// There isn't a `try` block, so a `?` will use `return`.454 Function,455 /// We're inside a `try { … }` block, so a `?` will block-break456 /// from that block using a type depending only on the argument.457 Homogeneous(HirId),458 /// We're inside a `try as _ { … }` block, so a `?` will block-break459 /// from that block using the type specified.460 Heterogeneous(HirId),461}462463fn index_crate<'a, 'b>(464 resolver: &'b ResolverAstLowering<'b>,465 krate: &'a Crate,466) -> IndexVec<LocalDefId, AstOwner<'a>> {467 let mut indexer = Indexer { resolver, index: IndexVec::new() };468 *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) =469 AstOwner::Crate(krate);470 visit::walk_crate(&mut indexer, krate);471472 return indexer.index;473474 struct Indexer<'a, 'b> {475 resolver: &'b ResolverAstLowering<'b>,476 index: IndexVec<LocalDefId, AstOwner<'a>>,477 }478479 impl<'a, 'b> visit::Visitor<'a> for Indexer<'a, 'b> {480 fn visit_attribute(&mut self, _: &'a Attribute) {481 // We do not want to lower expressions that appear in attributes,482 // as they are not accessible to the rest of the HIR.483 }484485 fn visit_item(&mut self, item: &'a ast::Item) {486 let def_id = self.resolver.local_def_id(item.id);487 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item);488 visit::walk_item(self, item)489 }490491 fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {492 let def_id = self.resolver.local_def_id(item.id);493 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =494 AstOwner::AssocItem(item, ctxt);495 visit::walk_assoc_item(self, item, ctxt);496 }497498 fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {499 let def_id = self.resolver.local_def_id(item.id);500 *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) =501 AstOwner::ForeignItem(item);502 visit::walk_item(self, item);503 }504 }505}506507/// Compute the hash for the HIR of the full crate.508/// This hash will then be part of the crate_hash which is stored in the metadata.509fn compute_hir_hash(510 tcx: TyCtxt<'_>,511 owners: &IndexSlice<LocalDefId, hir::MaybeOwner<'_>>,512) -> Fingerprint {513 let mut hir_body_nodes: Vec<_> = owners514 .iter_enumerated()515 .filter_map(|(def_id, info)| {516 let info = info.as_owner()?;517 let def_path_hash = tcx.hir_def_path_hash(def_id);518 Some((def_path_hash, info))519 })520 .collect();521 hir_body_nodes.sort_unstable_by_key(|bn| bn.0);522523 tcx.with_stable_hashing_context(|mut hcx| {524 let mut stable_hasher = StableHasher::new();525 hir_body_nodes.stable_hash(&mut hcx, &mut stable_hasher);526 stable_hasher.finish()527 })528}529530pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {531 // Queries that borrow `resolver_for_lowering`.532 tcx.ensure_done().output_filenames(());533 tcx.ensure_done().early_lint_checks(());534 tcx.ensure_done().debugger_visualizers(LOCAL_CRATE);535 tcx.ensure_done().get_lang_items(());536 let (resolver, krate) = tcx.resolver_for_lowering().steal();537538 let ast_index = index_crate(&resolver, &krate);539 let mut owners = IndexVec::from_fn_n(540 |_| hir::MaybeOwner::Phantom,541 tcx.definitions_untracked().def_index_count(),542 );543544 let mut lowerer = item::ItemLowerer {545 tcx,546 resolver: &resolver,547 ast_index: &ast_index,548 owners: Owners::IndexVec(&mut owners),549 };550551 let mut delayed_ids: FxIndexSet<LocalDefId> = Default::default();552553 for def_id in ast_index.indices() {554 match &ast_index[def_id] {555 AstOwner::Item(Item { kind: ItemKind::Delegation { .. }, .. })556 | AstOwner::AssocItem(Item { kind: AssocItemKind::Delegation { .. }, .. }, _) => {557 delayed_ids.insert(def_id);558 }559 _ => lowerer.lower_node(def_id),560 };561 }562563 // Don't hash unless necessary, because it's expensive.564 let opt_hir_hash =565 if tcx.needs_hir_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };566567 let delayed_resolver = Steal::new((resolver, krate));568 mid_hir::Crate::new(owners, delayed_ids, delayed_resolver, opt_hir_hash)569}570571/// Lowers an AST owner corresponding to `def_id`, now only delegations are lowered this way.572pub fn lower_delayed_owner(tcx: TyCtxt<'_>, def_id: LocalDefId) {573 let krate = tcx.hir_crate(());574575 let (resolver, krate) = &*krate.delayed_resolver.borrow();576577 // FIXME!!!(fn_delegation): make ast index lifetime same as resolver,578 // as it is too bad to reindex whole crate on each delegation lowering.579 let ast_index = index_crate(resolver, krate);580581 let mut map = Default::default();582 let mut lowerer = item::ItemLowerer {583 tcx,584 resolver: &resolver,585 ast_index: &ast_index,586 owners: Owners::Map(&mut map),587 };588589 lowerer.lower_node(def_id);590591 for (child_def_id, owner) in map {592 tcx.feed_delayed_owner(child_def_id, owner);593 }594}595596#[derive(Copy, Clone, PartialEq, Debug)]597enum ParamMode {598 /// Any path in a type context.599 Explicit,600 /// The `module::Type` in `module::Type::method` in an expression.601 Optional,602}603604#[derive(Copy, Clone, Debug)]605enum AllowReturnTypeNotation {606 /// Only in types, since RTN is denied later during HIR lowering.607 Yes,608 /// All other positions (path expr, method, use tree).609 No,610}611612enum GenericArgsMode {613 /// Allow paren sugar, don't allow RTN.614 ParenSugar,615 /// Allow RTN, don't allow paren sugar.616 ReturnTypeNotation,617 // Error if parenthesized generics or RTN are encountered.618 Err,619 /// Silence errors when lowering generics. Only used with `Res::Err`.620 Silence,621}622623impl<'hir> LoweringContext<'_, 'hir> {624 fn create_def(625 &mut self,626 node_id: NodeId,627 name: Option<Symbol>,628 def_kind: DefKind,629 span: Span,630 ) -> LocalDefId {631 let parent = self.current_hir_id_owner.def_id;632 assert_ne!(node_id, ast::DUMMY_NODE_ID);633 assert!(634 self.opt_local_def_id(node_id).is_none(),635 "adding a def'n for node-id {:?} and def kind {:?} but a previous def'n exists: {:?}",636 node_id,637 def_kind,638 self.tcx.hir_def_key(self.local_def_id(node_id)),639 );640641 let def_id = self642 .tcx643 .at(span)644 .create_def(parent, name, def_kind, None, &mut self.current_disambiguator)645 .def_id();646647 debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);648 self.node_id_to_def_id.insert(node_id, def_id);649650 def_id651 }652653 fn next_node_id(&mut self) -> NodeId {654 let start = self.next_node_id;655 let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");656 self.next_node_id = NodeId::from_u32(next);657 start658 }659660 /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name661 /// resolver (if any).662 fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {663 self.node_id_to_def_id664 .get(&node)665 .or_else(|| self.resolver.node_id_to_def_id.get(&node))666 .copied()667 }668669 fn local_def_id(&self, node: NodeId) -> LocalDefId {670 self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))671 }672673 fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {674 match self.partial_res_overrides.get(&id) {675 Some(self_param_id) => Some(PartialRes::new(Res::Local(*self_param_id))),676 None => self.resolver.partial_res_map.get(&id).copied(),677 }678 }679680 /// Given the id of an owner node in the AST, returns the corresponding `OwnerId`.681 fn owner_id(&self, node: NodeId) -> hir::OwnerId {682 hir::OwnerId { def_id: self.local_def_id(node) }683 }684685 /// Freshen the `LoweringContext` and ready it to lower a nested item.686 /// The lowered item is registered into `self.children`.687 ///688 /// This function sets up `HirId` lowering infrastructure,689 /// and stashes the shared mutable state to avoid pollution by the closure.690 #[instrument(level = "debug", skip(self, f))]691 fn with_hir_id_owner(692 &mut self,693 owner: NodeId,694 f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,695 ) {696 let owner_id = self.owner_id(owner);697 let def_id = owner_id.def_id;698699 let new_disambig = self700 .resolver701 .disambiguators702 .get(&def_id)703 .map(|s| s.steal())704 .unwrap_or_else(|| PerParentDisambiguatorState::new(def_id));705706 let disambiguator = std::mem::replace(&mut self.current_disambiguator, new_disambig);707 let current_attrs = std::mem::take(&mut self.attrs);708 let current_bodies = std::mem::take(&mut self.bodies);709 let current_define_opaque = std::mem::take(&mut self.define_opaque);710 let current_ident_and_label_to_local_id =711 std::mem::take(&mut self.ident_and_label_to_local_id);712713 #[cfg(debug_assertions)]714 let current_node_id_to_local_id = std::mem::take(&mut self.node_id_to_local_id);715 let current_trait_map = std::mem::take(&mut self.trait_map);716 let current_owner = std::mem::replace(&mut self.current_hir_id_owner, owner_id);717 let current_local_counter =718 std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));719 let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);720 let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);721 let current_delayed_lints = std::mem::take(&mut self.delayed_lints);722723 // Do not reset `next_node_id` and `node_id_to_def_id`:724 // we want `f` to be able to refer to the `LocalDefId`s that the caller created.725 // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.726727 // Always allocate the first `HirId` for the owner itself.728 #[cfg(debug_assertions)]729 {730 let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO);731 debug_assert_eq!(_old, None);732 }733734 let item = f(self);735 assert_eq!(owner_id, item.def_id());736 // `f` should have consumed all the elements in these vectors when constructing `item`.737 assert!(self.impl_trait_defs.is_empty());738 assert!(self.impl_trait_bounds.is_empty());739 let info = self.make_owner_info(item);740741 self.current_disambiguator = disambiguator;742 self.attrs = current_attrs;743 self.bodies = current_bodies;744 self.define_opaque = current_define_opaque;745 self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;746747 #[cfg(debug_assertions)]748 {749 self.node_id_to_local_id = current_node_id_to_local_id;750 }751 self.trait_map = current_trait_map;752 self.current_hir_id_owner = current_owner;753 self.item_local_id_counter = current_local_counter;754 self.impl_trait_defs = current_impl_trait_defs;755 self.impl_trait_bounds = current_impl_trait_bounds;756 self.delayed_lints = current_delayed_lints;757758 debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id));759 self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info)));760 }761762 fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {763 let attrs = std::mem::take(&mut self.attrs);764 let mut bodies = std::mem::take(&mut self.bodies);765 let define_opaque = std::mem::take(&mut self.define_opaque);766 let trait_map = std::mem::take(&mut self.trait_map);767 let delayed_lints = Steal::new(std::mem::take(&mut self.delayed_lints).into_boxed_slice());768769 #[cfg(debug_assertions)]770 for (id, attrs) in attrs.iter() {771 // Verify that we do not store empty slices in the map.772 if attrs.is_empty() {773 panic!("Stored empty attributes for {:?}", id);774 }775 }776777 bodies.sort_by_key(|(k, _)| *k);778 let bodies = SortedMap::from_presorted_elements(bodies);779780 // Don't hash unless necessary, because it's expensive.781 let rustc_middle::hir::Hashes { opt_hash_including_bodies, attrs_hash } =782 self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque);783 let num_nodes = self.item_local_id_counter.as_usize();784 let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);785 let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };786 let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };787788 self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map, delayed_lints })789 }790791 /// This method allocates a new `HirId` for the given `NodeId`.792 /// Take care not to call this method if the resulting `HirId` is then not793 /// actually used in the HIR, as that would trigger an assertion in the794 /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped795 /// properly. Calling the method twice with the same `NodeId` is also forbidden.796 #[instrument(level = "debug", skip(self), ret)]797 fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId {798 assert_ne!(ast_node_id, DUMMY_NODE_ID);799800 let owner = self.current_hir_id_owner;801 let local_id = self.item_local_id_counter;802 assert_ne!(local_id, hir::ItemLocalId::ZERO);803 self.item_local_id_counter.increment_by(1);804 let hir_id = HirId { owner, local_id };805806 if let Some(def_id) = self.opt_local_def_id(ast_node_id) {807 self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));808 }809810 if let Some(traits) = self.resolver.trait_map.get(&ast_node_id) {811 self.trait_map.insert(hir_id.local_id, &traits[..]);812 }813814 // Check whether the same `NodeId` is lowered more than once.815 #[cfg(debug_assertions)]816 {817 let old = self.node_id_to_local_id.insert(ast_node_id, local_id);818 assert_eq!(old, None);819 }820821 hir_id822 }823824 /// Generate a new `HirId` without a backing `NodeId`.825 #[instrument(level = "debug", skip(self), ret)]826 fn next_id(&mut self) -> HirId {827 let owner = self.current_hir_id_owner;828 let local_id = self.item_local_id_counter;829 assert_ne!(local_id, hir::ItemLocalId::ZERO);830 self.item_local_id_counter.increment_by(1);831 HirId { owner, local_id }832 }833834 #[instrument(level = "trace", skip(self))]835 fn lower_res(&mut self, res: Res<NodeId>) -> Res {836 let res: Result<Res, ()> = res.apply_id(|id| {837 let owner = self.current_hir_id_owner;838 let local_id = self.ident_and_label_to_local_id.get(&id).copied().ok_or(())?;839 Ok(HirId { owner, local_id })840 });841 trace!(?res);842843 // We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.844 // This can happen when trying to lower the return type `x` in erroneous code like845 // async fn foo(x: u8) -> x {}846 // In that case, `x` is lowered as a function parameter, and the return type is lowered as847 // an opaque type as a synthesized HIR owner.848 res.unwrap_or(Res::Err)849 }850851 fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {852 self.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())853 }854855 fn lower_import_res(&mut self, id: NodeId, span: Span) -> PerNS<Option<Res>> {856 let per_ns = self.resolver.get_import_res(id);857 let per_ns = per_ns.map(|res| res.map(|res| self.lower_res(res)));858 if per_ns.is_empty() {859 // Propagate the error to all namespaces, just to be sure.860 self.dcx().span_delayed_bug(span, "no resolution for an import");861 let err = Some(Res::Err);862 return PerNS { type_ns: err, value_ns: err, macro_ns: err };863 }864 per_ns865 }866867 fn make_lang_item_qpath(868 &mut self,869 lang_item: hir::LangItem,870 span: Span,871 args: Option<&'hir hir::GenericArgs<'hir>>,872 ) -> hir::QPath<'hir> {873 hir::QPath::Resolved(None, self.make_lang_item_path(lang_item, span, args))874 }875876 fn make_lang_item_path(877 &mut self,878 lang_item: hir::LangItem,879 span: Span,880 args: Option<&'hir hir::GenericArgs<'hir>>,881 ) -> &'hir hir::Path<'hir> {882 let def_id = self.tcx.require_lang_item(lang_item, span);883 let def_kind = self.tcx.def_kind(def_id);884 let res = Res::Def(def_kind, def_id);885 self.arena.alloc(hir::Path {886 span,887 res,888 segments: self.arena.alloc_from_iter([hir::PathSegment {889 ident: Ident::new(lang_item.name(), span),890 hir_id: self.next_id(),891 res,892 args,893 infer_args: args.is_none(),894 }]),895 })896 }897898 /// Reuses the span but adds information like the kind of the desugaring and features that are899 /// allowed inside this span.900 fn mark_span_with_reason(901 &self,902 reason: DesugaringKind,903 span: Span,904 allow_internal_unstable: Option<Arc<[Symbol]>>,905 ) -> Span {906 self.tcx.with_stable_hashing_context(|hcx| {907 span.mark_with_reason(allow_internal_unstable, reason, span.edition(), hcx)908 })909 }910911 fn span_lowerer(&self) -> SpanLowerer {912 SpanLowerer {913 is_incremental: self.tcx.sess.opts.incremental.is_some(),914 def_id: self.current_hir_id_owner.def_id,915 }916 }917918 /// Intercept all spans entering HIR.919 /// Mark a span as relative to the current owning item.920 fn lower_span(&self, span: Span) -> Span {921 self.span_lowerer().lower(span)922 }923924 fn lower_ident(&self, ident: Ident) -> Ident {925 Ident::new(ident.name, self.lower_span(ident.span))926 }927928 /// Converts a lifetime into a new generic parameter.929 #[instrument(level = "debug", skip(self))]930 fn lifetime_res_to_generic_param(931 &mut self,932 ident: Ident,933 node_id: NodeId,934 res: LifetimeRes,935 source: hir::GenericParamSource,936 ) -> Option<hir::GenericParam<'hir>> {937 let (name, kind) = match res {938 LifetimeRes::Param { .. } => {939 (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)940 }941 LifetimeRes::Fresh { param, kind, .. } => {942 // Late resolution delegates to us the creation of the `LocalDefId`.943 let _def_id = self.create_def(944 param,945 Some(kw::UnderscoreLifetime),946 DefKind::LifetimeParam,947 ident.span,948 );949 debug!(?_def_id);950951 (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided(kind))952 }953 LifetimeRes::Static { .. } | LifetimeRes::Error(..) => return None,954 res => panic!(955 "Unexpected lifetime resolution {:?} for {:?} at {:?}",956 res, ident, ident.span957 ),958 };959 let hir_id = self.lower_node_id(node_id);960 let def_id = self.local_def_id(node_id);961 Some(hir::GenericParam {962 hir_id,963 def_id,964 name,965 span: self.lower_span(ident.span),966 pure_wrt_drop: false,967 kind: hir::GenericParamKind::Lifetime { kind },968 colon_span: None,969 source,970 })971 }972973 /// Lowers a lifetime binder that defines `generic_params`, returning the corresponding HIR974 /// nodes. The returned list includes any "extra" lifetime parameters that were added by the975 /// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id976 /// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime977 /// parameters will be successful.978 #[instrument(level = "debug", skip(self), ret)]979 #[inline]980 fn lower_lifetime_binder(981 &mut self,982 binder: NodeId,983 generic_params: &[GenericParam],984 ) -> &'hir [hir::GenericParam<'hir>] {985 // Start by creating params for extra lifetimes params, as this creates the definitions986 // that may be referred to by the AST inside `generic_params`.987 let extra_lifetimes = self.resolver.extra_lifetime_params(binder);988 debug!(?extra_lifetimes);989 let extra_lifetimes: Vec<_> = extra_lifetimes990 .iter()991 .filter_map(|&(ident, node_id, res)| {992 self.lifetime_res_to_generic_param(993 ident,994 node_id,995 res,996 hir::GenericParamSource::Binder,997 )998 })999 .collect();1000 let arena = self.arena;1001 let explicit_generic_params =1002 self.lower_generic_params_mut(generic_params, hir::GenericParamSource::Binder);1003 arena.alloc_from_iter(explicit_generic_params.chain(extra_lifetimes.into_iter()))1004 }10051006 fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {1007 let was_in_dyn_type = self.is_in_dyn_type;1008 self.is_in_dyn_type = in_scope;10091010 let result = f(self);10111012 self.is_in_dyn_type = was_in_dyn_type;10131014 result1015 }10161017 fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {1018 let current_item = self.current_item;1019 self.current_item = Some(scope_span);10201021 let was_in_loop_condition = self.is_in_loop_condition;1022 self.is_in_loop_condition = false;10231024 let old_contract = self.contract_ensures.take();10251026 let try_block_scope = mem::replace(&mut self.try_block_scope, TryBlockScope::Function);1027 let loop_scope = self.loop_scope.take();1028 let ret = f(self);1029 self.try_block_scope = try_block_scope;1030 self.loop_scope = loop_scope;10311032 self.contract_ensures = old_contract;10331034 self.is_in_loop_condition = was_in_loop_condition;10351036 self.current_item = current_item;10371038 ret1039 }10401041 fn lower_attrs(1042 &mut self,1043 id: HirId,1044 attrs: &[Attribute],1045 target_span: Span,1046 target: Target,1047 ) -> &'hir [hir::Attribute] {1048 self.lower_attrs_with_extra(id, attrs, target_span, target, &[])1049 }10501051 fn lower_attrs_with_extra(1052 &mut self,1053 id: HirId,1054 attrs: &[Attribute],1055 target_span: Span,1056 target: Target,1057 extra_hir_attributes: &[hir::Attribute],1058 ) -> &'hir [hir::Attribute] {1059 if attrs.is_empty() && extra_hir_attributes.is_empty() {1060 &[]1061 } else {1062 let mut lowered_attrs =1063 self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target);1064 lowered_attrs.extend(extra_hir_attributes.iter().cloned());10651066 assert_eq!(id.owner, self.current_hir_id_owner);1067 let ret = self.arena.alloc_from_iter(lowered_attrs);10681069 // this is possible if an item contained syntactical attribute,1070 // but none of them parse successfully or all of them were ignored1071 // for not being built-in attributes at all. They could be remaining1072 // unexpanded attributes used as markers in proc-macro derives for example.1073 // This will have emitted some diagnostics for the misparse, but will then1074 // not emit the attribute making the list empty.1075 if ret.is_empty() {1076 &[]1077 } else {1078 self.attrs.insert(id.local_id, ret);1079 ret1080 }1081 }1082 }10831084 fn lower_attrs_vec(1085 &mut self,1086 attrs: &[Attribute],1087 target_span: Span,1088 target_hir_id: HirId,1089 target: Target,1090 ) -> Vec<hir::Attribute> {1091 let l = self.span_lowerer();1092 self.attribute_parser.parse_attribute_list(1093 attrs,1094 target_span,1095 target,1096 OmitDoc::Lower,1097 |s| l.lower(s),1098 |lint_id, span, kind| {1099 self.delayed_lints.push(DelayedLint {1100 lint_id,1101 id: target_hir_id,1102 span,1103 callback: Box::new(move |dcx, level, sess: &dyn std::any::Any| {1104 let sess = sess1105 .downcast_ref::<rustc_session::Session>()1106 .expect("expected `Session`");1107 (kind.0)(dcx, level, sess)1108 }),1109 });1110 },1111 )1112 }11131114 fn alias_attrs(&mut self, id: HirId, target_id: HirId) {1115 assert_eq!(id.owner, self.current_hir_id_owner);1116 assert_eq!(target_id.owner, self.current_hir_id_owner);1117 if let Some(&a) = self.attrs.get(&target_id.local_id) {1118 assert!(!a.is_empty());1119 self.attrs.insert(id.local_id, a);1120 }1121 }11221123 fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs {1124 args.clone()1125 }11261127 /// Lower an associated item constraint.1128 #[instrument(level = "debug", skip_all)]1129 fn lower_assoc_item_constraint(1130 &mut self,1131 constraint: &AssocItemConstraint,1132 itctx: ImplTraitContext,1133 ) -> hir::AssocItemConstraint<'hir> {1134 debug!(?constraint, ?itctx);1135 // Lower the generic arguments for the associated item.1136 let gen_args = if let Some(gen_args) = &constraint.gen_args {1137 let gen_args_ctor = match gen_args {1138 GenericArgs::AngleBracketed(data) => {1139 self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).01140 }1141 GenericArgs::Parenthesized(data) => {1142 if let Some(first_char) = constraint.ident.as_str().chars().next()1143 && first_char.is_ascii_lowercase()1144 {1145 let err = match (&data.inputs[..], &data.output) {1146 ([_, ..], FnRetTy::Default(_)) => {1147 errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }1148 }1149 ([], FnRetTy::Default(_)) => {1150 errors::BadReturnTypeNotation::NeedsDots { span: data.inputs_span }1151 }1152 // The case `T: Trait<method(..) -> Ret>` is handled in the parser.1153 (_, FnRetTy::Ty(ty)) => {1154 let span = data.inputs_span.shrink_to_hi().to(ty.span);1155 errors::BadReturnTypeNotation::Output {1156 span,1157 suggestion: errors::RTNSuggestion {1158 output: span,1159 input: data.inputs_span,1160 },1161 }1162 }1163 };1164 let mut err = self.dcx().create_err(err);1165 if !self.tcx.features().return_type_notation()1166 && self.tcx.sess.is_nightly_build()1167 {1168 add_feature_diagnostics(1169 &mut err,1170 &self.tcx.sess,1171 sym::return_type_notation,1172 );1173 }1174 err.emit();1175 GenericArgsCtor {1176 args: Default::default(),1177 constraints: &[],1178 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,1179 span: data.span,1180 }1181 } else {1182 self.emit_bad_parenthesized_trait_in_assoc_ty(data);1183 // FIXME(return_type_notation): we could issue a feature error1184 // if the parens are empty and there's no return type.1185 self.lower_angle_bracketed_parameter_data(1186 &data.as_angle_bracketed_args(),1187 ParamMode::Explicit,1188 itctx,1189 )1190 .01191 }1192 }1193 GenericArgs::ParenthesizedElided(span) => GenericArgsCtor {1194 args: Default::default(),1195 constraints: &[],1196 parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,1197 span: *span,1198 },1199 };1200 gen_args_ctor.into_generic_args(self)1201 } else {1202 hir::GenericArgs::NONE1203 };1204 let kind = match &constraint.kind {1205 AssocItemConstraintKind::Equality { term } => {1206 let term = match term {1207 Term::Ty(ty) => self.lower_ty_alloc(ty, itctx).into(),1208 Term::Const(c) => self.lower_anon_const_to_const_arg_and_alloc(c).into(),1209 };1210 hir::AssocItemConstraintKind::Equality { term }1211 }1212 AssocItemConstraintKind::Bound { bounds } => {1213 // Disallow ATB in dyn types1214 if self.is_in_dyn_type {1215 let suggestion = match itctx {1216 ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {1217 let bound_end_span = constraint1218 .gen_args1219 .as_ref()1220 .map_or(constraint.ident.span, |args| args.span());1221 if bound_end_span.eq_ctxt(constraint.span) {1222 Some(self.tcx.sess.source_map().next_point(bound_end_span))1223 } else {1224 None1225 }1226 }1227 _ => None,1228 };12291230 let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {1231 span: constraint.span,1232 suggestion,1233 });1234 let err_ty =1235 &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));1236 hir::AssocItemConstraintKind::Equality { term: err_ty.into() }1237 } else {1238 let bounds = self.lower_param_bounds(1239 bounds,1240 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::AssocTyBounds),1241 itctx,1242 );1243 hir::AssocItemConstraintKind::Bound { bounds }1244 }1245 }1246 };12471248 hir::AssocItemConstraint {1249 hir_id: self.lower_node_id(constraint.id),1250 ident: self.lower_ident(constraint.ident),1251 gen_args,1252 kind,1253 span: self.lower_span(constraint.span),1254 }1255 }12561257 fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {1258 // Suggest removing empty parentheses: "Trait()" -> "Trait"1259 let sub = if data.inputs.is_empty() {1260 let parentheses_span =1261 data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());1262 AssocTyParenthesesSub::Empty { parentheses_span }1263 }1264 // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`1265 else {1266 // Start of parameters to the 1st argument1267 let open_param = data.inputs_span.shrink_to_lo().to(data1268 .inputs1269 .first()1270 .unwrap()1271 .span1272 .shrink_to_lo());1273 // End of last argument to end of parameters1274 let close_param =1275 data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());1276 AssocTyParenthesesSub::NotEmpty { open_param, close_param }1277 };1278 self.dcx().emit_err(AssocTyParentheses { span: data.span, sub });1279 }12801281 #[instrument(level = "debug", skip(self))]1282 fn lower_generic_arg(1283 &mut self,1284 arg: &ast::GenericArg,1285 itctx: ImplTraitContext,1286 ) -> hir::GenericArg<'hir> {1287 match arg {1288 ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(1289 lt,1290 LifetimeSource::Path { angle_brackets: hir::AngleBrackets::Full },1291 lt.ident.into(),1292 )),1293 ast::GenericArg::Type(ty) => {1294 // We cannot just match on `TyKind::Infer` as `(_)` is represented as1295 // `TyKind::Paren(TyKind::Infer)` and should also be lowered to `GenericArg::Infer`1296 if ty.is_maybe_parenthesised_infer() {1297 return GenericArg::Infer(hir::InferArg {1298 hir_id: self.lower_node_id(ty.id),1299 span: self.lower_span(ty.span),1300 });1301 }13021303 match &ty.kind {1304 // We parse const arguments as path types as we cannot distinguish them during1305 // parsing. We try to resolve that ambiguity by attempting resolution in both the1306 // type and value namespaces. If we resolved the path in the value namespace, we1307 // transform it into a generic const argument.1308 //1309 // FIXME: Should we be handling `(PATH_TO_CONST)`?1310 TyKind::Path(None, path) => {1311 if let Some(res) = self1312 .get_partial_res(ty.id)1313 .and_then(|partial_res| partial_res.full_res())1314 {1315 if !res.matches_ns(Namespace::TypeNS)1316 && path.is_potential_trivial_const_arg()1317 {1318 debug!(1319 "lower_generic_arg: Lowering type argument as const argument: {:?}",1320 ty,1321 );13221323 let ct =1324 self.lower_const_path_to_const_arg(path, res, ty.id, ty.span);1325 return GenericArg::Const(ct.try_as_ambig_ct().unwrap());1326 }1327 }1328 }1329 _ => {}1330 }1331 GenericArg::Type(self.lower_ty_alloc(ty, itctx).try_as_ambig_ty().unwrap())1332 }1333 ast::GenericArg::Const(ct) => {1334 let ct = self.lower_anon_const_to_const_arg_and_alloc(ct);1335 match ct.try_as_ambig_ct() {1336 Some(ct) => GenericArg::Const(ct),1337 None => GenericArg::Infer(hir::InferArg { hir_id: ct.hir_id, span: ct.span }),1338 }1339 }1340 }1341 }13421343 #[instrument(level = "debug", skip(self))]1344 fn lower_ty_alloc(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {1345 self.arena.alloc(self.lower_ty(t, itctx))1346 }13471348 fn lower_path_ty(1349 &mut self,1350 t: &Ty,1351 qself: &Option<Box<QSelf>>,1352 path: &Path,1353 param_mode: ParamMode,1354 itctx: ImplTraitContext,1355 ) -> hir::Ty<'hir> {1356 // Check whether we should interpret this as a bare trait object.1357 // This check mirrors the one in late resolution. We only introduce this special case in1358 // the rare occurrence we need to lower `Fresh` anonymous lifetimes.1359 // The other cases when a qpath should be opportunistically made a trait object are handled1360 // by `ty_path`.1361 if qself.is_none()1362 && let Some(partial_res) = self.get_partial_res(t.id)1363 && let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()1364 {1365 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {1366 let bound = this.lower_poly_trait_ref(1367 &PolyTraitRef {1368 bound_generic_params: ThinVec::new(),1369 modifiers: TraitBoundModifiers::NONE,1370 trait_ref: TraitRef { path: path.clone(), ref_id: t.id },1371 span: t.span,1372 parens: ast::Parens::No,1373 },1374 RelaxedBoundPolicy::Forbidden(RelaxedBoundForbiddenReason::TraitObjectTy),1375 itctx,1376 );1377 let bounds = this.arena.alloc_from_iter([bound]);1378 let lifetime_bound = this.elided_dyn_bound(t.span);1379 (bounds, lifetime_bound)1380 });1381 let kind = hir::TyKind::TraitObject(1382 bounds,1383 TaggedRef::new(lifetime_bound, TraitObjectSyntax::None),1384 );1385 return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };1386 }13871388 let id = self.lower_node_id(t.id);1389 let qpath = self.lower_qpath(1390 t.id,1391 qself,1392 path,1393 param_mode,1394 AllowReturnTypeNotation::Yes,1395 itctx,1396 None,1397 );1398 self.ty_path(id, t.span, qpath)1399 }14001401 fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {1402 hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }1403 }14041405 fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {1406 self.ty(span, hir::TyKind::Tup(tys))1407 }14081409 fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {1410 let kind = match &t.kind {1411 TyKind::Infer => hir::TyKind::Infer(()),1412 TyKind::Err(guar) => hir::TyKind::Err(*guar),1413 TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty_alloc(ty, itctx)),1414 TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),1415 TyKind::Ref(region, mt) => {1416 let lifetime = self.lower_ty_direct_lifetime(t, *region);1417 hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx))1418 }1419 TyKind::PinnedRef(region, mt) => {1420 let lifetime = self.lower_ty_direct_lifetime(t, *region);1421 let kind = hir::TyKind::Ref(lifetime, self.lower_mt(mt, itctx));1422 let span = self.lower_span(t.span);1423 let arg = hir::Ty { kind, span, hir_id: self.next_id() };1424 let args = self.arena.alloc(hir::GenericArgs {1425 args: self.arena.alloc([hir::GenericArg::Type(self.arena.alloc(arg))]),1426 constraints: &[],1427 parenthesized: hir::GenericArgsParentheses::No,1428 span_ext: span,1429 });1430 let path = self.make_lang_item_qpath(hir::LangItem::Pin, span, Some(args));1431 hir::TyKind::Path(path)1432 }1433 TyKind::FnPtr(f) => {1434 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);1435 hir::TyKind::FnPtr(self.arena.alloc(hir::FnPtrTy {1436 generic_params,1437 safety: self.lower_safety(f.safety, hir::Safety::Safe),1438 abi: self.lower_extern(f.ext),1439 decl: self.lower_fn_decl(&f.decl, t.id, t.span, FnDeclKind::Pointer, None),1440 param_idents: self.lower_fn_params_to_idents(&f.decl),1441 }))1442 }1443 TyKind::UnsafeBinder(f) => {1444 let generic_params = self.lower_lifetime_binder(t.id, &f.generic_params);1445 hir::TyKind::UnsafeBinder(self.arena.alloc(hir::UnsafeBinderTy {1446 generic_params,1447 inner_ty: self.lower_ty_alloc(&f.inner_ty, itctx),1448 }))1449 }1450 TyKind::Never => hir::TyKind::Never,1451 TyKind::Tup(tys) => hir::TyKind::Tup(1452 self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty(ty, itctx))),1453 ),1454 TyKind::Paren(ty) => {1455 return self.lower_ty(ty, itctx);1456 }1457 TyKind::Path(qself, path) => {1458 return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);1459 }1460 TyKind::ImplicitSelf => {1461 let hir_id = self.next_id();1462 let res = self.expect_full_res(t.id);1463 let res = self.lower_res(res);1464 hir::TyKind::Path(hir::QPath::Resolved(1465 None,1466 self.arena.alloc(hir::Path {1467 res,1468 segments: arena_vec![self; hir::PathSegment::new(1469 Ident::with_dummy_span(kw::SelfUpper),1470 hir_id,1471 res1472 )],1473 span: self.lower_span(t.span),1474 }),1475 ))1476 }1477 TyKind::Array(ty, length) => hir::TyKind::Array(1478 self.lower_ty_alloc(ty, itctx),1479 self.lower_array_length_to_const_arg(length),1480 ),1481 TyKind::TraitObject(bounds, kind) => {1482 let mut lifetime_bound = None;1483 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {1484 let bounds =1485 this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| match bound {1486 // We can safely ignore constness here since AST validation1487 // takes care of rejecting invalid modifier combinations and1488 // const trait bounds in trait object types.1489 GenericBound::Trait(ty) => {1490 let trait_ref = this.lower_poly_trait_ref(1491 ty,1492 RelaxedBoundPolicy::Forbidden(1493 RelaxedBoundForbiddenReason::TraitObjectTy,1494 ),1495 itctx,1496 );1497 Some(trait_ref)1498 }1499 GenericBound::Outlives(lifetime) => {1500 if lifetime_bound.is_none() {1501 lifetime_bound = Some(this.lower_lifetime(1502 lifetime,1503 LifetimeSource::Other,1504 lifetime.ident.into(),1505 ));1506 }1507 None1508 }1509 // Ignore `use` syntax since that is not valid in objects.1510 GenericBound::Use(_, span) => {1511 this.dcx()1512 .span_delayed_bug(*span, "use<> not allowed in dyn types");1513 None1514 }1515 }));1516 let lifetime_bound =1517 lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));1518 (bounds, lifetime_bound)1519 });1520 hir::TyKind::TraitObject(bounds, TaggedRef::new(lifetime_bound, *kind))1521 }1522 TyKind::ImplTrait(def_node_id, bounds) => {1523 let span = t.span;1524 match itctx {1525 ImplTraitContext::OpaqueTy { origin } => {1526 self.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, itctx)1527 }1528 ImplTraitContext::Universal => {1529 if let Some(span) = bounds.iter().find_map(|bound| match *bound {1530 ast::GenericBound::Use(_, span) => Some(span),1531 _ => None,1532 }) {1533 self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span });1534 }15351536 let def_id = self.local_def_id(*def_node_id);1537 let name = self.tcx.item_name(def_id.to_def_id());1538 let ident = Ident::new(name, span);1539 let (param, bounds, path) = self.lower_universal_param_and_bounds(1540 *def_node_id,1541 span,1542 ident,1543 bounds,1544 );1545 self.impl_trait_defs.push(param);1546 if let Some(bounds) = bounds {1547 self.impl_trait_bounds.push(bounds);1548 }1549 path1550 }1551 ImplTraitContext::InBinding => hir::TyKind::TraitAscription(1552 self.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx),1553 ),1554 ImplTraitContext::FeatureGated(position, feature) => {1555 let guar = self1556 .tcx1557 .sess1558 .create_feature_err(1559 MisplacedImplTrait {1560 span: t.span,1561 position: DiagArgFromDisplay(&position),1562 },1563 feature,1564 )1565 .emit();1566 hir::TyKind::Err(guar)1567 }1568 ImplTraitContext::Disallowed(position) => {1569 let guar = self.dcx().emit_err(MisplacedImplTrait {1570 span: t.span,1571 position: DiagArgFromDisplay(&position),1572 });1573 hir::TyKind::Err(guar)1574 }1575 }1576 }1577 TyKind::Pat(ty, pat) => {1578 hir::TyKind::Pat(self.lower_ty_alloc(ty, itctx), self.lower_ty_pat(pat, ty.span))1579 }1580 TyKind::FieldOf(ty, variant, field) => hir::TyKind::FieldOf(1581 self.lower_ty_alloc(ty, itctx),1582 self.arena.alloc(hir::TyFieldPath {1583 variant: variant.map(|variant| self.lower_ident(variant)),1584 field: self.lower_ident(*field),1585 }),1586 ),1587 TyKind::MacCall(_) => {1588 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")1589 }1590 TyKind::CVarArgs => {1591 let guar = self.dcx().span_delayed_bug(1592 t.span,1593 "`TyKind::CVarArgs` should have been handled elsewhere",1594 );1595 hir::TyKind::Err(guar)1596 }1597 TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),1598 };15991600 hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }1601 }16021603 fn lower_ty_direct_lifetime(1604 &mut self,1605 t: &Ty,1606 region: Option<Lifetime>,1607 ) -> &'hir hir::Lifetime {1608 let (region, syntax) = match region {1609 Some(region) => (region, region.ident.into()),16101611 None => {1612 let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =1613 self.resolver.get_lifetime_res(t.id)1614 {1615 assert_eq!(start.plus(1), end);1616 start1617 } else {1618 self.next_node_id()1619 };1620 let span = self.tcx.sess.source_map().start_point(t.span).shrink_to_hi();1621 let region = Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id };1622 (region, LifetimeSyntax::Implicit)1623 }1624 };1625 self.lower_lifetime(®ion, LifetimeSource::Reference, syntax)1626 }16271628 /// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =1629 /// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a1630 /// HIR type that references the TAIT.1631 ///1632 /// Given a function definition like:1633 ///1634 /// ```rust1635 /// use std::fmt::Debug;1636 ///1637 /// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {1638 /// x1639 /// }1640 /// ```1641 ///1642 /// we will create a TAIT definition in the HIR like1643 ///1644 /// ```rust,ignore (pseudo-Rust)1645 /// type TestReturn<'a, T, 'x> = impl Debug + 'x1646 /// ```1647 ///1648 /// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:1649 ///1650 /// ```rust,ignore (pseudo-Rust)1651 /// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>1652 /// ```1653 ///1654 /// Note the subtlety around type parameters! The new TAIT, `TestReturn`, inherits all the1655 /// type parameters from the function `test` (this is implemented in the query layer, they aren't1656 /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to1657 /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters1658 /// for the lifetimes that get captured (`'x`, in our example above) and reference those.1659 #[instrument(level = "debug", skip(self), ret)]1660 fn lower_opaque_impl_trait(1661 &mut self,1662 span: Span,1663 origin: hir::OpaqueTyOrigin<LocalDefId>,1664 opaque_ty_node_id: NodeId,1665 bounds: &GenericBounds,1666 itctx: ImplTraitContext,1667 ) -> hir::TyKind<'hir> {1668 // Make sure we know that some funky desugaring has been going on here.1669 // This is a first: there is code in other places like for loop1670 // desugaring that explicitly states that we don't want to track that.1671 // Not tracking it makes lints in rustc and clippy very fragile, as1672 // frequently opened issues show.1673 let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);16741675 self.lower_opaque_inner(opaque_ty_node_id, origin, opaque_ty_span, |this| {1676 this.lower_param_bounds(bounds, RelaxedBoundPolicy::Allowed, itctx)1677 })1678 }16791680 fn lower_opaque_inner(1681 &mut self,1682 opaque_ty_node_id: NodeId,1683 origin: hir::OpaqueTyOrigin<LocalDefId>,1684 opaque_ty_span: Span,1685 lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>],1686 ) -> hir::TyKind<'hir> {1687 let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);1688 let opaque_ty_hir_id = self.lower_node_id(opaque_ty_node_id);1689 debug!(?opaque_ty_def_id, ?opaque_ty_hir_id);16901691 let bounds = lower_item_bounds(self);1692 let opaque_ty_def = hir::OpaqueTy {1693 hir_id: opaque_ty_hir_id,1694 def_id: opaque_ty_def_id,1695 bounds,1696 origin,1697 span: self.lower_span(opaque_ty_span),1698 };1699 let opaque_ty_def = self.arena.alloc(opaque_ty_def);17001701 hir::TyKind::OpaqueDef(opaque_ty_def)1702 }17031704 fn lower_precise_capturing_args(1705 &mut self,1706 precise_capturing_args: &[PreciseCapturingArg],1707 ) -> &'hir [hir::PreciseCapturingArg<'hir>] {1708 self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg {1709 PreciseCapturingArg::Lifetime(lt) => hir::PreciseCapturingArg::Lifetime(1710 self.lower_lifetime(lt, LifetimeSource::PreciseCapturing, lt.ident.into()),1711 ),1712 PreciseCapturingArg::Arg(path, id) => {1713 let [segment] = path.segments.as_slice() else {1714 panic!();1715 };1716 let res = self.get_partial_res(*id).map_or(Res::Err, |partial_res| {1717 partial_res.full_res().expect("no partial res expected for precise capture arg")1718 });1719 hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {1720 hir_id: self.lower_node_id(*id),1721 ident: self.lower_ident(segment.ident),1722 res: self.lower_res(res),1723 })1724 }1725 }))1726 }17271728 fn lower_fn_params_to_idents(&mut self, decl: &FnDecl) -> &'hir [Option<Ident>] {1729 self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind {1730 PatKind::Missing => None,1731 PatKind::Ident(_, ident, _) => Some(self.lower_ident(ident)),1732 PatKind::Wild => Some(Ident::new(kw::Underscore, self.lower_span(param.pat.span))),1733 _ => {1734 self.dcx().span_delayed_bug(1735 param.pat.span,1736 "non-missing/ident/wild param pat must trigger an error",1737 );1738 None1739 }1740 }))1741 }17421743 /// Lowers a function declaration.1744 ///1745 /// `decl`: the unlowered (AST) function declaration.1746 ///1747 /// `fn_node_id`: `impl Trait` arguments are lowered into generic parameters on the given1748 /// `NodeId`.1749 ///1750 /// `transform_return_type`: if `Some`, applies some conversion to the return type, such as is1751 /// needed for `async fn` and `gen fn`. See [`CoroutineKind`] for more details.1752 #[instrument(level = "debug", skip(self))]1753 fn lower_fn_decl(1754 &mut self,1755 decl: &FnDecl,1756 fn_node_id: NodeId,1757 fn_span: Span,1758 kind: FnDeclKind,1759 coro: Option<CoroutineKind>,1760 ) -> &'hir hir::FnDecl<'hir> {1761 let c_variadic = decl.c_variadic();17621763 // Skip the `...` (`CVarArgs`) trailing arguments from the AST,1764 // as they are not explicit in HIR/Ty function signatures.1765 // (instead, the `c_variadic` flag is set to `true`)1766 let mut inputs = &decl.inputs[..];1767 if decl.c_variadic() {1768 inputs = &inputs[..inputs.len() - 1];1769 }1770 let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {1771 let itctx = match kind {1772 FnDeclKind::Fn | FnDeclKind::Inherent | FnDeclKind::Impl | FnDeclKind::Trait => {1773 ImplTraitContext::Universal1774 }1775 FnDeclKind::ExternFn => {1776 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnParam)1777 }1778 FnDeclKind::Closure => {1779 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureParam)1780 }1781 FnDeclKind::Pointer => {1782 ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)1783 }1784 };1785 self.lower_ty(¶m.ty, itctx)1786 }));17871788 let output = match coro {1789 Some(coro) => {1790 let fn_def_id = self.local_def_id(fn_node_id);1791 self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind)1792 }1793 None => match &decl.output {1794 FnRetTy::Ty(ty) => {1795 let itctx = match kind {1796 FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy {1797 origin: hir::OpaqueTyOrigin::FnReturn {1798 parent: self.local_def_id(fn_node_id),1799 in_trait_or_impl: None,1800 },1801 },1802 FnDeclKind::Trait => ImplTraitContext::OpaqueTy {1803 origin: hir::OpaqueTyOrigin::FnReturn {1804 parent: self.local_def_id(fn_node_id),1805 in_trait_or_impl: Some(hir::RpitContext::Trait),1806 },1807 },1808 FnDeclKind::Impl => ImplTraitContext::OpaqueTy {1809 origin: hir::OpaqueTyOrigin::FnReturn {1810 parent: self.local_def_id(fn_node_id),1811 in_trait_or_impl: Some(hir::RpitContext::TraitImpl),1812 },1813 },1814 FnDeclKind::ExternFn => {1815 ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)1816 }1817 FnDeclKind::Closure => {1818 ImplTraitContext::Disallowed(ImplTraitPosition::ClosureReturn)1819 }1820 FnDeclKind::Pointer => {1821 ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)1822 }1823 };1824 hir::FnRetTy::Return(self.lower_ty_alloc(ty, itctx))1825 }1826 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),1827 },1828 };18291830 let fn_decl_kind = hir::FnDeclFlags::default()1831 .set_implicit_self(decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {1832 let is_mutable_pat = matches!(1833 arg.pat.kind,1834 PatKind::Ident(hir::BindingMode(_, Mutability::Mut), ..)1835 );18361837 match &arg.ty.kind {1838 TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,1839 TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,1840 // Given we are only considering `ImplicitSelf` types, we needn't consider1841 // the case where we have a mutable pattern to a reference as that would1842 // no longer be an `ImplicitSelf`.1843 TyKind::Ref(_, mt) | TyKind::PinnedRef(_, mt)1844 if mt.ty.kind.is_implicit_self() =>1845 {1846 match mt.mutbl {1847 hir::Mutability::Not => hir::ImplicitSelfKind::RefImm,1848 hir::Mutability::Mut => hir::ImplicitSelfKind::RefMut,1849 }1850 }1851 _ => hir::ImplicitSelfKind::None,1852 }1853 }))1854 .set_lifetime_elision_allowed(self.resolver.lifetime_elision_allowed(fn_node_id))1855 .set_c_variadic(c_variadic);18561857 self.arena.alloc(hir::FnDecl { inputs, output, fn_decl_kind })1858 }18591860 // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`1861 // combined with the following definition of `OpaqueTy`:1862 //1863 // type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;1864 //1865 // `output`: unlowered output type (`T` in `-> T`)1866 // `fn_node_id`: `NodeId` of the parent function (used to create child impl trait definition)1867 // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created1868 #[instrument(level = "debug", skip(self))]1869 fn lower_coroutine_fn_ret_ty(1870 &mut self,1871 output: &FnRetTy,1872 fn_def_id: LocalDefId,1873 coro: CoroutineKind,1874 fn_kind: FnDeclKind,1875 ) -> hir::FnRetTy<'hir> {1876 let span = self.lower_span(output.span());18771878 let (opaque_ty_node_id, allowed_features) = match coro {1879 CoroutineKind::Async { return_impl_trait_id, .. } => (return_impl_trait_id, None),1880 CoroutineKind::Gen { return_impl_trait_id, .. } => (return_impl_trait_id, None),1881 CoroutineKind::AsyncGen { return_impl_trait_id, .. } => {1882 (return_impl_trait_id, Some(Arc::clone(&self.allow_async_iterator)))1883 }1884 };18851886 let opaque_ty_span =1887 self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features);18881889 let in_trait_or_impl = match fn_kind {1890 FnDeclKind::Trait => Some(hir::RpitContext::Trait),1891 FnDeclKind::Impl => Some(hir::RpitContext::TraitImpl),1892 FnDeclKind::Fn | FnDeclKind::Inherent => None,1893 FnDeclKind::ExternFn | FnDeclKind::Closure | FnDeclKind::Pointer => unreachable!(),1894 };18951896 let opaque_ty_ref = self.lower_opaque_inner(1897 opaque_ty_node_id,1898 hir::OpaqueTyOrigin::AsyncFn { parent: fn_def_id, in_trait_or_impl },1899 opaque_ty_span,1900 |this| {1901 let bound = this.lower_coroutine_fn_output_type_to_bound(1902 output,1903 coro,1904 opaque_ty_span,1905 ImplTraitContext::OpaqueTy {1906 origin: hir::OpaqueTyOrigin::FnReturn {1907 parent: fn_def_id,1908 in_trait_or_impl,1909 },1910 },1911 );1912 arena_vec![this; bound]1913 },1914 );19151916 let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);1917 hir::FnRetTy::Return(self.arena.alloc(opaque_ty))1918 }19191920 /// Transforms `-> T` into `Future<Output = T>`.1921 fn lower_coroutine_fn_output_type_to_bound(1922 &mut self,1923 output: &FnRetTy,1924 coro: CoroutineKind,1925 opaque_ty_span: Span,1926 itctx: ImplTraitContext,1927 ) -> hir::GenericBound<'hir> {1928 // Compute the `T` in `Future<Output = T>` from the return type.1929 let output_ty = match output {1930 FnRetTy::Ty(ty) => {1931 // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the1932 // `impl Future` opaque type that `async fn` implicitly1933 // generates.1934 self.lower_ty_alloc(ty, itctx)1935 }1936 FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),1937 };19381939 // "<$assoc_ty_name = T>"1940 let (assoc_ty_name, trait_lang_item) = match coro {1941 CoroutineKind::Async { .. } => (sym::Output, hir::LangItem::Future),1942 CoroutineKind::Gen { .. } => (sym::Item, hir::LangItem::Iterator),1943 CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),1944 };19451946 let bound_args = self.arena.alloc(hir::GenericArgs {1947 args: &[],1948 constraints: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],1949 parenthesized: hir::GenericArgsParentheses::No,1950 span_ext: DUMMY_SP,1951 });19521953 hir::GenericBound::Trait(hir::PolyTraitRef {1954 bound_generic_params: &[],1955 modifiers: hir::TraitBoundModifiers::NONE,1956 trait_ref: hir::TraitRef {1957 path: self.make_lang_item_path(trait_lang_item, opaque_ty_span, Some(bound_args)),1958 hir_ref_id: self.next_id(),1959 },1960 span: opaque_ty_span,1961 })1962 }19631964 #[instrument(level = "trace", skip(self))]1965 fn lower_param_bound(1966 &mut self,1967 tpb: &GenericBound,1968 rbp: RelaxedBoundPolicy<'_>,1969 itctx: ImplTraitContext,1970 ) -> hir::GenericBound<'hir> {1971 match tpb {1972 GenericBound::Trait(p) => {1973 hir::GenericBound::Trait(self.lower_poly_trait_ref(p, rbp, itctx))1974 }1975 GenericBound::Outlives(lifetime) => hir::GenericBound::Outlives(self.lower_lifetime(1976 lifetime,1977 LifetimeSource::OutlivesBound,1978 lifetime.ident.into(),1979 )),1980 GenericBound::Use(args, span) => hir::GenericBound::Use(1981 self.lower_precise_capturing_args(args),1982 self.lower_span(*span),1983 ),1984 }1985 }19861987 fn lower_lifetime(1988 &mut self,1989 l: &Lifetime,1990 source: LifetimeSource,1991 syntax: LifetimeSyntax,1992 ) -> &'hir hir::Lifetime {1993 self.new_named_lifetime(l.id, l.id, l.ident, source, syntax)1994 }19951996 fn lower_lifetime_hidden_in_path(1997 &mut self,1998 id: NodeId,1999 span: Span,2000 angle_brackets: AngleBrackets,
Findings
✓ No findings reported for this file.