Don't call await a method

This commit is contained in:
Michael Goulet 2023-04-25 19:48:59 +00:00
parent e6077fc1b8
commit 6c9249f689
8 changed files with 43 additions and 7 deletions

View File

@ -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

View File

@ -1084,6 +1084,14 @@ fn explain_captures(
);
}
}
} else {
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,
@ -1091,6 +1099,7 @@ fn explain_captures(
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;

View File

@ -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]

View File

@ -184,6 +184,9 @@ macro_rules! error {
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));

View File

@ -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 @@ pub fn trait_def_id(self, tcx: TyCtxt<'_>) -> DefId {
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
};

View File

@ -208,6 +208,7 @@
Input,
Into,
IntoDiagnostic,
IntoFuture,
IntoIterator,
IoRead,
IoWrite,

View File

@ -99,6 +99,7 @@
/// }
/// ```
#[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")]

View File

@ -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
|