Auto merge of #149442 - chenyukang:yukang-fix-mark-span-note-144304, r=estebank
Fix span note for question mark expression Fixes rust-lang/rust#144304 Seems it's better to fix the note instead of modifying the span to cover the whole expression. r? `@estebank`
This commit is contained in:
commit
31010ca61c
5 changed files with 68 additions and 17 deletions
|
|
@ -1229,7 +1229,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
chain.push((expr.span, prev_ty));
|
||||
|
||||
let mut prev = None;
|
||||
for (span, err_ty) in chain.into_iter().rev() {
|
||||
let mut iter = chain.into_iter().rev().peekable();
|
||||
while let Some((span, err_ty)) = iter.next() {
|
||||
let is_last = iter.peek().is_none();
|
||||
let err_ty = get_e_type(err_ty);
|
||||
let err_ty = match (err_ty, prev) {
|
||||
(Some(err_ty), Some(prev)) if !self.can_eq(obligation.param_env, err_ty, prev) => {
|
||||
|
|
@ -1241,27 +1243,27 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
continue;
|
||||
}
|
||||
};
|
||||
if self
|
||||
|
||||
let implements_from = self
|
||||
.infcx
|
||||
.type_implements_trait(
|
||||
self.tcx.get_diagnostic_item(sym::From).unwrap(),
|
||||
[self_ty, err_ty],
|
||||
obligation.param_env,
|
||||
)
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
if !suggested {
|
||||
let err_ty = self.tcx.short_string(err_ty, err.long_ty_path());
|
||||
err.span_label(span, format!("this has type `Result<_, {err_ty}>`"));
|
||||
}
|
||||
.must_apply_modulo_regions();
|
||||
|
||||
let err_ty_str = self.tcx.short_string(err_ty, err.long_ty_path());
|
||||
let label = if !implements_from && is_last {
|
||||
format!(
|
||||
"this can't be annotated with `?` because it has type `Result<_, {err_ty_str}>`"
|
||||
)
|
||||
} else {
|
||||
let err_ty = self.tcx.short_string(err_ty, err.long_ty_path());
|
||||
err.span_label(
|
||||
span,
|
||||
format!(
|
||||
"this can't be annotated with `?` because it has type `Result<_, {err_ty}>`",
|
||||
),
|
||||
);
|
||||
format!("this has type `Result<_, {err_ty_str}>`")
|
||||
};
|
||||
|
||||
if !suggested || !implements_from {
|
||||
err.span_label(span, label);
|
||||
}
|
||||
prev = Some(err_ty);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ fn foo() -> Result<String, String> { //~ NOTE expected `String` because of this
|
|||
});
|
||||
let one = x
|
||||
.map(|s| ())
|
||||
.map_err(|e| { //~ NOTE this can't be annotated with `?` because it has type `Result<_, ()>`
|
||||
.map_err(|e| { //~ NOTE this has type `Result<_, ()>`
|
||||
e; //~ HELP remove this semicolon
|
||||
})
|
||||
.map(|()| "")?; //~ ERROR `?` couldn't convert the error to `String`
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ LL | .map_err(|e| {
|
|||
LL | | e;
|
||||
| | - help: remove this semicolon
|
||||
LL | | })
|
||||
| |__________- this can't be annotated with `?` because it has type `Result<_, ()>`
|
||||
| |__________- this has type `Result<_, ()>`
|
||||
LL | .map(|()| "")?;
|
||||
| ^ the trait `From<()>` is not implemented for `String`
|
||||
|
|
||||
|
|
|
|||
8
tests/ui/traits/question-mark-span-144304.rs
Normal file
8
tests/ui/traits/question-mark-span-144304.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
//@ ignore-arm - armhf-gnu have more types implement trait `From<T>`, let's skip it
|
||||
fn f() -> Result<(), i32> {
|
||||
Err("str").map_err(|e| e)?; //~ ERROR `?` couldn't convert the error to `i32`
|
||||
Err("str").map_err(|e| e.to_string())?; //~ ERROR `?` couldn't convert the error to `i32`
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
41
tests/ui/traits/question-mark-span-144304.stderr
Normal file
41
tests/ui/traits/question-mark-span-144304.stderr
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
error[E0277]: `?` couldn't convert the error to `i32`
|
||||
--> $DIR/question-mark-span-144304.rs:3:30
|
||||
|
|
||||
LL | fn f() -> Result<(), i32> {
|
||||
| --------------- expected `i32` because of this
|
||||
LL | Err("str").map_err(|e| e)?;
|
||||
| ---------- ^ the trait `From<&str>` is not implemented for `i32`
|
||||
| |
|
||||
| this has type `Result<_, &str>`
|
||||
|
|
||||
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
|
||||
= help: the following other types implement trait `From<T>`:
|
||||
`i32` implements `From<bool>`
|
||||
`i32` implements `From<i16>`
|
||||
`i32` implements `From<i8>`
|
||||
`i32` implements `From<u16>`
|
||||
`i32` implements `From<u8>`
|
||||
|
||||
error[E0277]: `?` couldn't convert the error to `i32`
|
||||
--> $DIR/question-mark-span-144304.rs:4:42
|
||||
|
|
||||
LL | fn f() -> Result<(), i32> {
|
||||
| --------------- expected `i32` because of this
|
||||
LL | Err("str").map_err(|e| e)?;
|
||||
LL | Err("str").map_err(|e| e.to_string())?;
|
||||
| ---------- --------------------------^ the trait `From<String>` is not implemented for `i32`
|
||||
| | |
|
||||
| | this can't be annotated with `?` because it has type `Result<_, String>`
|
||||
| this has type `Result<_, &str>`
|
||||
|
|
||||
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
|
||||
= help: the following other types implement trait `From<T>`:
|
||||
`i32` implements `From<bool>`
|
||||
`i32` implements `From<i16>`
|
||||
`i32` implements `From<i8>`
|
||||
`i32` implements `From<u16>`
|
||||
`i32` implements `From<u8>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue