Skip to content

Commit

Permalink
Rollup merge of #127129 - compiler-errors:full-expr-span, r=jieyouxu
Browse files Browse the repository at this point in the history
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
  • Loading branch information
GuillaumeGomez authored Jul 1, 2024
2 parents f5810c4 + 583b5fc commit 61fe6b6
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 16 deletions.
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
36 changes: 28 additions & 8 deletions tests/ui/return/tail-expr-as-potential-return.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//@ edition:2018

// > Suggest returning tail expressions that match return type
// >
// > Some newcomers are confused by the behavior of tail expressions,
Expand All @@ -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)
}
Expand All @@ -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
}
33 changes: 26 additions & 7 deletions tests/ui/return/tail-expr-as-potential-return.stderr
Original file line number Diff line number Diff line change
@@ -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 `()`
|
Expand All @@ -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 `()`
|
Expand All @@ -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 `()`
|
Expand All @@ -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();
| ++++++

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0282, E0308.
For more information about an error, try `rustc --explain E0282`.

0 comments on commit 61fe6b6

Please sign in to comment.