Rollup merge of #99222 - atsuzaki:generic_const_err, r=lcnr

Better error message for generic_const_exprs inference failure

Fixes #90531

This code:
```rs
#![feature(generic_const_exprs)]

fn foo<const N: usize>(_arr: [u64; N + 1]) where [u64; N + 1]: {}

fn main() {
  let arr = [5; 5];
  foo(arr);
}
```

Will now emit the following error:
```rs
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
 --> test.rs:1:12
  |
1 | #![feature(generic_const_exprs)]
  |            ^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(incomplete_features)]` on by default
  = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information

error[E0284]: type annotations needed
 --> test.rs:8:7
  |
8 |       foo(arr);
  |       ^^^ cannot infer the value of the const parameter `N` declared on the function `foo`
  |
note: required by a bound in `foo`
 --> test.rs:3:56
  |
3 | fn foo<const N: usize>(_arr: [u64; N + 1]) where [u64; N + 1]: {}
  |                                                        ^^^^^ required by this bound in `foo`
help: consider specifying the generic argument
  |
8 |       foo::<N>(arr);
  |          +++++

error: aborting due to previous error; 1 warning emitted
```

cc: `@lcnr` thanks a lot again for the help on this
This commit is contained in:
Dylan DPC 2022-07-14 19:24:06 +05:30 committed by GitHub
commit 39936fd0b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 7 deletions

View File

@ -2179,6 +2179,33 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
}
}
ty::PredicateKind::ConstEvaluatable(data) => {
if predicate.references_error() || self.is_tainted_by_errors() {
return;
}
let subst = data.substs.iter().find(|g| g.has_infer_types_or_consts());
if let Some(subst) = subst {
let err = self.emit_inference_failure_err(
body_id,
span,
subst,
ErrorCode::E0284,
true,
);
err
} else {
// If we can't find a substitution, just print a generic error
let mut err = struct_span_err!(
self.tcx.sess,
span,
E0284,
"type annotations needed: cannot satisfy `{}`",
predicate,
);
err.span_label(span, &format!("cannot satisfy `{}`", predicate));
err
}
}
_ => {
if self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() {
return;

View File

@ -16,7 +16,6 @@ fn use_dyn<const N: usize>(v: &dyn Foo<N>) where [u8; N + 1]: Sized {
}
fn main() {
// FIXME(generic_const_exprs): Improve the error message here.
use_dyn(&());
//~^ ERROR type annotations needed
}

View File

@ -1,14 +1,18 @@
error[E0284]: type annotations needed: cannot satisfy `the constant `use_dyn::<{_: usize}>::{constant#0}` can be evaluated`
--> $DIR/object-safety-ok-infer-err.rs:20:5
error[E0284]: type annotations needed
--> $DIR/object-safety-ok-infer-err.rs:19:5
|
LL | use_dyn(&());
| ^^^^^^^ cannot satisfy `the constant `use_dyn::<{_: usize}>::{constant#0}` can be evaluated`
| ^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `use_dyn`
|
note: required by a bound in `use_dyn`
--> $DIR/object-safety-ok-infer-err.rs:14:55
|
LL | fn use_dyn<const N: usize>(v: &dyn Foo<N>) where [u8; N + 1]: Sized {
| ^^^^^ required by this bound in `use_dyn`
help: consider specifying the generic argument
|
LL | use_dyn::<N>(&());
| +++++
error: aborting due to previous error

View File

@ -7,5 +7,5 @@ extern crate generics_of_parent_impl_trait;
fn main() {
// check for `impl Trait<{ const }>` which has a parent of a `DefKind::TyParam`
generics_of_parent_impl_trait::foo([()]);
//~^ error: type annotations needed:
//~^ error: type annotations needed
}

View File

@ -1,8 +1,8 @@
error[E0284]: type annotations needed: cannot satisfy `the constant `foo::{opaque#0}::{constant#0}` can be evaluated`
error[E0284]: type annotations needed
--> $DIR/parent_generics_of_encoding_impl_trait.rs:9:5
|
LL | generics_of_parent_impl_trait::foo([()]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `foo::{opaque#0}::{constant#0}` can be evaluated`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `foo`
|
note: required by a bound in `foo`
--> $DIR/auxiliary/generics_of_parent_impl_trait.rs:6:48