From 1c2f6ad4c3c80a5a4d188248671aa850863e5a00 Mon Sep 17 00:00:00 2001 From: "addie.sh" Date: Wed, 3 Jun 2026 17:22:00 +0200 Subject: [PATCH 1/4] all of this --- .../src/attributes/rustc_dump.rs | 18 +++++ compiler/rustc_attr_parsing/src/context.rs | 1 + compiler/rustc_feature/src/builtin_attrs.rs | 1 + .../rustc_hir/src/attrs/data_structures.rs | 3 + .../rustc_hir/src/attrs/encode_cross_crate.rs | 1 + .../rustc_hir_analysis/src/collect/dump.rs | 18 +++++ compiler/rustc_hir_analysis/src/lib.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + library/backtrace | 2 +- .../rustc-dev-guide/src/compiler-debugging.md | 1 + tests/ui/attributes/dump_generics.rs | 18 +++++ tests/ui/attributes/dump_generics.stderr | 71 +++++++++++++++++++ 13 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 tests/ui/attributes/dump_generics.rs create mode 100644 tests/ui/attributes/dump_generics.stderr diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs index a80a46e90ac0c..84c5c6d840cfd 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs @@ -45,6 +45,24 @@ impl SingleAttributeParser for RustcDumpDefPathParser { } } +pub(crate) struct RustcDumpGenericsParser; + +impl NoArgsAttributeParser for RustcDumpGenericsParser { + const PATH: &[Symbol] = &[sym::rustc_dump_generics]; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Struct), + Allow(Target::Enum), + Allow(Target::Union), + Allow(Target::Trait), + Allow(Target::Fn), + Allow(Target::Closure), + Allow(Target::Union), + Allow(Target::TyAlias), + Allow(Target::TraitAlias), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpGenerics; +} + pub(crate) struct RustcDumpHiddenTypeOfOpaquesParser; impl NoArgsAttributeParser for RustcDumpHiddenTypeOfOpaquesParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 8d56717be48aa..ebfcf8d58bdec 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -275,6 +275,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 673ac38a1d338..f78c6875440c8 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -491,6 +491,7 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[ sym::rustc_strict_coherence, sym::rustc_dump_variances, sym::rustc_dump_variances_of_opaques, + sym::rustc_dump_generics, sym::rustc_dump_hidden_type_of_opaques, sym::rustc_dump_layout, sym::rustc_abi, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 4ff56a640c19e..1cd72d66873a7 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1359,6 +1359,9 @@ pub enum AttributeKind { /// Represents `#[rustc_dump_def_path]` RustcDumpDefPath(Span), + /// Represents `#[rustc_dump_generics]` + RustcDumpGenerics, + /// Represents `#[rustc_dump_hidden_type_of_opaques]` RustcDumpHiddenTypeOfOpaques, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index 7169fa433ffd8..e252ce56c1de1 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -126,6 +126,7 @@ impl AttributeKind { RustcDummy => No, RustcDumpDefParents => No, RustcDumpDefPath(..) => No, + RustcDumpGenerics => No, RustcDumpHiddenTypeOfOpaques => No, RustcDumpInferredOutlives => No, RustcDumpItemBounds => No, diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 6f875a5bbde49..80654dd822a51 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -6,6 +6,24 @@ use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, Unnormalized}; use rustc_span::sym; +pub(crate) fn generics(tcx: TyCtxt<'_>) { + for iid in tcx.hir_free_items() { + let did = iid.owner_id.def_id; + if find_attr!(tcx, did, RustcDumpGenerics) { + let span = tcx.def_span(did); + + let mut diag = tcx + .dcx() + .struct_span_err(span, format!("{}: {did:?}", sym::rustc_dump_generics.as_str())); + + let current_did = did.to_def_id(); + let generics = tcx.generics_of(current_did); + diag.span_note(tcx.def_span(did), format!("{generics:#?}")); + diag.emit(); + } + } +} + pub(crate) fn opaque_hidden_types(tcx: TyCtxt<'_>) { if !find_attr!(tcx, crate, RustcDumpHiddenTypeOfOpaques) { return; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 1e9bc80749881..24d6411294645 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -201,6 +201,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { tcx.sess.time("dumping_rustc_attr_data", || { outlives::dump::inferred_outlives(tcx); variance::dump::variances(tcx); + collect::dump::generics(tcx); collect::dump::opaque_hidden_types(tcx); collect::dump::predicates_and_item_bounds(tcx); collect::dump::def_parents(tcx); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index a265325fd8e77..eb5a595b06405 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -342,6 +342,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { AttributeKind::RustcDummy => (), AttributeKind::RustcDumpDefParents => (), AttributeKind::RustcDumpDefPath(..) => (), + AttributeKind::RustcDumpGenerics => (), AttributeKind::RustcDumpHiddenTypeOfOpaques => (), AttributeKind::RustcDumpInferredOutlives => (), AttributeKind::RustcDumpItemBounds => (), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7263680c302f1..cfbcced3d6351 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1744,6 +1744,7 @@ symbols! { rustc_dummy, rustc_dump_def_parents, rustc_dump_def_path, + rustc_dump_generics, rustc_dump_hidden_type_of_opaques, rustc_dump_inferred_outlives, rustc_dump_item_bounds, diff --git a/library/backtrace b/library/backtrace index 28ec93b503bf0..0cc1553f13b63 160000 --- a/library/backtrace +++ b/library/backtrace @@ -1 +1 @@ -Subproject commit 28ec93b503bf0410745bc3d571bf3dc1caac3019 +Subproject commit 0cc1553f13b63404a9d71ff69171172d3cd26d27 diff --git a/src/doc/rustc-dev-guide/src/compiler-debugging.md b/src/doc/rustc-dev-guide/src/compiler-debugging.md index dc9d4b9a5cfe1..1750dee1f34ae 100644 --- a/src/doc/rustc-dev-guide/src/compiler-debugging.md +++ b/src/doc/rustc-dev-guide/src/compiler-debugging.md @@ -275,6 +275,7 @@ Here are some notable ones: |----------------|-------------| | `rustc_dump_def_parents` | Dumps the chain of `DefId` parents of certain definitions. | | `rustc_dump_def_path` | Dumps the [`def_path_str`] of an item. | +| `rustc_dump_generics` | Dumps the generics of an item. | | `rustc_dump_hidden_type_of_opaques` | Dumps the [hidden type of each opaque types][opaq] in the crate. | | `rustc_dump_inferred_outlives` | Dumps implied bounds of an item. More precisely, the [`inferred_outlives_of`] an item. | | `rustc_dump_item_bounds` | Dumps the [`item_bounds`] of an item. | diff --git a/tests/ui/attributes/dump_generics.rs b/tests/ui/attributes/dump_generics.rs new file mode 100644 index 0000000000000..2a91c86937e6e --- /dev/null +++ b/tests/ui/attributes/dump_generics.rs @@ -0,0 +1,18 @@ +//adashdkashdkajsd@ normalize-stderr-test "DefId\(.+?\)" -> "DefId(..)" +#![feature(rustc_attrs)] + +fn bar() { + fn foo() { + fn baz() { + || { + qux::<'_, '_, 400, u32, u64>(); + }; + } + } +} + +#[rustc_dump_generics] +const fn qux<'a: 'a, 'b: 'b, const N: usize, T, U>() {} +//~^ ERROR: rustc_dump_generics: DefId(0:8 ~ dump_generics[c1f6]::qux) + +fn main() {} diff --git a/tests/ui/attributes/dump_generics.stderr b/tests/ui/attributes/dump_generics.stderr new file mode 100644 index 0000000000000..d8a3b2f97e4c9 --- /dev/null +++ b/tests/ui/attributes/dump_generics.stderr @@ -0,0 +1,71 @@ +error: rustc_dump_generics: DefId(0:8 ~ dump_generics[c1f6]::qux) + --> $DIR/dump_generics.rs:15:1 + | +LL | const fn qux<'a: 'a, 'b: 'b, const N: usize, T, U>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: Generics { + parent: None, + parent_count: 0, + own_params: [ + GenericParamDef { + name: "'a", + def_id: DefId(0:9 ~ dump_generics[c1f6]::qux::'a), + index: 0, + pure_wrt_drop: false, + kind: Lifetime, + }, + GenericParamDef { + name: "'b", + def_id: DefId(0:10 ~ dump_generics[c1f6]::qux::'b), + index: 1, + pure_wrt_drop: false, + kind: Lifetime, + }, + GenericParamDef { + name: "N", + def_id: DefId(0:11 ~ dump_generics[c1f6]::qux::N), + index: 2, + pure_wrt_drop: false, + kind: Const { + has_default: false, + }, + }, + GenericParamDef { + name: "T", + def_id: DefId(0:12 ~ dump_generics[c1f6]::qux::T), + index: 3, + pure_wrt_drop: false, + kind: Type { + has_default: false, + synthetic: false, + }, + }, + GenericParamDef { + name: "U", + def_id: DefId(0:13 ~ dump_generics[c1f6]::qux::U), + index: 4, + pure_wrt_drop: false, + kind: Type { + has_default: false, + synthetic: false, + }, + }, + ], + param_def_id_to_index: { + DefId(0:9 ~ dump_generics[c1f6]::qux::'a): 0, + DefId(0:11 ~ dump_generics[c1f6]::qux::N): 2, + DefId(0:12 ~ dump_generics[c1f6]::qux::T): 3, + DefId(0:10 ~ dump_generics[c1f6]::qux::'b): 1, + DefId(0:13 ~ dump_generics[c1f6]::qux::U): 4, + }, + has_self: false, + has_late_bound_regions: None, + } + --> $DIR/dump_generics.rs:15:1 + | +LL | const fn qux<'a: 'a, 'b: 'b, const N: usize, T, U>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + From 08cf89c12179a07534ed23dcd7fd8dd97f6f9632 Mon Sep 17 00:00:00 2001 From: "addie.sh" Date: Wed, 3 Jun 2026 17:06:42 +0200 Subject: [PATCH 2/4] remove keysmash --- tests/ui/attributes/dump_generics.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/ui/attributes/dump_generics.rs b/tests/ui/attributes/dump_generics.rs index 2a91c86937e6e..944a6185bfeb3 100644 --- a/tests/ui/attributes/dump_generics.rs +++ b/tests/ui/attributes/dump_generics.rs @@ -1,4 +1,5 @@ -//adashdkashdkajsd@ normalize-stderr-test "DefId\(.+?\)" -> "DefId(..)" +//@ normalize-stderr: "DefId\(.+?\)" -> "DefId(..)" + #![feature(rustc_attrs)] fn bar() { From bce83d79233e32f623354fe781a4c2f171d1045e Mon Sep 17 00:00:00 2001 From: "addie.sh" Date: Wed, 3 Jun 2026 17:38:49 +0200 Subject: [PATCH 3/4] add stability attrib --- compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs index 84c5c6d840cfd..4d23a11b974c4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs @@ -60,6 +60,7 @@ impl NoArgsAttributeParser for RustcDumpGenericsParser { Allow(Target::TyAlias), Allow(Target::TraitAlias), ]); + const STABILITY: AttributeStability = unstable!(rustc_attrs); const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpGenerics; } From 2b51d967120cebfffd1b3cbbb54587cd655c655f Mon Sep 17 00:00:00 2001 From: "addie.sh" Date: Wed, 3 Jun 2026 19:23:54 +0200 Subject: [PATCH 4/4] i never knew git could be this frustrating, only a matter of time before I'm indoctrinated into using jj --- tests/ui/attributes/dump_generics.stderr | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/ui/attributes/dump_generics.stderr b/tests/ui/attributes/dump_generics.stderr index d8a3b2f97e4c9..7b8563e6b3f2a 100644 --- a/tests/ui/attributes/dump_generics.stderr +++ b/tests/ui/attributes/dump_generics.stderr @@ -1,5 +1,5 @@ -error: rustc_dump_generics: DefId(0:8 ~ dump_generics[c1f6]::qux) - --> $DIR/dump_generics.rs:15:1 +error: rustc_dump_generics: DefId(..) + --> $DIR/dump_generics.rs:16:1 | LL | const fn qux<'a: 'a, 'b: 'b, const N: usize, T, U>() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -10,21 +10,21 @@ note: Generics { own_params: [ GenericParamDef { name: "'a", - def_id: DefId(0:9 ~ dump_generics[c1f6]::qux::'a), + def_id: DefId(..), index: 0, pure_wrt_drop: false, kind: Lifetime, }, GenericParamDef { name: "'b", - def_id: DefId(0:10 ~ dump_generics[c1f6]::qux::'b), + def_id: DefId(..), index: 1, pure_wrt_drop: false, kind: Lifetime, }, GenericParamDef { name: "N", - def_id: DefId(0:11 ~ dump_generics[c1f6]::qux::N), + def_id: DefId(..), index: 2, pure_wrt_drop: false, kind: Const { @@ -33,7 +33,7 @@ note: Generics { }, GenericParamDef { name: "T", - def_id: DefId(0:12 ~ dump_generics[c1f6]::qux::T), + def_id: DefId(..), index: 3, pure_wrt_drop: false, kind: Type { @@ -43,7 +43,7 @@ note: Generics { }, GenericParamDef { name: "U", - def_id: DefId(0:13 ~ dump_generics[c1f6]::qux::U), + def_id: DefId(..), index: 4, pure_wrt_drop: false, kind: Type { @@ -53,16 +53,16 @@ note: Generics { }, ], param_def_id_to_index: { - DefId(0:9 ~ dump_generics[c1f6]::qux::'a): 0, - DefId(0:11 ~ dump_generics[c1f6]::qux::N): 2, - DefId(0:12 ~ dump_generics[c1f6]::qux::T): 3, - DefId(0:10 ~ dump_generics[c1f6]::qux::'b): 1, - DefId(0:13 ~ dump_generics[c1f6]::qux::U): 4, + DefId(..): 0, + DefId(..): 2, + DefId(..): 3, + DefId(..): 1, + DefId(..): 4, }, has_self: false, has_late_bound_regions: None, } - --> $DIR/dump_generics.rs:15:1 + --> $DIR/dump_generics.rs:16:1 | LL | const fn qux<'a: 'a, 'b: 'b, const N: usize, T, U>() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^