From 9dce1fcdc944e5550c991796dba03cbf8b4a702a Mon Sep 17 00:00:00 2001 From: khyperia <953151+khyperia@users.noreply.github.com> Date: Wed, 16 Sep 2026 12:19:03 +0200 Subject: [PATCH] reintroduce check for ConstParamTy in direct consts --- .../rustc_hir_analysis/src/check/check.rs | 3 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 37 ++++++---- .../src/hir_ty_lowering/mod.rs | 7 +- ...pe_const-generic-param-in-type.gate.stderr | 38 ---------- ..._const-generic-param-in-type.nogate.stderr | 69 ++++++++++++------- .../mgca/type_const-generic-param-in-type.rs | 40 ++++++----- .../assoc-const-no-infer-ice-115806.rs | 4 +- .../assoc-const-no-infer-ice-115806.stderr | 20 ++---- 8 files changed, 99 insertions(+), 119 deletions(-) delete mode 100644 tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8fde417b764d8..705bb780a3ecf 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -961,8 +961,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.require_lang_item(LangItem::Sized, ty_span), ); check_where_clauses(wfcx, def_id); - wfcheck::check_const_item(wfcx, def_id, ty); - Ok(()) + wfcheck::check_const_item(wfcx, def_id, ty) })); // Only `Node::Item` and `Node::ForeignItem` still have HIR based diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 9aded3aeb9318..429f45c2d8358 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -47,8 +47,7 @@ use tracing::{debug, instrument}; use super::compare_eii::{compare_eii_function_types, compare_eii_statics}; use crate::autoderef::Autoderef; use crate::constrained_generic_params::{Parameter, identify_constrained_generic_params}; -use crate::diagnostics; -use crate::diagnostics::InvalidReceiverTyHint; +use crate::diagnostics::{self, InvalidReceiverTyHint, ParamInTyOfConstParam}; pub(super) struct WfCheckingCtxt<'a, 'tcx> { pub(super) ocx: ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>, @@ -927,7 +926,6 @@ pub(crate) fn check_associated_item( let ty = tcx.type_of(def_id).instantiate_identity(); let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); - check_const_item(wfcx, def_id, ty); if item.defaultness(tcx).has_value() { let code = ObligationCauseCode::SizedConstOrStatic; @@ -939,7 +937,7 @@ pub(crate) fn check_associated_item( ); } - Ok(()) + check_const_item(wfcx, def_id, ty) } ty::AssocKind::Fn { .. } => { let sig = tcx.fn_sig(def_id).instantiate_identity().skip_norm_wip(); @@ -1259,22 +1257,33 @@ pub(crate) fn check_static_item<'tcx>( } /// Runs checks common to both free consts and associated consts -#[instrument(level = "debug", skip(wfcx))] +#[instrument(level = "debug", skip(wfcx), ret)] pub(super) fn check_const_item<'tcx>( wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id: LocalDefId, item_ty: Ty<'tcx>, -) { +) -> Result<(), ErrorGuaranteed> { let tcx = wfcx.tcx(); let span = tcx.def_span(def_id); - if tcx.is_direct_const(def_id.into()) && !tcx.features().const_param_ty_unchecked() { - wfcx.register_bound( - ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)), - wfcx.param_env, - item_ty, - tcx.require_lang_item(LangItem::ConstParamTy, span), - ); + let mut res = Ok(()); + + if tcx.is_direct_const(def_id.into()) { + if !tcx.features().const_param_ty_unchecked() { + wfcx.register_bound( + ObligationCause::new(span, def_id, ObligationCauseCode::ConstParam(item_ty)), + wfcx.param_env, + item_ty, + tcx.require_lang_item(LangItem::ConstParamTy, span), + ); + } + // FIXME(min_generic_const_args): We *might* want to move this check to `type_of`, so we can + // return `ty::Error` if it references invalid params. However, doing so is hard, because + // `type_of` doesn't know if it's a direct const - `const_of_item` determines that, and + // `const_of_item` calls `type_of`. + if !tcx.features().generic_const_parameter_types() && item_ty.has_param() { + res = Err(tcx.dcx().emit_err(ParamInTyOfConstParam { span, ty: item_ty })); + } } if let Some(direct_rhs) = tcx.const_of_item(def_id) { @@ -1289,6 +1298,8 @@ pub(super) fn check_const_item<'tcx>( ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(norm_ct, item_ty)), )); } + + res } #[instrument(level = "debug", skip(tcx, impl_))] 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 b659dd896aba0..0cd095e0a262a 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2396,16 +2396,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // we have the ability to intermix typeck of anon const const args with the parent // bodies typeck. - // FIXME(min_generic_const_args): This check should be removed for mGCA, it is due to - // the lack of ConstParamTy rib-checking in nameres for directly represented const - // items. - // We also error if the type contains any regions as effectively any region will wind // up as a region variable in mir borrowck. It would also be somewhat concerning if // hir typeck was using equality but mir borrowck wound up using subtyping as that could // result in a non-infer in hir typeck but a region variable in borrowck. - if (tcx.features().generic_const_parameter_types() - || tcx.features().min_generic_const_args()) + if tcx.features().generic_const_parameter_types() && (ty.has_free_regions() || ty.has_erased_regions()) { let e = self.dcx().span_err( diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr deleted file mode 100644 index a236198f4abc9..0000000000000 --- a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr +++ /dev/null @@ -1,38 +0,0 @@ -error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:8:77 - | -LL | const FOO: [T; 0] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ - -error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:11:62 - | -LL | const BAR: [(); N] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ - -error: anonymous constants with lifetimes in their type are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:14:54 - | -LL | const BAZ<'a>: [&'a (); 0] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ - -error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:30:83 - | -LL | const ASSOC: [T; 0] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ - -error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:33:74 - | -LL | const ASSOC_CONST: [(); N] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ - -error: anonymous constants with lifetimes in their type are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:36:63 - | -LL | const ASSOC_LT<'a>: [&'a (); 0] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ - -error: aborting due to 6 previous errors - diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr index a236198f4abc9..03251f4c7bd2b 100644 --- a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr @@ -1,38 +1,57 @@ -error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:8:77 +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:12:1 | -LL | const FOO: [T; 0] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ +LL | const FOO: [T; 0] = core::direct_const_arg!([]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[T; 0]` must not depend on other generic parameter -error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:11:62 +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:15:1 | -LL | const BAR: [(); N] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ +LL | const BAR: StructWithConstParam = + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `StructWithConstParam` must not depend on other generic parameter -error: anonymous constants with lifetimes in their type are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:14:54 +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:19:1 | -LL | const BAZ<'a>: [&'a (); 0] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ +LL | const BAZ<'a>: [&'a (); 0] = core::direct_const_arg!([]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[&'a (); 0]` must not depend on other generic parameter -error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:30:83 +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:37:5 | -LL | const ASSOC: [T; 0] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ +LL | const ASSOC: [T; 0] = core::direct_const_arg!([]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[T; 0]` must not depend on other generic parameter -error: anonymous constants referencing generics are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:33:74 +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:40:5 | -LL | const ASSOC_CONST: [(); N] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ +LL | const ASSOC_CONST: StructWithConstParam = + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `StructWithConstParam` must not depend on other generic parameter -error: anonymous constants with lifetimes in their type are not yet supported - --> $DIR/type_const-generic-param-in-type.rs:36:63 +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:44:5 | -LL | const ASSOC_LT<'a>: [&'a (); 0] = core::direct_const_arg!(const { [] }); - | ^^^^^^^^^^^^ +LL | const ASSOC_LT<'a>: [&'a (); 0] = core::direct_const_arg!([]); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[&'a (); 0]` must not depend on other generic parameter -error: aborting due to 6 previous errors +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:24:5 + | +LL | const ASSOC: [T; 0]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[T; 0]` must not depend on other generic parameter + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:28:5 + | +LL | const ASSOC_CONST: StructWithConstParam; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `StructWithConstParam` must not depend on other generic parameter + +error[E0770]: the type of const parameters must not depend on other generic parameters + --> $DIR/type_const-generic-param-in-type.rs:32:5 + | +LL | const ASSOC_LT<'a>: [&'a (); 0]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the type `[&'a (); 0]` must not depend on other generic parameter + +error: aborting due to 9 previous errors +For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs index e6cf2fd60eb0a..e5e36b79eca57 100644 --- a/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs @@ -1,40 +1,48 @@ //@ revisions: nogate gate -//@ [gate] check-fail -// FIXME(generic_const_parameter_types): this should pass +//@ [gate] check-pass #![expect(incomplete_features)] #![feature(adt_const_params, unsized_const_params, min_generic_const_args, generic_const_items)] #![cfg_attr(gate, feature(generic_const_parameter_types))] -const FOO: [T; 0] = core::direct_const_arg!(const { [] }); -//~^ ERROR anonymous constants referencing generics are not yet supported +use std::marker::ConstParamTy; -const BAR: [(); N] = core::direct_const_arg!(const { [] }); -//~^ ERROR anonymous constants referencing generics are not yet supported +#[derive(ConstParamTy, PartialEq, Eq, Debug)] +struct StructWithConstParam; -const BAZ<'a>: [&'a (); 0] = core::direct_const_arg!(const { [] }); -//~^ ERROR anonymous constants with lifetimes in their type are not yet supported +const FOO: [T; 0] = core::direct_const_arg!([]); +//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + +const BAR: StructWithConstParam = + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + core::direct_const_arg!(StructWithConstParam::); + +const BAZ<'a>: [&'a (); 0] = core::direct_const_arg!([]); +//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters trait Tr { - // FIXME(min_generic_const_args): These should error under [nogate] #[rustc_always_gca] const ASSOC: [T; 0]; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters #[rustc_always_gca] - const ASSOC_CONST: [(); N]; + const ASSOC_CONST: StructWithConstParam; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters #[rustc_always_gca] const ASSOC_LT<'a>: [&'a (); 0]; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters } impl Tr for () { - const ASSOC: [T; 0] = core::direct_const_arg!(const { [] }); - //~^ ERROR anonymous constants referencing generics are not yet supported + const ASSOC: [T; 0] = core::direct_const_arg!([]); + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters - const ASSOC_CONST: [(); N] = core::direct_const_arg!(const { [] }); - //~^ ERROR anonymous constants referencing generics are not yet supported + const ASSOC_CONST: StructWithConstParam = + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + core::direct_const_arg!(StructWithConstParam::); - const ASSOC_LT<'a>: [&'a (); 0] = core::direct_const_arg!(const { [] }); - //~^ ERROR anonymous constants with lifetimes in their type are not yet supported + const ASSOC_LT<'a>: [&'a (); 0] = core::direct_const_arg!([]); + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters } fn main() {} diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs index d321f8ce802c0..31bca180df8a8 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.rs @@ -11,7 +11,6 @@ impl Pins for NoPin {} pub trait PinA { #[rustc_always_gca] const A: &'static () = core::direct_const_arg!(const { &() }); - //~^ ERROR anonymous constants with lifetimes in their type are not yet supported } pub trait Pins {} @@ -19,8 +18,7 @@ pub trait Pins {} impl Pins for T //~^ ERROR conflicting implementations of trait `Pins<_>` for type `NoPin` where - T: PinA, - //~^ ERROR anonymous constants with lifetimes in their type are not yet supported + T: PinA { } diff --git a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr index 5ccca6bb0c677..515ee3f0af8be 100644 --- a/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr +++ b/tests/ui/generic-const-items/assoc-const-no-infer-ice-115806.stderr @@ -1,11 +1,5 @@ -error: anonymous constants with lifetimes in their type are not yet supported - --> $DIR/assoc-const-no-infer-ice-115806.rs:22:50 - | -LL | T: PinA, - | ^^^^^^^^^^^^^ - error[E0119]: conflicting implementations of trait `Pins<_>` for type `NoPin` - --> $DIR/assoc-const-no-infer-ice-115806.rs:19:1 + --> $DIR/assoc-const-no-infer-ice-115806.rs:18:1 | LL | impl Pins for NoPin {} | --------------------------- first implementation here @@ -13,17 +7,11 @@ LL | impl Pins for NoPin {} LL | / impl Pins for T LL | | LL | | where -LL | | T: PinA, - | |___________________________________________________________________^ conflicting implementation for `NoPin` +LL | | T: PinA + | |__________________________________________________________________^ conflicting implementation for `NoPin` | = note: downstream crates may implement trait `PinA<_>` for type `NoPin` -error: anonymous constants with lifetimes in their type are not yet supported - --> $DIR/assoc-const-no-infer-ice-115806.rs:13:52 - | -LL | const A: &'static () = core::direct_const_arg!(const { &() }); - | ^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0119`.