diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 9295fb2ee327b..f48ff87689fb0 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>, 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 4702b504f157d..8cde239ca6edf 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 b608c6c99be89..e5b035e50aa93 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 8b7fc80bdb6b7..d1d6390cce35b 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) {} //~^ ERROR method `bar` has an incompatible type for trait //~| NOTE expected u8 + //~| NOTE expected type `fn(std::option::Option)` 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 b6e3d663e36bd..d9871b8970c5c 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 991197c2afba3..349432f64bbc2 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