diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-01-14 07:47:32 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-01-14 07:47:32 +0100 |
| commit | 347c744fe0e464737dbbdc44d148c84fc07568cb (patch) | |
| tree | 14030d488ca3fccf39bff1c20f3d22807c828211 | |
| parent | f13e871ac561b54ddeac2b6173b1905fb4b20138 (diff) | |
| parent | ab7c4464920531559c4da0a9e9b8972ae2443ed1 (diff) | |
| download | rust-347c744fe0e464737dbbdc44d148c84fc07568cb.tar.gz rust-347c744fe0e464737dbbdc44d148c84fc07568cb.zip | |
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.
| -rw-r--r-- | compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs | 13 | ||||
| -rw-r--r-- | src/test/ui/return/tail-expr-as-potential-return.rs | 22 | ||||
| -rw-r--r-- | src/test/ui/return/tail-expr-as-potential-return.stderr | 22 |
3 files changed, 54 insertions, 3 deletions
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs index 6c7d3a0c9c0..e8a0cc946b5 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs @@ -9,7 +9,7 @@ use rustc_hir as hir; 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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", diff --git a/src/test/ui/return/tail-expr-as-potential-return.rs b/src/test/ui/return/tail-expr-as-potential-return.rs index 83266abfa06..2c3610fb24d 100644 --- a/src/test/ui/return/tail-expr-as-potential-return.rs +++ b/src/test/ui/return/tail-expr-as-potential-return.rs @@ -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) } diff --git a/src/test/ui/return/tail-expr-as-potential-return.stderr b/src/test/ui/return/tail-expr-as-potential-return.stderr index 87ef18878d6..dec1cbc4624 100644 --- a/src/test/ui/return/tail-expr-as-potential-return.stderr +++ b/src/test/ui/return/tail-expr-as-potential-return.stderr @@ -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`. |
