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:
commit
4ad3cf2533
14 changed files with 206 additions and 62 deletions
|
|
@ -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 `()`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 `()`
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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<_>`
|
||||
|
|
|
|||
|
|
@ -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() { }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
45
src/test/ui/match/match-type-err-first-arm.rs
Normal file
45
src/test/ui/match/match-type-err-first-arm.rs
Normal 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
|
||||
}
|
||||
53
src/test/ui/match/match-type-err-first-arm.stderr
Normal file
53
src/test/ui/match/match-type-err-first-arm.stderr
Normal 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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue