From d5fcdffb29e75b7f7513de12c2206e32b2f4ffa4 Mon Sep 17 00:00:00 2001 From: "Mark Z. Ding" Date: Tue, 11 Nov 2025 17:43:14 -0500 Subject: [PATCH] Handle Node::ConstArg in generics_of by reusing the parent's generics --- .../src/collect/generics_of.rs | 28 +++++++++++++++++++ .../ui/const-generics/const-arg-unresolved.rs | 10 +++++++ .../const-arg-unresolved.stderr | 27 ++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 tests/ui/const-generics/const-arg-unresolved.rs create mode 100644 tests/ui/const-generics/const-arg-unresolved.stderr diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 3d2f0466cad08..fb8cc80e8e2ee 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -166,6 +166,34 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { ty::AnonConstKind::NonTypeSystem => None, } } + Node::ConstArg(_) => { + let parent_did = tcx.parent(def_id.to_def_id()); + debug!(?parent_did); + + if let Node::GenericParam(hir::GenericParam { + def_id: param_id, + kind: hir::GenericParamKind::Const { .. }, + .. + }) = tcx.parent_hir_node(hir_id) + { + let generics = tcx.generics_of(parent_did); + let param_def_idx = generics.param_def_id_to_index[¶m_id.to_def_id()]; + let own_params = generics.params_to(param_def_idx as usize, tcx).to_owned(); + let param_def_id_to_index = + own_params.iter().map(|param| (param.def_id, param.index)).collect(); + + return ty::Generics { + parent: generics.parent, + parent_count: generics.parent_count, + own_params, + param_def_id_to_index, + has_self: generics.has_self, + has_late_bound_regions: generics.has_late_bound_regions, + }; + } + + Some(parent_did) + } Node::ConstBlock(_) | Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { Some(tcx.typeck_root_def_id(def_id.to_def_id())) diff --git a/tests/ui/const-generics/const-arg-unresolved.rs b/tests/ui/const-generics/const-arg-unresolved.rs new file mode 100644 index 0000000000000..ea2dccec76878 --- /dev/null +++ b/tests/ui/const-generics/const-arg-unresolved.rs @@ -0,0 +1,10 @@ +#![feature(min_generic_const_args)] +#![feature(generic_const_exprs)] +#![expect(incomplete_features)] + +struct Both { //~ ERROR generic parameters with a default must be trailing + a: A<{ B::<1>::M }>, //~ ERROR cannot find type `A` in this scope + //~| ERROR failed to resolve: use of undeclared type `B` +} + +fn main() {} diff --git a/tests/ui/const-generics/const-arg-unresolved.stderr b/tests/ui/const-generics/const-arg-unresolved.stderr new file mode 100644 index 0000000000000..276b84b1f86ac --- /dev/null +++ b/tests/ui/const-generics/const-arg-unresolved.stderr @@ -0,0 +1,27 @@ +error: generic parameters with a default must be trailing + --> $DIR/const-arg-unresolved.rs:5:19 + | +LL | struct Both { + | ^^^^^^ + +error[E0412]: cannot find type `A` in this scope + --> $DIR/const-arg-unresolved.rs:6:8 + | +LL | struct Both { + | - similarly named type parameter `T` defined here +LL | a: A<{ B::<1>::M }>, + | ^ help: a type parameter with a similar name exists: `T` + +error[E0433]: failed to resolve: use of undeclared type `B` + --> $DIR/const-arg-unresolved.rs:6:12 + | +LL | a: A<{ B::<1>::M }>, + | ^ + | | + | use of undeclared type `B` + | help: a type parameter with a similar name exists: `T` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0412, E0433. +For more information about an error, try `rustc --explain E0412`.