report_not_const_evaluatable_error to avoid ICEing on ConstKind::Expr

This commit is contained in:
Lenko Donchev 2023-10-14 14:47:24 -05:00
parent ce670339c3
commit 69a2bd6c04
3 changed files with 112 additions and 13 deletions

View File

@ -3525,20 +3525,30 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
match obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => {
let ty::ConstKind::Unevaluated(uv) = ct.kind() else {
ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(ct)) => match ct.kind() {
ty::ConstKind::Unevaluated(uv) => {
let mut err =
self.tcx.sess.struct_span_err(span, "unconstrained generic constant");
let const_span = self.tcx.def_span(uv.def);
match self.tcx.sess.source_map().span_to_snippet(const_span) {
Ok(snippet) => err.help(format!(
"try adding a `where` bound using this expression: `where [(); {snippet}]:`"
)),
_ => err.help("consider adding a `where` bound using this expression"),
};
Some(err)
}
ty::ConstKind::Expr(_) => {
let err = self
.tcx
.sess
.struct_span_err(span, format!("unconstrained generic constant `{ct}`"));
Some(err)
}
_ => {
bug!("const evaluatable failed for non-unevaluated const `{ct:?}`");
};
let mut err = self.tcx.sess.struct_span_err(span, "unconstrained generic constant");
let const_span = self.tcx.def_span(uv.def);
match self.tcx.sess.source_map().span_to_snippet(const_span) {
Ok(snippet) => err.help(format!(
"try adding a `where` bound using this expression: `where [(); {snippet}]:`"
)),
_ => err.help("consider adding a `where` bound using this expression"),
};
Some(err)
}
}
},
_ => {
span_bug!(
span,

View File

@ -0,0 +1,25 @@
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
fn foo<const N: usize>(
_: [u8; {
{
N
}
}],
) {
}
fn ice<const L: usize>()
where
[(); (L - 1) + 1 + L]:,
{
foo::<_, L>([(); L + 1 + L]);
//~^ ERROR: mismatched types
//~^^ ERROR: unconstrained generic constant
//~^^^ ERROR: function takes 1 generic argument but 2 generic arguments were supplied
//~^^^^ ERROR: unconstrained generic constant
//~^^^^^ ERROR: unconstrained generic constant `{const expr}`
}
fn main() {}

View File

@ -0,0 +1,64 @@
error[E0107]: function takes 1 generic argument but 2 generic arguments were supplied
--> $DIR/issue_114151.rs:17:5
|
LL | foo::<_, L>([(); L + 1 + L]);
| ^^^ - help: remove this generic argument
| |
| expected 1 generic argument
|
note: function defined here, with 1 generic parameter: `N`
--> $DIR/issue_114151.rs:4:4
|
LL | fn foo<const N: usize>(
| ^^^ --------------
error[E0308]: mismatched types
--> $DIR/issue_114151.rs:17:18
|
LL | foo::<_, L>([(); L + 1 + L]);
| ^^ expected `u8`, found `()`
error: unconstrained generic constant
--> $DIR/issue_114151.rs:17:22
|
LL | foo::<_, L>([(); L + 1 + L]);
| ^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); L + 1 + L]:`
error: unconstrained generic constant
--> $DIR/issue_114151.rs:17:17
|
LL | foo::<_, L>([(); L + 1 + L]);
| ----------- ^^^^^^^^^^^^^^^
| |
| required by a bound introduced by this call
|
= help: try adding a `where` bound using this expression: `where [(); {
{
N
}
}]:`
note: required by a bound in `foo`
--> $DIR/issue_114151.rs:5:13
|
LL | fn foo<const N: usize>(
| --- required by a bound in this function
LL | _: [u8; {
| _____________^
LL | | {
LL | | N
LL | | }
LL | | }],
| |_____^ required by this bound in `foo`
error: unconstrained generic constant `{const expr}`
--> $DIR/issue_114151.rs:17:5
|
LL | foo::<_, L>([(); L + 1 + L]);
| ^^^^^^^^^^^
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0107, E0308.
For more information about an error, try `rustc --explain E0107`.