Skip to content

Commit 317465c

Browse files
committed
Add min_generic_const_args and gate new const path lowering with it
1 parent 94e4efe commit 317465c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+405
-183
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -2063,8 +2063,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20632063
ty_id: NodeId,
20642064
span: Span,
20652065
) -> &'hir hir::ConstArg<'hir> {
2066+
let tcx = self.tcx;
2067+
20662068
// FIXME(min_generic_const_args): we only allow one-segment const paths for now
2067-
let ct_kind = if path.is_potential_trivial_const_arg() {
2069+
let ct_kind = if path.is_potential_trivial_const_arg()
2070+
&& (tcx.features().min_generic_const_args()
2071+
|| matches!(res, Res::Def(DefKind::ConstParam, _)))
2072+
{
20682073
let qpath = self.lower_qpath(
20692074
ty_id,
20702075
&None,
@@ -2127,6 +2132,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21272132

21282133
#[instrument(level = "debug", skip(self))]
21292134
fn lower_anon_const_to_const_arg_direct(&mut self, anon: &AnonConst) -> hir::ConstArg<'hir> {
2135+
let tcx = self.tcx;
21302136
// Unwrap a block, so that e.g. `{ P }` is recognised as a parameter. Const arguments
21312137
// currently have to be wrapped in curly brackets, so it's necessary to special-case.
21322138
let expr = if let ExprKind::Block(block, _) = &anon.value.kind
@@ -2138,9 +2144,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
21382144
} else {
21392145
&anon.value
21402146
};
2147+
let maybe_res =
2148+
self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
21412149
// FIXME(min_generic_const_args): we only allow one-segment const paths for now
21422150
if let ExprKind::Path(None, path) = &expr.kind
21432151
&& path.is_potential_trivial_const_arg()
2152+
&& (tcx.features().min_generic_const_args()
2153+
|| matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
21442154
{
21452155
let qpath = self.lower_qpath(
21462156
expr.id,

compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,8 @@ declare_features! (
529529
(unstable, macro_metavar_expr_concat, "1.81.0", Some(124225)),
530530
/// Allows `#[marker]` on certain traits allowing overlapping implementations.
531531
(unstable, marker_trait_attr, "1.30.0", Some(29864)),
532+
/// Enables the generic const args MVP (only bare paths, not arbitrary computation).
533+
(incomplete, min_generic_const_args, "CURRENT_RUSTC_VERSION", Some(132980)),
532534
/// A minimal, sound subset of specialization intended to be used by the
533535
/// standard library until the soundness issues with specialization
534536
/// are fixed.

compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs

+10
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@ fn generic_arg_mismatch_err(
121121
{
122122
err.help(format!("`{}` is a function item, not a type", tcx.item_name(id)));
123123
err.help("function item types cannot be named directly");
124+
} else if let hir::ConstArgKind::Anon(anon) = cnst.kind
125+
&& let body = tcx.hir().body(anon.body)
126+
&& let rustc_hir::ExprKind::Path(rustc_hir::QPath::Resolved(_, path)) =
127+
body.value.kind
128+
&& let Res::Def(DefKind::Fn { .. }, id) = path.res
129+
{
130+
// FIXME(min_generic_const_args): this branch is dead once new const path lowering
131+
// (for single-segment paths) is no longer gated
132+
err.help(format!("`{}` is a function item, not a type", tcx.item_name(id)));
133+
err.help("function item types cannot be named directly");
124134
}
125135
}
126136
_ => {}

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,7 @@ symbols! {
12251225
min_const_generics,
12261226
min_const_unsafe_fn,
12271227
min_exhaustive_patterns,
1228+
min_generic_const_args,
12281229
min_specialization,
12291230
min_type_alias_impl_trait,
12301231
minnumf128,

tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ impl Wrapper<{ bar() }> {
1515

1616
fn main() {
1717
Wrapper::<function>::call;
18+
//~^ ERROR: the function or associated item `call` exists for struct `Wrapper<function>`,
1819
}

tests/ui/const-generics/adt_const_params/non_valtreeable_const_arg-2.stderr

+20-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,25 @@ error[E0741]: using function pointers as const generic parameters is forbidden
1515
LL | struct Wrapper<const F: fn()>;
1616
| ^^^^
1717

18-
error: aborting due to 2 previous errors
18+
error[E0599]: the function or associated item `call` exists for struct `Wrapper<function>`, but its trait bounds were not satisfied
19+
--> $DIR/non_valtreeable_const_arg-2.rs:17:26
20+
|
21+
LL | struct Wrapper<const F: fn()>;
22+
| ----------------------------- function or associated item `call` not found for this struct because it doesn't satisfy `Wrapper<function>: Fn<_>`
23+
...
24+
LL | Wrapper::<function>::call;
25+
| ^^^^ function or associated item cannot be called on `Wrapper<function>` due to unsatisfied trait bounds
26+
|
27+
= note: the following trait bounds were not satisfied:
28+
`Wrapper<function>: Fn<_>`
29+
which is required by `&Wrapper<function>: Fn<_>`
30+
note: the trait `Fn` must be implemented
31+
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
32+
= help: items from traits can only be used if the trait is implemented and in scope
33+
= note: the following trait defines an item `call`, perhaps you need to implement it:
34+
candidate #1: `Fn`
35+
36+
error: aborting due to 3 previous errors
1937

20-
Some errors have detailed explanations: E0425, E0741.
38+
Some errors have detailed explanations: E0425, E0599, E0741.
2139
For more information about an error, try `rustc --explain E0425`.

tests/ui/const-generics/bad-generic-in-copy-impl.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
#[derive(Copy, Clone)]
2-
//~^ ERROR the trait `Copy` cannot be implemented for this type
32
pub struct Foo {
43
x: [u8; SIZE],
5-
//~^ ERROR the constant `1` is not of type `usize`
6-
//~| ERROR the constant `1` is not of type `usize`
4+
//~^ ERROR mismatched types
5+
//~| ERROR mismatched types
76
}
87

98
const SIZE: u32 = 1;
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,17 @@
1-
error: the constant `1` is not of type `usize`
2-
--> $DIR/bad-generic-in-copy-impl.rs:4:8
1+
error[E0308]: mismatched types
2+
--> $DIR/bad-generic-in-copy-impl.rs:3:13
33
|
44
LL | x: [u8; SIZE],
5-
| ^^^^^^^^^^ expected `usize`, found `u32`
5+
| ^^^^ expected `usize`, found `u32`
66

7-
error[E0204]: the trait `Copy` cannot be implemented for this type
8-
--> $DIR/bad-generic-in-copy-impl.rs:1:10
7+
error[E0308]: mismatched types
8+
--> $DIR/bad-generic-in-copy-impl.rs:3:13
99
|
10-
LL | #[derive(Copy, Clone)]
11-
| ^^^^
12-
...
1310
LL | x: [u8; SIZE],
14-
| ------------- this field does not implement `Copy`
11+
| ^^^^ expected `usize`, found `u32`
1512
|
16-
note: the `Copy` impl for `[u8; 1]` requires that `the constant `1` has type `usize``
17-
--> $DIR/bad-generic-in-copy-impl.rs:4:8
18-
|
19-
LL | x: [u8; SIZE],
20-
| ^^^^^^^^^^
21-
= note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
22-
23-
error: the constant `1` is not of type `usize`
24-
--> $DIR/bad-generic-in-copy-impl.rs:4:5
25-
|
26-
LL | #[derive(Copy, Clone)]
27-
| ----- in this derive macro expansion
28-
...
29-
LL | x: [u8; SIZE],
30-
| ^^^^^^^^^^^^^ expected `usize`, found `u32`
31-
|
32-
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
13+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
3314

34-
error: aborting due to 3 previous errors
15+
error: aborting due to 2 previous errors
3516

36-
For more information about this error, try `rustc --explain E0204`.
17+
For more information about this error, try `rustc --explain E0308`.

tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
77
= note: const parameters may not be used in the type of const parameters
88

99
error[E0770]: the type of const parameters must not depend on other generic parameters
10-
--> $DIR/const-param-type-depends-on-const-param.rs:14:40
10+
--> $DIR/const-param-type-depends-on-const-param.rs:15:40
1111
|
1212
LL | pub struct SelfDependent<const N: [u8; N]>;
1313
| ^ the type must not depend on the parameter `N`

tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr

+26-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,37 @@ LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
77
= note: const parameters may not be used in the type of const parameters
88

99
error[E0770]: the type of const parameters must not depend on other generic parameters
10-
--> $DIR/const-param-type-depends-on-const-param.rs:14:40
10+
--> $DIR/const-param-type-depends-on-const-param.rs:15:40
1111
|
1212
LL | pub struct SelfDependent<const N: [u8; N]>;
1313
| ^ the type must not depend on the parameter `N`
1414
|
1515
= note: const parameters may not be used in the type of const parameters
1616

17-
error: aborting due to 2 previous errors
17+
error: `[u8; N]` is forbidden as the type of a const generic parameter
18+
--> $DIR/const-param-type-depends-on-const-param.rs:11:47
19+
|
20+
LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
21+
| ^^^^^^^
22+
|
23+
= note: the only supported types are integers, `bool`, and `char`
24+
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
25+
|
26+
LL + #![feature(adt_const_params)]
27+
|
28+
29+
error: `[u8; N]` is forbidden as the type of a const generic parameter
30+
--> $DIR/const-param-type-depends-on-const-param.rs:15:35
31+
|
32+
LL | pub struct SelfDependent<const N: [u8; N]>;
33+
| ^^^^^^^
34+
|
35+
= note: the only supported types are integers, `bool`, and `char`
36+
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
37+
|
38+
LL + #![feature(adt_const_params)]
39+
|
40+
41+
error: aborting due to 4 previous errors
1842

1943
For more information about this error, try `rustc --explain E0770`.

tests/ui/const-generics/const-param-type-depends-on-const-param.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010

1111
pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
1212
//~^ ERROR: the type of const parameters must not depend on other generic parameters
13+
//[min]~^^ ERROR `[u8; N]` is forbidden
1314

1415
pub struct SelfDependent<const N: [u8; N]>;
1516
//~^ ERROR: the type of const parameters must not depend on other generic parameters
17+
//[min]~^^ ERROR `[u8; N]` is forbidden
1618

1719
fn main() {}

tests/ui/const-generics/fn-const-param-infer.adt_const_params.stderr

+14-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,18 @@ LL | let _ = Checked::<{ generic_arg::<u32> }>;
1313
= note: expected fn pointer `fn(usize) -> _`
1414
found fn item `fn(u32) -> _ {generic_arg::<u32>}`
1515

16-
error: aborting due to 2 previous errors
16+
error[E0282]: type annotations needed
17+
--> $DIR/fn-const-param-infer.rs:35:23
18+
|
19+
LL | let _ = Checked::<generic>;
20+
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
21+
|
22+
help: consider specifying the generic argument
23+
|
24+
LL | let _ = Checked::<generic::<T>>;
25+
| +++++
26+
27+
error: aborting due to 3 previous errors
1728

18-
Some errors have detailed explanations: E0308, E0741.
19-
For more information about an error, try `rustc --explain E0308`.
29+
Some errors have detailed explanations: E0282, E0308, E0741.
30+
For more information about an error, try `rustc --explain E0282`.

tests/ui/const-generics/fn-const-param-infer.full.stderr

+14-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,18 @@ LL | let _ = Checked::<{ generic_arg::<u32> }>;
1313
= note: expected fn pointer `fn(usize) -> _`
1414
found fn item `fn(u32) -> _ {generic_arg::<u32>}`
1515

16-
error: aborting due to 2 previous errors
16+
error[E0282]: type annotations needed
17+
--> $DIR/fn-const-param-infer.rs:35:23
18+
|
19+
LL | let _ = Checked::<generic>;
20+
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
21+
|
22+
help: consider specifying the generic argument
23+
|
24+
LL | let _ = Checked::<generic::<T>>;
25+
| +++++
26+
27+
error: aborting due to 3 previous errors
1728

18-
Some errors have detailed explanations: E0308, E0741.
19-
For more information about an error, try `rustc --explain E0308`.
29+
Some errors have detailed explanations: E0282, E0308, E0741.
30+
For more information about an error, try `rustc --explain E0282`.

tests/ui/const-generics/fn-const-param-infer.min.stderr

+14-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ LL | let _ = Checked::<{ generic_arg::<u32> }>;
1515
= note: expected fn pointer `fn(usize) -> _`
1616
found fn item `fn(u32) -> _ {generic_arg::<u32>}`
1717

18-
error: aborting due to 2 previous errors
18+
error[E0282]: type annotations needed
19+
--> $DIR/fn-const-param-infer.rs:35:23
20+
|
21+
LL | let _ = Checked::<generic>;
22+
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the function `generic`
23+
|
24+
help: consider specifying the generic argument
25+
|
26+
LL | let _ = Checked::<generic::<T>>;
27+
| +++++
28+
29+
error: aborting due to 3 previous errors
1930

20-
For more information about this error, try `rustc --explain E0308`.
31+
Some errors have detailed explanations: E0282, E0308.
32+
For more information about an error, try `rustc --explain E0282`.

tests/ui/const-generics/fn-const-param-infer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ fn main() {
3232
let _ = Checked::<{ generic_arg::<usize> }>;
3333
let _ = Checked::<{ generic_arg::<u32> }>; //~ ERROR: mismatched types
3434

35-
let _ = Checked::<generic>;
35+
let _ = Checked::<generic>; //~ ERROR: type annotations needed
3636
let _ = Checked::<{ generic::<u16> }>;
3737
let _: Checked<{ generic::<u16> }> = Checked::<{ generic::<u16> }>;
3838
let _: Checked<{ generic::<u32> }> = Checked::<{ generic::<u16> }>;

tests/ui/const-generics/generic_const_exprs/adt_wf_hang.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
struct U;
88

99
struct S<const N: U>()
10-
//~^ ERROR: `U` must implement `ConstParamTy` to be used as the type of a const generic parameter
1110
where
1211
S<{ U }>:;
12+
//~^ ERROR: overflow evaluating the requirement `S<{ U }> well-formed`
1313

1414
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
error[E0741]: `U` must implement `ConstParamTy` to be used as the type of a const generic parameter
2-
--> $DIR/adt_wf_hang.rs:9:19
1+
error[E0275]: overflow evaluating the requirement `S<{ U }> well-formed`
2+
--> $DIR/adt_wf_hang.rs:11:5
33
|
4-
LL | struct S<const N: U>()
5-
| ^
6-
|
7-
help: add `#[derive(ConstParamTy)]` to the struct
4+
LL | S<{ U }>:;
5+
| ^^^^^^^^
86
|
9-
LL + #[derive(ConstParamTy)]
10-
LL | struct U;
7+
note: required by a bound in `S`
8+
--> $DIR/adt_wf_hang.rs:11:5
119
|
10+
LL | struct S<const N: U>()
11+
| - required by a bound in this struct
12+
LL | where
13+
LL | S<{ U }>:;
14+
| ^^^^^^^^ required by this bound in `S`
1215

1316
error: aborting due to 1 previous error
1417

15-
For more information about this error, try `rustc --explain E0741`.
18+
For more information about this error, try `rustc --explain E0275`.

tests/ui/const-generics/generic_const_exprs/error_in_ty.rs

+3
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55

66
pub struct A<const z: [usize; x]> {}
77
//~^ ERROR: cannot find value `x` in this scope
8+
//~| ERROR: `[usize; x]` is forbidden as the type of a const generic parameter
89

910
impl A<2> {
11+
//~^ ERROR: mismatched types
1012
pub const fn B() {}
1113
//~^ ERROR: duplicate definitions
1214
}
1315

1416
impl A<2> {
17+
//~^ ERROR: mismatched types
1518
pub const fn B() {}
1619
}
1720

tests/ui/const-generics/generic_const_exprs/error_in_ty.stderr

+28-4
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,40 @@ LL | pub struct A<const z: [usize; x]> {}
66
| |
77
| similarly named const parameter `z` defined here
88

9+
error: `[usize; x]` is forbidden as the type of a const generic parameter
10+
--> $DIR/error_in_ty.rs:6:23
11+
|
12+
LL | pub struct A<const z: [usize; x]> {}
13+
| ^^^^^^^^^^
14+
|
15+
= note: the only supported types are integers, `bool`, and `char`
16+
help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
17+
|
18+
LL + #![feature(adt_const_params)]
19+
|
20+
21+
error[E0308]: mismatched types
22+
--> $DIR/error_in_ty.rs:10:8
23+
|
24+
LL | impl A<2> {
25+
| ^ expected `[usize; x]`, found integer
26+
27+
error[E0308]: mismatched types
28+
--> $DIR/error_in_ty.rs:16:8
29+
|
30+
LL | impl A<2> {
31+
| ^ expected `[usize; x]`, found integer
32+
933
error[E0592]: duplicate definitions with name `B`
10-
--> $DIR/error_in_ty.rs:10:5
34+
--> $DIR/error_in_ty.rs:12:5
1135
|
1236
LL | pub const fn B() {}
1337
| ^^^^^^^^^^^^^^^^ duplicate definitions for `B`
1438
...
1539
LL | pub const fn B() {}
1640
| ---------------- other definition for `B`
1741

18-
error: aborting due to 2 previous errors
42+
error: aborting due to 5 previous errors
1943

20-
Some errors have detailed explanations: E0425, E0592.
21-
For more information about an error, try `rustc --explain E0425`.
44+
Some errors have detailed explanations: E0308, E0425, E0592.
45+
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)