1
Fork 0

When .await is called on a non-Future expression, suggest removal

Keep track of the origin of a `T: Future` obligation when caused by an
`.await` expression.

Address #66731.
This commit is contained in:
Esteban Kuber 2021-11-16 00:57:53 +00:00
parent 06a6674a7d
commit 7227a87371
36 changed files with 190 additions and 121 deletions

View file

@ -439,6 +439,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
self.suggest_remove_reference(&obligation, &mut err, trait_ref);
self.suggest_semicolon_removal(&obligation, &mut err, span, trait_ref);
self.note_version_mismatch(&mut err, &trait_ref);
self.suggest_remove_await(&obligation, &mut err);
if Some(trait_ref.def_id()) == tcx.lang_items().try_trait() {
self.suggest_await_before_try(&mut err, &obligation, trait_ref, span);

View file

@ -89,6 +89,12 @@ pub trait InferCtxtExt<'tcx> {
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
);
fn suggest_remove_await(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut DiagnosticBuilder<'_>,
);
fn suggest_change_mut(
&self,
obligation: &PredicateObligation<'tcx>,
@ -873,6 +879,25 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
}
fn suggest_remove_await(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut DiagnosticBuilder<'_>,
) {
let span = obligation.cause.span;
if let ObligationCauseCode::AwaitableExpr = obligation.cause.code {
// FIXME: use `trait_ref.self_ty().no_bound_vars()` to typecheck if `()` and if not
// maybe suggest returning instead?
err.span_suggestion_verbose(
span,
"do not `.await` the expression",
String::new(),
Applicability::MachineApplicable,
);
}
}
/// Check if the trait bound is implemented for a different mutability and note it in the
/// final error.
fn suggest_change_mut(
@ -1935,6 +1960,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
| ObligationCauseCode::ReturnType
| ObligationCauseCode::ReturnValue(_)
| ObligationCauseCode::BlockTailExpression(_)
| ObligationCauseCode::AwaitableExpr
| ObligationCauseCode::LetElse => {}
ObligationCauseCode::SliceOrArrayElem => {
err.note("slice and array elements must have `Sized` type");