diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-07-01 08:53:07 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-01 08:53:07 +0200 |
| commit | b067ee82f83b339609808d25e704fa457645445e (patch) | |
| tree | 5a05df0adc87667cee02be8c59f320cdb5da8a9a | |
| parent | c7e64dcbf155b237a1662a6377e6157bfc5bf316 (diff) | |
| parent | 552794410a9237a26aded88990dbe8be26c72dfc (diff) | |
Rollup merge of #127181 - BoxyUwU:dump_def_parents, r=compiler-errors
Introduce a `rustc_` attribute to dump all the `DefId` parents of a `DefId` We've run into a bunch of issues with anon consts having the wrong generics and it would have been incredibly helpful to be able to quickly slap a `rustc_` attribute to check what `tcx.parent(` will return on the relevant DefIds. I wasn't sure of a better way to make this work for anon consts than requiring the attribute to be on the enclosing item and then walking the inside of it to look for any anon consts. This particular method will honestly break at some point when we stop having a `DefId` available for anon consts in hir but that's for another day... r? ``@compiler-errors``
| -rw-r--r-- | compiler/rustc_feature/src/builtin_attrs.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect/dump.rs | 50 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/lib.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 | ||||
| -rw-r--r-- | tests/ui/attributes/dump_def_parents.rs | 34 | ||||
| -rw-r--r-- | tests/ui/attributes/dump_def_parents.stderr | 128 |
6 files changed, 217 insertions, 1 deletions
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index a4245f0908e..910402d5499 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1118,6 +1118,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ WarnFollowing, EncodeCrossCrate::No ), rustc_attr!( + TEST, rustc_dump_def_parents, Normal, template!(Word), + WarnFollowing, EncodeCrossCrate::No + ), + rustc_attr!( TEST, rustc_object_lifetime_default, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::No ), diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs index 85e1c600d6d..c73d3a5390d 100644 --- a/compiler/rustc_hir_analysis/src/collect/dump.rs +++ b/compiler/rustc_hir_analysis/src/collect/dump.rs @@ -1,5 +1,7 @@ use rustc_hir::def::DefKind; -use rustc_hir::def_id::CRATE_DEF_ID; +use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; +use rustc_hir::intravisit; +use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::ty::TyCtxt; use rustc_span::sym; @@ -41,3 +43,49 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) { } } } + +pub(crate) fn def_parents(tcx: TyCtxt<'_>) { + for did in tcx.hir().body_owners() { + if tcx.has_attr(did, sym::rustc_dump_def_parents) { + struct AnonConstFinder<'tcx> { + tcx: TyCtxt<'tcx>, + anon_consts: Vec<LocalDefId>, + } + + impl<'tcx> intravisit::Visitor<'tcx> for AnonConstFinder<'tcx> { + type NestedFilter = OnlyBodies; + + fn nested_visit_map(&mut self) -> Self::Map { + self.tcx.hir() + } + + fn visit_anon_const(&mut self, c: &'tcx rustc_hir::AnonConst) { + self.anon_consts.push(c.def_id); + intravisit::walk_anon_const(self, c) + } + } + + // Look for any anon consts inside of this body owner as there is no way to apply + // the `rustc_dump_def_parents` attribute to the anon const so it would not be possible + // to see what its def parent is. + let mut anon_ct_finder = AnonConstFinder { tcx, anon_consts: vec![] }; + intravisit::walk_expr(&mut anon_ct_finder, tcx.hir().body_owned_by(did).value); + + for did in [did].into_iter().chain(anon_ct_finder.anon_consts) { + let span = tcx.def_span(did); + + let mut diag = tcx.dcx().struct_span_err( + span, + format!("{}: {did:?}", sym::rustc_dump_def_parents.as_str()), + ); + + let mut current_did = did.to_def_id(); + while let Some(parent_did) = tcx.opt_parent(current_did) { + current_did = parent_did; + diag.span_note(tcx.def_span(parent_did), format!("{parent_did:?}")); + } + diag.emit(); + } + } + } +} diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index cf41f51f748..44f1830a3b1 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -175,6 +175,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) { tcx.sess.time("variance_dumping", || variance::dump::variances(tcx)); collect::dump::opaque_hidden_types(tcx); collect::dump::predicates_and_item_bounds(tcx); + collect::dump::def_parents(tcx); } // Make sure we evaluate all static and (non-associated) const items, even if unused. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 8b7a63f5eb9..7da9211bcbf 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1614,6 +1614,7 @@ symbols! { rustc_do_not_const_check, rustc_doc_primitive, rustc_dummy, + rustc_dump_def_parents, rustc_dump_item_bounds, rustc_dump_predicates, rustc_dump_user_args, diff --git a/tests/ui/attributes/dump_def_parents.rs b/tests/ui/attributes/dump_def_parents.rs new file mode 100644 index 00000000000..af1c210d2cd --- /dev/null +++ b/tests/ui/attributes/dump_def_parents.rs @@ -0,0 +1,34 @@ +//@ normalize-stderr-test "DefId\(.+?\)" -> "DefId(..)" +#![feature(rustc_attrs)] + +fn bar() { + fn foo() { + fn baz() { + #[rustc_dump_def_parents] + || { + //~^ ERROR: rustc_dump_def_parents: DefId + qux::< + { + //~^ ERROR: rustc_dump_def_parents: DefId + fn inhibits_dump() { + qux::< + { + "hi"; + 1 + }, + >(); + } + + qux::<{ 1 + 1 }>(); + //~^ ERROR: rustc_dump_def_parents: DefId + 1 + }, + >(); + }; + } + } +} + +const fn qux<const N: usize>() {} + +fn main() {} diff --git a/tests/ui/attributes/dump_def_parents.stderr b/tests/ui/attributes/dump_def_parents.stderr new file mode 100644 index 00000000000..b2cc32d09b0 --- /dev/null +++ b/tests/ui/attributes/dump_def_parents.stderr @@ -0,0 +1,128 @@ +error: rustc_dump_def_parents: DefId(..) + --> $DIR/dump_def_parents.rs:8:13 + | +LL | || { + | ^^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:6:9 + | +LL | fn baz() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:5:5 + | +LL | fn foo() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:4:1 + | +LL | fn bar() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:2:1 + | +LL | / #![feature(rustc_attrs)] +LL | | +LL | | fn bar() { +LL | | fn foo() { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: rustc_dump_def_parents: DefId(..) + --> $DIR/dump_def_parents.rs:11:21 + | +LL | / { +LL | | +LL | | fn inhibits_dump() { +LL | | qux::< +... | +LL | | 1 +LL | | }, + | |_____________________^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:8:13 + | +LL | || { + | ^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:6:9 + | +LL | fn baz() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:5:5 + | +LL | fn foo() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:4:1 + | +LL | fn bar() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:2:1 + | +LL | / #![feature(rustc_attrs)] +LL | | +LL | | fn bar() { +LL | | fn foo() { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: rustc_dump_def_parents: DefId(..) + --> $DIR/dump_def_parents.rs:22:31 + | +LL | qux::<{ 1 + 1 }>(); + | ^^^^^^^^^ + | +note: DefId(..) + --> $DIR/dump_def_parents.rs:11:21 + | +LL | / { +LL | | +LL | | fn inhibits_dump() { +LL | | qux::< +... | +LL | | 1 +LL | | }, + | |_____________________^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:8:13 + | +LL | || { + | ^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:6:9 + | +LL | fn baz() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:5:5 + | +LL | fn foo() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:4:1 + | +LL | fn bar() { + | ^^^^^^^^ +note: DefId(..) + --> $DIR/dump_def_parents.rs:2:1 + | +LL | / #![feature(rustc_attrs)] +LL | | +LL | | fn bar() { +LL | | fn foo() { +... | +LL | | +LL | | fn main() {} + | |____________^ + +error: aborting due to 3 previous errors + |
