about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-11-16 23:58:24 +0100
committerGitHub <noreply@github.com>2021-11-16 23:58:24 +0100
commiteb9859f00d58d9bbed3db67952ef986e18277f01 (patch)
tree39410657d0acad46aae36136ad76ea02ea419d77 /compiler
parentb7b335593fcd86dedac3396dc94bfb7247f30f30 (diff)
parentfc816c37b734e594037f36114a2844d7e7b30f76 (diff)
downloadrust-eb9859f00d58d9bbed3db67952ef986e18277f01.tar.gz
rust-eb9859f00d58d9bbed3db67952ef986e18277f01.zip
Rollup merge of #90933 - compiler-errors:master, r=estebank
Fix await suggestion on non-future type

Remove a match block that would suggest to add `.await` in the case where the expected type's `Future::Output` equals the found type. We only want to suggest `.await`ing in the opposite case (the found type's `Future::Output` equals the expected type).

The code sample is here: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6ba6b83d4dddda263553b79dca9f6bcb

Before:
```
➜  ~ rustc --edition=2021 --crate-type=lib test.rs
error[E0308]: `match` arms have incompatible types
 --> test.rs:4:14
  |
2 |       let x = match 1 {
  |  _____________-
3 | |         1 => other(),
  | |              ------- this is found to be of type `impl Future`
4 | |         2 => other().await,
  | |              ^^^^^^^^^^^^^ expected opaque type, found enum `Result`
5 | |     };
  | |_____- `match` arms have incompatible types
  |
  = note: expected type `impl Future`
             found enum `Result<(), ()>`
help: consider `await`ing on the `Future`
  |
4 |         2 => other().await.await,
  |                           ++++++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
```

After:
```
➜  ~ rustc +stage1 --edition=2021 --crate-type=lib test.rs
error[E0308]: `match` arms have incompatible types
 --> test.rs:4:14
  |
2 |       let x = match 1 {
  |  _____________-
3 | |         1 => other(),
  | |              ------- this is found to be of type `impl Future`
4 | |         2 => other().await,
  | |              ^^^^^^^^^^^^^ expected opaque type, found enum `Result`
5 | |     };
  | |_____- `match` arms have incompatible types
  |
  = note: expected type `impl Future`
             found enum `Result<(), ()>`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
```

Fixes #90931
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs45
1 files changed, 26 insertions, 19 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 7a0db820c9c..c25ec1356e2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1794,31 +1794,38 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 }
             },
             (_, Some(ty)) if ty::TyS::same_type(exp_found.expected, ty) => {
-                let span = match cause.code {
-                    // scrutinee's span
-                    ObligationCauseCode::Pattern { span: Some(span), .. } => span,
-                    _ => exp_span,
-                };
-                diag.span_suggestion_verbose(
-                    span.shrink_to_hi(),
-                    "consider `await`ing on the `Future`",
-                    ".await".to_string(),
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            (Some(ty), _) if ty::TyS::same_type(ty, exp_found.found) => {
-                let span = match cause.code {
-                    // scrutinee's span
-                    ObligationCauseCode::Pattern { span: Some(span), .. } => span,
-                    _ => exp_span,
-                };
                 diag.span_suggestion_verbose(
-                    span.shrink_to_hi(),
+                    exp_span.shrink_to_hi(),
                     "consider `await`ing on the `Future`",
                     ".await".to_string(),
                     Applicability::MaybeIncorrect,
                 );
             }
+            (Some(ty), _) if ty::TyS::same_type(ty, exp_found.found) => match cause.code {
+                ObligationCauseCode::Pattern { span: Some(span), .. }
+                | ObligationCauseCode::IfExpression(box IfExpressionCause { then: span, .. }) => {
+                    diag.span_suggestion_verbose(
+                        span.shrink_to_hi(),
+                        "consider `await`ing on the `Future`",
+                        ".await".to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+                ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
+                    ref prior_arms,
+                    ..
+                }) => {
+                    diag.multipart_suggestion_verbose(
+                        "consider `await`ing on the `Future`",
+                        prior_arms
+                            .iter()
+                            .map(|arm| (arm.shrink_to_hi(), ".await".to_string()))
+                            .collect(),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+                _ => {}
+            },
             _ => {}
         }
     }