about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-07-14 19:24:06 +0530
committerGitHub <noreply@github.com>2022-07-14 19:24:06 +0530
commit39936fd0b72ab9f25590ef6a2ffda0b08ff147e5 (patch)
tree2630fd6d5c100dc4428bee76b53c80fefe9f1d87
parentd3a1aa0b4380b7ab217a1e2889a4217e70237f61 (diff)
parent96d34dc9ff557c189fef19cb00b36f5cd5c7ac49 (diff)
downloadrust-39936fd0b72ab9f25590ef6a2ffda0b08ff147e5.tar.gz
rust-39936fd0b72ab9f25590ef6a2ffda0b08ff147e5.zip
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
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs27
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs1
-rw-r--r--src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr10
-rw-r--r--src/test/ui/const-generics/parent_generics_of_encoding_impl_trait.rs2
-rw-r--r--src/test/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr4
5 files changed, 37 insertions, 7 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index d47860f95b8..02196a8f16d 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -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;
diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs b/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs
index c6c196db6f2..79e9834b54e 100644
--- a/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs
+++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs
@@ -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
 }
diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr b/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr
index ce75314ada7..59e9fee1eaf 100644
--- a/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr
+++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr
@@ -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
 
diff --git a/src/test/ui/const-generics/parent_generics_of_encoding_impl_trait.rs b/src/test/ui/const-generics/parent_generics_of_encoding_impl_trait.rs
index ed81c01bb17..7a78e0f109c 100644
--- a/src/test/ui/const-generics/parent_generics_of_encoding_impl_trait.rs
+++ b/src/test/ui/const-generics/parent_generics_of_encoding_impl_trait.rs
@@ -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
 }
diff --git a/src/test/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr b/src/test/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr
index 99085711513..87ff7babe71 100644
--- a/src/test/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr
+++ b/src/test/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr
@@ -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