Rollup merge of #58267 - estebank:match-arms, r=matthewjasper

Tweak "incompatible match arms" error

- Point at the body expression of the match arm with the type error.
- Point at the prior match arms explicitly stating the evaluated type.
- Point at the entire match expr in a secondary span, instead of primary.
- For type errors in the first match arm, the cause is outside of the
  match, treat as implicit block error to give a more appropriate error.

Fix #46776, fix #57206.
CC #24157, #38234.
This commit is contained in:
Mazdak Farrokhzad 2019-02-14 02:41:20 +01:00 committed by GitHub
commit 4ad3cf2533
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 206 additions and 62 deletions

View file

@ -1,10 +1,11 @@
fn main() {
if let Some(b) = None { //~ ERROR: `if let` arms have incompatible types
//~^ expected (), found integer
//~| expected type `()`
//~| found type `{integer}`
if let Some(b) = None {
//~^ NOTE if let` arms have incompatible types
()
} else {
1
};
//~^^ ERROR: `if let` arms have incompatible types
//~| NOTE expected (), found integer
//~| NOTE expected type `()`
}

View file

@ -1,25 +1,17 @@
error[E0308]: `if let` arms have incompatible types
--> $DIR/if-let-arm-types.rs:2:5
--> $DIR/if-let-arm-types.rs:6:9
|
LL | / if let Some(b) = None { //~ ERROR: `if let` arms have incompatible types
LL | | //~^ expected (), found integer
LL | | //~| expected type `()`
LL | | //~| found type `{integer}`
... |
LL | / if let Some(b) = None {
LL | | //~^ NOTE if let` arms have incompatible types
LL | | ()
LL | | } else {
LL | | 1
| | ^ expected (), found integer
LL | | };
| |_____^ expected (), found integer
| |_____- `if let` arms have incompatible types
|
= note: expected type `()`
found type `{integer}`
note: `if let` arm with an incompatible type
--> $DIR/if-let-arm-types.rs:7:12
|
LL | } else {
| ____________^
LL | | 1
LL | | };
| |_____^
error: aborting due to previous error

View file

@ -1,12 +1,14 @@
fn main() {
match Some(10) {
//~^ ERROR match arms have incompatible types
//~| expected type `bool`
//~| found type `()`
//~| expected bool, found ()
//~^ NOTE `match` arms have incompatible types
Some(5) => false,
//~^ NOTE this is found to be of type `bool`
Some(2) => true,
//~^ NOTE this is found to be of type `bool`
None => (),
//~^ ERROR match arms have incompatible types
//~| NOTE expected bool, found ()
//~| NOTE expected type `bool`
_ => true
}
}

View file

@ -1,16 +1,20 @@
error[E0308]: match arms have incompatible types
--> $DIR/issue-11319.rs:2:5
--> $DIR/issue-11319.rs:8:20
|
LL | / match Some(10) {
LL | | //~^ ERROR match arms have incompatible types
LL | | //~| expected type `bool`
LL | | //~| found type `()`
... |
LL | | //~^ NOTE `match` arms have incompatible types
LL | | Some(5) => false,
| | ----- this is found to be of type `bool`
LL | | //~^ NOTE this is found to be of type `bool`
LL | | Some(2) => true,
| | ---- this is found to be of type `bool`
LL | | //~^ NOTE this is found to be of type `bool`
LL | | None => (),
| | -- match arm with an incompatible type
| | ^^ expected bool, found ()
... |
LL | | _ => true
LL | | }
| |_____^ expected bool, found ()
| |_____- `match` arms have incompatible types
|
= note: expected type `bool`
found type `()`

View file

@ -97,7 +97,7 @@ impl Debug for Player {
}
fn str_to_direction(to_parse: &str) -> RoomDirection {
match to_parse { //~ ERROR match arms have incompatible types
match to_parse {
"w" | "west" => RoomDirection::West,
"e" | "east" => RoomDirection::East,
"n" | "north" => RoomDirection::North,
@ -108,6 +108,7 @@ fn str_to_direction(to_parse: &str) -> RoomDirection {
"down" => RoomDirection::Down,
_ => None
}
//~^^ ERROR match arms have incompatible types
}
fn main() {

View file

@ -10,17 +10,19 @@ LL | Some(entry) => Ok(entry),
| ^^^^^^^^^ ...but data from `room` is returned here
error[E0308]: match arms have incompatible types
--> $DIR/issue-17728.rs:100:5
--> $DIR/issue-17728.rs:109:14
|
LL | / match to_parse { //~ ERROR match arms have incompatible types
LL | / match to_parse {
LL | | "w" | "west" => RoomDirection::West,
LL | | "e" | "east" => RoomDirection::East,
LL | | "n" | "north" => RoomDirection::North,
... |
LL | | "down" => RoomDirection::Down,
| | ------------------- this and all prior arms are found to be of type `RoomDirection`
LL | | _ => None
| | ---- match arm with an incompatible type
| | ^^^^ expected enum `RoomDirection`, found enum `std::option::Option`
LL | | }
| |_____^ expected enum `RoomDirection`, found enum `std::option::Option`
| |_____- `match` arms have incompatible types
|
= note: expected type `RoomDirection`
found type `std::option::Option<_>`

View file

@ -6,11 +6,11 @@ fn closure_to_loc() {
fn closure_from_match() {
let x = match 1usize {
//~^ ERROR match arms have incompatible types
1 => |c| c + 1,
2 => |c| c - 1,
_ => |c| c - 1
};
//~^^^ ERROR match arms have incompatible types
}
fn main() { }

View file

@ -10,20 +10,20 @@ LL | x = |c| c + 1;
= help: consider boxing your closure and/or using it as a trait object
error[E0308]: match arms have incompatible types
--> $DIR/issue-24036.rs:8:13
--> $DIR/issue-24036.rs:10:14
|
LL | let x = match 1usize {
| _____________^
LL | | //~^ ERROR match arms have incompatible types
| _____________-
LL | | 1 => |c| c + 1,
| | --------- this is found to be of type `[closure@$DIR/issue-24036.rs:9:14: 9:23]`
LL | | 2 => |c| c - 1,
| | --------- match arm with an incompatible type
| | ^^^^^^^^^ expected closure, found a different closure
LL | | _ => |c| c - 1
LL | | };
| |_____^ expected closure, found a different closure
| |_____- `match` arms have incompatible types
|
= note: expected type `[closure@$DIR/issue-24036.rs:10:14: 10:23]`
found type `[closure@$DIR/issue-24036.rs:11:14: 11:23]`
= note: expected type `[closure@$DIR/issue-24036.rs:9:14: 9:23]`
found type `[closure@$DIR/issue-24036.rs:10:14: 10:23]`
= note: no two closures, even if identical, have the same type
= help: consider boxing your closure and/or using it as a trait object

View file

@ -0,0 +1,45 @@
fn main() {
let _ = test_func1(1);
let _ = test_func2(1);
}
fn test_func1(n: i32) -> i32 {
//~^ NOTE expected `i32` because of return type
match n {
12 => 'b',
//~^ ERROR mismatched types
//~| NOTE expected i32, found char
_ => 42,
}
}
fn test_func2(n: i32) -> i32 {
let x = match n {
//~^ NOTE `match` arms have incompatible types
12 => 'b',
//~^ NOTE this is found to be of type `char`
_ => 42,
//~^ ERROR match arms have incompatible types
//~| NOTE expected char, found integer
//~| NOTE expected type `char`
};
x
}
fn test_func3(n: i32) -> i32 {
let x = match n {
//~^ NOTE `match` arms have incompatible types
1 => 'b',
2 => 'b',
3 => 'b',
4 => 'b',
5 => 'b',
6 => 'b',
//~^ NOTE this and all prior arms are found to be of type `char`
_ => 42,
//~^ ERROR match arms have incompatible types
//~| NOTE expected char, found integer
//~| NOTE expected type `char`
};
x
}

View file

@ -0,0 +1,53 @@
error[E0308]: mismatched types
--> $DIR/match-type-err-first-arm.rs:9:15
|
LL | fn test_func1(n: i32) -> i32 {
| --- expected `i32` because of return type
...
LL | 12 => 'b',
| ^^^ expected i32, found char
error[E0308]: match arms have incompatible types
--> $DIR/match-type-err-first-arm.rs:21:14
|
LL | let x = match n {
| _____________-
LL | | //~^ NOTE `match` arms have incompatible types
LL | | 12 => 'b',
| | --- this is found to be of type `char`
LL | | //~^ NOTE this is found to be of type `char`
LL | | _ => 42,
| | ^^ expected char, found integer
... |
LL | | //~| NOTE expected type `char`
LL | | };
| |_____- `match` arms have incompatible types
|
= note: expected type `char`
found type `{integer}`
error[E0308]: match arms have incompatible types
--> $DIR/match-type-err-first-arm.rs:39:14
|
LL | let x = match n {
| _____________-
LL | | //~^ NOTE `match` arms have incompatible types
LL | | 1 => 'b',
LL | | 2 => 'b',
... |
LL | | 6 => 'b',
| | --- this and all prior arms are found to be of type `char`
LL | | //~^ NOTE this and all prior arms are found to be of type `char`
LL | | _ => 42,
| | ^^ expected char, found integer
... |
LL | | //~| NOTE expected type `char`
LL | | };
| |_____- `match` arms have incompatible types
|
= note: expected type `char`
found type `{integer}`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0308`.