about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-09-16 12:34:21 +0200
committerGitHub <noreply@github.com>2020-09-16 12:34:21 +0200
commit3f9e7fc0497a08983078cbe987af79f131da6419 (patch)
treed8a81a3a6ed44da399a38d35af845c53bebd6290
parent54d77285fcba0ab3d9d5ad8ff8a02bd6187bcf58 (diff)
parent035f8791668406bc49fc315253835cbdec247549 (diff)
downloadrust-3f9e7fc0497a08983078cbe987af79f131da6419.tar.gz
rust-3f9e7fc0497a08983078cbe987af79f131da6419.zip
Rollup merge of #76699 - lcnr:const-infer-err, r=varkor
improve const infer error

cc #72328

reduces it from
```
error[E0282]: type annotations needed
  --> src/main.rs:17:5
   |
17 |     Foo.bar().bar().bar().bar().baz();
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: unable to infer the value of a const parameter
```
to
```
error[E0282]: type annotations needed
  --> $DIR/method-chain.rs:21:33
   |
LL |     Foo.bar().bar().bar().bar().baz();
   |                                 ^^^
   |
   = note: cannot infer the value of the const parameter `N`
```

r? @varkor
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs27
-rw-r--r--compiler/rustc_middle/src/infer/unify_key.rs1
-rw-r--r--src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr (renamed from src/test/ui/const-generics/cannot-infer-const-args.full.stderr)2
-rw-r--r--src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr (renamed from src/test/ui/const-generics/cannot-infer-const-args.min.stderr)2
-rw-r--r--src/test/ui/const-generics/infer/cannot-infer-const-args.rs (renamed from src/test/ui/const-generics/cannot-infer-const-args.rs)0
-rw-r--r--src/test/ui/const-generics/infer/method-chain.full.stderr11
-rw-r--r--src/test/ui/const-generics/infer/method-chain.min.stderr11
-rw-r--r--src/test/ui/const-generics/infer/method-chain.rs22
-rw-r--r--src/test/ui/const-generics/infer/uninferred-consts.full.stderr (renamed from src/test/ui/const-generics/uninferred-consts.full.stderr)6
-rw-r--r--src/test/ui/const-generics/infer/uninferred-consts.min.stderr (renamed from src/test/ui/const-generics/uninferred-consts.min.stderr)6
-rw-r--r--src/test/ui/const-generics/infer/uninferred-consts.rs (renamed from src/test/ui/const-generics/uninferred-consts.rs)0
11 files changed, 73 insertions, 15 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 4de84e5ba39..f87406c2ce4 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -6,9 +6,10 @@ use rustc_hir::def::{DefKind, Namespace};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::{Body, Expr, ExprKind, FnRetTy, HirId, Local, Pat};
 use rustc_middle::hir::map::Map;
+use rustc_middle::infer::unify_key::ConstVariableOriginKind;
 use rustc_middle::ty::print::Print;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
-use rustc_middle::ty::{self, DefIdTree, Ty};
+use rustc_middle::ty::{self, DefIdTree, InferConst, Ty};
 use rustc_span::source_map::DesugaringKind;
 use rustc_span::symbol::kw;
 use rustc_span::Span;
@@ -569,14 +570,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             local_visitor.visit_expr(expr);
         }
 
+        let mut param_name = None;
+        let span = if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val {
+            let origin = self.inner.borrow_mut().const_unification_table().probe_value(vid).origin;
+            if let ConstVariableOriginKind::ConstParameterDefinition(param) = origin.kind {
+                param_name = Some(param);
+            }
+            origin.span
+        } else {
+            local_visitor.target_span
+        };
+
         let error_code = error_code.into();
-        let mut err = self.tcx.sess.struct_span_err_with_code(
-            local_visitor.target_span,
-            "type annotations needed",
-            error_code,
-        );
+        let mut err =
+            self.tcx.sess.struct_span_err_with_code(span, "type annotations needed", error_code);
 
-        err.note("unable to infer the value of a const parameter");
+        if let Some(param_name) = param_name {
+            err.note(&format!("cannot infer the value of the const parameter `{}`", param_name));
+        } else {
+            err.note("unable to infer the value of a const parameter");
+        }
 
         err
     }
diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs
index 2580ac6bebd..a60a17befef 100644
--- a/compiler/rustc_middle/src/infer/unify_key.rs
+++ b/compiler/rustc_middle/src/infer/unify_key.rs
@@ -124,6 +124,7 @@ pub struct ConstVariableOrigin {
 pub enum ConstVariableOriginKind {
     MiscVariable,
     ConstInference,
+    // FIXME(const_generics): Consider storing the `DefId` of the param here.
     ConstParameterDefinition(Symbol),
     SubstitutionPlaceholder,
 }
diff --git a/src/test/ui/const-generics/cannot-infer-const-args.full.stderr b/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr
index 053139787ed..84e75cc3764 100644
--- a/src/test/ui/const-generics/cannot-infer-const-args.full.stderr
+++ b/src/test/ui/const-generics/infer/cannot-infer-const-args.full.stderr
@@ -4,7 +4,7 @@ error[E0282]: type annotations needed
 LL |     foo();
    |     ^^^
    |
-   = note: unable to infer the value of a const parameter
+   = note: cannot infer the value of the const parameter `X`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/cannot-infer-const-args.min.stderr b/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr
index 053139787ed..84e75cc3764 100644
--- a/src/test/ui/const-generics/cannot-infer-const-args.min.stderr
+++ b/src/test/ui/const-generics/infer/cannot-infer-const-args.min.stderr
@@ -4,7 +4,7 @@ error[E0282]: type annotations needed
 LL |     foo();
    |     ^^^
    |
-   = note: unable to infer the value of a const parameter
+   = note: cannot infer the value of the const parameter `X`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/cannot-infer-const-args.rs b/src/test/ui/const-generics/infer/cannot-infer-const-args.rs
index 2d74b4788bf..2d74b4788bf 100644
--- a/src/test/ui/const-generics/cannot-infer-const-args.rs
+++ b/src/test/ui/const-generics/infer/cannot-infer-const-args.rs
diff --git a/src/test/ui/const-generics/infer/method-chain.full.stderr b/src/test/ui/const-generics/infer/method-chain.full.stderr
new file mode 100644
index 00000000000..e65bc3f1096
--- /dev/null
+++ b/src/test/ui/const-generics/infer/method-chain.full.stderr
@@ -0,0 +1,11 @@
+error[E0282]: type annotations needed
+  --> $DIR/method-chain.rs:21:33
+   |
+LL |     Foo.bar().bar().bar().bar().baz();
+   |                                 ^^^
+   |
+   = note: cannot infer the value of the const parameter `N`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/const-generics/infer/method-chain.min.stderr b/src/test/ui/const-generics/infer/method-chain.min.stderr
new file mode 100644
index 00000000000..e65bc3f1096
--- /dev/null
+++ b/src/test/ui/const-generics/infer/method-chain.min.stderr
@@ -0,0 +1,11 @@
+error[E0282]: type annotations needed
+  --> $DIR/method-chain.rs:21:33
+   |
+LL |     Foo.bar().bar().bar().bar().baz();
+   |                                 ^^^
+   |
+   = note: cannot infer the value of the const parameter `N`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/src/test/ui/const-generics/infer/method-chain.rs b/src/test/ui/const-generics/infer/method-chain.rs
new file mode 100644
index 00000000000..9389ca20d10
--- /dev/null
+++ b/src/test/ui/const-generics/infer/method-chain.rs
@@ -0,0 +1,22 @@
+// revisions: full min
+
+#![cfg_attr(full, feature(const_generics))]
+#![cfg_attr(full, allow(incomplete_features))]
+#![cfg_attr(min, feature(min_const_generics))]
+
+struct Foo;
+
+impl Foo {
+    fn bar(self) -> Foo {
+        Foo
+    }
+
+    fn baz<const N: usize>(self) -> Foo {
+        println!("baz: {}", N);
+        Foo
+    }
+}
+
+fn main() {
+    Foo.bar().bar().bar().bar().baz(); //~ ERROR type annotations needed
+}
diff --git a/src/test/ui/const-generics/uninferred-consts.full.stderr b/src/test/ui/const-generics/infer/uninferred-consts.full.stderr
index 2c5af9e65f8..e47b6bd5dc6 100644
--- a/src/test/ui/const-generics/uninferred-consts.full.stderr
+++ b/src/test/ui/const-generics/infer/uninferred-consts.full.stderr
@@ -1,10 +1,10 @@
 error[E0282]: type annotations needed
-  --> $DIR/uninferred-consts.rs:14:5
+  --> $DIR/uninferred-consts.rs:14:9
    |
 LL |     Foo.foo();
-   |     ^^^^^^^^^
+   |         ^^^
    |
-   = note: unable to infer the value of a const parameter
+   = note: cannot infer the value of the const parameter `N`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/uninferred-consts.min.stderr b/src/test/ui/const-generics/infer/uninferred-consts.min.stderr
index 2c5af9e65f8..e47b6bd5dc6 100644
--- a/src/test/ui/const-generics/uninferred-consts.min.stderr
+++ b/src/test/ui/const-generics/infer/uninferred-consts.min.stderr
@@ -1,10 +1,10 @@
 error[E0282]: type annotations needed
-  --> $DIR/uninferred-consts.rs:14:5
+  --> $DIR/uninferred-consts.rs:14:9
    |
 LL |     Foo.foo();
-   |     ^^^^^^^^^
+   |         ^^^
    |
-   = note: unable to infer the value of a const parameter
+   = note: cannot infer the value of the const parameter `N`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/uninferred-consts.rs b/src/test/ui/const-generics/infer/uninferred-consts.rs
index ec5b3ffe544..ec5b3ffe544 100644
--- a/src/test/ui/const-generics/uninferred-consts.rs
+++ b/src/test/ui/const-generics/infer/uninferred-consts.rs