From 3656fbff06416cbc89ca4379fdc9b2e3d046b19e Mon Sep 17 00:00:00 2001 From: aerooneqq Date: Wed, 18 Mar 2026 17:31:38 +0300 Subject: [PATCH] Abstract AST lowering resolver --- compiler/rustc_ast_lowering/src/asm.rs | 2 +- compiler/rustc_ast_lowering/src/block.rs | 4 +- compiler/rustc_ast_lowering/src/contract.rs | 4 +- compiler/rustc_ast_lowering/src/delegation.rs | 39 +++---- .../src/delegation/generics.rs | 18 +-- compiler/rustc_ast_lowering/src/expr.rs | 7 +- compiler/rustc_ast_lowering/src/format.rs | 7 +- compiler/rustc_ast_lowering/src/item.rs | 18 +-- compiler/rustc_ast_lowering/src/lib.rs | 106 +++++++++++++----- compiler/rustc_ast_lowering/src/pat.rs | 2 +- compiler/rustc_ast_lowering/src/path.rs | 2 +- 11 files changed, 129 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index a7bf1c99a7e23..51994c2e92f96 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -23,7 +23,7 @@ use crate::{ AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringExt, }; -impl<'a, 'hir> LoweringContext<'a, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { pub(crate) fn lower_inline_asm( &mut self, sp: Span, diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index cf3f331a701b4..94839485c6036 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -4,9 +4,9 @@ use rustc_hir::Target; use rustc_span::sym; use smallvec::SmallVec; -use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext}; +use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext, ResolverAstLoweringExt}; -impl<'a, 'hir> LoweringContext<'a, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { pub(super) fn lower_block( &mut self, b: &Block, diff --git a/compiler/rustc_ast_lowering/src/contract.rs b/compiler/rustc_ast_lowering/src/contract.rs index 6cffd8e119b7e..fd05ed0c78e43 100644 --- a/compiler/rustc_ast_lowering/src/contract.rs +++ b/compiler/rustc_ast_lowering/src/contract.rs @@ -2,9 +2,9 @@ use std::sync::Arc; use thin_vec::thin_vec; -use crate::LoweringContext; +use crate::{LoweringContext, ResolverAstLoweringExt}; -impl<'a, 'hir> LoweringContext<'a, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { /// Lowered contracts are guarded with the `contract_checks` compiler flag, /// i.e. the flag turns into a boolean guard in the lowered HIR. The reason /// for not eliminating the contract code entirely when the `contract_checks` diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 68b76f7bd3dda..269b9957dc7af 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -37,6 +37,7 @@ //! also be emitted during HIR ty lowering. use std::iter; +use std::marker::PhantomData; use ast::visit::Visitor; use hir::def::{DefKind, PartialRes, Res}; @@ -51,7 +52,7 @@ use rustc_hir as hir; use rustc_hir::attrs::{AttributeKind, InlineAttr}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::span_bug; -use rustc_middle::ty::{Asyncness, DelegationAttrs, DelegationFnSigAttrs, ResolverAstLowering}; +use rustc_middle::ty::{Asyncness, DelegationAttrs, DelegationFnSigAttrs}; use rustc_span::symbol::kw; use rustc_span::{DUMMY_SP, Ident, Span, Symbol}; use smallvec::SmallVec; @@ -134,16 +135,14 @@ impl DelegationIds { } } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { fn is_method(&self, def_id: DefId, span: Span) -> bool { match self.tcx.def_kind(def_id) { DefKind::Fn => false, DefKind::AssocFn => match def_id.as_local() { - Some(local_def_id) => self - .resolver - .delegation_fn_sigs - .get(&local_def_id) - .is_some_and(|sig| sig.has_self), + Some(local_def_id) => { + self.resolver.delegation_fn_sig(local_def_id).is_some_and(|sig| sig.has_self) + } None => self.tcx.associated_item(def_id).is_method(), }, _ => span_bug!(span, "unexpected DefKind for delegation item"), @@ -159,7 +158,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Delegation can be unresolved in illegal places such as function bodies in extern blocks (see #151356) let ids = if let Some(delegation_info) = - self.resolver.delegation_infos.get(&self.local_def_id(item_id)) + self.resolver.delegation_info(self.local_def_id(item_id)) { self.get_delegation_ids(delegation_info.resolution_node, span) } else { @@ -344,10 +343,10 @@ impl<'hir> LoweringContext<'_, 'hir> { fn get_attrs(&self, local_id: LocalDefId) -> &DelegationAttrs { // local_id can correspond either to a function or other delegation - if let Some(fn_sig) = self.resolver.delegation_fn_sigs.get(&local_id) { + if let Some(fn_sig) = self.resolver.delegation_fn_sig(local_id) { &fn_sig.attrs } else { - &self.resolver.delegation_infos[&local_id].attrs + &self.resolver.delegation_info(local_id).expect("processing delegation").attrs } } @@ -378,7 +377,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // it means that we refer to another delegation as a callee, so in order to obtain // a signature DefId we obtain NodeId of the callee delegation and try to get signature from it. if let Some(local_id) = def_id.as_local() - && let Some(delegation_info) = self.resolver.delegation_infos.get(&local_id) + && let Some(delegation_info) = self.resolver.delegation_info(local_id) { node_id = delegation_info.resolution_node; if visited.contains(&node_id) { @@ -402,7 +401,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Function parameter count, including C variadic `...` if present. fn param_count(&self, def_id: DefId) -> (usize, bool /*c_variadic*/) { if let Some(local_sig_id) = def_id.as_local() { - match self.resolver.delegation_fn_sigs.get(&local_sig_id) { + match self.resolver.delegation_fn_sig(local_sig_id) { Some(sig) => (sig.param_count, sig.c_variadic), None => (0, false), } @@ -457,7 +456,7 @@ impl<'hir> LoweringContext<'_, 'hir> { span: Span, ) -> hir::FnSig<'hir> { let header = if let Some(local_sig_id) = sig_id.as_local() { - match self.resolver.delegation_fn_sigs.get(&local_sig_id) { + match self.resolver.delegation_fn_sig(local_sig_id) { Some(sig) => { let parent = self.tcx.parent(sig_id); // HACK: we override the default safety instead of generating attributes from the ether. @@ -573,6 +572,7 @@ impl<'hir> LoweringContext<'_, 'hir> { resolver: this.resolver, path_id: delegation.id, self_param_id: pat_node_id, + phantom: PhantomData, }; self_resolver.visit_block(block); // Target expr needs to lower `self` path. @@ -816,25 +816,26 @@ impl<'hir> LoweringContext<'_, 'hir> { } } -struct SelfResolver<'a, 'tcx> { - resolver: &'a mut ResolverAstLowering<'tcx>, +struct SelfResolver<'a, 'tcx, R> { + resolver: &'a mut R, path_id: NodeId, self_param_id: NodeId, + phantom: PhantomData<&'tcx ()>, } -impl SelfResolver<'_, '_> { +impl<'tcx, R: ResolverAstLoweringExt<'tcx>> SelfResolver<'_, 'tcx, R> { fn try_replace_id(&mut self, id: NodeId) { - if let Some(res) = self.resolver.partial_res_map.get(&id) + if let Some(res) = self.resolver.get_partial_res(id) && let Some(Res::Local(sig_id)) = res.full_res() && sig_id == self.path_id { let new_res = PartialRes::new(Res::Local(self.self_param_id)); - self.resolver.partial_res_map.insert(id, new_res); + self.resolver.insert_partial_res(id, new_res); } } } -impl<'ast, 'a> Visitor<'ast> for SelfResolver<'a, '_> { +impl<'ast, 'a, 'tcx, R: ResolverAstLoweringExt<'tcx>> Visitor<'ast> for SelfResolver<'a, 'tcx, R> { fn visit_id(&mut self, id: NodeId) { self.try_replace_id(id); } diff --git a/compiler/rustc_ast_lowering/src/delegation/generics.rs b/compiler/rustc_ast_lowering/src/delegation/generics.rs index 9e7ec04d38fb7..29ae75b30c5ad 100644 --- a/compiler/rustc_ast_lowering/src/delegation/generics.rs +++ b/compiler/rustc_ast_lowering/src/delegation/generics.rs @@ -10,7 +10,7 @@ use rustc_span::symbol::kw; use rustc_span::{DUMMY_SP, Ident, Span}; use thin_vec::{ThinVec, thin_vec}; -use crate::{AstOwner, LoweringContext}; +use crate::{AstOwner, LoweringContext, ResolverAstLoweringExt}; pub(super) enum DelegationGenerics { /// User-specified args are present: `reuse foo::;`. @@ -60,7 +60,7 @@ impl DelegationGenerics { impl<'hir> HirOrAstGenerics<'hir> { pub(super) fn into_hir_generics( &mut self, - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, item_id: NodeId, span: Span, ) -> &mut HirOrAstGenerics<'hir> { @@ -100,7 +100,7 @@ impl<'hir> HirOrAstGenerics<'hir> { pub(super) fn into_generic_args( &self, - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, add_lifetimes: bool, span: Span, ) -> Option<&'hir hir::GenericArgs<'hir>> { @@ -140,7 +140,7 @@ impl<'hir> GenericsGenerationResults<'hir> { &mut self, item_id: NodeId, span: Span, - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, ) -> impl Iterator> { // Now we always call `into_hir_generics` both on child and parent, // however in future we would not do that, when scenarios like @@ -182,7 +182,7 @@ impl<'hir> GenericsGenerationResults<'hir> { &mut self, item_id: NodeId, span: Span, - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, ) -> impl Iterator> { // Now we always call `into_hir_generics` both on child and parent, // however in future we would not do that, when scenarios like @@ -207,7 +207,7 @@ impl<'hir> GenericsGenerationResults<'hir> { } } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { pub(super) fn lower_delegation_generics( &mut self, delegation: &Delegation, @@ -289,11 +289,11 @@ impl<'hir> LoweringContext<'_, 'hir> { // Note that we use self.disambiguator here, if we will create new every time // we will get ICE if params have the same name. - self.resolver.node_id_to_def_id.insert( + self.resolver.insert_new_def_id( p.id, self.tcx .create_def( - self.resolver.node_id_to_def_id[&item_id], + self.local_def_id(item_id), Some(p.ident.name), match p.kind { GenericParamKind::Lifetime => DefKind::LifetimeParam, @@ -509,7 +509,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let node_id = self.next_node_id(); - self.resolver.partial_res_map.insert(node_id, hir::def::PartialRes::new(res)); + self.resolver.insert_partial_res(node_id, hir::def::PartialRes::new(res)); GenericParamKind::Const { ty: Box::new(Ty { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 4a2992038003c..ec243c1e77d1e 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -53,7 +53,7 @@ impl<'v> rustc_ast::visit::Visitor<'v> for WillCreateDefIdsVisitor { } } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { fn lower_exprs(&mut self, exprs: &[Box]) -> &'hir [hir::Expr<'hir>] { self.arena.alloc_from_iter(exprs.iter().map(|x| self.lower_expr_mut(x))) } @@ -1232,7 +1232,10 @@ impl<'hir> LoweringContext<'_, 'hir> { whole_span: Span, ) -> hir::ExprKind<'hir> { // Return early in case of an ordinary assignment. - fn is_ordinary(lower_ctx: &mut LoweringContext<'_, '_>, lhs: &Expr) -> bool { + fn is_ordinary<'hir>( + lower_ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, + lhs: &Expr, + ) -> bool { match &lhs.kind { ExprKind::Array(..) | ExprKind::Struct(..) diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 602635af1324e..1f1f86f7edfd7 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -7,8 +7,9 @@ use rustc_session::config::FmtDebug; use rustc_span::{ByteSymbol, DesugaringKind, Ident, Span, Symbol, sym}; use super::LoweringContext; +use crate::ResolverAstLoweringExt; -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { pub(crate) fn lower_format_args(&mut self, sp: Span, fmt: &FormatArgs) -> hir::ExprKind<'hir> { // Never call the const constructor of `fmt::Arguments` if the // format_args!() had any arguments _before_ flattening/inlining. @@ -230,7 +231,7 @@ enum ArgumentType { /// ::new_…(arg) /// ``` fn make_argument<'hir>( - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, sp: Span, arg: &'hir hir::Expr<'hir>, ty: ArgumentType, @@ -277,7 +278,7 @@ fn make_count( } fn expand_format_args<'hir>( - ctx: &mut LoweringContext<'_, 'hir>, + ctx: &mut LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, macsp: Span, fmt: &FormatArgs, allow_const: bool, diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index ed78b77a704f6..12e178be98581 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -10,7 +10,7 @@ use rustc_hir::{ }; use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::span_bug; -use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_span::def_id::DefId; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; @@ -25,9 +25,9 @@ use super::{ RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt, }; -pub(super) struct ItemLowerer<'a, 'hir> { +pub(super) struct ItemLowerer<'a, 'hir, R> { pub(super) tcx: TyCtxt<'hir>, - pub(super) resolver: &'a mut ResolverAstLowering<'hir>, + pub(super) resolver: &'a mut R, pub(super) ast_index: &'a IndexSlice>, pub(super) owners: &'a mut IndexVec>, } @@ -51,11 +51,11 @@ fn add_ty_alias_where_clause( if before.0 || !after.0 { before } else { after }; } -impl<'a, 'hir> ItemLowerer<'a, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> ItemLowerer<'_, 'hir, R> { fn with_lctx( &mut self, owner: NodeId, - f: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::OwnerNode<'hir>, + f: impl FnOnce(&mut LoweringContext<'_, 'hir, R>) -> hir::OwnerNode<'hir>, ) { let mut lctx = LoweringContext::new(self.tcx, self.ast_index, self.resolver); lctx.with_hir_id_owner(owner, |lctx| f(lctx)); @@ -77,7 +77,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { match node { AstOwner::NonOwner => {} AstOwner::Crate(c) => { - assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID); + assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID); self.with_lctx(CRATE_NODE_ID, |lctx| { let module = lctx.lower_mod(&c.items, &c.spans); // FIXME(jdonszelman): is dummy span ever a problem here? @@ -99,7 +99,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { } } -impl<'hir> LoweringContext<'_, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { pub(super) fn lower_mod( &mut self, items: &[Box], @@ -1475,7 +1475,7 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(crate) fn lower_coroutine_body_with_moved_arguments( &mut self, decl: &FnDecl, - lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir>) -> hir::Expr<'hir>, + lower_body: impl FnOnce(&mut LoweringContext<'_, 'hir, R>) -> hir::Expr<'hir>, fn_decl_span: Span, body_span: Span, coroutine_kind: CoroutineKind, @@ -1612,7 +1612,7 @@ impl<'hir> LoweringContext<'_, 'hir> { parameters.push(new_parameter); } - let mkbody = |this: &mut LoweringContext<'_, 'hir>| { + let mkbody = |this: &mut LoweringContext<'_, 'hir, R>| { // Create a block from the user's function body: let user_body = lower_body(this); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c3525d1246705..f3d082db761b4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -58,7 +58,7 @@ use rustc_hir::{ use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; use rustc_middle::span_bug; -use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; +use rustc_middle::ty::{DelegationFnSig, DelegationInfo, ResolverAstLowering, TyCtxt}; use rustc_session::parse::add_feature_diagnostics; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, DesugaringKind, Span}; @@ -87,7 +87,7 @@ mod pat; mod path; pub mod stability; -struct LoweringContext<'a, 'hir> { +struct LoweringContext<'a, 'hir, R> { tcx: TyCtxt<'hir>, // During lowering of delegation we need to access AST of other functions @@ -98,7 +98,7 @@ struct LoweringContext<'a, 'hir> { // will be in AST index. ast_index: &'a IndexSlice>, - resolver: &'a mut ResolverAstLowering<'hir>, + resolver: &'a mut R, disambiguator: DisambiguatorState, /// Used to allocate HIR nodes. @@ -157,15 +157,14 @@ struct LoweringContext<'a, 'hir> { attribute_parser: AttributeParser<'hir>, } -impl<'a, 'hir> LoweringContext<'a, 'hir> { +impl<'a, 'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'a, 'hir, R> { fn new( tcx: TyCtxt<'hir>, ast_index: &'a IndexSlice>, - resolver: &'a mut ResolverAstLowering<'hir>, + resolver: &'a mut R, ) -> Self { let registered_tools = tcx.registered_tools(()).iter().map(|x| x.name).collect(); Self { - // Pseudo-globals. tcx, ast_index, resolver, @@ -246,9 +245,11 @@ impl SpanLowerer { } } -#[extension(trait ResolverAstLoweringExt)] -impl ResolverAstLowering<'_> { - fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'_>) -> Option> { +// LoweringContext now uses this trait for #153489, if #153489 is not merged, +// feel free to do whatever you want with this trait. +#[extension(trait ResolverAstLoweringExt<'tcx>)] +impl<'tcx> ResolverAstLowering<'tcx> { + fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'tcx>) -> Option> { let ExprKind::Path(None, path) = &expr.kind else { return None; }; @@ -259,7 +260,7 @@ impl ResolverAstLowering<'_> { return None; } - let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?; + let def_id = self.get_partial_res(expr.id)?.full_res()?.opt_def_id()?; // We only support cross-crate argument rewriting. Uses // within the same crate should be updated to use the new @@ -302,9 +303,50 @@ impl ResolverAstLowering<'_> { /// /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring /// should appear at the enclosing `PolyTraitRef`. - fn extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> { + fn extra_lifetime_params(&self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> { self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default() } + + fn delegation_fn_sig(&self, id: LocalDefId) -> Option<&DelegationFnSig> { + self.delegation_fn_sigs.get(&id) + } + + fn delegation_info(&self, id: LocalDefId) -> Option<&DelegationInfo> { + self.delegation_infos.get(&id) + } + + fn opt_local_def_id(&self, id: NodeId) -> Option { + self.node_id_to_def_id.get(&id).copied() + } + + fn local_def_id(&self, id: NodeId) -> LocalDefId { + self.opt_local_def_id(id).expect("must have def_id") + } + + fn lifetime_elision_allowed(&self, id: NodeId) -> bool { + self.lifetime_elision_allowed.contains(&id) + } + + fn insert_new_def_id(&mut self, node_id: NodeId, def_id: LocalDefId) { + self.node_id_to_def_id.insert(node_id, def_id); + } + + fn insert_partial_res(&mut self, node_id: NodeId, res: PartialRes) { + self.partial_res_map.insert(node_id, res); + } + + fn trait_candidates(&self, node_id: NodeId) -> Option<&'tcx [hir::TraitCandidate<'tcx>]> { + self.trait_map.get(&node_id).copied() + } + + #[inline] + fn next_node_id(&mut self) -> NodeId { + let start = self.next_node_id; + let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds"); + self.next_node_id = ast::NodeId::from_u32(next); + + start + } } /// How relaxed bounds `?Trait` should be treated. @@ -444,42 +486,43 @@ enum TryBlockScope { Heterogeneous(HirId), } -fn index_crate<'a>( - node_id_to_def_id: &NodeMap, +fn index_crate<'a, 'b>( + resolver: &'b impl ResolverAstLoweringExt<'a>, krate: &'a Crate, ) -> IndexVec> { - let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() }; + let mut indexer = Indexer { resolver, index: IndexVec::new() }; *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) = AstOwner::Crate(krate); visit::walk_crate(&mut indexer, krate); + return indexer.index; - struct Indexer<'s, 'a> { - node_id_to_def_id: &'s NodeMap, + struct Indexer<'a, 'b, R> { + resolver: &'b R, index: IndexVec>, } - impl<'a> visit::Visitor<'a> for Indexer<'_, 'a> { + impl<'a, 'b, R: ResolverAstLoweringExt<'a>> visit::Visitor<'a> for Indexer<'a, 'b, R> { fn visit_attribute(&mut self, _: &'a Attribute) { // We do not want to lower expressions that appear in attributes, // as they are not accessible to the rest of the HIR. } fn visit_item(&mut self, item: &'a ast::Item) { - let def_id = self.node_id_to_def_id[&item.id]; + let def_id = self.resolver.local_def_id(item.id); *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item); visit::walk_item(self, item) } fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) { - let def_id = self.node_id_to_def_id[&item.id]; + let def_id = self.resolver.local_def_id(item.id); *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::AssocItem(item, ctxt); visit::walk_assoc_item(self, item, ctxt); } fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) { - let def_id = self.node_id_to_def_id[&item.id]; + let def_id = self.resolver.local_def_id(item.id); *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::ForeignItem(item); visit::walk_item(self, item); @@ -519,7 +562,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> { tcx.ensure_done().get_lang_items(()); let (mut resolver, krate) = tcx.resolver_for_lowering().steal(); - let ast_index = index_crate(&resolver.node_id_to_def_id, &krate); + let ast_index = index_crate(&resolver, &krate); let mut owners = IndexVec::from_fn_n( |_| hir::MaybeOwner::Phantom, tcx.definitions_untracked().def_index_count(), @@ -531,6 +574,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> { ast_index: &ast_index, owners: &mut owners, }; + for def_id in ast_index.indices() { lowerer.lower_node(def_id); } @@ -577,7 +621,7 @@ enum GenericArgsMode { Silence, } -impl<'a, 'hir> LoweringContext<'a, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { fn create_def( &mut self, node_id: ast::NodeId, @@ -603,22 +647,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .def_id(); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); - self.resolver.node_id_to_def_id.insert(node_id, def_id); + self.resolver.insert_new_def_id(node_id, def_id); def_id } fn next_node_id(&mut self) -> NodeId { - let start = self.resolver.next_node_id; - let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds"); - self.resolver.next_node_id = ast::NodeId::from_u32(next); - start + self.resolver.next_node_id() } /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name /// resolver (if any). fn opt_local_def_id(&self, node: NodeId) -> Option { - self.resolver.node_id_to_def_id.get(&node).copied() + self.resolver.opt_local_def_id(node) } fn local_def_id(&self, node: NodeId) -> LocalDefId { @@ -747,7 +788,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); } - if let Some(&traits) = self.resolver.trait_map.get(&ast_node_id) { + if let Some(traits) = self.resolver.trait_candidates(ast_node_id) { self.trait_map.insert(hir_id.local_id, traits); } @@ -1764,7 +1805,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { inputs, output, c_variadic, - lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id), + lifetime_elision_allowed: self.resolver.lifetime_elision_allowed(fn_node_id), implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| { let is_mutable_pat = matches!( arg.pat.kind, @@ -2951,7 +2992,10 @@ impl<'hir> GenericArgsCtor<'hir> { && self.parenthesized == hir::GenericArgsParentheses::No } - fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> { + fn into_generic_args( + self, + this: &LoweringContext<'_, 'hir, impl ResolverAstLoweringExt<'hir>>, + ) -> &'hir hir::GenericArgs<'hir> { let ga = hir::GenericArgs { args: this.arena.alloc_from_iter(self.args), constraints: self.constraints, diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index e066bce95158d..e73b342e964fd 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -15,7 +15,7 @@ use super::errors::{ use super::{ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt}; use crate::{AllowReturnTypeNotation, ImplTraitPosition}; -impl<'a, 'hir> LoweringContext<'a, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { pub(crate) fn lower_pat(&mut self, pattern: &Pat) -> &'hir hir::Pat<'hir> { self.arena.alloc(self.lower_pat_mut(pattern)) } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index ec57720387c02..83cebed3a4594 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -19,7 +19,7 @@ use super::{ LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt, }; -impl<'a, 'hir> LoweringContext<'a, 'hir> { +impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> { #[instrument(level = "trace", skip(self))] pub(crate) fn lower_qpath( &mut self,