Skip to content

Commit dd0507c

Browse files
committed
Make TooGeneric error in WF checking a proper error
`TooGeneric` is encountered during WF checking when we cannot determine that a constant involving a generic parameter will always be evaluated successfully (rather than resulting in an error). In these cases, the burden of proof should be with the caller, so that we can avoid post-monomorphisation tim errors (which was the previous previous behaviour). This commit ensures that this situation produces a proper compiler error, rather than silently ignoring it or ICEing.
1 parent 900811e commit dd0507c

File tree

3 files changed

+45
-16
lines changed

3 files changed

+45
-16
lines changed

Diff for: src/librustc/traits/error_reporting/mod.rs

+23-11
Original file line numberDiff line numberDiff line change
@@ -914,17 +914,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
914914
report_object_safety_error(self.tcx, span, did, violations)
915915
}
916916

917-
// already reported in the query
918-
ConstEvalFailure(err) => {
919-
if let ErrorHandled::TooGeneric = err {
920-
// Silence this error, as it can be produced during intermediate steps
921-
// when a constant is not yet able to be evaluated (but will be later).
922-
return;
923-
}
924-
self.tcx.sess.delay_span_bug(
925-
span,
926-
&format!("constant in type had an ignored error: {:?}", err),
927-
);
917+
ConstEvalFailure(ErrorHandled::TooGeneric) => {
918+
// In this instance, we have a const expression containing an unevaluated
919+
// generic parameter. We have no idea whether this expression is valid or
920+
// not (e.g. it might result in an error), but we don't want to just assume
921+
// that it's okay, because that might result in post-monomorphisation time
922+
// errors. The onus is really on the caller to provide values that it can
923+
// prove are well-formed.
924+
let mut err = self
925+
.tcx
926+
.sess
927+
.struct_span_err(span, "constant expression depends on a generic parameter");
928+
// FIXME(const_generics): we should suggest to the user how they can resolve this
929+
// issue. However, this is currently not actually possible
930+
// (see https://github.com/rust-lang/rust/issues/66962#issuecomment-575907083).
931+
err.note("this may fail depending on what value the parameter takes");
932+
err
933+
}
934+
935+
// Already reported in the query.
936+
ConstEvalFailure(ErrorHandled::Reported) => {
937+
self.tcx
938+
.sess
939+
.delay_span_bug(span, &format!("constant in type had an ignored error"));
928940
return;
929941
}
930942

Diff for: src/test/ui/const-generics/array-size-in-generic-struct-param.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
// run-pass
2-
31
#![feature(const_generics)]
42
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
53

64
#[allow(dead_code)]
7-
struct ArithArrayLen<const N: usize>([u32; 0 + N]); // ok
5+
struct ArithArrayLen<const N: usize>([u32; 0 + N]);
6+
//~^ ERROR constant expression depends on a generic parameter
87

98
#[derive(PartialEq, Eq)]
109
struct Config {
1110
arr_size: usize,
1211
}
1312

1413
struct B<const CFG: Config> {
15-
arr: [u8; CFG.arr_size], // ok
14+
arr: [u8; CFG.arr_size], //~ ERROR constant expression depends on a generic parameter
1615
}
1716

1817
const C: Config = Config { arr_size: 5 };
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
11
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
2-
--> $DIR/array-size-in-generic-struct-param.rs:3:12
2+
--> $DIR/array-size-in-generic-struct-param.rs:1:12
33
|
44
LL | #![feature(const_generics)]
55
| ^^^^^^^^^^^^^^
66
|
77
= note: `#[warn(incomplete_features)]` on by default
88

9+
error: constant expression depends on a generic parameter
10+
--> $DIR/array-size-in-generic-struct-param.rs:5:38
11+
|
12+
LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
13+
| ^^^^^^^^^^^^
14+
|
15+
= note: this may fail depending on what value the parameter takes
16+
17+
error: constant expression depends on a generic parameter
18+
--> $DIR/array-size-in-generic-struct-param.rs:14:5
19+
|
20+
LL | arr: [u8; CFG.arr_size],
21+
| ^^^^^^^^^^^^^^^^^^^^^^^
22+
|
23+
= note: this may fail depending on what value the parameter takes
24+
25+
error: aborting due to 2 previous errors
26+

0 commit comments

Comments
 (0)