From d1cb52cfa36e8292c9724b6818e445b6ca65e459 Mon Sep 17 00:00:00 2001 From: Edvin Bryntesson Date: Mon, 9 Feb 2026 00:36:07 +0100 Subject: [PATCH] remove unnecessary iteration over almost all items in the dep graph instead just check and emit this attribute error through `check_attr.rs` --- Cargo.lock | 2 + compiler/rustc_interface/src/passes.rs | 6 -- compiler/rustc_passes/Cargo.toml | 2 + compiler/rustc_passes/src/check_attr.rs | 69 +++++++++++++++- compiler/rustc_symbol_mangling/src/lib.rs | 1 - compiler/rustc_symbol_mangling/src/test.rs | 96 ---------------------- tests/ui/symbol-names/impl1.legacy.stderr | 48 +++++------ tests/ui/symbol-names/impl1.v0.stderr | 48 +++++------ 8 files changed, 118 insertions(+), 154 deletions(-) delete mode 100644 compiler/rustc_symbol_mangling/src/test.rs diff --git a/Cargo.lock b/Cargo.lock index 545c776b4805e..c9a6bbbb796c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4392,6 +4392,7 @@ dependencies = [ name = "rustc_passes" version = "0.0.0" dependencies = [ + "rustc-demangle", "rustc_abi", "rustc_ast", "rustc_ast_lowering", @@ -4407,6 +4408,7 @@ dependencies = [ "rustc_privacy", "rustc_session", "rustc_span", + "rustc_symbol_mangling", "rustc_target", "rustc_trait_selection", "tracing", diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 42ef66847858a..ea6855e917897 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1232,12 +1232,6 @@ pub(crate) fn start_codegen<'tcx>( tcx.ensure_ok().trigger_delayed_bug(def_id); } - // Don't run this test assertions when not doing codegen. Compiletest tries to build - // build-fail tests in check mode first and expects it to not give an error in that case. - if tcx.sess.opts.output_types.should_codegen() { - rustc_symbol_mangling::test::report_symbol_names(tcx); - } - // Don't do code generation if there were any errors. Likewise if // there were any delayed bugs, because codegen will likely cause // more ICEs, obscuring the original problem. diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index b65a0ad404a53..4a14c397947a0 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -5,6 +5,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start +rustc-demangle = "0.1.27" rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_lowering = { path = "../rustc_ast_lowering" } @@ -20,6 +21,7 @@ rustc_middle = { path = "../rustc_middle" } rustc_privacy = { path = "../rustc_privacy" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } +rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } tracing = "0.1" diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 5f8e887675d0f..2f0ce13c06669 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -38,7 +38,8 @@ use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::{self, TyCtxt, TypingMode}; +use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::{self, GenericArgs, TyCtxt, TypingMode}; use rustc_middle::{bug, span_bug}; use rustc_session::config::CrateType; use rustc_session::lint; @@ -231,6 +232,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_rustc_must_implement_one_of(*attr_span, fn_names, hir_id,target) }, Attribute::Parsed(AttributeKind::DoNotRecommend{attr_span}) => {self.check_do_not_recommend(*attr_span, hir_id, target, item)}, + Attribute::Parsed(AttributeKind::RustcSymbolName(attr_span)) => { + self.check_rustc_symbol_name(*attr_span, hir_id, target) + } + Attribute::Parsed(AttributeKind::RustcDefPath(attr_span)) => { + self.check_rustc_def_path(*attr_span, hir_id, target); + } Attribute::Parsed( // tidy-alphabetical-start AttributeKind::RustcAllowIncoherentImpl(..) @@ -300,7 +307,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcConfusables { .. } | AttributeKind::RustcConstStabilityIndirect | AttributeKind::RustcDeallocator - | AttributeKind::RustcDefPath(..) | AttributeKind::RustcDelayedBugFromInsideQuery | AttributeKind::RustcDenyExplicitImpl(..) | AttributeKind::RustcDummy @@ -347,7 +353,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcSkipDuringMethodDispatch { .. } | AttributeKind::RustcSpecializationTrait(..) | AttributeKind::RustcStdInternalSymbol (..) - | AttributeKind::RustcSymbolName(..) | AttributeKind::RustcThenThisWouldNeed(..) | AttributeKind::RustcUnsafeSpecializationMarker(..) | AttributeKind::RustcVariance @@ -507,6 +512,64 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_mix_no_mangle_export(hir_id, attrs); } + fn is_valid_symbol_attr(&self, target: &Target) -> bool { + self.tcx.sess.opts.output_types.should_codegen() + && [ + Target::Fn, + Target::Method(MethodKind::TraitImpl), + Target::Method(MethodKind::Inherent), + Target::Method(MethodKind::Trait { body: true }), + Target::ForeignFn, + Target::ForeignStatic, + Target::Impl { of_trait: false }, + ] + .contains(target) + } + + fn check_rustc_symbol_name(&self, attr_span: Span, hir_id: HirId, target: Target) { + use rustc_symbol_mangling::errors::{Kind, TestOutput}; + let tcx = self.tcx; + if !self.is_valid_symbol_attr(&target) { + return; + } + let def_id = hir_id.owner.def_id.to_def_id(); + let instance = ty::Instance::new_raw( + def_id, + tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(tcx, def_id)), + ); + let mangled = tcx.symbol_name(instance); + tcx.dcx().emit_err(TestOutput { + span: attr_span, + kind: Kind::SymbolName, + content: format!("{mangled}"), + }); + if let Ok(demangling) = rustc_demangle::try_demangle(mangled.name) { + tcx.dcx().emit_err(TestOutput { + span: attr_span, + kind: Kind::Demangling, + content: format!("{demangling}"), + }); + tcx.dcx().emit_err(TestOutput { + span: attr_span, + kind: Kind::DemanglingAlt, + content: format!("{demangling:#}"), + }); + } + } + + fn check_rustc_def_path(&self, attr_span: Span, hir_id: HirId, target: Target) { + use rustc_symbol_mangling::errors::{Kind, TestOutput}; + let tcx = self.tcx; + if !self.is_valid_symbol_attr(&target) { + return; + } + tcx.dcx().emit_err(TestOutput { + span: attr_span, + kind: Kind::DefPath, + content: with_no_trimmed_paths!(tcx.def_path_str(hir_id.owner.def_id)), + }); + } + fn check_rustc_must_implement_one_of( &self, attr_span: Span, diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 7e126cb6a6e95..9c62e109be8ef 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -106,7 +106,6 @@ mod legacy; mod v0; pub mod errors; -pub mod test; pub use v0::mangle_internal_symbol; diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs deleted file mode 100644 index 8f842e0300113..0000000000000 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ /dev/null @@ -1,96 +0,0 @@ -//! Walks the crate looking for items/impl-items/trait-items that have -//! either a `rustc_symbol_name` or `rustc_def_path` attribute and -//! generates an error giving, respectively, the symbol name or -//! def-path. This is used for unit testing the code that generates -//! paths etc in all kinds of annoying scenarios. - -use rustc_hir::attrs::AttributeKind; -use rustc_hir::def_id::LocalDefId; -use rustc_hir::find_attr; -use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{GenericArgs, Instance, TyCtxt}; - -use crate::errors::{Kind, TestOutput}; - -pub fn report_symbol_names(tcx: TyCtxt<'_>) { - // if the `rustc_attrs` feature is not enabled, then the - // attributes we are interested in cannot be present anyway, so - // skip the walk. - if !tcx.features().rustc_attrs() { - return; - } - - tcx.dep_graph.with_ignore(|| { - let mut symbol_names = SymbolNamesTest { tcx }; - let crate_items = tcx.hir_crate_items(()); - - for id in crate_items.free_items() { - symbol_names.process_attrs(id.owner_id.def_id); - } - - for id in crate_items.trait_items() { - symbol_names.process_attrs(id.owner_id.def_id); - } - - for id in crate_items.impl_items() { - symbol_names.process_attrs(id.owner_id.def_id); - } - - for id in crate_items.foreign_items() { - symbol_names.process_attrs(id.owner_id.def_id); - } - }) -} - -struct SymbolNamesTest<'tcx> { - tcx: TyCtxt<'tcx>, -} - -impl SymbolNamesTest<'_> { - fn process_attrs(&mut self, def_id: LocalDefId) { - let tcx = self.tcx; - // The formatting of `tag({})` is chosen so that tests can elect - // to test the entirety of the string, if they choose, or else just - // some subset. - - if let Some(attr_span) = find_attr!( - tcx.get_all_attrs(def_id), - AttributeKind::RustcSymbolName(span) => span - ) { - let def_id = def_id.to_def_id(); - let instance = Instance::new_raw( - def_id, - tcx.erase_and_anonymize_regions(GenericArgs::identity_for_item(tcx, def_id)), - ); - let mangled = tcx.symbol_name(instance); - tcx.dcx().emit_err(TestOutput { - span: *attr_span, - kind: Kind::SymbolName, - content: format!("{mangled}"), - }); - if let Ok(demangling) = rustc_demangle::try_demangle(mangled.name) { - tcx.dcx().emit_err(TestOutput { - span: *attr_span, - kind: Kind::Demangling, - content: format!("{demangling}"), - }); - tcx.dcx().emit_err(TestOutput { - span: *attr_span, - kind: Kind::DemanglingAlt, - content: format!("{demangling:#}"), - }); - } - } - - if let Some(attr_span) = find_attr!( - tcx.get_all_attrs(def_id), - AttributeKind::RustcDefPath(span) => span - ) { - tcx.dcx().emit_err(TestOutput { - span: *attr_span, - kind: Kind::DefPath, - content: with_no_trimmed_paths!(tcx.def_path_str(def_id)), - }); - } - } -} diff --git a/tests/ui/symbol-names/impl1.legacy.stderr b/tests/ui/symbol-names/impl1.legacy.stderr index 3d438df92b85d..e8edbce50eb90 100644 --- a/tests/ui/symbol-names/impl1.legacy.stderr +++ b/tests/ui/symbol-names/impl1.legacy.stderr @@ -1,3 +1,27 @@ +error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17) + --> $DIR/impl1.rs:62:13 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::) + --> $DIR/impl1.rs:62:13 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method) + --> $DIR/impl1.rs:62:13 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: def-path(<[&dyn Foo extern "C" fn(&'a u8, ...)> + AutoTrait; 3] as main::{closure#1}::Bar>::method) + --> $DIR/impl1.rs:69:13 + | +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ + error: symbol-name(_ZN5impl13foo3Foo3bar17) --> $DIR/impl1.rs:14:9 | @@ -46,29 +70,5 @@ error: def-path(bar::::baz) LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_ZN209_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$C$$u20$...$RP$$u2b$impl1..AutoTrait$u3b$$u20$3$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method17) - --> $DIR/impl1.rs:62:13 - | -LL | #[rustc_symbol_name] - | ^^^^^^^^^^^^^^^^^^^^ - -error: demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method::) - --> $DIR/impl1.rs:62:13 - | -LL | #[rustc_symbol_name] - | ^^^^^^^^^^^^^^^^^^^^ - -error: demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8, ::.)+impl1::AutoTrait; 3] as impl1::main::{{closure}}::Bar>::method) - --> $DIR/impl1.rs:62:13 - | -LL | #[rustc_symbol_name] - | ^^^^^^^^^^^^^^^^^^^^ - -error: def-path(<[&dyn Foo extern "C" fn(&'a u8, ...)> + AutoTrait; 3] as main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:69:13 - | -LL | #[rustc_def_path] - | ^^^^^^^^^^^^^^^^^ - error: aborting due to 12 previous errors diff --git a/tests/ui/symbol-names/impl1.v0.stderr b/tests/ui/symbol-names/impl1.v0.stderr index a7cc5fc8ed211..9b3326900b7bb 100644 --- a/tests/ui/symbol-names/impl1.v0.stderr +++ b/tests/ui/symbol-names/impl1.v0.stderr @@ -1,3 +1,27 @@ +error: symbol-name(_RNvXNCNvCsCRATE_HASH_5impl14mains_0ARDNtB_3Foop5AssocFG_KCRL0_hvEuNtB_9AutoTraitEL_j3_NtB_3Bar6method) + --> $DIR/impl1.rs:62:13 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling(<[&dyn impl1[d5591eb39db23cbb]::Foo extern "C" fn(&'a u8, ...)> + impl1[d5591eb39db23cbb]::AutoTrait; 3usize] as impl1[d5591eb39db23cbb]::main::{closure#1}::Bar>::method) + --> $DIR/impl1.rs:62:13 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) + --> $DIR/impl1.rs:62:13 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: def-path(<[&dyn Foo extern "C" fn(&'a u8, ...)> + AutoTrait; 3] as main::{closure#1}::Bar>::method) + --> $DIR/impl1.rs:69:13 + | +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ + error: symbol-name(_RNvMNtCsCRATE_HASH_5impl13fooNtB_3Foo3bar) --> $DIR/impl1.rs:14:9 | @@ -46,29 +70,5 @@ error: def-path(bar::::baz) LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_RNvXNCNvCsCRATE_HASH_5impl14mains_0ARDNtB_3Foop5AssocFG_KCRL0_hvEuNtB_9AutoTraitEL_j3_NtB_3Bar6method) - --> $DIR/impl1.rs:62:13 - | -LL | #[rustc_symbol_name] - | ^^^^^^^^^^^^^^^^^^^^ - -error: demangling(<[&dyn impl1[d5591eb39db23cbb]::Foo extern "C" fn(&'a u8, ...)> + impl1[d5591eb39db23cbb]::AutoTrait; 3usize] as impl1[d5591eb39db23cbb]::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:62:13 - | -LL | #[rustc_symbol_name] - | ^^^^^^^^^^^^^^^^^^^^ - -error: demangling-alt(<[&dyn impl1::Foo extern "C" fn(&'a u8, ...)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:62:13 - | -LL | #[rustc_symbol_name] - | ^^^^^^^^^^^^^^^^^^^^ - -error: def-path(<[&dyn Foo extern "C" fn(&'a u8, ...)> + AutoTrait; 3] as main::{closure#1}::Bar>::method) - --> $DIR/impl1.rs:69:13 - | -LL | #[rustc_def_path] - | ^^^^^^^^^^^^^^^^^ - error: aborting due to 12 previous errors