Skip to content

Commit dda2372

Browse files
committed
Auto merge of #122802 - estebank:unconstrained-generic-const, r=Nadrieril
Provide structured suggestion for unconstrained generic constant ``` error: unconstrained generic constant --> $DIR/const-argument-if-length.rs:18:10 | LL | pad: [u8; is_zst::<T>()], | ^^^^^^^^^^^^^^^^^^^ | help: try adding a `where` bound | LL | pub struct AtLeastByte<T: ?Sized> where [(); is_zst::<T>()]: { | ++++++++++++++++++++++++++ ``` Detect when the constant expression isn't `usize` and suggest casting: ``` error: unconstrained generic constant --> f300.rs:6:10 | 6 | bb::<{!N}>(); | ^^^^ -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs:3539:36 | help: try adding a `where` bound | 5 | fn b<const N: bool>() where [(); {!N} as usize]: { | ++++++++++++++++++++++++++ ``` Fix #122395.
2 parents 42198bf + 6b24fdf commit dda2372

Some content is hidden

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

41 files changed

+351
-111
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3536,12 +3536,39 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
35363536
let mut err =
35373537
self.dcx().struct_span_err(span, "unconstrained generic constant");
35383538
let const_span = self.tcx.def_span(uv.def);
3539+
3540+
let const_ty = self.tcx.type_of(uv.def).instantiate(self.tcx, uv.args);
3541+
let cast = if const_ty != self.tcx.types.usize { " as usize" } else { "" };
3542+
let msg = "try adding a `where` bound";
35393543
match self.tcx.sess.source_map().span_to_snippet(const_span) {
3540-
Ok(snippet) => err.help(format!(
3541-
"try adding a `where` bound using this expression: `where [(); {snippet}]:`"
3542-
)),
3543-
_ => err.help("consider adding a `where` bound using this expression"),
3544-
};
3544+
Ok(snippet) => {
3545+
let code = format!("[(); {snippet}{cast}]:");
3546+
let def_id = if let ObligationCauseCode::CompareImplItemObligation {
3547+
trait_item_def_id,
3548+
..
3549+
} = obligation.cause.code()
3550+
{
3551+
trait_item_def_id.as_local()
3552+
} else {
3553+
Some(obligation.cause.body_id)
3554+
};
3555+
if let Some(def_id) = def_id
3556+
&& let Some(generics) = self.tcx.hir().get_generics(def_id)
3557+
{
3558+
err.span_suggestion_verbose(
3559+
generics.tail_span_for_predicate_suggestion(),
3560+
msg,
3561+
format!("{} {code}", generics.add_where_or_trailing_comma()),
3562+
Applicability::MaybeIncorrect,
3563+
);
3564+
} else {
3565+
err.help(format!("{msg}: where {code}"));
3566+
};
3567+
}
3568+
_ => {
3569+
err.help(msg);
3570+
}
3571+
};
35453572
Ok(err)
35463573
}
35473574
ty::ConstKind::Expr(_) => {

tests/ui/const-generics/const-argument-if-length.full.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error: unconstrained generic constant
44
LL | pad: [u8; is_zst::<T>()],
55
| ^^^^^^^^^^^^^^^^^^^
66
|
7-
= help: try adding a `where` bound using this expression: `where [(); is_zst::<T>()]:`
7+
help: try adding a `where` bound
8+
|
9+
LL | pub struct AtLeastByte<T: ?Sized> where [(); is_zst::<T>()]: {
10+
| ++++++++++++++++++++++++++
811

912
error[E0277]: the size for values of type `T` cannot be known at compilation time
1013
--> $DIR/const-argument-if-length.rs:16:12

tests/ui/const-generics/defaults/generic-expr-default.stderr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,21 @@ error: unconstrained generic constant
44
LL | pub fn needs_evaluatable_bound<const N1: usize>() -> Foo<N1> {
55
| ^^^^^^^
66
|
7-
= help: try adding a `where` bound using this expression: `where [(); { N + 1 }]:`
7+
help: try adding a `where` bound
8+
|
9+
LL | pub fn needs_evaluatable_bound<const N1: usize>() -> Foo<N1> where [(); { N + 1 }]: {
10+
| ++++++++++++++++++++++
811

912
error: unconstrained generic constant
1013
--> $DIR/generic-expr-default.rs:14:58
1114
|
1215
LL | fn needs_evaluatable_bound_alias<T, const N: usize>() -> FooAlias<N>
1316
| ^^^^^^^^^^^
1417
|
15-
= help: try adding a `where` bound using this expression: `where [(); { N + 1 }]:`
18+
help: try adding a `where` bound
19+
|
20+
LL | fn needs_evaluatable_bound_alias<T, const N: usize>() -> FooAlias<N> where [(); { N + 1 }]:
21+
| ++++++++++++++++++++++
1622

1723
error: aborting due to 2 previous errors
1824

tests/ui/const-generics/ensure_is_evaluatable.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ error: unconstrained generic constant
44
LL | bar()
55
| ^^^^^
66
|
7-
= help: try adding a `where` bound using this expression: `where [(); N + 1]:`
87
note: required by a bound in `bar`
98
--> $DIR/ensure_is_evaluatable.rs:15:10
109
|
@@ -13,6 +12,10 @@ LL | fn bar<const N: usize>() -> [(); N]
1312
LL | where
1413
LL | [(); N + 1]:,
1514
| ^^^^^ required by this bound in `bar`
15+
help: try adding a `where` bound
16+
|
17+
LL | [(); M + 1]:, [(); N + 1]:
18+
| ~~~~~~~~~~~~~~
1619

1720
error: aborting due to 1 previous error
1821

tests/ui/const-generics/fn_with_two_const_inputs.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ error: unconstrained generic constant
44
LL | bar()
55
| ^^^^^
66
|
7-
= help: try adding a `where` bound using this expression: `where [(); N + 1]:`
87
note: required by a bound in `bar`
98
--> $DIR/fn_with_two_const_inputs.rs:18:10
109
|
@@ -13,6 +12,10 @@ LL | fn bar<const N: usize>() -> [(); N]
1312
LL | where
1413
LL | [(); N + 1]:,
1514
| ^^^^^ required by this bound in `bar`
15+
help: try adding a `where` bound
16+
|
17+
LL | [(); both(N + 1, M + 1)]:, [(); N + 1]:
18+
| ~~~~~~~~~~~~~~
1619

1720
error: aborting due to 1 previous error
1821

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@ run-rustfix
2+
#![feature(generic_const_exprs)]
3+
#![allow(incomplete_features, dead_code)]
4+
5+
struct Evaluatable<const N: u128> {}
6+
7+
struct Foo<const N: u8>([u8; N as usize])
8+
//~^ ERROR unconstrained generic constant
9+
where
10+
Evaluatable<{N as u128}>:, [(); N as usize]:;
11+
//~^ HELP try adding a `where` bound
12+
13+
struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:, [(); {N as u128} as usize]:;
14+
//~^ ERROR unconstrained generic constant
15+
//~| HELP try adding a `where` bound
16+
17+
struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:, [(); (N + 2) as usize]:;
18+
//~^ ERROR unconstrained generic constant
19+
//~| HELP try adding a `where` bound
20+
21+
fn main() {}
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1+
//@ run-rustfix
12
#![feature(generic_const_exprs)]
2-
#![allow(incomplete_features)]
3+
#![allow(incomplete_features, dead_code)]
34

45
struct Evaluatable<const N: u128> {}
56

67
struct Foo<const N: u8>([u8; N as usize])
7-
//~^ Error: unconstrained generic constant
8-
//~| help: try adding a `where` bound using this expression: `where [(); N as usize]:`
8+
//~^ ERROR unconstrained generic constant
99
where
1010
Evaluatable<{N as u128}>:;
11+
//~^ HELP try adding a `where` bound
1112

1213
struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
13-
//~^ Error: unconstrained generic constant
14-
//~| help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
14+
//~^ ERROR unconstrained generic constant
15+
//~| HELP try adding a `where` bound
1516

1617
struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
17-
//~^ Error: unconstrained generic constant
18-
//~| help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
18+
//~^ ERROR unconstrained generic constant
19+
//~| HELP try adding a `where` bound
1920

2021
fn main() {}
Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
11
error: unconstrained generic constant
2-
--> $DIR/abstract-const-as-cast-2.rs:6:25
2+
--> $DIR/abstract-const-as-cast-2.rs:7:25
33
|
44
LL | struct Foo<const N: u8>([u8; N as usize])
55
| ^^^^^^^^^^^^^^^^
66
|
7-
= help: try adding a `where` bound using this expression: `where [(); N as usize]:`
7+
help: try adding a `where` bound
8+
|
9+
LL | Evaluatable<{N as u128}>:, [(); N as usize]:;
10+
| +++++++++++++++++++
811

912
error: unconstrained generic constant
10-
--> $DIR/abstract-const-as-cast-2.rs:12:26
13+
--> $DIR/abstract-const-as-cast-2.rs:13:26
1114
|
1215
LL | struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:;
1316
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
1417
|
15-
= help: try adding a `where` bound using this expression: `where [(); {N as u128}]:`
18+
help: try adding a `where` bound
19+
|
20+
LL | struct Foo2<const N: u8>(Evaluatable::<{N as u128}>) where Evaluatable<{N as usize as u128 }>:, [(); {N as u128} as usize]:;
21+
| +++++++++++++++++++++++++++++
1622

1723
error: unconstrained generic constant
18-
--> $DIR/abstract-const-as-cast-2.rs:16:25
24+
--> $DIR/abstract-const-as-cast-2.rs:17:25
1925
|
2026
LL | struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:;
2127
| ^^^^^^^^^^^^^^^^^^^^^^
2228
|
23-
= help: try adding a `where` bound using this expression: `where [(); (N + 2) as usize]:`
29+
help: try adding a `where` bound
30+
|
31+
LL | struct Bar<const N: u8>([u8; (N + 2) as usize]) where [(); (N + 1) as usize]:, [(); (N + 2) as usize]:;
32+
| +++++++++++++++++++++++++
2433

2534
error: aborting due to 3 previous errors
2635

tests/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ error: unconstrained generic constant
44
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
87
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
98
--> $DIR/abstract-const-as-cast-3.rs:8:22
109
|
@@ -15,6 +14,10 @@ note: required by a bound in `use_trait_impl::assert_impl`
1514
|
1615
LL | fn assert_impl<T: Trait>() {}
1716
| ^^^^^ required by this bound in `assert_impl`
17+
help: try adding a `where` bound
18+
|
19+
LL | EvaluatableU128<{N as u128}>:, [(); { O as u128 } as usize]: {
20+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1821

1922
error[E0308]: mismatched types
2023
--> $DIR/abstract-const-as-cast-3.rs:17:5
@@ -36,7 +39,6 @@ error: unconstrained generic constant
3639
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
3740
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3841
|
39-
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
4042
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
4143
--> $DIR/abstract-const-as-cast-3.rs:8:22
4244
|
@@ -47,6 +49,10 @@ note: required by a bound in `use_trait_impl::assert_impl`
4749
|
4850
LL | fn assert_impl<T: Trait>() {}
4951
| ^^^^^ required by this bound in `assert_impl`
52+
help: try adding a `where` bound
53+
|
54+
LL | EvaluatableU128<{N as u128}>:, [(); { O as u128 } as usize]: {
55+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5056

5157
error[E0308]: mismatched types
5258
--> $DIR/abstract-const-as-cast-3.rs:20:5
@@ -96,7 +102,6 @@ error: unconstrained generic constant
96102
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as u128 }>>();
97103
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
98104
|
99-
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
100105
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as u128 }>` to implement `Trait`
101106
--> $DIR/abstract-const-as-cast-3.rs:8:22
102107
|
@@ -107,6 +112,10 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
107112
|
108113
LL | fn assert_impl<T: Trait>() {}
109114
| ^^^^^ required by this bound in `assert_impl`
115+
help: try adding a `where` bound
116+
|
117+
LL | EvaluatableU128<{N as _}>:, [(); { O as u128 } as usize]: {
118+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
110119

111120
error[E0308]: mismatched types
112121
--> $DIR/abstract-const-as-cast-3.rs:35:5
@@ -128,7 +137,6 @@ error: unconstrained generic constant
128137
LL | assert_impl::<HasCastInTraitImpl<{ N + 1 }, { N as _ }>>();
129138
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
130139
|
131-
= help: try adding a `where` bound using this expression: `where [(); { O as u128 }]:`
132140
note: required for `HasCastInTraitImpl<{ N + 1 }, { N as _ }>` to implement `Trait`
133141
--> $DIR/abstract-const-as-cast-3.rs:8:22
134142
|
@@ -139,6 +147,10 @@ note: required by a bound in `use_trait_impl_2::assert_impl`
139147
|
140148
LL | fn assert_impl<T: Trait>() {}
141149
| ^^^^^ required by this bound in `assert_impl`
150+
help: try adding a `where` bound
151+
|
152+
LL | EvaluatableU128<{N as _}>:, [(); { O as u128 } as usize]: {
153+
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142154

143155
error[E0308]: mismatched types
144156
--> $DIR/abstract-const-as-cast-3.rs:38:5

tests/ui/const-generics/generic_const_exprs/abstract-consts-as-cast-5.stderr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ error: unconstrained generic constant
44
LL | bar::<{ N as usize as usize }>();
55
| ^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
= help: try adding a `where` bound using this expression: `where [(); { N as usize as usize }]:`
7+
help: try adding a `where` bound
8+
|
9+
LL | fn foo<const N: u8>(a: [(); N as usize]) where [(); { N as usize as usize }]: {
10+
| ++++++++++++++++++++++++++++++++++++
811

912
error: aborting due to 1 previous error
1013

0 commit comments

Comments
 (0)