Forbid generic parameters in types of #[type_const] items
This commit is contained in:
parent
50d59402bf
commit
46bb414d69
12 changed files with 228 additions and 18 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
min_generic_const_args,
|
||||
adt_const_params,
|
||||
unsized_const_params,
|
||||
generic_const_parameter_types,
|
||||
)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
|
|
|
|||
|
|
@ -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 { () }
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
min_generic_const_args,
|
||||
adt_const_params,
|
||||
unsized_const_params,
|
||||
generic_const_parameter_types,
|
||||
)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
min_generic_const_args,
|
||||
adt_const_params,
|
||||
unsized_const_params,
|
||||
generic_const_parameter_types,
|
||||
)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
min_generic_const_args,
|
||||
adt_const_params,
|
||||
unsized_const_params,
|
||||
generic_const_parameter_types,
|
||||
)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue