Skip to content

Commit

Permalink
Rollup merge of rust-lang#39905 - estebank:useless-error, r=arielb1
Browse files Browse the repository at this point in the history
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 rust-lang#39343.
  • Loading branch information
eddyb authored Feb 25, 2017
2 parents a692417 + 038a166 commit aa7eb65
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 30 deletions.
53 changes: 27 additions & 26 deletions src/librustc/infer/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
_ => (),
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/test/compile-fail/default_ty_param_conflict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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`
}
4 changes: 4 additions & 0 deletions src/test/compile-fail/issue-35869.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
3 changes: 3 additions & 0 deletions src/test/ui/mismatched_types/E0053.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit aa7eb65

Please sign in to comment.