From 502d57cb78082efa16ed661ddfb501c189f18321 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Mar 2025 09:02:28 +0000 Subject: [PATCH 1/3] Deduplicate assoc item cfg handling --- compiler/rustc_builtin_macros/src/cfg_eval.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index 5788966b6e7b1..b3ba90731184d 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -121,18 +121,11 @@ impl CfgEval<'_> { let item = parser.parse_item(ForceCollect::Yes)?.unwrap(); Annotatable::Item(self.flat_map_item(item).pop().unwrap()) } - Annotatable::AssocItem(_, AssocCtxt::Trait) => { + Annotatable::AssocItem(_, ctxt) => { let item = parser.parse_trait_item(ForceCollect::Yes)?.unwrap().unwrap(); Annotatable::AssocItem( - self.flat_map_assoc_item(item, AssocCtxt::Trait).pop().unwrap(), - AssocCtxt::Trait, - ) - } - Annotatable::AssocItem(_, AssocCtxt::Impl) => { - let item = parser.parse_impl_item(ForceCollect::Yes)?.unwrap().unwrap(); - Annotatable::AssocItem( - self.flat_map_assoc_item(item, AssocCtxt::Impl).pop().unwrap(), - AssocCtxt::Impl, + self.flat_map_assoc_item(item, ctxt).pop().unwrap(), + ctxt, ) } Annotatable::ForeignItem(_) => { From 7cdc456727fb663bf53232ec414a9001410ac843 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Mar 2025 09:00:35 +0000 Subject: [PATCH 2/3] Track whether an assoc item is in a trait impl or an inherent impl --- compiler/rustc_ast/src/mut_visit.rs | 4 +- compiler/rustc_ast/src/visit.rs | 9 +- compiler/rustc_ast_lowering/src/item.rs | 31 ++---- .../rustc_ast_passes/src/ast_validation.rs | 6 +- compiler/rustc_builtin_macros/src/autodiff.rs | 6 +- compiler/rustc_expand/src/base.rs | 15 ++- compiler/rustc_expand/src/expand.rs | 101 +++++++++++++++--- compiler/rustc_expand/src/placeholders.rs | 14 ++- compiler/rustc_lint/src/early.rs | 4 +- .../rustc_resolve/src/build_reduced_graph.rs | 15 ++- compiler/rustc_resolve/src/late.rs | 4 +- compiler/rustc_resolve/src/lib.rs | 5 - compiler/rustc_resolve/src/macros.rs | 2 +- src/tools/rustfmt/src/visitor.rs | 3 +- 14 files changed, 151 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 4edd086430000..604555e2df748 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -1318,7 +1318,9 @@ impl WalkItemKind for ItemKind { visit_polarity(vis, polarity); visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref)); vis.visit_ty(self_ty); - items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Impl)); + items.flat_map_in_place(|item| { + vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() }) + }); } ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => { visit_safety(vis, safety); diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index ce8d6df75afb2..9f6a53248089d 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -23,7 +23,7 @@ use crate::ptr::P; #[derive(Copy, Clone, Debug, PartialEq)] pub enum AssocCtxt { Trait, - Impl, + Impl { of_trait: bool }, } #[derive(Copy, Clone, Debug, PartialEq)] @@ -422,7 +422,12 @@ impl WalkItemKind for ItemKind { try_visit!(visitor.visit_generics(generics)); visit_opt!(visitor, visit_trait_ref, of_trait); try_visit!(visitor.visit_ty(self_ty)); - walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl); + walk_list!( + visitor, + visit_assoc_item, + items, + AssocCtxt::Impl { of_trait: of_trait.is_some() } + ); } ItemKind::Struct(struct_definition, generics) | ItemKind::Union(struct_definition, generics) => { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 518349343b3a1..cf7ffde836130 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -7,7 +7,6 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_hir::{self as hir, HirId, PredicateOrigin}; use rustc_index::{IndexSlice, IndexVec}; -use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym}; @@ -104,10 +103,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { } fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) { - let def_id = self.resolver.node_id_to_def_id[&item.id]; - let parent_id = self.tcx.local_parent(def_id); - let parent_hir = self.lower_node(parent_id).unwrap(); - self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt, parent_hir)) + self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt)) } fn lower_foreign_item(&mut self, item: &ForeignItem) { @@ -631,29 +627,18 @@ impl<'hir> LoweringContext<'_, 'hir> { } } - fn lower_assoc_item( - &mut self, - item: &AssocItem, - ctxt: AssocCtxt, - parent_hir: &'hir hir::OwnerInfo<'hir>, - ) -> hir::OwnerNode<'hir> { - let parent_item = parent_hir.node().expect_item(); - match parent_item.kind { - hir::ItemKind::Impl(impl_) => { - self.is_in_trait_impl = impl_.of_trait.is_some(); - } - hir::ItemKind::Trait(..) => {} - kind => { - span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr()) - } - } - + fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> { // Evaluate with the lifetimes in `params` in-scope. // This is used to track which lifetimes have already been defined, // and which need to be replicated when lowering an async fn. match ctxt { AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)), - AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)), + AssocCtxt::Impl { of_trait } => { + if of_trait { + self.is_in_trait_impl = of_trait; + } + hir::OwnerNode::ImplItem(self.lower_impl_item(item)) + } } } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 75839e86b8d3a..a1487ca74be87 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -860,7 +860,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { this.visit_trait_ref(t); this.visit_ty(self_ty); - walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl); + walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: true }); }); walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again. @@ -913,7 +913,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { |this| this.visit_generics(generics), ); this.visit_ty(self_ty); - walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl); + walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: false }); }); walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again. @@ -1414,7 +1414,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_defaultness(item.span, item.kind.defaultness()); } - if ctxt == AssocCtxt::Impl { + if let AssocCtxt::Impl { .. } = ctxt { match &item.kind { AssocItemKind::Const(box ConstItem { expr: None, .. }) => { self.dcx().emit_err(errors::AssocConstWithoutBody { diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 6591ed151cf6e..5cd653c794566 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -157,7 +157,7 @@ mod llvm_enzyme { }; (sig.clone(), false) } - Annotatable::AssocItem(assoc_item, _) => { + Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => { let sig = match &assoc_item.kind { ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) => sig, _ => { @@ -296,7 +296,7 @@ mod llvm_enzyme { } Annotatable::Item(iitem.clone()) } - Annotatable::AssocItem(ref mut assoc_item, i @ Impl) => { + Annotatable::AssocItem(ref mut assoc_item, i @ Impl { of_trait: false }) => { if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) { assoc_item.attrs.push(attr); } @@ -327,7 +327,7 @@ mod llvm_enzyme { kind: assoc_item, tokens: None, }); - Annotatable::AssocItem(d_fn, Impl) + Annotatable::AssocItem(d_fn, Impl { of_trait: false }) } else { let mut d_fn = ecx.item(span, d_ident, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf)); diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 1dd152beb475f..990d0f2e028aa 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -153,7 +153,7 @@ impl Annotatable { pub fn expect_impl_item(self) -> P { match self { - Annotatable::AssocItem(i, AssocCtxt::Impl) => i, + Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i, _ => panic!("expected Item"), } } @@ -403,6 +403,11 @@ pub trait MacResult { None } + /// Creates zero or more impl items. + fn make_trait_impl_items(self: Box) -> Option; 1]>> { + None + } + /// Creates zero or more trait items. fn make_trait_items(self: Box) -> Option; 1]>> { None @@ -516,6 +521,10 @@ impl MacResult for MacEager { self.impl_items } + fn make_trait_impl_items(self: Box) -> Option; 1]>> { + self.impl_items + } + fn make_trait_items(self: Box) -> Option; 1]>> { self.trait_items } @@ -613,6 +622,10 @@ impl MacResult for DummyResult { Some(SmallVec::new()) } + fn make_trait_impl_items(self: Box) -> Option; 1]>> { + Some(SmallVec::new()) + } + fn make_trait_items(self: Box) -> Option; 1]>> { Some(SmallVec::new()) } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index e2a557528504a..d0bd8a89d9bdb 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -188,9 +188,15 @@ ast_fragments! { ImplItems(SmallVec<[P; 1]>) { "impl item"; many fn flat_map_assoc_item; - fn visit_assoc_item(AssocCtxt::Impl); + fn visit_assoc_item(AssocCtxt::Impl { of_trait: false }); fn make_impl_items; } + TraitImplItems(SmallVec<[P; 1]>) { + "impl item"; + many fn flat_map_assoc_item; + fn visit_assoc_item(AssocCtxt::Impl { of_trait: true }); + fn make_trait_impl_items; + } ForeignItems(SmallVec<[P; 1]>) { "foreign item"; many fn flat_map_foreign_item; @@ -257,6 +263,7 @@ impl AstFragmentKind { AstFragmentKind::Items | AstFragmentKind::TraitItems | AstFragmentKind::ImplItems + | AstFragmentKind::TraitImplItems | AstFragmentKind::ForeignItems | AstFragmentKind::Crate => SupportsMacroExpansion::Yes { supports_inner_attrs: true }, AstFragmentKind::Arms @@ -306,6 +313,9 @@ impl AstFragmentKind { AstFragmentKind::ImplItems => { AstFragment::ImplItems(items.map(Annotatable::expect_impl_item).collect()) } + AstFragmentKind::TraitImplItems => { + AstFragment::TraitImplItems(items.map(Annotatable::expect_impl_item).collect()) + } AstFragmentKind::TraitItems => { AstFragment::TraitItems(items.map(Annotatable::expect_trait_item).collect()) } @@ -347,10 +357,10 @@ pub enum InvocationKind { }, Attr { attr: ast::Attribute, - // Re-insertion position for inert attributes. + /// Re-insertion position for inert attributes. pos: usize, item: Annotatable, - // Required for resolving derive helper attributes. + /// Required for resolving derive helper attributes. derives: Vec, }, Derive { @@ -360,6 +370,8 @@ pub enum InvocationKind { }, GlobDelegation { item: P, + /// Whether this is a trait impl or an inherent impl + of_trait: bool, }, } @@ -388,7 +400,7 @@ impl Invocation { InvocationKind::Bang { span, .. } => *span, InvocationKind::Attr { attr, .. } => attr.span, InvocationKind::Derive { path, .. } => path.span, - InvocationKind::GlobDelegation { item } => item.span, + InvocationKind::GlobDelegation { item, .. } => item.span, } } @@ -397,7 +409,7 @@ impl Invocation { InvocationKind::Bang { span, .. } => span, InvocationKind::Attr { attr, .. } => &mut attr.span, InvocationKind::Derive { path, .. } => &mut path.span, - InvocationKind::GlobDelegation { item } => &mut item.span, + InvocationKind::GlobDelegation { item, .. } => &mut item.span, } } } @@ -820,7 +832,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } _ => unreachable!(), }, - InvocationKind::GlobDelegation { item } => { + InvocationKind::GlobDelegation { item, of_trait } => { let AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() }; let suffixes = match ext { SyntaxExtensionKind::GlobDelegation(expander) => match expander.expand(self.cx) @@ -829,7 +841,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ExpandResult::Retry(()) => { // Reassemble the original invocation for retrying. return ExpandResult::Retry(Invocation { - kind: InvocationKind::GlobDelegation { item }, + kind: InvocationKind::GlobDelegation { item, of_trait }, ..invoc }); } @@ -847,7 +859,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.cx, deleg, &item, &suffixes, item.span, true, ); fragment_kind.expect_from_annotatables( - single_delegations.map(|item| Annotatable::AssocItem(P(item), AssocCtxt::Impl)), + single_delegations + .map(|item| Annotatable::AssocItem(P(item), AssocCtxt::Impl { of_trait })), ) } }) @@ -973,6 +986,13 @@ pub fn parse_ast_fragment<'a>( } AstFragment::ImplItems(items) } + AstFragmentKind::TraitImplItems => { + let mut items = SmallVec::new(); + while let Some(item) = this.parse_impl_item(ForceCollect::No)? { + items.extend(item); + } + AstFragment::TraitImplItems(items) + } AstFragmentKind::ForeignItems => { let mut items = SmallVec::new(); while let Some(item) = this.parse_foreign_item(ForceCollect::No)? { @@ -1355,13 +1375,13 @@ impl InvocationCollectorNode for AstNodeWrapper, ImplItemTag> type ItemKind = AssocItemKind; const KIND: AstFragmentKind = AstFragmentKind::ImplItems; fn to_annotatable(self) -> Annotatable { - Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl) + Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl { of_trait: false }) } fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { fragment.make_impl_items() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl) + walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: false }) } fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) @@ -1390,6 +1410,47 @@ impl InvocationCollectorNode for AstNodeWrapper, ImplItemTag> } } +struct TraitImplItemTag; +impl InvocationCollectorNode for AstNodeWrapper, TraitImplItemTag> { + type OutputTy = SmallVec<[P; 1]>; + type ItemKind = AssocItemKind; + const KIND: AstFragmentKind = AstFragmentKind::TraitImplItems; + fn to_annotatable(self) -> Annotatable { + Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl { of_trait: true }) + } + fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { + fragment.make_trait_impl_items() + } + fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { + walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: true }) + } + fn is_mac_call(&self) -> bool { + matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) + } + fn take_mac_call(self) -> (P, Self::AttrsTy, AddSemicolon) { + let item = self.wrapped.into_inner(); + match item.kind { + AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No), + _ => unreachable!(), + } + } + fn delegation(&self) -> Option<(&ast::DelegationMac, &ast::Item)> { + match &self.wrapped.kind { + AssocItemKind::DelegationMac(deleg) => Some((deleg, &self.wrapped)), + _ => None, + } + } + fn delegation_item_kind(deleg: Box) -> Self::ItemKind { + AssocItemKind::Delegation(deleg) + } + fn from_item(item: ast::Item) -> Self { + AstNodeWrapper::new(P(item), TraitImplItemTag) + } + fn flatten_outputs(items: impl Iterator) -> Self::OutputTy { + items.flatten().collect() + } +} + impl InvocationCollectorNode for P { const KIND: AstFragmentKind = AstFragmentKind::ForeignItems; fn to_annotatable(self) -> Annotatable { @@ -1855,9 +1916,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { fn collect_glob_delegation( &mut self, item: P, + of_trait: bool, kind: AstFragmentKind, ) -> AstFragment { - self.collect(kind, InvocationKind::GlobDelegation { item }) + self.collect(kind, InvocationKind::GlobDelegation { item, of_trait }) } /// If `item` is an attribute invocation, remove the attribute and return it together with @@ -2030,8 +2092,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { let Some(suffixes) = &deleg.suffixes else { let traitless_qself = matches!(&deleg.qself, Some(qself) if qself.position == 0); - let item = match node.to_annotatable() { - Annotatable::AssocItem(item, AssocCtxt::Impl) => item, + let (item, of_trait) = match node.to_annotatable() { + Annotatable::AssocItem(item, AssocCtxt::Impl { of_trait }) => { + (item, of_trait) + } ann @ (Annotatable::Item(_) | Annotatable::AssocItem(..) | Annotatable::Stmt(_)) => { @@ -2046,7 +2110,9 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { self.cx.dcx().emit_err(GlobDelegationTraitlessQpath { span }); return Default::default(); } - return self.collect_glob_delegation(item, Node::KIND).make_ast::(); + return self + .collect_glob_delegation(item, of_trait, Node::KIND) + .make_ast::(); }; let single_delegations = build_single_delegations::( @@ -2126,7 +2192,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { ) -> SmallVec<[P; 1]> { match ctxt { AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)), - AssocCtxt::Impl => self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag)), + AssocCtxt::Impl { of_trait: false } => { + self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag)) + } + AssocCtxt::Impl { of_trait: true } => { + self.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag)) + } } } diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 3a470924c7f69..a60a87244cc6e 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -86,6 +86,17 @@ pub(crate) fn placeholder( kind: ast::AssocItemKind::MacCall(mac_placeholder()), tokens: None, })]), + AstFragmentKind::TraitImplItems => { + AstFragment::TraitImplItems(smallvec![P(ast::AssocItem { + id, + span, + ident, + vis, + attrs, + kind: ast::AssocItemKind::MacCall(mac_placeholder()), + tokens: None, + })]) + } AstFragmentKind::ForeignItems => { AstFragment::ForeignItems(smallvec![P(ast::ForeignItem { id, @@ -308,7 +319,8 @@ impl MutVisitor for PlaceholderExpander { let it = self.remove(item.id); match ctxt { AssocCtxt::Trait => it.make_trait_items(), - AssocCtxt::Impl => it.make_impl_items(), + AssocCtxt::Impl { of_trait: false } => it.make_impl_items(), + AssocCtxt::Impl { of_trait: true } => it.make_trait_impl_items(), } } _ => walk_flat_map_assoc_item(self, item, ctxt), diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 723b894c43bc4..f9601fa5ef1d8 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -241,7 +241,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast> ast_visit::AssocCtxt::Trait => { lint_callback!(cx, check_trait_item, item); } - ast_visit::AssocCtxt::Impl => { + ast_visit::AssocCtxt::Impl { .. } => { lint_callback!(cx, check_impl_item, item); } } @@ -250,7 +250,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast> ast_visit::AssocCtxt::Trait => { lint_callback!(cx, check_trait_item_post, item); } - ast_visit::AssocCtxt::Impl => { + ast_visit::AssocCtxt::Impl { .. } => { lint_callback!(cx, check_impl_item_post, item); } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 763e9207a126b..2e70019ba8ad0 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -884,10 +884,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> { } // These items do not add names to modules. - ItemKind::Impl(box Impl { of_trait: Some(..), .. }) => { - self.r.trait_impl_items.insert(local_def_id); - } - ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {} + ItemKind::Impl(box Impl { of_trait: Some(..), .. }) + | ItemKind::Impl { .. } + | ItemKind::ForeignMod(..) + | ItemKind::GlobalAsm(..) => {} ItemKind::MacroDef(..) | ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => { unreachable!() @@ -1378,7 +1378,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { AssocCtxt::Trait => { self.visit_invoc_in_module(item.id); } - AssocCtxt::Impl => { + AssocCtxt::Impl { .. } => { let invoc_id = item.id.placeholder_to_expn_id(); if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) { self.r @@ -1398,9 +1398,8 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { let local_def_id = feed.key(); let def_id = local_def_id.to_def_id(); - if !(ctxt == AssocCtxt::Impl - && matches!(item.vis.kind, ast::VisibilityKind::Inherited) - && self.r.trait_impl_items.contains(&self.r.tcx.local_parent(local_def_id))) + if !(matches!(ctxt, AssocCtxt::Impl { of_trait: true }) + && matches!(item.vis.kind, ast::VisibilityKind::Inherited)) { // Trait impl item visibility is inherited from its trait when not specified // explicitly. In that case we cannot determine it here in early resolve, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index e04d0083548b1..177a2d00ac3cc 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3376,7 +3376,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |i, s, c| MethodNotMemberOfTrait(i, s, c), ); - visit::walk_assoc_item(this, item, AssocCtxt::Impl) + visit::walk_assoc_item(this, item, AssocCtxt::Impl { of_trait: true }) }, ); @@ -3410,7 +3410,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |i, s, c| TypeNotMemberOfTrait(i, s, c), ); - visit::walk_assoc_item(this, item, AssocCtxt::Impl) + visit::walk_assoc_item(this, item, AssocCtxt::Impl { of_trait: true }) }); }, ); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ff31af0025b54..e37acdd1ce721 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1191,10 +1191,6 @@ pub struct Resolver<'ra, 'tcx> { /// and how the `impl Trait` fragments were introduced. invocation_parents: FxHashMap, - /// Some way to know that we are in a *trait* impl in `visit_assoc_item`. - /// FIXME: Replace with a more general AST map (together with some other fields). - trait_impl_items: FxHashSet, - legacy_const_generic_args: FxHashMap>>, /// Amount of lifetime parameters for each item in the crate. item_generics_num_lifetimes: FxHashMap, @@ -1558,7 +1554,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { def_id_to_node_id, placeholder_field_indices: Default::default(), invocation_parents, - trait_impl_items: Default::default(), legacy_const_generic_args: Default::default(), item_generics_num_lifetimes: Default::default(), main_def: Default::default(), diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 34441d313f59f..aef98330e17e0 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -264,7 +264,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { } InvocationKind::Bang { ref mac, .. } => (&mac.path, MacroKind::Bang), InvocationKind::Derive { ref path, .. } => (path, MacroKind::Derive), - InvocationKind::GlobDelegation { ref item } => { + InvocationKind::GlobDelegation { ref item, .. } => { let ast::AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() }; deleg_impl = Some(self.invocation_parent(invoc_id)); // It is sufficient to consider glob delegation a bang macro for now. diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs index a5cfc542a17c8..5749d8c63faf4 100644 --- a/src/tools/rustfmt/src/visitor.rs +++ b/src/tools/rustfmt/src/visitor.rs @@ -624,7 +624,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { // TODO(calebcartwright): Not sure the skip spans are correct let (ai, skip_span, assoc_ctxt) = match visitor_kind { AssocTraitItem(ai) => (*ai, ai.span(), visit::AssocCtxt::Trait), - AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl), + // There is no difference between trait and inherent assoc item formatting + AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl { of_trait: false }), _ => unreachable!(), }; skip_out_of_file_lines_range_visitor!(self, ai.span); From 59e3380744d84c16c23e8d74438c515839306f99 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 25 Mar 2025 10:17:44 +0000 Subject: [PATCH 3/3] Avoid some more global state --- compiler/rustc_ast_lowering/src/delegation.rs | 16 ++++++-- compiler/rustc_ast_lowering/src/item.rs | 39 +++++++++++-------- compiler/rustc_ast_lowering/src/lib.rs | 2 - 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index efc1fa05c5f92..f7640c602d6fd 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -61,8 +61,14 @@ pub(crate) struct DelegationResults<'hir> { impl<'hir> LoweringContext<'_, 'hir> { /// Defines whether the delegatee is an associated function whose first parameter is `self`. - pub(crate) fn delegatee_is_method(&self, item_id: NodeId, path_id: NodeId, span: Span) -> bool { - let sig_id = self.get_delegation_sig_id(item_id, path_id, span); + pub(crate) fn delegatee_is_method( + &self, + item_id: NodeId, + path_id: NodeId, + span: Span, + is_in_trait_impl: bool, + ) -> bool { + let sig_id = self.get_delegation_sig_id(item_id, path_id, span, is_in_trait_impl); let Ok(sig_id) = sig_id else { return false; }; @@ -88,9 +94,10 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, delegation: &Delegation, item_id: NodeId, + is_in_trait_impl: bool, ) -> DelegationResults<'hir> { let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span); - let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span); + let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl); match sig_id { Ok(sig_id) => { let (param_count, c_variadic) = self.param_count(sig_id); @@ -110,8 +117,9 @@ impl<'hir> LoweringContext<'_, 'hir> { item_id: NodeId, path_id: NodeId, span: Span, + is_in_trait_impl: bool, ) -> Result { - let sig_id = if self.is_in_trait_impl { item_id } else { path_id }; + let sig_id = if is_in_trait_impl { item_id } else { path_id }; self.get_resolution_id(sig_id, span) } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index cf7ffde836130..2b4b379525bcf 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -404,10 +404,11 @@ impl<'hir> LoweringContext<'_, 'hir> { (trait_ref, lowered_ty) }); - self.is_in_trait_impl = trait_ref.is_some(); - let new_impl_items = self - .arena - .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item))); + let new_impl_items = self.arena.alloc_from_iter( + impl_items + .iter() + .map(|item| self.lower_impl_item_ref(item, trait_ref.is_some())), + ); // `defaultness.has_value()` is never called for an `impl`, always `true` in order // to not cause an assertion failure inside the `lower_defaultness` function. @@ -484,7 +485,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::Delegation(box delegation) => { debug_assert_ne!(ident.name, kw::Empty); let ident = self.lower_ident(ident); - let delegation_results = self.lower_delegation(delegation, id); + let delegation_results = self.lower_delegation(delegation, id, false); hir::ItemKind::Fn { ident, sig: delegation_results.sig, @@ -634,10 +635,7 @@ impl<'hir> LoweringContext<'_, 'hir> { match ctxt { AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)), AssocCtxt::Impl { of_trait } => { - if of_trait { - self.is_in_trait_impl = of_trait; - } - hir::OwnerNode::ImplItem(self.lower_impl_item(item)) + hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait)) } } } @@ -879,7 +877,7 @@ impl<'hir> LoweringContext<'_, 'hir> { (generics, kind, ty.is_some()) } AssocItemKind::Delegation(box delegation) => { - let delegation_results = self.lower_delegation(delegation, i.id); + let delegation_results = self.lower_delegation(delegation, i.id, false); let item_kind = hir::TraitItemKind::Fn( delegation_results.sig, hir::TraitFn::Provided(delegation_results.body_id), @@ -910,7 +908,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } } AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn { - has_self: self.delegatee_is_method(i.id, delegation.id, i.span), + has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false), }, AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { panic!("macros should have been expanded by now") @@ -930,7 +928,11 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(span, hir::ExprKind::Err(guar)) } - fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { + fn lower_impl_item( + &mut self, + i: &AssocItem, + is_in_trait_impl: bool, + ) -> &'hir hir::ImplItem<'hir> { debug_assert_ne!(i.ident.name, kw::Empty); // Since `default impl` is not yet implemented, this is always true in impls. let has_value = true; @@ -966,7 +968,7 @@ impl<'hir> LoweringContext<'_, 'hir> { generics, sig, i.id, - if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent }, + if is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent }, sig.header.coroutine_kind, attrs, ); @@ -1006,7 +1008,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) } AssocItemKind::Delegation(box delegation) => { - let delegation_results = self.lower_delegation(delegation, i.id); + let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl); ( delegation_results.generics, hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id), @@ -1029,7 +1031,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.arena.alloc(item) } - fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef { + fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef { hir::ImplItemRef { id: hir::ImplItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } }, ident: self.lower_ident(i.ident), @@ -1041,7 +1043,12 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } } AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn { - has_self: self.delegatee_is_method(i.id, delegation.id, i.span), + has_self: self.delegatee_is_method( + i.id, + delegation.id, + i.span, + is_in_trait_impl, + ), }, AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { panic!("macros should have been expanded by now") diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e08850da4a7a8..32e20f3f6f250 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -121,7 +121,6 @@ struct LoweringContext<'a, 'hir> { catch_scope: Option, loop_scope: Option, is_in_loop_condition: bool, - is_in_trait_impl: bool, is_in_dyn_type: bool, current_hir_id_owner: hir::OwnerId, @@ -173,7 +172,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { catch_scope: None, loop_scope: None, is_in_loop_condition: false, - is_in_trait_impl: false, is_in_dyn_type: false, coroutine_kind: None, task_context: None,