Skip to content

Commit 1e67baf

Browse files
committed
Forbid generic parameters in types of #[type_const] items
1 parent 50d5940 commit 1e67baf

File tree

5 files changed

+118
-153
lines changed

5 files changed

+118
-153
lines changed

compiler/rustc_resolve/src/late.rs

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2855,6 +2855,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
28552855
ref define_opaque,
28562856
..
28572857
}) => {
2858+
let is_type_const = attr::contains_name(&item.attrs, sym::type_const);
28582859
self.with_generic_param_rib(
28592860
&generics.params,
28602861
RibKind::Item(
@@ -2873,7 +2874,22 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
28732874

28742875
this.with_lifetime_rib(
28752876
LifetimeRibKind::Elided(LifetimeRes::Static),
2876-
|this| this.visit_ty(ty),
2877+
|this| {
2878+
if is_type_const
2879+
&& !this.r.tcx.features().generic_const_parameter_types()
2880+
{
2881+
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
2882+
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
2883+
this.with_lifetime_rib(
2884+
LifetimeRibKind::ConstParamTy,
2885+
|this| this.visit_ty(ty),
2886+
)
2887+
})
2888+
});
2889+
} else {
2890+
this.visit_ty(ty);
2891+
}
2892+
},
28772893
);
28782894

28792895
if let Some(rhs) = rhs {
@@ -3213,6 +3229,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
32133229
define_opaque,
32143230
..
32153231
}) => {
3232+
let is_type_const = attr::contains_name(&item.attrs, sym::type_const);
32163233
self.with_generic_param_rib(
32173234
&generics.params,
32183235
RibKind::AssocItem,
@@ -3227,7 +3244,20 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
32273244
},
32283245
|this| {
32293246
this.visit_generics(generics);
3230-
this.visit_ty(ty);
3247+
if is_type_const
3248+
&& !this.r.tcx.features().generic_const_parameter_types()
3249+
{
3250+
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3251+
this.with_rib(ValueNS, RibKind::ConstParamTy, |this| {
3252+
this.with_lifetime_rib(
3253+
LifetimeRibKind::ConstParamTy,
3254+
|this| this.visit_ty(ty),
3255+
)
3256+
})
3257+
});
3258+
} else {
3259+
this.visit_ty(ty);
3260+
}
32313261

32323262
// Only impose the restrictions of `ConstRibKind` for an
32333263
// actual constant expression in a provided default.
@@ -3422,6 +3452,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
34223452
..
34233453
}) => {
34243454
debug!("resolve_implementation AssocItemKind::Const");
3455+
let is_type_const = attr::contains_name(&item.attrs, sym::type_const);
34253456
self.with_generic_param_rib(
34263457
&generics.params,
34273458
RibKind::AssocItem,
@@ -3458,7 +3489,28 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
34583489
);
34593490

34603491
this.visit_generics(generics);
3461-
this.visit_ty(ty);
3492+
if is_type_const
3493+
&& !this
3494+
.r
3495+
.tcx
3496+
.features()
3497+
.generic_const_parameter_types()
3498+
{
3499+
this.with_rib(TypeNS, RibKind::ConstParamTy, |this| {
3500+
this.with_rib(
3501+
ValueNS,
3502+
RibKind::ConstParamTy,
3503+
|this| {
3504+
this.with_lifetime_rib(
3505+
LifetimeRibKind::ConstParamTy,
3506+
|this| this.visit_ty(ty),
3507+
)
3508+
},
3509+
)
3510+
});
3511+
} else {
3512+
this.visit_ty(ty);
3513+
}
34623514
if let Some(rhs) = rhs {
34633515
// We allow arbitrary const expressions inside of associated consts,
34643516
// even if they are potentially not const evaluatable.

tests/ui/associated-consts/assoc-const-eq-param-in-ty.rs

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,67 +13,27 @@ use std::marker::ConstParamTy_;
1313
trait Trait<'a, T: 'a + ConstParamTy_, const N: usize> {
1414
#[type_const]
1515
const K: &'a [T; N];
16+
//~^ ERROR the type of const parameters must not depend on other generic parameters
17+
//~| ERROR the type of const parameters must not depend on other generic parameters
18+
//~| ERROR the type of const parameters must not depend on other generic parameters
1619
}
1720

1821
fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(
19-
//~^ NOTE the lifetime parameter `'r` is defined here
20-
//~| NOTE the type parameter `A` is defined here
21-
//~| NOTE the const parameter `Q` is defined here
2222
_: impl Trait<'r, A, Q, K = const { loop {} }>
23-
//~^ ERROR the type of the associated constant `K` must not depend on generic parameters
24-
//~| NOTE its type must not depend on the lifetime parameter `'r`
25-
//~| NOTE `K` has type `&'r [A; Q]`
26-
//~| ERROR the type of the associated constant `K` must not depend on generic parameters
27-
//~| NOTE its type must not depend on the type parameter `A`
28-
//~| NOTE `K` has type `&'r [A; Q]`
29-
//~| ERROR the type of the associated constant `K` must not depend on generic parameters
30-
//~| NOTE its type must not depend on the const parameter `Q`
31-
//~| NOTE `K` has type `&'r [A; Q]`
3223
) {}
3324

3425
trait Project: ConstParamTy_ {
3526
#[type_const]
3627
const SELF: Self;
28+
//~^ ERROR the type of const parameters must not depend on other generic parameters
3729
}
3830

3931
fn take1(_: impl Project<SELF = const {}>) {}
40-
//~^ ERROR the type of the associated constant `SELF` must not depend on `impl Trait`
41-
//~| NOTE its type must not depend on `impl Trait`
42-
//~| NOTE the `impl Trait` is specified here
4332

4433
fn take2<P: Project<SELF = const {}>>(_: P) {}
45-
//~^ ERROR the type of the associated constant `SELF` must not depend on generic parameters
46-
//~| NOTE its type must not depend on the type parameter `P`
47-
//~| NOTE the type parameter `P` is defined here
48-
//~| NOTE `SELF` has type `P`
4934

5035
trait Iface<'r>: ConstParamTy_ {
51-
//~^ NOTE the lifetime parameter `'r` is defined here
52-
//~| NOTE the lifetime parameter `'r` is defined here
5336
type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
54-
//~^ ERROR the type of the associated constant `K` must not depend on generic parameters
55-
//~| ERROR the type of the associated constant `K` must not depend on generic parameters
56-
//~| NOTE its type must not depend on the lifetime parameter `'r`
57-
//~| NOTE `K` has type `&'r [Self; Q]`
58-
//~| ERROR the type of the associated constant `K` must not depend on `Self`
59-
//~| NOTE its type must not depend on `Self`
60-
//~| NOTE `K` has type `&'r [Self; Q]`
61-
//~| ERROR the type of the associated constant `K` must not depend on generic parameters
62-
//~| NOTE its type must not depend on the const parameter `Q`
63-
//~| NOTE the const parameter `Q` is defined here
64-
//~| NOTE `K` has type `&'r [Self; Q]`
65-
//~| NOTE its type must not depend on the lifetime parameter `'r`
66-
//~| NOTE `K` has type `&'r [Self; Q]`
67-
//~| ERROR the type of the associated constant `K` must not depend on `Self`
68-
//~| NOTE its type must not depend on `Self`
69-
//~| NOTE `K` has type `&'r [Self; Q]`
70-
//~| ERROR the type of the associated constant `K` must not depend on generic parameters
71-
//~| NOTE its type must not depend on the const parameter `Q`
72-
//~| NOTE the const parameter `Q` is defined here
73-
//~| NOTE `K` has type `&'r [Self; Q]`
74-
//~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
75-
//~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
76-
//~| NOTE duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
7737
where
7838
Self: Sized + 'r;
7939
}
Lines changed: 18 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,27 @@
1-
error: the type of the associated constant `K` must not depend on generic parameters
2-
--> $DIR/assoc-const-eq-param-in-ty.rs:22:29
1+
error[E0770]: the type of const parameters must not depend on other generic parameters
2+
--> $DIR/assoc-const-eq-param-in-ty.rs:15:15
33
|
4-
LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(
5-
| -- the lifetime parameter `'r` is defined here
6-
...
7-
LL | _: impl Trait<'r, A, Q, K = const { loop {} }>
8-
| ^ its type must not depend on the lifetime parameter `'r`
9-
|
10-
= note: `K` has type `&'r [A; Q]`
11-
12-
error: the type of the associated constant `K` must not depend on generic parameters
13-
--> $DIR/assoc-const-eq-param-in-ty.rs:22:29
14-
|
15-
LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(
16-
| - the type parameter `A` is defined here
17-
...
18-
LL | _: impl Trait<'r, A, Q, K = const { loop {} }>
19-
| ^ its type must not depend on the type parameter `A`
20-
|
21-
= note: `K` has type `&'r [A; Q]`
22-
23-
error: the type of the associated constant `K` must not depend on generic parameters
24-
--> $DIR/assoc-const-eq-param-in-ty.rs:22:29
25-
|
26-
LL | fn take0<'r, A: 'r + ConstParamTy_, const Q: usize>(
27-
| - the const parameter `Q` is defined here
28-
...
29-
LL | _: impl Trait<'r, A, Q, K = const { loop {} }>
30-
| ^ its type must not depend on the const parameter `Q`
31-
|
32-
= note: `K` has type `&'r [A; Q]`
33-
34-
error: the type of the associated constant `SELF` must not depend on `impl Trait`
35-
--> $DIR/assoc-const-eq-param-in-ty.rs:39:26
36-
|
37-
LL | fn take1(_: impl Project<SELF = const {}>) {}
38-
| -------------^^^^------------
39-
| | |
40-
| | its type must not depend on `impl Trait`
41-
| the `impl Trait` is specified here
42-
43-
error: the type of the associated constant `SELF` must not depend on generic parameters
44-
--> $DIR/assoc-const-eq-param-in-ty.rs:44:21
45-
|
46-
LL | fn take2<P: Project<SELF = const {}>>(_: P) {}
47-
| - ^^^^ its type must not depend on the type parameter `P`
48-
| |
49-
| the type parameter `P` is defined here
50-
|
51-
= note: `SELF` has type `P`
4+
LL | const K: &'a [T; N];
5+
| ^^ the type must not depend on the parameter `'a`
526

53-
error: the type of the associated constant `K` must not depend on generic parameters
54-
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
7+
error[E0770]: the type of const parameters must not depend on other generic parameters
8+
--> $DIR/assoc-const-eq-param-in-ty.rs:15:19
559
|
56-
LL | trait Iface<'r>: ConstParamTy_ {
57-
| -- the lifetime parameter `'r` is defined here
58-
...
59-
LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
60-
| ^ its type must not depend on the lifetime parameter `'r`
61-
|
62-
= note: `K` has type `&'r [Self; Q]`
63-
64-
error: the type of the associated constant `K` must not depend on `Self`
65-
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
66-
|
67-
LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
68-
| ^ its type must not depend on `Self`
69-
|
70-
= note: `K` has type `&'r [Self; Q]`
71-
72-
error: the type of the associated constant `K` must not depend on generic parameters
73-
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
74-
|
75-
LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
76-
| - ^ its type must not depend on the const parameter `Q`
77-
| |
78-
| the const parameter `Q` is defined here
79-
|
80-
= note: `K` has type `&'r [Self; Q]`
81-
82-
error: the type of the associated constant `K` must not depend on generic parameters
83-
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
84-
|
85-
LL | trait Iface<'r>: ConstParamTy_ {
86-
| -- the lifetime parameter `'r` is defined here
87-
...
88-
LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
89-
| ^ its type must not depend on the lifetime parameter `'r`
90-
|
91-
= note: `K` has type `&'r [Self; Q]`
92-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
10+
LL | const K: &'a [T; N];
11+
| ^ the type must not depend on the parameter `T`
9312

94-
error: the type of the associated constant `K` must not depend on `Self`
95-
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
96-
|
97-
LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
98-
| ^ its type must not depend on `Self`
13+
error[E0770]: the type of const parameters must not depend on other generic parameters
14+
--> $DIR/assoc-const-eq-param-in-ty.rs:15:22
9915
|
100-
= note: `K` has type `&'r [Self; Q]`
101-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
16+
LL | const K: &'a [T; N];
17+
| ^ the type must not depend on the parameter `N`
10218

103-
error: the type of the associated constant `K` must not depend on generic parameters
104-
--> $DIR/assoc-const-eq-param-in-ty.rs:53:52
105-
|
106-
LL | type Assoc<const Q: usize>: Trait<'r, Self, Q, K = const { loop {} }>
107-
| - ^ its type must not depend on the const parameter `Q`
108-
| |
109-
| the const parameter `Q` is defined here
19+
error[E0770]: the type of const parameters must not depend on other generic parameters
20+
--> $DIR/assoc-const-eq-param-in-ty.rs:27:17
11021
|
111-
= note: `K` has type `&'r [Self; Q]`
112-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
22+
LL | const SELF: Self;
23+
| ^^^^ the type must not depend on the parameter `Self`
11324

114-
error: aborting due to 11 previous errors
25+
error: aborting due to 4 previous errors
11526

27+
For more information about this error, try `rustc --explain E0770`.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#![expect(incomplete_features)]
2+
#![feature(adt_const_params, unsized_const_params, min_generic_const_args, generic_const_items)]
3+
4+
#[type_const]
5+
const FOO<T: core::marker::ConstParamTy_>: [T; 0] = const { [] };
6+
//~^ ERROR the type of const parameters must not depend on other generic parameters
7+
8+
trait Tr {
9+
#[type_const]
10+
const ASSOC<T: core::marker::ConstParamTy_>: [T; 0];
11+
//~^ ERROR the type of const parameters must not depend on other generic parameters
12+
}
13+
14+
impl Tr for () {
15+
#[type_const]
16+
const ASSOC<T: core::marker::ConstParamTy_>: [T; 0] = const { [] };
17+
//~^ ERROR the type of const parameters must not depend on other generic parameters
18+
}
19+
20+
fn main() {}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0770]: the type of const parameters must not depend on other generic parameters
2+
--> $DIR/type_const-generic-param-in-type.rs:5:45
3+
|
4+
LL | const FOO<T: core::marker::ConstParamTy_>: [T; 0] = const { [] };
5+
| ^ the type must not depend on the parameter `T`
6+
7+
error[E0770]: the type of const parameters must not depend on other generic parameters
8+
--> $DIR/type_const-generic-param-in-type.rs:10:51
9+
|
10+
LL | const ASSOC<T: core::marker::ConstParamTy_>: [T; 0];
11+
| ^ the type must not depend on the parameter `T`
12+
13+
error[E0770]: the type of const parameters must not depend on other generic parameters
14+
--> $DIR/type_const-generic-param-in-type.rs:16:51
15+
|
16+
LL | const ASSOC<T: core::marker::ConstParamTy_>: [T; 0] = const { [] };
17+
| ^ the type must not depend on the parameter `T`
18+
19+
error: aborting due to 3 previous errors
20+
21+
For more information about this error, try `rustc --explain E0770`.

0 commit comments

Comments
 (0)