From 277e049d918226981f86be50d10dde25282b022f Mon Sep 17 00:00:00 2001
From: Noah Lev <camelidcamel@gmail.com>
Date: Thu, 28 Nov 2024 22:04:03 -0800
Subject: [PATCH] Move `Const::{from_anon_const,try_from_lit}` to
 hir_ty_lowering

These operations are much more about lowering the HIR than about
`Const`s themselves. They fit better in hir_ty_lowering with
`lower_const_arg` (formerly `Const::from_const_arg`) and the rest.

To accomplish this, `const_evaluatable_predicates_of` had to be changed
to not use `from_anon_const` anymore. Instead of visiting the HIR and
lowering anon consts on the fly, it now visits the `rustc_middle::ty`
data structures instead and directly looks for `UnevaluatedConst`s. This
approach was proposed in:
https://github.com/rust-lang/rust/pull/131081#discussion_r1821189257
---
 .../rustc_hir_analysis/src/check/wfcheck.rs   | 21 ++--
 .../rustc_hir_analysis/src/collect/dump.rs    | 11 ++-
 .../src/collect/predicates_of.rs              | 96 +++++++++++--------
 .../src/hir_ty_lowering/mod.rs                | 88 ++++++++++++++++-
 compiler/rustc_middle/src/ty/consts.rs        | 84 +---------------
 tests/crashes/121429.rs                       | 13 +--
 tests/ui/attributes/dump_def_parents.rs       |  5 +-
 tests/ui/attributes/dump_def_parents.stderr   | 79 ++++++++++++---
 .../issues/cg-in-dyn-issue-128176.rs}         |  6 +-
 .../const-generics/issues/issue-83765.stderr  |  8 +-
 10 files changed, 244 insertions(+), 167 deletions(-)
 rename tests/{crashes/128176.rs => ui/const-generics/issues/cg-in-dyn-issue-128176.rs} (71%)

diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 8fa797db246..ed3ae1e12b9 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -13,6 +13,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
 use rustc_macros::LintDiagnostic;
+use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::trait_def::TraitSpecializationKind;
@@ -1170,19 +1171,13 @@ fn check_type_defn<'tcx>(
 
             // Explicit `enum` discriminant values must const-evaluate successfully.
             if let ty::VariantDiscr::Explicit(discr_def_id) = variant.discr {
-                let cause = traits::ObligationCause::new(
-                    tcx.def_span(discr_def_id),
-                    wfcx.body_def_id,
-                    ObligationCauseCode::Misc,
-                );
-                wfcx.register_obligation(Obligation::new(
-                    tcx,
-                    cause,
-                    wfcx.param_env,
-                    ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(
-                        ty::Const::from_anon_const(tcx, discr_def_id.expect_local()),
-                    ))),
-                ));
+                match tcx.const_eval_poly(discr_def_id) {
+                    Ok(_) => {}
+                    Err(ErrorHandled::Reported(..)) => {}
+                    Err(ErrorHandled::TooGeneric(sp)) => {
+                        span_bug!(sp, "enum variant discr was too generic to eval")
+                    }
+                }
             }
         }
 
diff --git a/compiler/rustc_hir_analysis/src/collect/dump.rs b/compiler/rustc_hir_analysis/src/collect/dump.rs
index 8648a7d1e32..f1022d95753 100644
--- a/compiler/rustc_hir_analysis/src/collect/dump.rs
+++ b/compiler/rustc_hir_analysis/src/collect/dump.rs
@@ -1,6 +1,6 @@
 use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
 use rustc_hir::intravisit;
-use rustc_middle::hir::nested_filter::OnlyBodies;
+use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::sym;
 
@@ -42,7 +42,8 @@ pub(crate) fn predicates_and_item_bounds(tcx: TyCtxt<'_>) {
 }
 
 pub(crate) fn def_parents(tcx: TyCtxt<'_>) {
-    for did in tcx.hir().body_owners() {
+    for iid in tcx.hir().items() {
+        let did = iid.owner_id.def_id;
         if tcx.has_attr(did, sym::rustc_dump_def_parents) {
             struct AnonConstFinder<'tcx> {
                 tcx: TyCtxt<'tcx>,
@@ -50,7 +51,7 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) {
             }
 
             impl<'tcx> intravisit::Visitor<'tcx> for AnonConstFinder<'tcx> {
-                type NestedFilter = OnlyBodies;
+                type NestedFilter = nested_filter::All;
 
                 fn nested_visit_map(&mut self) -> Self::Map {
                     self.tcx.hir()
@@ -62,11 +63,11 @@ pub(crate) fn def_parents(tcx: TyCtxt<'_>) {
                 }
             }
 
-            // Look for any anon consts inside of this body owner as there is no way to apply
+            // Look for any anon consts inside of this item 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);
+            intravisit::walk_item(&mut anon_ct_finder, tcx.hir().item(iid));
 
             for did in [did].into_iter().chain(anon_ct_finder.anon_consts) {
                 let span = tcx.def_span(did);
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index bfee5d33598..ca2597e79fd 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -1,12 +1,13 @@
 use std::assert_matches::assert_matches;
 
-use hir::{HirId, Node};
+use hir::Node;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::intravisit::{self, Visitor};
-use rustc_middle::ty::{self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, Upcast};
+use rustc_middle::ty::{
+    self, GenericPredicates, ImplTraitInTraitData, Ty, TyCtxt, TypeVisitable, TypeVisitor, Upcast,
+};
 use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::Ident;
 use rustc_span::{DUMMY_SP, Span};
@@ -305,7 +306,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     }
 
     if tcx.features().generic_const_exprs() {
-        predicates.extend(const_evaluatable_predicates_of(tcx, def_id));
+        predicates.extend(const_evaluatable_predicates_of(tcx, def_id, &predicates));
     }
 
     let mut predicates: Vec<_> = predicates.into_iter().collect();
@@ -369,32 +370,48 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
     }
 }
 
-fn const_evaluatable_predicates_of(
-    tcx: TyCtxt<'_>,
+#[instrument(level = "debug", skip(tcx, predicates), ret)]
+fn const_evaluatable_predicates_of<'tcx>(
+    tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
-) -> FxIndexSet<(ty::Clause<'_>, Span)> {
+    predicates: &FxIndexSet<(ty::Clause<'tcx>, Span)>,
+) -> FxIndexSet<(ty::Clause<'tcx>, Span)> {
     struct ConstCollector<'tcx> {
         tcx: TyCtxt<'tcx>,
         preds: FxIndexSet<(ty::Clause<'tcx>, Span)>,
     }
 
-    impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> {
-        fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
-            let ct = ty::Const::from_anon_const(self.tcx, c.def_id);
-            if let ty::ConstKind::Unevaluated(_) = ct.kind() {
-                let span = self.tcx.def_span(c.def_id);
-                self.preds.insert((ty::ClauseKind::ConstEvaluatable(ct).upcast(self.tcx), span));
-            }
-        }
+    fn is_const_param_default(tcx: TyCtxt<'_>, def: LocalDefId) -> bool {
+        let hir_id = tcx.local_def_id_to_hir_id(def);
+        let (_, parent_node) = tcx
+            .hir()
+            .parent_iter(hir_id)
+            .skip_while(|(_, n)| matches!(n, Node::ConstArg(..)))
+            .next()
+            .unwrap();
+        matches!(
+            parent_node,
+            Node::GenericParam(hir::GenericParam { kind: hir::GenericParamKind::Const { .. }, .. })
+        )
+    }
 
-        fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::ConstArg<'tcx>) {
-            // Do not look into const param defaults,
-            // these get checked when they are actually instantiated.
-            //
-            // We do not want the following to error:
-            //
-            //     struct Foo<const N: usize, const M: usize = { N + 1 }>;
-            //     struct Bar<const N: usize>(Foo<N, 3>);
+    impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstCollector<'tcx> {
+        fn visit_const(&mut self, c: ty::Const<'tcx>) {
+            if let ty::ConstKind::Unevaluated(uv) = c.kind() {
+                if is_const_param_default(self.tcx, uv.def.expect_local()) {
+                    // Do not look into const param defaults,
+                    // these get checked when they are actually instantiated.
+                    //
+                    // We do not want the following to error:
+                    //
+                    //     struct Foo<const N: usize, const M: usize = { N + 1 }>;
+                    //     struct Bar<const N: usize>(Foo<N, 3>);
+                    return;
+                }
+
+                let span = self.tcx.def_span(uv.def);
+                self.preds.insert((ty::ClauseKind::ConstEvaluatable(c).upcast(self.tcx), span));
+            }
         }
     }
 
@@ -402,29 +419,32 @@ fn const_evaluatable_predicates_of(
     let node = tcx.hir_node(hir_id);
 
     let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
+
+    for (clause, _sp) in predicates {
+        clause.visit_with(&mut collector);
+    }
+
     if let hir::Node::Item(item) = node
-        && let hir::ItemKind::Impl(impl_) = item.kind
+        && let hir::ItemKind::Impl(_) = item.kind
     {
-        if let Some(of_trait) = &impl_.of_trait {
-            debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id);
-            collector.visit_trait_ref(of_trait);
+        if let Some(of_trait) = tcx.impl_trait_ref(def_id) {
+            debug!("visit impl trait_ref");
+            of_trait.instantiate_identity().visit_with(&mut collector);
         }
 
-        debug!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id);
-        collector.visit_ty(impl_.self_ty);
+        debug!("visit self_ty");
+        let self_ty = tcx.type_of(def_id);
+        self_ty.instantiate_identity().visit_with(&mut collector);
     }
 
-    if let Some(generics) = node.generics() {
-        debug!("const_evaluatable_predicates_of({:?}): visit_generics", def_id);
-        collector.visit_generics(generics);
+    if let Some(_) = tcx.hir().fn_sig_by_hir_id(hir_id) {
+        debug!("visit fn sig");
+        let fn_sig = tcx.fn_sig(def_id);
+        let fn_sig = fn_sig.instantiate_identity();
+        debug!(?fn_sig);
+        fn_sig.visit_with(&mut collector);
     }
 
-    if let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(hir_id) {
-        debug!("const_evaluatable_predicates_of({:?}): visit_fn_decl", def_id);
-        collector.visit_fn_decl(fn_sig.decl);
-    }
-    debug!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.preds);
-
     collector.preds
 }
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 7b8e95f3434..cb4209116ac 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2089,7 +2089,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 qpath.span(),
                 format!("Const::lower_const_arg: invalid qpath {qpath:?}"),
             ),
-            hir::ConstArgKind::Anon(anon) => Const::from_anon_const(tcx, anon.def_id),
+            hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon.def_id),
             hir::ConstArgKind::Infer(span) => self.ct_infer(None, span),
         }
     }
@@ -2177,6 +2177,92 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
     }
 
+    /// Literals and const generic parameters are eagerly converted to a constant, everything else
+    /// becomes `Unevaluated`.
+    #[instrument(skip(self), level = "debug")]
+    fn lower_anon_const(&self, def: LocalDefId) -> Const<'tcx> {
+        let tcx = self.tcx();
+
+        let body_id = match tcx.hir_node_by_def_id(def) {
+            hir::Node::AnonConst(ac) => ac.body,
+            node => span_bug!(
+                tcx.def_span(def.to_def_id()),
+                "from_anon_const can only process anonymous constants, not {node:?}"
+            ),
+        };
+
+        let expr = &tcx.hir().body(body_id).value;
+        debug!(?expr);
+
+        let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic");
+
+        match self.try_lower_anon_const_lit(ty, expr) {
+            Some(v) => v,
+            None => ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst {
+                def: def.to_def_id(),
+                args: ty::GenericArgs::identity_for_item(tcx, def.to_def_id()),
+            }),
+        }
+    }
+
+    #[instrument(skip(self), level = "debug")]
+    fn try_lower_anon_const_lit(
+        &self,
+        ty: Ty<'tcx>,
+        expr: &'tcx hir::Expr<'tcx>,
+    ) -> Option<Const<'tcx>> {
+        let tcx = self.tcx();
+
+        // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
+        // currently have to be wrapped in curly brackets, so it's necessary to special-case.
+        let expr = match &expr.kind {
+            hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
+                block.expr.as_ref().unwrap()
+            }
+            _ => expr,
+        };
+
+        if let hir::ExprKind::Path(hir::QPath::Resolved(
+            _,
+            &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
+        )) = expr.kind
+        {
+            span_bug!(
+                expr.span,
+                "try_lower_anon_const_lit: received const param which shouldn't be possible"
+            );
+        };
+
+        let lit_input = match expr.kind {
+            hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
+            hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
+                hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }),
+                _ => None,
+            },
+            _ => None,
+        };
+
+        if let Some(lit_input) = lit_input {
+            // If an error occurred, ignore that it's a literal and leave reporting the error up to
+            // mir.
+            match tcx.at(expr.span).lit_to_const(lit_input) {
+                Ok(c) => return Some(c),
+                Err(_) if lit_input.ty.has_aliases() => {
+                    // allow the `ty` to be an alias type, though we cannot handle it here
+                    return None;
+                }
+                Err(e) => {
+                    tcx.dcx().span_delayed_bug(
+                        expr.span,
+                        format!("try_lower_anon_const_lit: couldn't lit_to_const {e:?}"),
+                    );
+                }
+            }
+        }
+
+        None
+    }
+
     fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
         let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
         match idx {
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index d27205e26ab..31055276422 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -2,15 +2,11 @@ use std::borrow::Cow;
 
 use rustc_data_structures::intern::Interned;
 use rustc_error_messages::MultiSpan;
-use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::LocalDefId;
-use rustc_hir::{self as hir};
 use rustc_macros::HashStable;
 use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};
-use tracing::{debug, instrument};
 
-use crate::mir::interpret::{LitToConstInput, Scalar};
-use crate::ty::{self, GenericArgs, Ty, TyCtxt, TypeVisitableExt};
+use crate::mir::interpret::Scalar;
+use crate::ty::{self, Ty, TyCtxt};
 
 mod int;
 mod kind;
@@ -181,82 +177,6 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
 }
 
 impl<'tcx> Const<'tcx> {
-    // FIXME: move this and try_from_lit to hir_ty_lowering like lower_const_arg/from_const_arg
-    /// Literals and const generic parameters are eagerly converted to a constant, everything else
-    /// becomes `Unevaluated`.
-    #[instrument(skip(tcx), level = "debug")]
-    pub fn from_anon_const(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Self {
-        let body_id = match tcx.hir_node_by_def_id(def) {
-            hir::Node::AnonConst(ac) => ac.body,
-            node => span_bug!(
-                tcx.def_span(def.to_def_id()),
-                "from_anon_const can only process anonymous constants, not {node:?}"
-            ),
-        };
-
-        let expr = &tcx.hir().body(body_id).value;
-        debug!(?expr);
-
-        let ty = tcx.type_of(def).no_bound_vars().expect("const parameter types cannot be generic");
-
-        match Self::try_from_lit(tcx, ty, expr) {
-            Some(v) => v,
-            None => ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst {
-                def: def.to_def_id(),
-                args: GenericArgs::identity_for_item(tcx, def.to_def_id()),
-            }),
-        }
-    }
-
-    #[instrument(skip(tcx), level = "debug")]
-    fn try_from_lit(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, expr: &'tcx hir::Expr<'tcx>) -> Option<Self> {
-        // Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
-        // currently have to be wrapped in curly brackets, so it's necessary to special-case.
-        let expr = match &expr.kind {
-            hir::ExprKind::Block(block, _) if block.stmts.is_empty() && block.expr.is_some() => {
-                block.expr.as_ref().unwrap()
-            }
-            _ => expr,
-        };
-
-        if let hir::ExprKind::Path(hir::QPath::Resolved(
-            _,
-            &hir::Path { res: Res::Def(DefKind::ConstParam, _), .. },
-        )) = expr.kind
-        {
-            span_bug!(expr.span, "try_from_lit: received const param which shouldn't be possible");
-        };
-
-        let lit_input = match expr.kind {
-            hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
-            hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
-                hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }),
-                _ => None,
-            },
-            _ => None,
-        };
-
-        if let Some(lit_input) = lit_input {
-            // If an error occurred, ignore that it's a literal and leave reporting the error up to
-            // mir.
-            match tcx.at(expr.span).lit_to_const(lit_input) {
-                Ok(c) => return Some(c),
-                Err(_) if lit_input.ty.has_aliases() => {
-                    // allow the `ty` to be an alias type, though we cannot handle it here
-                    return None;
-                }
-                Err(e) => {
-                    tcx.dcx().span_delayed_bug(
-                        expr.span,
-                        format!("Const::try_from_lit: couldn't lit_to_const {e:?}"),
-                    );
-                }
-            }
-        }
-
-        None
-    }
-
     /// Creates a constant with the given integer value and interns it.
     #[inline]
     pub fn from_bits(
diff --git a/tests/crashes/121429.rs b/tests/crashes/121429.rs
index 09bd343e0ba..e407754db5c 100644
--- a/tests/crashes/121429.rs
+++ b/tests/crashes/121429.rs
@@ -1,13 +1,10 @@
 //@ known-bug: #121429
+
 #![feature(generic_const_exprs)]
-
-pub trait True {}
-
-impl<const N: usize = { const { 3 } }> PartialEq<FixedI8<FRAC_RHS>> for FixedI8<FRAC_LHS> where
-    If<{}>: True
-{
-}
-#![feature(generic_const_exprs)]
+
+struct FixedI8<const X: usize>;
+const FRAC_LHS: usize = 0;
+const FRAC_RHS: usize = 1;
 
 pub trait True {}
 
diff --git a/tests/ui/attributes/dump_def_parents.rs b/tests/ui/attributes/dump_def_parents.rs
index de0c88bb6c3..04a725f6c14 100644
--- a/tests/ui/attributes/dump_def_parents.rs
+++ b/tests/ui/attributes/dump_def_parents.rs
@@ -3,16 +3,17 @@
 
 fn bar() {
     fn foo() {
+        #[rustc_dump_def_parents]
         fn baz() {
-            #[rustc_dump_def_parents]
+            //~^ ERROR: rustc_dump_def_parents: DefId
             || {
-                //~^ ERROR: rustc_dump_def_parents: DefId
                 qux::<
                     {
                         //~^ ERROR: rustc_dump_def_parents: DefId
                         fn inhibits_dump() {
                             qux::<
                                 {
+                                    //~^ ERROR: rustc_dump_def_parents: DefId
                                     "hi";
                                     1
                                 },
diff --git a/tests/ui/attributes/dump_def_parents.stderr b/tests/ui/attributes/dump_def_parents.stderr
index b2cc32d09b0..a928e8e33a4 100644
--- a/tests/ui/attributes/dump_def_parents.stderr
+++ b/tests/ui/attributes/dump_def_parents.stderr
@@ -1,14 +1,9 @@
 error: rustc_dump_def_parents: DefId(..)
-  --> $DIR/dump_def_parents.rs:8:13
-   |
-LL |             || {
-   |             ^^
-   |
-note: DefId(..)
-  --> $DIR/dump_def_parents.rs:6:9
+  --> $DIR/dump_def_parents.rs:7:9
    |
 LL |         fn baz() {
    |         ^^^^^^^^
+   |
 note: DefId(..)
   --> $DIR/dump_def_parents.rs:5:5
    |
@@ -44,12 +39,12 @@ LL | |                     },
    | |_____________________^
    |
 note: DefId(..)
-  --> $DIR/dump_def_parents.rs:8:13
+  --> $DIR/dump_def_parents.rs:9:13
    |
 LL |             || {
    |             ^^
 note: DefId(..)
-  --> $DIR/dump_def_parents.rs:6:9
+  --> $DIR/dump_def_parents.rs:7:9
    |
 LL |         fn baz() {
    |         ^^^^^^^^
@@ -76,7 +71,65 @@ LL | | fn main() {}
    | |____________^
 
 error: rustc_dump_def_parents: DefId(..)
-  --> $DIR/dump_def_parents.rs:22:31
+  --> $DIR/dump_def_parents.rs:15:33
+   |
+LL | / ...                   {
+LL | | ...
+LL | | ...                       "hi";
+LL | | ...                       1
+LL | | ...                   },
+   | |_______________________^
+   |
+note: DefId(..)
+  --> $DIR/dump_def_parents.rs:13:25
+   |
+LL |                         fn inhibits_dump() {
+   |                         ^^^^^^^^^^^^^^^^^^
+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:9:13
+   |
+LL |             || {
+   |             ^^
+note: DefId(..)
+  --> $DIR/dump_def_parents.rs:7: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:23:31
    |
 LL |                         qux::<{ 1 + 1 }>();
    |                               ^^^^^^^^^
@@ -93,12 +146,12 @@ LL | |                         1
 LL | |                     },
    | |_____________________^
 note: DefId(..)
-  --> $DIR/dump_def_parents.rs:8:13
+  --> $DIR/dump_def_parents.rs:9:13
    |
 LL |             || {
    |             ^^
 note: DefId(..)
-  --> $DIR/dump_def_parents.rs:6:9
+  --> $DIR/dump_def_parents.rs:7:9
    |
 LL |         fn baz() {
    |         ^^^^^^^^
@@ -124,5 +177,5 @@ LL | |
 LL | | fn main() {}
    | |____________^
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/tests/crashes/128176.rs b/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.rs
similarity index 71%
rename from tests/crashes/128176.rs
rename to tests/ui/const-generics/issues/cg-in-dyn-issue-128176.rs
index 970ad9ff2cd..d163238c6d5 100644
--- a/tests/crashes/128176.rs
+++ b/tests/ui/const-generics/issues/cg-in-dyn-issue-128176.rs
@@ -1,7 +1,11 @@
-//@ known-bug: rust-lang/rust#128176
+//@ check-pass
+
+// Regression test for #128176.
 
 #![feature(generic_const_exprs)]
 #![feature(dyn_compatible_for_dispatch)]
+#![allow(incomplete_features)]
+
 trait X {
     type Y<const N: i16>;
 }
diff --git a/tests/ui/const-generics/issues/issue-83765.stderr b/tests/ui/const-generics/issues/issue-83765.stderr
index cce62749912..6b62012c14f 100644
--- a/tests/ui/const-generics/issues/issue-83765.stderr
+++ b/tests/ui/const-generics/issues/issue-83765.stderr
@@ -10,11 +10,11 @@ note: ...which requires computing candidate for `<LazyUpdim<'_, T, <T as TensorD
 LL | trait TensorDimension {
    | ^^^^^^^^^^^^^^^^^^^^^
    = note: ...which again requires resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`, completing the cycle
-note: cycle used when computing candidate for `<LazyUpdim<'_, T, { T::DIM }, DIM> as TensorDimension>`
-  --> $DIR/issue-83765.rs:4:1
+note: cycle used when checking assoc item `<impl at $DIR/issue-83765.rs:50:1: 50:94>::size` is compatible with trait definition
+  --> $DIR/issue-83765.rs:51:5
    |
-LL | trait TensorDimension {
-   | ^^^^^^^^^^^^^^^^^^^^^
+LL |     fn size(&self) -> [usize; DIM] {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error[E0391]: cycle detected when resolving instance `<LazyUpdim<'_, T, <T as TensorDimension>::DIM, DIM> as TensorDimension>::DIM`