diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index dd80f5da508c..2bbaacce53f8 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -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. diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs index 7f8b3036c3e8..50914fb192ff 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.rs @@ -5,6 +5,7 @@ min_generic_const_args, adt_const_params, unsized_const_params, + generic_const_parameter_types, )] #![allow(incomplete_features)] diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr index 76868715b861..fd49e151b8e6 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty-not-wf.stderr @@ -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 { () } | ^^^^^^^^^^^^ diff --git a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs index d3975bc19ad3..54e199d702c9 100644 --- a/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-bound-var-in-ty.rs @@ -8,6 +8,7 @@ min_generic_const_args, adt_const_params, unsized_const_params, + generic_const_parameter_types, )] #![allow(incomplete_features)] diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs index 2571af57e66b..7f9a04bbf0fc 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.rs @@ -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> { diff --git a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr index 44304443ac54..e22d9bfed7ef 100644 --- a/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-esc-bound-var-in-ty.stderr @@ -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` diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs index 242ad385947a..ea2f60cd6187 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs @@ -5,6 +5,7 @@ min_generic_const_args, adt_const_params, unsized_const_params, + generic_const_parameter_types, )] #![allow(incomplete_features)] diff --git a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr index b742e68044b0..ae6a35b4b9f2 100644 --- a/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-param-in-ty.stderr @@ -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) {} | -------------^^^^------------ @@ -41,7 +41,7 @@ LL | fn take1(_: impl Project) {} | 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) {} | - ^^^^ its type must not depend on the type parameter `P` @@ -51,7 +51,7 @@ LL | fn take2>(_: 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: 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: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` @@ -70,7 +70,7 @@ LL | type Assoc: 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: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` @@ -80,7 +80,7 @@ LL | type Assoc: 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: 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: Trait<'r, Self, Q, K = const { loop {} }> | ^ its type must not depend on `Self` @@ -101,7 +101,7 @@ LL | type Assoc: 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: Trait<'r, Self, Q, K = const { loop {} }> | - ^ its type must not depend on the const parameter `Q` diff --git a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs index d9b8a8cd43d7..c092285dfcd4 100644 --- a/tests/ui/associated-consts/assoc-const-eq-supertraits.rs +++ b/tests/ui/associated-consts/assoc-const-eq-supertraits.rs @@ -8,6 +8,7 @@ min_generic_const_args, adt_const_params, unsized_const_params, + generic_const_parameter_types, )] #![allow(incomplete_features)] 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 new file mode 100644 index 000000000000..8a64af285da5 --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.gate.stderr @@ -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; 0] = const { [] }; + | ^^^^^^^^^^^^ + +error: anonymous constants referencing generics are not yet supported + --> $DIR/type_const-generic-param-in-type.rs:14:38 + | +LL | const BAR: [(); 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; 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: [(); 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 + 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 new file mode 100644 index 000000000000..14ae276324ad --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.nogate.stderr @@ -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; 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: [(); 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; 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: [(); 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; 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: [(); 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`. 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 new file mode 100644 index 000000000000..f1a4aba9bcee --- /dev/null +++ b/tests/ui/const-generics/mgca/type_const-generic-param-in-type.rs @@ -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; 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: [(); 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; 0]; + //[nogate]~^ ERROR the type of const parameters must not depend on other generic parameters + + #[type_const] + const ASSOC_CONST: [(); 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; 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: [(); 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() {}