Skip to content

Commit 25479ea

Browse files
committed
Fix span note for question mark expression
1 parent 1eb0657 commit 25479ea

File tree

5 files changed

+63
-9
lines changed

5 files changed

+63
-9
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
12291229
chain.push((expr.span, prev_ty));
12301230

12311231
let mut prev = None;
1232-
for (span, err_ty) in chain.into_iter().rev() {
1232+
let mut iter = chain.into_iter().rev().peekable();
1233+
while let Some((span, err_ty)) = iter.next() {
1234+
let is_last = iter.peek().is_none();
12331235
let err_ty = get_e_type(err_ty);
12341236
let err_ty = match (err_ty, prev) {
12351237
(Some(err_ty), Some(prev)) if !self.can_eq(obligation.param_env, err_ty, prev) => {
@@ -1256,12 +1258,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
12561258
}
12571259
} else {
12581260
let err_ty = self.tcx.short_string(err_ty, err.long_ty_path());
1259-
err.span_label(
1260-
span,
1261-
format!(
1262-
"this can't be annotated with `?` because it has type `Result<_, {err_ty}>`",
1263-
),
1264-
);
1261+
if is_last {
1262+
err.span_label(
1263+
span,
1264+
format!(
1265+
"this can't be annotated with `?` because it has type `Result<_, {err_ty}>`",
1266+
),
1267+
);
1268+
} else {
1269+
err.span_label(span, format!("this has type `Result<_, {err_ty}>`"));
1270+
}
12651271
}
12661272
prev = Some(err_ty);
12671273
}

tests/ui/traits/question-mark-result-err-mismatch.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ fn foo() -> Result<String, String> { //~ NOTE expected `String` because of this
99
});
1010
let one = x
1111
.map(|s| ())
12-
.map_err(|e| { //~ NOTE this can't be annotated with `?` because it has type `Result<_, ()>`
12+
.map_err(|e| { //~ NOTE this has type `Result<_, ()>`
1313
e; //~ HELP remove this semicolon
1414
})
1515
.map(|()| "")?; //~ ERROR `?` couldn't convert the error to `String`

tests/ui/traits/question-mark-result-err-mismatch.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | .map_err(|e| {
99
LL | | e;
1010
| | - help: remove this semicolon
1111
LL | | })
12-
| |__________- this can't be annotated with `?` because it has type `Result<_, ()>`
12+
| |__________- this has type `Result<_, ()>`
1313
LL | .map(|()| "")?;
1414
| ^ the trait `From<()>` is not implemented for `String`
1515
|
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn f() -> Result<(), i32> {
2+
Err("str").map_err(|e| e)?; //~ ERROR `?` couldn't convert the error to `i32`
3+
Err("str").map_err(|e| e.to_string())?; //~ ERROR `?` couldn't convert the error to `i32`
4+
Ok(())
5+
}
6+
7+
fn main() {}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
error[E0277]: `?` couldn't convert the error to `i32`
2+
--> $DIR/question-mark-span-144304.rs:2:30
3+
|
4+
LL | fn f() -> Result<(), i32> {
5+
| --------------- expected `i32` because of this
6+
LL | Err("str").map_err(|e| e)?;
7+
| ---------- ^ the trait `From<&str>` is not implemented for `i32`
8+
| |
9+
| this has type `Result<_, &str>`
10+
|
11+
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
12+
= help: the following other types implement trait `From<T>`:
13+
`i32` implements `From<bool>`
14+
`i32` implements `From<i16>`
15+
`i32` implements `From<i8>`
16+
`i32` implements `From<u16>`
17+
`i32` implements `From<u8>`
18+
19+
error[E0277]: `?` couldn't convert the error to `i32`
20+
--> $DIR/question-mark-span-144304.rs:3:42
21+
|
22+
LL | fn f() -> Result<(), i32> {
23+
| --------------- expected `i32` because of this
24+
LL | Err("str").map_err(|e| e)?;
25+
LL | Err("str").map_err(|e| e.to_string())?;
26+
| ---------- --------------------------^ the trait `From<String>` is not implemented for `i32`
27+
| | |
28+
| | this can't be annotated with `?` because it has type `Result<_, String>`
29+
| this has type `Result<_, &str>`
30+
|
31+
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
32+
= help: the following other types implement trait `From<T>`:
33+
`i32` implements `From<bool>`
34+
`i32` implements `From<i16>`
35+
`i32` implements `From<i8>`
36+
`i32` implements `From<u16>`
37+
`i32` implements `From<u8>`
38+
39+
error: aborting due to 2 previous errors
40+
41+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)