about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-04-25 19:48:59 +0000
committerMichael Goulet <michael@errs.io>2023-04-27 17:18:12 +0000
commit6c9249f68935c789231b89c15986795dbc95511e (patch)
tree4dfcfd608abc4cf7a53f7a579d52f4c07db77ea4
parente6077fc1b885c525279d127fd78db4574f735900 (diff)
downloadrust-6c9249f68935c789231b89c15986795dbc95511e.tar.gz
rust-6c9249f68935c789231b89c15986795dbc95511e.zip
Don't call await a method
-rw-r--r--compiler/rustc_borrowck/messages.ftl9
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs21
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs8
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/ops.rs3
-rw-r--r--compiler/rustc_middle/src/util/call_kind.rs5
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--library/core/src/future/into_future.rs1
-rw-r--r--tests/ui/async-await/clone-suggestion.stderr2
8 files changed, 43 insertions, 7 deletions
diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl
index 0b8123c9703..4a616dc2464 100644
--- a/compiler/rustc_borrowck/messages.ftl
+++ b/compiler/rustc_borrowck/messages.ftl
@@ -203,6 +203,15 @@ borrowck_moved_due_to_method_call =
         *[false] call
     }
 
+borrowck_moved_due_to_await =
+    {$place_name} {$is_partial ->
+        [true] partially moved
+        *[false] moved
+    } due to this {$is_loop_message ->
+        [true] await, in previous iteration of loop
+        *[false] await
+    }
+
 borrowck_value_moved_here =
     value {$is_partial ->
         [true] partially moved
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 4243ec214b0..a780255725e 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -1085,12 +1085,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             }
                         }
                     } else {
-                        err.subdiagnostic(CaptureReasonLabel::MethodCall {
-                            fn_call_span,
-                            place_name: &place_name,
-                            is_partial,
-                            is_loop_message,
-                        });
+                        if let Some((CallDesugaringKind::Await, _)) = desugaring {
+                            err.subdiagnostic(CaptureReasonLabel::Await {
+                                fn_call_span,
+                                place_name: &place_name,
+                                is_partial,
+                                is_loop_message,
+                            });
+                        } else {
+                            err.subdiagnostic(CaptureReasonLabel::MethodCall {
+                                fn_call_span,
+                                place_name: &place_name,
+                                is_partial,
+                                is_loop_message,
+                            });
+                        }
                         // Erase and shadow everything that could be passed to the new infcx.
                         let ty = moved_place.ty(self.body, tcx).ty;
 
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index bb95101845f..fceae5bb3ff 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -338,6 +338,14 @@ pub(crate) enum CaptureReasonLabel<'a> {
         is_partial: bool,
         is_loop_message: bool,
     },
+    #[label(borrowck_moved_due_to_await)]
+    Await {
+        #[primary_span]
+        fn_call_span: Span,
+        place_name: &'a str,
+        is_partial: bool,
+        is_loop_message: bool,
+    },
     #[label(borrowck_value_moved_here)]
     MovedHere {
         #[primary_span]
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
index 6c11edb742c..4cef2fcec1b 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs
@@ -184,6 +184,9 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
                     CallDesugaringKind::TryBlockFromOutput => {
                         error!("`try` block cannot convert `{}` to the result in {}s")
                     }
+                    CallDesugaringKind::Await => {
+                        error!("cannot convert `{}` into a future in {}s")
+                    }
                 };
 
                 diag_trait(&mut err, self_ty, kind.trait_def_id(tcx));
diff --git a/compiler/rustc_middle/src/util/call_kind.rs b/compiler/rustc_middle/src/util/call_kind.rs
index 627c84c388c..98d55ea6d40 100644
--- a/compiler/rustc_middle/src/util/call_kind.rs
+++ b/compiler/rustc_middle/src/util/call_kind.rs
@@ -19,6 +19,8 @@ pub enum CallDesugaringKind {
     QuestionFromResidual,
     /// try { ..; x } calls type_of(x)::from_output(x)
     TryBlockFromOutput,
+    /// `.await` calls `IntoFuture::into_future`
+    Await,
 }
 
 impl CallDesugaringKind {
@@ -29,6 +31,7 @@ impl CallDesugaringKind {
                 tcx.require_lang_item(LangItem::Try, None)
             }
             Self::QuestionFromResidual => tcx.get_diagnostic_item(sym::FromResidual).unwrap(),
+            Self::Await => tcx.get_diagnostic_item(sym::IntoFuture).unwrap(),
         }
     }
 }
@@ -129,6 +132,8 @@ pub fn call_kind<'tcx>(
             && fn_call_span.desugaring_kind() == Some(DesugaringKind::TryBlock)
         {
             Some((CallDesugaringKind::TryBlockFromOutput, method_substs.type_at(0)))
+        } else if fn_call_span.is_desugaring(DesugaringKind::Await) {
+            Some((CallDesugaringKind::Await, method_substs.type_at(0)))
         } else {
             None
         };
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index abf19c30e3d..c905eea202d 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -208,6 +208,7 @@ symbols! {
         Input,
         Into,
         IntoDiagnostic,
+        IntoFuture,
         IntoIterator,
         IoRead,
         IoWrite,
diff --git a/library/core/src/future/into_future.rs b/library/core/src/future/into_future.rs
index 649b4338772..38c654e76b4 100644
--- a/library/core/src/future/into_future.rs
+++ b/library/core/src/future/into_future.rs
@@ -99,6 +99,7 @@ use crate::future::Future;
 /// }
 /// ```
 #[stable(feature = "into_future", since = "1.64.0")]
+#[rustc_diagnostic_item = "IntoFuture"]
 pub trait IntoFuture {
     /// The output that the future will produce on completion.
     #[stable(feature = "into_future", since = "1.64.0")]
diff --git a/tests/ui/async-await/clone-suggestion.stderr b/tests/ui/async-await/clone-suggestion.stderr
index 8eea8bc3911..c02206f6f9b 100644
--- a/tests/ui/async-await/clone-suggestion.stderr
+++ b/tests/ui/async-await/clone-suggestion.stderr
@@ -4,7 +4,7 @@ error[E0382]: use of moved value: `f`
 LL |     let f = SharedFuture;
    |         - move occurs because `f` has type `SharedFuture`, which does not implement the `Copy` trait
 LL |     f.await;
-   |       ----- `f` moved due to this method call
+   |       ----- `f` moved due to this await
 LL |     f.await;
    |     ^ value used here after move
    |