diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs index a80a46e90ac0c..4d23a11b974c4 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_dump.rs @@ -45,6 +45,25 @@ 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 STABILITY: AttributeStability = unstable!(rustc_attrs); + 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..944a6185bfeb3 --- /dev/null +++ b/tests/ui/attributes/dump_generics.rs @@ -0,0 +1,19 @@ +//@ normalize-stderr: "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..7b8563e6b3f2a --- /dev/null +++ b/tests/ui/attributes/dump_generics.stderr @@ -0,0 +1,71 @@ +error: rustc_dump_generics: DefId(..) + --> $DIR/dump_generics.rs:16: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(..), + index: 0, + pure_wrt_drop: false, + kind: Lifetime, + }, + GenericParamDef { + name: "'b", + def_id: DefId(..), + index: 1, + pure_wrt_drop: false, + kind: Lifetime, + }, + GenericParamDef { + name: "N", + def_id: DefId(..), + index: 2, + pure_wrt_drop: false, + kind: Const { + has_default: false, + }, + }, + GenericParamDef { + name: "T", + def_id: DefId(..), + index: 3, + pure_wrt_drop: false, + kind: Type { + has_default: false, + synthetic: false, + }, + }, + GenericParamDef { + name: "U", + def_id: DefId(..), + index: 4, + pure_wrt_drop: false, + kind: Type { + has_default: false, + synthetic: false, + }, + }, + ], + param_def_id_to_index: { + DefId(..): 0, + DefId(..): 2, + DefId(..): 3, + DefId(..): 1, + DefId(..): 4, + }, + has_self: false, + has_late_bound_regions: None, + } + --> $DIR/dump_generics.rs:16:1 + | +LL | const fn qux<'a: 'a, 'b: 'b, const N: usize, T, U>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error +