Rollup merge of #127129 - compiler-errors:full-expr-span, r=jieyouxu

Use full expr span for return suggestion on type error/ambiguity

We sometimes use parts of an expression rather than the whole thing for an obligation span. For example, a method obligation will just point to the path segment corresponding to the `method` in `rcvr.method(args)`.

So let's not use that assuming it'll point to the *whole* expression span, which we can access from the expr hir id we store in `ObligationCauseCode::WhereClauseInExpr`.

Fixes #127109
This commit is contained in:
Guillaume Gomez 2024-07-01 20:29:58 +02:00 committed by GitHub
commit 61fe6b6c0c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 16 deletions

View File

@ -2042,7 +2042,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
if block_num > 1 && found_semi {
err.span_suggestion_verbose(
span.shrink_to_lo(),
// use the span of the *whole* expr
self.tcx.hir().span(binding_hir_id).shrink_to_lo(),
"you might have meant to return this to infer its type parameters",
"return ",
Applicability::MaybeIncorrect,

View File

@ -1,3 +1,5 @@
//@ edition:2018
// > Suggest returning tail expressions that match return type
// >
// > Some newcomers are confused by the behavior of tail expressions,
@ -8,24 +10,24 @@
//
// This test was amended to also serve as a regression test for #92308, where
// this suggestion would not trigger with async functions.
//
//@ edition:2018
fn main() {
}
fn foo(x: bool) -> Result<f64, i32> {
if x {
Err(42) //~ ERROR mismatched types
//| HELP you might have meant to return this value
Err(42)
//~^ ERROR mismatched types
//~| HELP you might have meant to return this value
}
Ok(42.0)
}
async fn bar(x: bool) -> Result<f64, i32> {
if x {
Err(42) //~ ERROR mismatched types
//| HELP you might have meant to return this value
Err(42)
//~^ ERROR mismatched types
//~| HELP you might have meant to return this value
}
Ok(42.0)
}
@ -40,8 +42,26 @@ impl<T> Identity for T {
async fn foo2() -> i32 {
if true {
1i32 //~ ERROR mismatched types
//| HELP you might have meant to return this value
1i32
//~^ ERROR mismatched types
//~| HELP you might have meant to return this value
}
0
}
struct Receiver;
impl Receiver {
fn generic<T>(self) -> Option<T> {
None
}
}
fn method() -> Option<i32> {
if true {
Receiver.generic();
//~^ ERROR type annotations needed
//~| HELP consider specifying the generic argument
//~| HELP you might have meant to return this to infer its type parameters
}
None
}

View File

@ -1,10 +1,11 @@
error[E0308]: mismatched types
--> $DIR/tail-expr-as-potential-return.rs:27:9
--> $DIR/tail-expr-as-potential-return.rs:28:9
|
LL | / if x {
LL | | Err(42)
| | ^^^^^^^ expected `()`, found `Result<_, {integer}>`
LL | | //| HELP you might have meant to return this value
LL | |
LL | |
LL | | }
| |_____- expected this to be `()`
|
@ -16,12 +17,13 @@ LL | return Err(42);
| ++++++ +
error[E0308]: mismatched types
--> $DIR/tail-expr-as-potential-return.rs:43:9
--> $DIR/tail-expr-as-potential-return.rs:45:9
|
LL | / if true {
LL | | 1i32
| | ^^^^ expected `()`, found `i32`
LL | | //| HELP you might have meant to return this value
LL | |
LL | |
LL | | }
| |_____- expected this to be `()`
|
@ -36,7 +38,8 @@ error[E0308]: mismatched types
LL | / if x {
LL | | Err(42)
| | ^^^^^^^ expected `()`, found `Result<_, {integer}>`
LL | | //| HELP you might have meant to return this value
LL | |
LL | |
LL | | }
| |_____- expected this to be `()`
|
@ -47,6 +50,22 @@ help: you might have meant to return this value
LL | return Err(42);
| ++++++ +
error: aborting due to 3 previous errors
error[E0282]: type annotations needed
--> $DIR/tail-expr-as-potential-return.rs:60:18
|
LL | Receiver.generic();
| ^^^^^^^ cannot infer type of the type parameter `T` declared on the method `generic`
|
help: consider specifying the generic argument
|
LL | Receiver.generic::<T>();
| +++++
help: you might have meant to return this to infer its type parameters
|
LL | return Receiver.generic();
| ++++++
For more information about this error, try `rustc --explain E0308`.
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0282, E0308.
For more information about an error, try `rustc --explain E0282`.