Do not give incorrect label for return type mismatch
This commit is contained in:
parent
daa53a52a2
commit
90507295db
5 changed files with 142 additions and 3 deletions
|
@ -1224,12 +1224,34 @@ impl<'gcx, 'tcx, 'exprs, E> CoerceMany<'gcx, 'tcx, 'exprs, E>
|
|||
cause.span,
|
||||
blk_id,
|
||||
);
|
||||
// TODO: replace with navigating up the chain until hitting an fn or
|
||||
// bailing if no "pass-through" Node is found, in order to provide a
|
||||
// suggestion when encountering something like:
|
||||
// ```
|
||||
// fn foo(a: bool) -> impl Debug {
|
||||
// if a {
|
||||
// bar()?;
|
||||
// }
|
||||
// {
|
||||
// let x = unsafe { bar() };
|
||||
// x
|
||||
// }
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// Verify that this is a tail expression of a function, otherwise the
|
||||
// label pointing out the cause for the type coercion will be wrong
|
||||
// as prior return coercions would not be relevant (#57664).
|
||||
let parent_id = fcx.tcx.hir().get_parent_node(blk_id);
|
||||
let parent = fcx.tcx.hir().get(fcx.tcx.hir().get_parent_node(parent_id));
|
||||
if fcx.get_node_fn_decl(parent).is_some() {
|
||||
if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() {
|
||||
if !sp.overlaps(cause.span) {
|
||||
db.span_label(*sp, reason_label);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
db = fcx.report_mismatched_types(cause, expected, found, err);
|
||||
if let Some(sp) = fcx.ret_coercion_span.borrow().as_ref() {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
fn unrelated() -> Result<(), std::string::ParseError> { // #57664
|
||||
let x = 0;
|
||||
|
||||
match x {
|
||||
1 => {
|
||||
let property_value_as_string = "a".parse()?;
|
||||
}
|
||||
2 => {
|
||||
let value: &bool = unsafe { &42 };
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,12 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/point-to-type-err-cause-on-impl-trait-return-2.rs:9:41
|
||||
|
|
||||
LL | let value: &bool = unsafe { &42 };
|
||||
| ^^^ expected bool, found integer
|
||||
|
|
||||
= note: expected type `&bool`
|
||||
found type `&{integer}`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
36
src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
Normal file
36
src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
fn foo() -> impl std::fmt::Display {
|
||||
if false {
|
||||
return 0i32;
|
||||
}
|
||||
1u32
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn bar() -> impl std::fmt::Display {
|
||||
if false {
|
||||
return 0i32;
|
||||
} else {
|
||||
return 1u32;
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
||||
fn baz() -> impl std::fmt::Display {
|
||||
if false {
|
||||
//~^ ERROR mismatched types
|
||||
return 0i32;
|
||||
} else {
|
||||
1u32
|
||||
}
|
||||
}
|
||||
|
||||
fn qux() -> impl std::fmt::Display {
|
||||
if false {
|
||||
//~^ ERROR if and else have incompatible types
|
||||
0i32
|
||||
} else {
|
||||
1u32
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,52 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5
|
||||
|
|
||||
LL | return 0i32;
|
||||
| ---- expected because of this statement
|
||||
LL | }
|
||||
LL | 1u32
|
||||
| ^^^^ expected i32, found u32
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `u32`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16
|
||||
|
|
||||
LL | return 1u32;
|
||||
| ^^^^ expected i32, found u32
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `u32`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:19:5
|
||||
|
|
||||
LL | / if false {
|
||||
LL | | //~^ ERROR mismatched types
|
||||
LL | | return 0i32;
|
||||
LL | | } else {
|
||||
LL | | 1u32
|
||||
LL | | }
|
||||
| |_____^ expected i32, found u32
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `u32`
|
||||
|
||||
error[E0308]: if and else have incompatible types
|
||||
--> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:5
|
||||
|
|
||||
LL | / if false {
|
||||
LL | | //~^ ERROR if and else have incompatible types
|
||||
LL | | 0i32
|
||||
LL | | } else {
|
||||
LL | | 1u32
|
||||
LL | | }
|
||||
| |_____^ expected i32, found u32
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found type `u32`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Add a link
Reference in a new issue