Forbid generic parameters in types of #[type_const] items

This commit is contained in:
enthropy7 2026-01-03 16:22:29 +03:00
parent 50d59402bf
commit 46bb414d69
No known key found for this signature in database
12 changed files with 228 additions and 18 deletions

View file

@ -2855,6 +2855,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
ref define_opaque,
..
}) => {
let is_type_const = attr::contains_name(&item.attrs, sym::type_const);
self.with_generic_param_rib(
&generics.params,
RibKind::Item(
@ -2873,7 +2874,22 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
this.with_lifetime_rib(
LifetimeRibKind::Elided(LifetimeRes::Static),
|this| this.visit_ty(ty),
|this| {
if is_type_const
&& !this.r.tcx.features().generic_const_parameter_types()
{
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
this.with_lifetime_rib(
LifetimeRibKind::ConstParamTy,
|this| this.visit_ty(ty),
)
})
});
} else {
this.visit_ty(ty);
}
},
);
if let Some(rhs) = rhs {
@ -3213,6 +3229,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
define_opaque,
..
}) => {
let is_type_const = attr::contains_name(&item.attrs, sym::type_const);
self.with_generic_param_rib(
&generics.params,
RibKind::AssocItem,
@ -3227,7 +3244,20 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
},
|this| {
this.visit_generics(generics);
this.visit_ty(ty);
if is_type_const
&& !this.r.tcx.features().generic_const_parameter_types()
{
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
this.with_lifetime_rib(
LifetimeRibKind::ConstParamTy,
|this| this.visit_ty(ty),
)
})
});
} else {
this.visit_ty(ty);
}
// Only impose the restrictions of `ConstRibKind` for an
// actual constant expression in a provided default.
@ -3422,6 +3452,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
..
}) => {
debug!("resolve_implementation AssocItemKind::Const");
let is_type_const = attr::contains_name(&item.attrs, sym::type_const);
self.with_generic_param_rib(
&generics.params,
RibKind::AssocItem,
@ -3458,7 +3489,28 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
);
this.visit_generics(generics);
this.visit_ty(ty);
if is_type_const
&& !this
.r
.tcx
.features()
.generic_const_parameter_types()
{
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
this.with_rib(
ValueNS,
RibKind::ConstParamTy,
|this| {
this.with_lifetime_rib(
LifetimeRibKind::ConstParamTy,
|this| this.visit_ty(ty),
)
},
)
});
} else {
this.visit_ty(ty);
}
if let Some(rhs) = rhs {
// We allow arbitrary const expressions inside of associated consts,
// even if they are potentially not const evaluatable.

View file

@ -5,6 +5,7 @@
min_generic_const_args,
adt_const_params,
unsized_const_params,
generic_const_parameter_types,
)]
#![allow(incomplete_features)]

View file

@ -1,11 +1,11 @@
error: higher-ranked subtype error
--> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13
--> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:22:13
|
LL | K = const { () }
| ^^^^^^^^^^^^
error: higher-ranked subtype error
--> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:21:13
--> $DIR/assoc-const-eq-bound-var-in-ty-not-wf.rs:22:13
|
LL | K = const { () }
| ^^^^^^^^^^^^

View file

@ -8,6 +8,7 @@
min_generic_const_args,
adt_const_params,
unsized_const_params,
generic_const_parameter_types,
)]
#![allow(incomplete_features)]

View file

@ -1,6 +1,11 @@
// Detect and reject escaping late-bound generic params in
// the type of assoc consts used in an equality bound.
#![feature(associated_const_equality, min_generic_const_args, unsized_const_params)]
#![feature(
associated_const_equality,
min_generic_const_args,
unsized_const_params,
generic_const_parameter_types,
)]
#![allow(incomplete_features)]
trait Trait<'a> {

View file

@ -1,5 +1,5 @@
error: the type of the associated constant `K` cannot capture late-bound generic parameters
--> $DIR/assoc-const-eq-esc-bound-var-in-ty.rs:11:35
--> $DIR/assoc-const-eq-esc-bound-var-in-ty.rs:16:35
|
LL | fn take(_: impl for<'r> Trait<'r, K = const { &() }>) {}
| -- ^ its type cannot capture the late-bound lifetime parameter `'r`

View file

@ -5,6 +5,7 @@
min_generic_const_args,
adt_const_params,
unsized_const_params,
generic_const_parameter_types,
)]
#![allow(incomplete_features)]

View file

@ -1,5 +1,5 @@
error: the type of the associated constant `K` must not depend on generic parameters
--> $DIR/assoc-const-eq-param-in-ty.rs:22:29
--> $DIR/assoc-const-eq-param-in-ty.rs:23:29
|
LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(
| -- the lifetime parameter `'r` is defined here
@ -10,7 +10,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }>
= note: `K` has type `&'r [A; Q]`
error: the type of the associated constant `K` must not depend on generic parameters
--> $DIR/assoc-const-eq-param-in-ty.rs:22:29
--> $DIR/assoc-const-eq-param-in-ty.rs:23:29
|
LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(
| - the type parameter `A` is defined here
@ -21,7 +21,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }>
= note: `K` has type `&'r [A; Q]`
error: the type of the associated constant `K` must not depend on generic parameters
--> $DIR/assoc-const-eq-param-in-ty.rs:22:29
--> $DIR/assoc-const-eq-param-in-ty.rs:23:29
|
LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(
| - the const parameter `Q` is defined here
@ -32,7 +32,7 @@ LL | _: impl Trait<'r, A, Q, K = const { loop {} }>
= note: `K` has type `&'r [A; Q]`
error: the type of the associated constant `SELF` must not depend on `impl Trait`
--> $DIR/assoc-const-eq-param-in-ty.rs:39:26
--> $DIR/assoc-const-eq-param-in-ty.rs:40:26
|
LL | fn take1(_: impl Project<SELF = const {}>) {}
| -------------^^^^------------
@ -41,7 +41,7 @@ LL | fn take1(_: impl Project<SELF = const {}>) {}
| the `impl Trait` is specified here
error: the type of the associated constant `SELF` must not depend on generic parameters
--> $DIR/assoc-const-eq-param-in-ty.rs:44:21
--> $DIR/assoc-const-eq-param-in-ty.rs:45:21
|
LL | fn take2<P: Project<SELF = const {}>>(_: P) {}
| - ^^^^ its type must not depend on the type parameter `P`
@ -51,7 +51,7 @@ LL | fn take2<P: Project<SELF = const {}>>(_: P) {}
= note: `SELF` has type `P`
error: the type of the associated constant `K` must not depend on generic parameters
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
--> $DIR/assoc-const-eq-param-in-ty.rs:54:52
|
LL | trait Iface<'r>: ConstParamTy_ {
| -- the lifetime parameter `'r` is defined here
@ -62,7 +62,7 @@ LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
= note: `K` has type `&'r [Self; Q]`
error: the type of the associated constant `K` must not depend on `Self`
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
--> $DIR/assoc-const-eq-param-in-ty.rs:54:52
|
LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
| ^ its type must not depend on `Self`
@ -70,7 +70,7 @@ LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
= note: `K` has type `&'r [Self; Q]`
error: the type of the associated constant `K` must not depend on generic parameters
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
--> $DIR/assoc-const-eq-param-in-ty.rs:54:52
|
LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
| - ^ its type must not depend on the const parameter `Q`
@ -80,7 +80,7 @@ LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
= note: `K` has type `&'r [Self; Q]`
error: the type of the associated constant `K` must not depend on generic parameters
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
--> $DIR/assoc-const-eq-param-in-ty.rs:54:52
|
LL | trait Iface<'r>: ConstParamTy_ {
| -- the lifetime parameter `'r` is defined here
@ -92,7 +92,7 @@ LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: the type of the associated constant `K` must not depend on `Self`
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
--> $DIR/assoc-const-eq-param-in-ty.rs:54:52
|
LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
| ^ its type must not depend on `Self`
@ -101,7 +101,7 @@ LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: the type of the associated constant `K` must not depend on generic parameters
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
--> $DIR/assoc-const-eq-param-in-ty.rs:54:52
|
LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
| - ^ its type must not depend on the const parameter `Q`

View file

@ -8,6 +8,7 @@
min_generic_const_args,
adt_const_params,
unsized_const_params,
generic_const_parameter_types,
)]
#![allow(incomplete_features)]

View file

@ -0,0 +1,38 @@
error: anonymous constants referencing generics are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:9:53
|
LL | const FOO<T: core::marker::ConstParamTy_>: [T; 0] = const { [] };
| ^^^^^^^^^^^^
error: anonymous constants referencing generics are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:14:38
|
LL | const BAR<const N: usize>: [(); N] = const { [] };
| ^^^^^^^^^^^^
error: anonymous constants with lifetimes in their type are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:19:30
|
LL | const BAZ<'a>: [&'a (); 0] = const { [] };
| ^^^^^^^^^^^^
error: anonymous constants referencing generics are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:39:59
|
LL | const ASSOC<T: core::marker::ConstParamTy_>: [T; 0] = const { [] };
| ^^^^^^^^^^^^
error: anonymous constants referencing generics are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:44:50
|
LL | const ASSOC_CONST<const N: usize>: [(); N] = const { [] };
| ^^^^^^^^^^^^
error: anonymous constants with lifetimes in their type are not yet supported
--> $DIR/type_const-generic-param-in-type.rs:49:39
|
LL | const ASSOC_LT<'a>: [&'a (); 0] = const { [] };
| ^^^^^^^^^^^^
error: aborting due to 6 previous errors

View file

@ -0,0 +1,57 @@
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:9:45
|
LL | const FOO<T: core::marker::ConstParamTy_>: [T; 0] = const { [] };
| ^ the type must not depend on the parameter `T`
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:14:33
|
LL | const BAR<const N: usize>: [(); N] = const { [] };
| ^ the type must not depend on the parameter `N`
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:19:18
|
LL | const BAZ<'a>: [&'a (); 0] = const { [] };
| ^^ the type must not depend on the parameter `'a`
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:25:51
|
LL | const ASSOC<T: core::marker::ConstParamTy_>: [T; 0];
| ^ the type must not depend on the parameter `T`
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:29:45
|
LL | const ASSOC_CONST<const N: usize>: [(); N];
| ^ the type must not depend on the parameter `N`
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:33:27
|
LL | const ASSOC_LT<'a>: [&'a (); 0];
| ^^ the type must not depend on the parameter `'a`
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:39:51
|
LL | const ASSOC<T: core::marker::ConstParamTy_>: [T; 0] = const { [] };
| ^ the type must not depend on the parameter `T`
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:44:45
|
LL | const ASSOC_CONST<const N: usize>: [(); N] = const { [] };
| ^ the type must not depend on the parameter `N`
error[E0770]: the type of const parameters must not depend on other generic parameters
--> $DIR/type_const-generic-param-in-type.rs:49:27
|
LL | const ASSOC_LT<'a>: [&'a (); 0] = const { [] };
| ^^ the type must not depend on the parameter `'a`
error: aborting due to 9 previous errors
For more information about this error, try `rustc --explain E0770`.

View file

@ -0,0 +1,54 @@
//@ revisions: nogate gate
//@ [gate] check-fail
// FIXME(generic_const_parameter_types): this should 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))]
#[type_const]
const FOO<T: core::marker::ConstParamTy_>: [T; 0] = const { [] };
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
//[gate]~^^ ERROR anonymous constants referencing generics are not yet supported
#[type_const]
const BAR<const N: usize>: [(); N] = const { [] };
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
//[gate]~^^ ERROR anonymous constants referencing generics are not yet supported
#[type_const]
const BAZ<'a>: [&'a (); 0] = const { [] };
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
//[gate]~^^ ERROR anonymous constants with lifetimes in their type are not yet supported
trait Tr {
#[type_const]
const ASSOC<T: core::marker::ConstParamTy_>: [T; 0];
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
#[type_const]
const ASSOC_CONST<const N: usize>: [(); N];
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
#[type_const]
const ASSOC_LT<'a>: [&'a (); 0];
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
}
impl Tr for () {
#[type_const]
const ASSOC<T: core::marker::ConstParamTy_>: [T; 0] = const { [] };
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
//[gate]~^^ ERROR anonymous constants referencing generics are not yet supported
#[type_const]
const ASSOC_CONST<const N: usize>: [(); N] = const { [] };
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
//[gate]~^^ ERROR anonymous constants referencing generics are not yet supported
#[type_const]
const ASSOC_LT<'a>: [&'a (); 0] = const { [] };
//[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters
//[gate]~^^ ERROR anonymous constants with lifetimes in their type are not yet supported
}
fn main() {}