Rollup merge of #92381 - ThePuzzlemaker:issue-92308, r=estebank
Suggest `return`ing tail expressions in async functions This PR fixes #92308. Previously, the suggestion to `return` tail expressions (introduced in #81769) did not apply to `async` functions, as the suggestion checked whether the types were equal disregarding `impl Future<Output = T>` syntax sugar for `async` functions. This PR changes that in order to fix a potential papercut. I'm not sure if this is the "right" way to do this, so if there is a better way then please let me know. I amended an existing test introduced in #81769 to add a regression test for this, if you think I should make a separate test I will.
This commit is contained in:
commit
347c744fe0
@ -9,7 +9,7 @@
|
||||
use rustc_hir::def::{CtorOf, DefKind};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{Expr, ExprKind, ItemKind, Node, Path, QPath, Stmt, StmtKind, TyKind};
|
||||
use rustc_infer::infer;
|
||||
use rustc_infer::infer::{self, TyCtxtInferExt};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_middle::ty::{self, Binder, Ty};
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
@ -608,6 +608,17 @@ pub(in super::super) fn suggest_missing_break_or_return_expr(
|
||||
let bound_vars = self.tcx.late_bound_vars(fn_id);
|
||||
let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
|
||||
let ty = self.normalize_associated_types_in(expr.span, ty);
|
||||
let ty = match self.tcx.asyncness(fn_id.owner) {
|
||||
hir::IsAsync::Async => self.tcx.infer_ctxt().enter(|infcx| {
|
||||
infcx.get_impl_future_output_ty(ty).unwrap_or_else(|| {
|
||||
span_bug!(
|
||||
fn_decl.output.span(),
|
||||
"failed to get output type of async function"
|
||||
)
|
||||
})
|
||||
}),
|
||||
hir::IsAsync::NotAsync => ty,
|
||||
};
|
||||
if self.can_coerce(found, ty) {
|
||||
err.multipart_suggestion(
|
||||
"you might have meant to return this value",
|
||||
|
@ -1,3 +1,16 @@
|
||||
// > Suggest `return`ing tail expressions that match return type
|
||||
// >
|
||||
// > Some newcomers are confused by the behavior of tail expressions,
|
||||
// > interpreting that "leaving out the `;` makes it the return value".
|
||||
// > To help them go in the right direction, suggest using `return` instead
|
||||
// > when applicable.
|
||||
// (original commit description for this test)
|
||||
//
|
||||
// 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() {
|
||||
let _ = foo(true);
|
||||
}
|
||||
@ -5,6 +18,15 @@ 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
|
||||
}
|
||||
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
|
||||
}
|
||||
Ok(42.0)
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/tail-expr-as-potential-return.rs:7:9
|
||||
--> $DIR/tail-expr-as-potential-return.rs:28:9
|
||||
|
|
||||
LL | / if x {
|
||||
LL | | Err(42)
|
||||
| | ^^^^^^^ expected `()`, found enum `Result`
|
||||
LL | | //| HELP you might have meant to return this value
|
||||
LL | | }
|
||||
| |_____- expected this to be `()`
|
||||
|
|
||||
@ -14,6 +15,23 @@ help: you might have meant to return this value
|
||||
LL | return Err(42);
|
||||
| ++++++ +
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/tail-expr-as-potential-return.rs:20:9
|
||||
|
|
||||
LL | / if x {
|
||||
LL | | Err(42)
|
||||
| | ^^^^^^^ expected `()`, found enum `Result`
|
||||
LL | | //| HELP you might have meant to return this value
|
||||
LL | | }
|
||||
| |_____- expected this to be `()`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found enum `Result<_, {integer}>`
|
||||
help: you might have meant to return this value
|
||||
|
|
||||
LL | return Err(42);
|
||||
| ++++++ +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
Loading…
Reference in New Issue
Block a user