about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2017-02-25 14:13:19 +0200
committerGitHub <noreply@github.com>2017-02-25 14:13:19 +0200
commitaa7eb6512315ae3340969a53c9161e91361d074c (patch)
tree7bc553abd55e0f6e3972a3596f5d78d3492dbbec /src
parenta6924177e4953eee1fa0ebcff59eede1684781eb (diff)
parent038a166e092ab5497dcb8e6785949a954d692cfd (diff)
Rollup merge of #39905 - estebank:useless-error, r=arielb1
Properly display note/expected details

Given a file

```rust
fn takes_cb(f: fn(i8)) {}

fn main() {
    fn callback(x: i32) {}
    takes_cb(callback)
}
```

output

```rust
error[E0308]: mismatched types
 --> file2.rs:5:22
  |
5 |             takes_cb(callback)
  |                      ^^^^^^^^ expected i8, found i32
  |
  = note: expected type `fn(i8)`
             found type `fn(i32) {main::callback}`
```

Fix #39343.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/infer/error_reporting.rs53
-rw-r--r--src/test/compile-fail/default_ty_param_conflict.rs2
-rw-r--r--src/test/compile-fail/default_ty_param_conflict_cross_crate.rs2
-rw-r--r--src/test/compile-fail/issue-35869.rs4
-rw-r--r--src/test/ui/mismatched_types/E0053.stderr3
-rw-r--r--src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr3
6 files changed, 37 insertions, 30 deletions
diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs
index 9295fb2ee32..f48ff87689f 100644
--- a/src/librustc/infer/error_reporting.rs
+++ b/src/librustc/infer/error_reporting.rs
@@ -379,40 +379,41 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                          values: Option<ValuePairs<'tcx>>,
                          terr: &TypeError<'tcx>)
     {
-        let expected_found = match values {
-            None => None,
-            Some(values) => match self.values_str(&values) {
-                Some((expected, found)) => Some((expected, found)),
-                None => {
-                    // Derived error. Cancel the emitter.
-                    self.tcx.sess.diagnostic().cancel(diag);
-                    return
-                }
+        let (expected_found, is_simple_error) = match values {
+            None => (None, false),
+            Some(values) => {
+                let is_simple_error = match values {
+                    ValuePairs::Types(exp_found) => {
+                        exp_found.expected.is_primitive() && exp_found.found.is_primitive()
+                    }
+                    _ => false,
+                };
+                let vals = match self.values_str(&values) {
+                    Some((expected, found)) => Some((expected, found)),
+                    None => {
+                        // Derived error. Cancel the emitter.
+                        self.tcx.sess.diagnostic().cancel(diag);
+                        return
+                    }
+                };
+                (vals, is_simple_error)
             }
         };
 
         let span = cause.span;
 
         if let Some((expected, found)) = expected_found {
-            let is_simple_error = if let &TypeError::Sorts(ref values) = terr {
-                values.expected.is_primitive() && values.found.is_primitive()
-            } else {
-                false
-            };
-
-            if !is_simple_error {
-                if expected == found {
-                    if let &TypeError::Sorts(ref values) = terr {
-                        diag.note_expected_found_extra(
-                            &"type", &expected, &found,
-                            &format!(" ({})", values.expected.sort_string(self.tcx)),
-                            &format!(" ({})", values.found.sort_string(self.tcx)));
-                    } else {
-                        diag.note_expected_found(&"type", &expected, &found);
-                    }
-                } else {
+            match (terr, is_simple_error, expected == found) {
+                (&TypeError::Sorts(ref values), false,  true) => {
+                    diag.note_expected_found_extra(
+                        &"type", &expected, &found,
+                        &format!(" ({})", values.expected.sort_string(self.tcx)),
+                        &format!(" ({})", values.found.sort_string(self.tcx)));
+                }
+                (_, false,  _) => {
                     diag.note_expected_found(&"type", &expected, &found);
                 }
+                _ => (),
             }
         }
 
diff --git a/src/test/compile-fail/default_ty_param_conflict.rs b/src/test/compile-fail/default_ty_param_conflict.rs
index 4702b504f15..8cde239ca6e 100644
--- a/src/test/compile-fail/default_ty_param_conflict.rs
+++ b/src/test/compile-fail/default_ty_param_conflict.rs
@@ -23,8 +23,6 @@ fn main() {
     // Here, F is instantiated with $0=uint
     let x = foo();
     //~^ ERROR: mismatched types
-    //~| expected type `usize`
-    //~| found type `isize`
     //~| NOTE: conflicting type parameter defaults `usize` and `isize`
     //~| NOTE: conflicting type parameter defaults `usize` and `isize`
     //~| NOTE: ...that was applied to an unconstrained type variable here
diff --git a/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs b/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs
index b608c6c99be..e5b035e50aa 100644
--- a/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs
+++ b/src/test/compile-fail/default_ty_param_conflict_cross_crate.rs
@@ -29,6 +29,4 @@ fn main() {
     //~| NOTE: conflicting type parameter defaults `bool` and `char`
     //~| a second default is defined on `default_param_test::bleh`
     //~| NOTE:  ...that was applied to an unconstrained type variable here
-    //~| expected type `bool`
-    //~| found type `char`
 }
diff --git a/src/test/compile-fail/issue-35869.rs b/src/test/compile-fail/issue-35869.rs
index 8b7fc80bdb6..d1d6390cce3 100644
--- a/src/test/compile-fail/issue-35869.rs
+++ b/src/test/compile-fail/issue-35869.rs
@@ -23,15 +23,19 @@ impl Foo for Bar {
     fn foo(_: fn(u16) -> ()) {}
     //~^ ERROR method `foo` has an incompatible type for trait
     //~| NOTE expected u8
+    //~| NOTE expected type `fn(fn(u8))`
     fn bar(_: Option<u16>) {}
     //~^ ERROR method `bar` has an incompatible type for trait
     //~| NOTE expected u8
+    //~| NOTE expected type `fn(std::option::Option<u8>)`
     fn baz(_: (u16, u16)) {}
     //~^ ERROR method `baz` has an incompatible type for trait
     //~| NOTE expected u8
+    //~| NOTE expected type `fn((u8, u16))`
     fn qux() -> u16 { 5u16 }
     //~^ ERROR method `qux` has an incompatible type for trait
     //~| NOTE expected u8
+    //~| NOTE expected type `fn() -> u8`
 }
 
 fn main() {}
diff --git a/src/test/ui/mismatched_types/E0053.stderr b/src/test/ui/mismatched_types/E0053.stderr
index b6e3d663e36..d9871b8970c 100644
--- a/src/test/ui/mismatched_types/E0053.stderr
+++ b/src/test/ui/mismatched_types/E0053.stderr
@@ -6,6 +6,9 @@ error[E0053]: method `foo` has an incompatible type for trait
 ...
 19 |     fn foo(x: i16) { }
    |               ^^^ expected u16, found i16
+   |
+   = note: expected type `fn(u16)`
+              found type `fn(i16)`
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/E0053.rs:22:12
diff --git a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
index 991197c2afb..349432f64bb 100644
--- a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
+++ b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
@@ -6,6 +6,9 @@ error[E0053]: method `foo` has an incompatible type for trait
 ...
 21 |     fn foo(x: i16) { }
    |               ^^^ expected u16, found i16
+   |
+   = note: expected type `fn(u16)`
+              found type `fn(i16)`
 
 error[E0053]: method `bar` has an incompatible type for trait
   --> $DIR/trait-impl-fn-incompatibility.rs:22:28