Rollup merge of #41205 - estebank:shorter-mismatched-types-2, r=nikomatsakis

Highlight and simplify mismatched types

Shorten mismatched types errors by replacing subtypes that are not
different with `_`, and highlighting only the subtypes that are
different.

Given a file

```rust
struct X<T1, T2> {
    x: T1,
    y: T2,
}

fn foo() -> X<X<String, String>, String> {
    X { x: X {x: "".to_string(), y: 2}, y: "".to_string()}
}

fn bar() -> Option<String> {
    "".to_string()
}
```

provide the following output

```rust
error[E0308]: mismatched types
  --> file.rs:6:5
   |
 6 |     X { x: X {x: "".to_string(), y: 2}, y: "".to_string()}
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `std::string::String`, found {integer}
   |
   = note: expected type `X<X<_, std::string::String>, _>`
                                 ^^^^^^^^^^^^^^^^^^^   // < highlighted
              found type `X<X<_, {integer}>, _>`
                                 ^^^^^^^^^             // < highlighted

error[E0308]: mismatched types
  --> file.rs:6:5
   |
10 |     "".to_string()
   |     ^^^^^^^^^^^^^^ expected struct `std::option::Option`, found `std::string::String`
   |
   = note: expected type `Option<std::string::String>`
                          ^^^^^^^                   ^  // < highlighted
              found type `std::string::String`
```

Fix #21025. Re: #40186. Follow up to #39906.

I'm looking to change how this output is accomplished so that it doesn't create list of strings to pass around, but rather add an elided `Ty` placeholder, and use the same string formatting for normal types. I'll be doing that soonish.

r? @nikomatsakis
This commit is contained in:
Tim Neumann 2017-04-12 14:45:45 +02:00 committed by GitHub
commit afb300d831
11 changed files with 485 additions and 32 deletions

View file

@ -4,8 +4,8 @@ error[E0308]: mismatched types
16 | x.push(y);
| ^ lifetime mismatch
|
= note: expected type `Ref<'a, i32>`
found type `Ref<'_, i32>`
= note: expected type `Ref<'a, _>`
found type `Ref<'_, _>`
note: the anonymous lifetime #2 defined on the body at 15:51...
--> $DIR/ex2a-push-one-existing-name.rs:15:52
|

View file

@ -4,8 +4,8 @@ error[E0308]: mismatched types
16 | x.push(y);
| ^ lifetime mismatch
|
= note: expected type `Ref<'_, i32>`
found type `Ref<'_, i32>`
= note: expected type `Ref<'_, _>`
found type `Ref<'_, _>`
note: the anonymous lifetime #3 defined on the body at 15:43...
--> $DIR/ex2b-push-no-existing-names.rs:15:44
|

View file

@ -27,7 +27,7 @@ note: but, the lifetime must be valid for the lifetime 'b as defined on the body
17 | | x.push(z);
18 | | }
| |_^ ...ending here
note: ...so that expression is assignable (expected Ref<'b, i32>, found Ref<'_, i32>)
note: ...so that expression is assignable (expected Ref<'b, _>, found Ref<'_, _>)
--> $DIR/ex2c-push-inference-variable.rs:17:12
|
17 | x.push(z);

View file

@ -0,0 +1,61 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
enum Bar {
Qux,
Zar,
}
struct Foo {
bar: usize,
}
struct X<T1, T2> {
x: T1,
y: T2,
}
fn a() -> Foo {
Some(Foo { bar: 1 })
}
fn a2() -> Foo {
Ok(Foo { bar: 1})
}
fn b() -> Option<Foo> {
Foo { bar: 1 }
}
fn c() -> Result<Foo, Bar> {
Foo { bar: 1 }
}
fn d() -> X<X<String, String>, String> {
X {
x: X {
x: "".to_string(),
y: 2,
},
y: 3,
}
}
fn e() -> X<X<String, String>, String> {
X {
x: X {
x: "".to_string(),
y: 2,
},
y: "".to_string(),
}
}
fn main() {}

View file

@ -0,0 +1,70 @@
error[E0308]: mismatched types
--> $DIR/abridged.rs:26:5
|
26 | Some(Foo { bar: 1 })
| ^^^^^^^^^^^^^^^^^^^^ expected struct `Foo`, found enum `std::option::Option`
|
= note: expected type `Foo`
found type `std::option::Option<Foo>`
error[E0308]: mismatched types
--> $DIR/abridged.rs:30:5
|
30 | Ok(Foo { bar: 1})
| ^^^^^^^^^^^^^^^^^ expected struct `Foo`, found enum `std::result::Result`
|
= note: expected type `Foo`
found type `std::result::Result<Foo, _>`
error[E0308]: mismatched types
--> $DIR/abridged.rs:34:5
|
34 | Foo { bar: 1 }
| ^^^^^^^^^^^^^^ expected enum `std::option::Option`, found struct `Foo`
|
= note: expected type `std::option::Option<Foo>`
found type `Foo`
error[E0308]: mismatched types
--> $DIR/abridged.rs:38:5
|
38 | Foo { bar: 1 }
| ^^^^^^^^^^^^^^ expected enum `std::result::Result`, found struct `Foo`
|
= note: expected type `std::result::Result<Foo, Bar>`
found type `Foo`
error[E0308]: mismatched types
--> $DIR/abridged.rs:42:5
|
42 | X {
| _____^ starting here...
43 | | x: X {
44 | | x: "".to_string(),
45 | | y: 2,
46 | | },
47 | | y: 3,
48 | | }
| |_____^ ...ending here: expected struct `std::string::String`, found integral variable
|
= note: expected type `X<X<_, std::string::String>, std::string::String>`
found type `X<X<_, {integer}>, {integer}>`
error[E0308]: mismatched types
--> $DIR/abridged.rs:52:5
|
52 | X {
| _____^ starting here...
53 | | x: X {
54 | | x: "".to_string(),
55 | | y: 2,
56 | | },
57 | | y: "".to_string(),
58 | | }
| |_____^ ...ending here: expected struct `std::string::String`, found integral variable
|
= note: expected type `X<X<_, std::string::String>, _>`
found type `X<X<_, {integer}>, _>`
error: aborting due to 6 previous errors