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

@ -607,6 +607,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
/// } /// }
/// ``` /// ```
fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind<'hir> { fn lower_expr_await(&mut self, await_span: Span, expr: &Expr) -> hir::ExprKind<'hir> {
let dot_await_span = expr.span.shrink_to_hi().to(await_span);
match self.generator_kind { match self.generator_kind {
Some(hir::GeneratorKind::Async(_)) => {} Some(hir::GeneratorKind::Async(_)) => {}
Some(hir::GeneratorKind::Gen) | None => { Some(hir::GeneratorKind::Gen) | None => {
@ -623,7 +624,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
err.emit(); err.emit();
} }
} }
let span = self.mark_span_with_reason(DesugaringKind::Await, await_span, None); let span = self.mark_span_with_reason(DesugaringKind::Await, dot_await_span, None);
let gen_future_span = self.mark_span_with_reason( let gen_future_span = self.mark_span_with_reason(
DesugaringKind::Await, DesugaringKind::Await,
await_span, await_span,
@ -682,7 +683,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let break_x = self.with_loop_scope(loop_node_id, move |this| { let break_x = self.with_loop_scope(loop_node_id, move |this| {
let expr_break = let expr_break =
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr)); hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
this.arena.alloc(this.expr(await_span, expr_break, ThinVec::new())) this.arena.alloc(this.expr(span, expr_break, ThinVec::new()))
}); });
self.arm(ready_pat, break_x) self.arm(ready_pat, break_x)
}; };

View File

@ -348,6 +348,8 @@ pub enum ObligationCauseCode<'tcx> {
/// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y` /// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y`
OpaqueType, OpaqueType,
AwaitableExpr,
/// Well-formed checking. If a `WellFormedLoc` is provided, /// Well-formed checking. If a `WellFormedLoc` is provided,
/// then it will be used to eprform HIR-based wf checking /// then it will be used to eprform HIR-based wf checking
/// after an error occurs, in order to generate a more precise error span. /// after an error occurs, in order to generate a more precise error span.

View File

@ -2838,8 +2838,8 @@ impl<'a> Parser<'a> {
ExprKind::Call(f, args) ExprKind::Call(f, args)
} }
fn mk_await_expr(&mut self, self_arg: P<Expr>, lo: Span) -> P<Expr> { fn mk_await_expr(&mut self, self_arg: P<Expr>, _lo: Span) -> P<Expr> {
let span = lo.to(self.prev_token.span); let span = self.prev_token.span;
let await_expr = self.mk_expr(span, ExprKind::Await(self_arg), AttrVec::new()); let await_expr = self.mk_expr(span, ExprKind::Await(self_arg), AttrVec::new());
self.recover_from_await_method_call(); self.recover_from_await_method_call();
await_expr await_expr

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_remove_reference(&obligation, &mut err, trait_ref);
self.suggest_semicolon_removal(&obligation, &mut err, span, trait_ref); self.suggest_semicolon_removal(&obligation, &mut err, span, trait_ref);
self.note_version_mismatch(&mut err, &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() { if Some(trait_ref.def_id()) == tcx.lang_items().try_trait() {
self.suggest_await_before_try(&mut err, &obligation, trait_ref, span); 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>>, trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
); );
fn suggest_remove_await(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut DiagnosticBuilder<'_>,
);
fn suggest_change_mut( fn suggest_change_mut(
&self, &self,
obligation: &PredicateObligation<'tcx>, 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 /// Check if the trait bound is implemented for a different mutability and note it in the
/// final error. /// final error.
fn suggest_change_mut( fn suggest_change_mut(
@ -1935,6 +1960,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
| ObligationCauseCode::ReturnType | ObligationCauseCode::ReturnType
| ObligationCauseCode::ReturnValue(_) | ObligationCauseCode::ReturnValue(_)
| ObligationCauseCode::BlockTailExpression(_) | ObligationCauseCode::BlockTailExpression(_)
| ObligationCauseCode::AwaitableExpr
| ObligationCauseCode::LetElse => {} | ObligationCauseCode::LetElse => {}
ObligationCauseCode::SliceOrArrayElem => { ObligationCauseCode::SliceOrArrayElem => {
err.note("slice and array elements must have `Sized` type"); err.note("slice and array elements must have `Sized` type");

View File

@ -804,7 +804,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ty = item_ty.subst(self.tcx, substs); let ty = item_ty.subst(self.tcx, substs);
self.write_resolution(hir_id, Ok((def_kind, def_id))); self.write_resolution(hir_id, Ok((def_kind, def_id)));
self.add_required_obligations(span, def_id, &substs); self.add_required_obligations_with_code(
span,
def_id,
&substs,
match lang_item {
hir::LangItem::FuturePoll => ObligationCauseCode::AwaitableExpr,
// FIXME: see if there are other obligation specializations we could do here beyond
// what we do above for `.await`.
_ => traits::ItemObligation(def_id),
},
);
(Res::Def(def_kind, def_id), ty) (Res::Def(def_kind, def_id), ty)
} }
@ -1486,12 +1496,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
/// Add all the obligations that are required, substituting and normalized appropriately. /// Add all the obligations that are required, substituting and normalized appropriately.
#[tracing::instrument(level = "debug", skip(self, span, def_id, substs))]
crate fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) { crate fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
self.add_required_obligations_with_code(
span,
def_id,
substs,
traits::ItemObligation(def_id),
)
}
#[tracing::instrument(level = "debug", skip(self, span, def_id, substs))]
fn add_required_obligations_with_code(
&self,
span: Span,
def_id: DefId,
substs: &SubstsRef<'tcx>,
code: ObligationCauseCode<'tcx>,
) {
let (bounds, _) = self.instantiate_bounds(span, def_id, &substs); let (bounds, _) = self.instantiate_bounds(span, def_id, &substs);
for obligation in traits::predicates_for_generics( for obligation in traits::predicates_for_generics(
traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)), traits::ObligationCause::new(span, self.body_id, code),
self.param_env, self.param_env,
bounds, bounds,
) { ) {

View File

@ -14,10 +14,10 @@ LL | let a;
| ^ cannot infer type | ^ cannot infer type
| |
note: the type is part of the `async fn` body because of this `await` note: the type is part of the `async fn` body because of this `await`
--> $DIR/async-error-span.rs:14:5 --> $DIR/async-error-span.rs:14:17
| |
LL | get_future().await; LL | get_future().await;
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -6,13 +6,13 @@ LL | assert_send(local_dropped_before_await());
| |
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>` = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/async-fn-nonsend.rs:24:5 --> $DIR/async-fn-nonsend.rs:24:10
| |
LL | let x = non_send(); LL | let x = non_send();
| - has type `impl Debug` which is not `Send` | - has type `impl Debug` which is not `Send`
LL | drop(x); LL | drop(x);
LL | fut().await; LL | fut().await;
| ^^^^^^^^^^^ await occurs here, with `x` maybe used later | ^^^^^^ await occurs here, with `x` maybe used later
LL | } LL | }
| - `x` is later dropped here | - `x` is later dropped here
note: required by a bound in `assert_send` note: required by a bound in `assert_send`
@ -29,12 +29,12 @@ LL | assert_send(non_send_temporary_in_match());
| |
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>` = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/async-fn-nonsend.rs:33:20 --> $DIR/async-fn-nonsend.rs:33:25
| |
LL | match Some(non_send()) { LL | match Some(non_send()) {
| ---------- has type `impl Debug` which is not `Send` | ---------- has type `impl Debug` which is not `Send`
LL | Some(_) => fut().await, LL | Some(_) => fut().await,
| ^^^^^^^^^^^ await occurs here, with `non_send()` maybe used later | ^^^^^^ await occurs here, with `non_send()` maybe used later
... ...
LL | } LL | }
| - `non_send()` is later dropped here | - `non_send()` is later dropped here
@ -52,13 +52,13 @@ LL | assert_send(non_sync_with_method_call());
| |
= help: the trait `Send` is not implemented for `dyn std::fmt::Write` = help: the trait `Send` is not implemented for `dyn std::fmt::Write`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/async-fn-nonsend.rs:42:9 --> $DIR/async-fn-nonsend.rs:42:14
| |
LL | let f: &mut std::fmt::Formatter = panic!(); LL | let f: &mut std::fmt::Formatter = panic!();
| - has type `&mut Formatter<'_>` which is not `Send` | - has type `&mut Formatter<'_>` which is not `Send`
LL | if non_sync().fmt(f).unwrap() == () { LL | if non_sync().fmt(f).unwrap() == () {
LL | fut().await; LL | fut().await;
| ^^^^^^^^^^^ await occurs here, with `f` maybe used later | ^^^^^^ await occurs here, with `f` maybe used later
LL | } LL | }
LL | } LL | }
| - `f` is later dropped here | - `f` is later dropped here

View File

@ -162,52 +162,52 @@ LL | let _ = (await bar())?;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^^^^^^^ only allowed inside `async` functions and blocks
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:71:13 --> $DIR/incorrect-syntax-suggestions.rs:71:19
| |
LL | fn foo13() -> Result<(), ()> { LL | fn foo13() -> Result<(), ()> {
| ----- this is not `async` | ----- this is not `async`
LL | let _ = bar().await(); LL | let _ = bar().await();
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:76:13 --> $DIR/incorrect-syntax-suggestions.rs:76:19
| |
LL | fn foo14() -> Result<(), ()> { LL | fn foo14() -> Result<(), ()> {
| ----- this is not `async` | ----- this is not `async`
LL | let _ = bar().await()?; LL | let _ = bar().await()?;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:81:13 --> $DIR/incorrect-syntax-suggestions.rs:81:19
| |
LL | fn foo15() -> Result<(), ()> { LL | fn foo15() -> Result<(), ()> {
| ----- this is not `async` | ----- this is not `async`
LL | let _ = bar().await; LL | let _ = bar().await;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:85:13 --> $DIR/incorrect-syntax-suggestions.rs:85:19
| |
LL | fn foo16() -> Result<(), ()> { LL | fn foo16() -> Result<(), ()> {
| ----- this is not `async` | ----- this is not `async`
LL | let _ = bar().await?; LL | let _ = bar().await?;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:90:17 --> $DIR/incorrect-syntax-suggestions.rs:90:23
| |
LL | fn foo() -> Result<(), ()> { LL | fn foo() -> Result<(), ()> {
| --- this is not `async` | --- this is not `async`
LL | let _ = bar().await?; LL | let _ = bar().await?;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:97:17 --> $DIR/incorrect-syntax-suggestions.rs:97:23
| |
LL | let foo = || { LL | let foo = || {
| -- this is not `async` | -- this is not `async`
LL | let _ = bar().await?; LL | let _ = bar().await?;
| ^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/incorrect-syntax-suggestions.rs:113:17 --> $DIR/incorrect-syntax-suggestions.rs:113:17

View File

@ -6,12 +6,12 @@ LL | is_sync(bar());
| |
= help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `Foo` = help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `Foo`
note: future is not `Sync` as this value is used across an await note: future is not `Sync` as this value is used across an await
--> $DIR/issue-64130-1-sync.rs:15:5 --> $DIR/issue-64130-1-sync.rs:15:10
| |
LL | let x = Foo; LL | let x = Foo;
| - has type `Foo` which is not `Sync` | - has type `Foo` which is not `Sync`
LL | baz().await; LL | baz().await;
| ^^^^^^^^^^^ await occurs here, with `x` maybe used later | ^^^^^^ await occurs here, with `x` maybe used later
LL | } LL | }
| - `x` is later dropped here | - `x` is later dropped here
note: required by a bound in `is_sync` note: required by a bound in `is_sync`

View File

@ -6,12 +6,12 @@ LL | is_send(bar());
| |
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Foo` = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Foo`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/issue-64130-2-send.rs:15:5 --> $DIR/issue-64130-2-send.rs:15:10
| |
LL | let x = Foo; LL | let x = Foo;
| - has type `Foo` which is not `Send` | - has type `Foo` which is not `Send`
LL | baz().await; LL | baz().await;
| ^^^^^^^^^^^ await occurs here, with `x` maybe used later | ^^^^^^ await occurs here, with `x` maybe used later
LL | } LL | }
| - `x` is later dropped here | - `x` is later dropped here
note: required by a bound in `is_send` note: required by a bound in `is_send`

View File

@ -8,12 +8,12 @@ LL | is_qux(bar());
| ^^^^^ within `impl Future<Output = ()>`, the trait `Qux` is not implemented for `Foo` | ^^^^^ within `impl Future<Output = ()>`, the trait `Qux` is not implemented for `Foo`
| |
note: future does not implement `Qux` as this value is used across an await note: future does not implement `Qux` as this value is used across an await
--> $DIR/issue-64130-3-other.rs:18:5 --> $DIR/issue-64130-3-other.rs:18:10
| |
LL | let x = Foo; LL | let x = Foo;
| - has type `Foo` which does not implement `Qux` | - has type `Foo` which does not implement `Qux`
LL | baz().await; LL | baz().await;
| ^^^^^^^^^^^ await occurs here, with `x` maybe used later | ^^^^^^ await occurs here, with `x` maybe used later
LL | } LL | }
| - `x` is later dropped here | - `x` is later dropped here
note: required by a bound in `is_qux` note: required by a bound in `is_qux`

View File

@ -6,13 +6,13 @@ LL | pub fn foo() -> impl Future + Send {
| |
= help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)` = help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/issue-64130-4-async-move.rs:21:26 --> $DIR/issue-64130-4-async-move.rs:21:31
| |
LL | match client.status() { LL | match client.status() {
| ------ has type `&Client` which is not `Send` | ------ has type `&Client` which is not `Send`
LL | 200 => { LL | 200 => {
LL | let _x = get().await; LL | let _x = get().await;
| ^^^^^^^^^^^ await occurs here, with `client` maybe used later | ^^^^^^ await occurs here, with `client` maybe used later
... ...
LL | } LL | }
| - `client` is later dropped here | - `client` is later dropped here

View File

@ -6,12 +6,12 @@ LL | is_send(foo());
| |
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, u32>` = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, u32>`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/issue-64130-non-send-future-diags.rs:17:5 --> $DIR/issue-64130-non-send-future-diags.rs:17:10
| |
LL | let g = x.lock().unwrap(); LL | let g = x.lock().unwrap();
| - has type `MutexGuard<'_, u32>` which is not `Send` | - has type `MutexGuard<'_, u32>` which is not `Send`
LL | baz().await; LL | baz().await;
| ^^^^^^^^^^^ await occurs here, with `g` maybe used later | ^^^^^^ await occurs here, with `g` maybe used later
LL | } LL | }
| - `g` is later dropped here | - `g` is later dropped here
note: required by a bound in `is_send` note: required by a bound in `is_send`

View File

@ -6,12 +6,12 @@ LL | spawn(async {
| |
= help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*mut ()` = help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*mut ()`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/issue-67252-unnamed-future.rs:20:9 --> $DIR/issue-67252-unnamed-future.rs:20:16
| |
LL | let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send` LL | let _a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
| -- has type `*mut ()` which is not `Send` | -- has type `*mut ()` which is not `Send`
LL | AFuture.await; LL | AFuture.await;
| ^^^^^^^^^^^^^ await occurs here, with `_a` maybe used later | ^^^^^^ await occurs here, with `_a` maybe used later
LL | }); LL | });
| - `_a` is later dropped here | - `_a` is later dropped here
note: required by a bound in `spawn` note: required by a bound in `spawn`

View File

@ -6,6 +6,7 @@ async fn fun() {
//~| error: `.await` is not allowed in a `const` //~| error: `.await` is not allowed in a `const`
//~| error: `.await` is not allowed in a `const` //~| error: `.await` is not allowed in a `const`
//~| error: `()` is not a future //~| error: `()` is not a future
//~| error: `()` is not a future
} }
fn main() {} fn main() {}

View File

@ -1,34 +1,48 @@
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/issue-70594.rs:4:9 --> $DIR/issue-70594.rs:4:12
| |
LL | async fn fun() { LL | async fn fun() {
| --- this is not `async` | --- this is not `async`
LL | [1; ().await]; LL | [1; ().await];
| ^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error[E0744]: `.await` is not allowed in a `const` error[E0744]: `.await` is not allowed in a `const`
--> $DIR/issue-70594.rs:4:9 --> $DIR/issue-70594.rs:4:12
| |
LL | [1; ().await]; LL | [1; ().await];
| ^^^^^^^^ | ^^^^^
error[E0744]: `.await` is not allowed in a `const` error[E0744]: `.await` is not allowed in a `const`
--> $DIR/issue-70594.rs:4:9 --> $DIR/issue-70594.rs:4:11
| |
LL | [1; ().await]; LL | [1; ().await];
| ^^^^^^^^ | ^^^^^^
error[E0277]: `()` is not a future error[E0277]: `()` is not a future
--> $DIR/issue-70594.rs:4:9 --> $DIR/issue-70594.rs:4:12
| |
LL | [1; ().await]; LL | [1; ().await];
| ^^^^^^^^ `()` is not a future | ^^^^^ `()` is not a future
| |
= help: the trait `Future` is not implemented for `()` = help: the trait `Future` is not implemented for `()`
= note: () must be a future or must implement `IntoFuture` to be awaited = note: () must be a future or must implement `IntoFuture` to be awaited
= note: required because of the requirements on the impl of `IntoFuture` for `()` = note: required because of the requirements on the impl of `IntoFuture` for `()`
error: aborting due to 4 previous errors error[E0277]: `()` is not a future
--> $DIR/issue-70594.rs:4:11
|
LL | [1; ().await];
| ^^^^^^ `()` is not a future
|
= help: the trait `Future` is not implemented for `()`
= note: () must be a future or must implement `IntoFuture` to be awaited
help: do not `.await` the expression
|
LL - [1; ().await];
LL + [1; ()];
|
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0277, E0728, E0744. Some errors have detailed explanations: E0277, E0728, E0744.
For more information about an error, try `rustc --explain E0277`. For more information about an error, try `rustc --explain E0277`.

View File

@ -6,25 +6,16 @@ LL | fn foo(tx: std::sync::mpsc::Sender<i32>) -> impl Future + Send {
| |
= help: the trait `Sync` is not implemented for `Sender<i32>` = help: the trait `Sync` is not implemented for `Sender<i32>`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/issue-70935-complex-spans.rs:13:9 --> $DIR/issue-70935-complex-spans.rs:15:11
|
LL | / baz(|| async{
LL | | foo(tx.clone());
LL | | }).await;
| |________________^ first, await occurs here, with the value maybe used later...
note: the value is later dropped here
--> $DIR/issue-70935-complex-spans.rs:15:17
|
LL | }).await;
| ^
note: this has type `[closure@$DIR/issue-70935-complex-spans.rs:13:13: 15:10]` which is not `Send`
--> $DIR/issue-70935-complex-spans.rs:13:13
| |
LL | baz(|| async{ LL | baz(|| async{
| _____________^ | _____________-
LL | | foo(tx.clone()); LL | | foo(tx.clone());
LL | | }).await; LL | | }).await;
| |_________^ | | - ^^^^^^- the value is later dropped here
| | | |
| |_________| await occurs here, with the value maybe used later
| has type `[closure@$DIR/issue-70935-complex-spans.rs:13:13: 15:10]` which is not `Send`
error: aborting due to previous error error: aborting due to previous error

View File

@ -6,12 +6,12 @@ LL | fake_spawn(wrong_mutex());
| |
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, i32>` = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, i32>`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/issue-71137.rs:14:5 --> $DIR/issue-71137.rs:14:25
| |
LL | let mut guard = m.lock().unwrap(); LL | let mut guard = m.lock().unwrap();
| --------- has type `MutexGuard<'_, i32>` which is not `Send` | --------- has type `MutexGuard<'_, i32>` which is not `Send`
LL | (async { "right"; }).await; LL | (async { "right"; }).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ await occurs here, with `mut guard` maybe used later | ^^^^^^ await occurs here, with `mut guard` maybe used later
LL | *guard += 1; LL | *guard += 1;
LL | } LL | }
| - `mut guard` is later dropped here | - `mut guard` is later dropped here

View File

@ -1,8 +1,8 @@
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/issue-51719.rs:8:19 --> $DIR/issue-51719.rs:8:25
| |
LL | let _gen = || foo().await; LL | let _gen = || foo().await;
| -- ^^^^^^^^^^^ only allowed inside `async` functions and blocks | -- ^^^^^ only allowed inside `async` functions and blocks
| | | |
| this is not `async` | this is not `async`

View File

@ -1,11 +1,11 @@
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/issue-51751.rs:9:20 --> $DIR/issue-51751.rs:9:27
| |
LL | fn main() { LL | fn main() {
| ---- this is not `async` | ---- this is not `async`
LL | let result = inc(10000); LL | let result = inc(10000);
LL | let finished = result.await; LL | let finished = result.await;
| ^^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error: aborting due to previous error error: aborting due to previous error

View File

@ -6,10 +6,11 @@ fn main() {
async { let (); }.await; async { let (); }.await;
//~^ ERROR `await` is only allowed inside `async` functions and blocks //~^ ERROR `await` is only allowed inside `async` functions and blocks
async { async {
//~^ ERROR `await` is only allowed inside `async` functions and blocks
let task1 = print_dur().await; let task1 = print_dur().await;
}.await; }.await;
//~^ ERROR `await` is only allowed inside `async` functions and blocks
(|_| 2333).await; (|_| 2333).await;
//~^ ERROR `await` is only allowed inside `async` functions and blocks //~^ ERROR `await` is only allowed inside `async` functions and blocks
//~^^ ERROR //~| ERROR is not a future
//~| ERROR is not a future
} }

View File

@ -1,43 +1,54 @@
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/issue-62009-1.rs:6:5 --> $DIR/issue-62009-1.rs:6:23
| |
LL | fn main() { LL | fn main() {
| ---- this is not `async` | ---- this is not `async`
LL | async { let (); }.await; LL | async { let (); }.await;
| ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/issue-62009-1.rs:8:5 --> $DIR/issue-62009-1.rs:10:7
| |
LL | fn main() { LL | fn main() {
| ---- this is not `async` | ---- this is not `async`
... ...
LL | / async { LL | }.await;
LL | | | ^^^^^ only allowed inside `async` functions and blocks
LL | | let task1 = print_dur().await;
LL | | }.await;
| |___________^ only allowed inside `async` functions and blocks
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/issue-62009-1.rs:12:5 --> $DIR/issue-62009-1.rs:12:16
| |
LL | fn main() { LL | fn main() {
| ---- this is not `async` | ---- this is not `async`
... ...
LL | (|_| 2333).await; LL | (|_| 2333).await;
| ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
--> $DIR/issue-62009-1.rs:12:5 --> $DIR/issue-62009-1.rs:12:16
| |
LL | (|_| 2333).await; LL | (|_| 2333).await;
| ^^^^^^^^^^^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future | ^^^^^ `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
| |
= help: the trait `Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` = help: the trait `Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
= note: [closure@$DIR/issue-62009-1.rs:12:5: 12:15] must be a future or must implement `IntoFuture` to be awaited = note: [closure@$DIR/issue-62009-1.rs:12:5: 12:15] must be a future or must implement `IntoFuture` to be awaited
= note: required because of the requirements on the impl of `IntoFuture` for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` = note: required because of the requirements on the impl of `IntoFuture` for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
error: aborting due to 4 previous errors error[E0277]: `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
--> $DIR/issue-62009-1.rs:12:15
|
LL | (|_| 2333).await;
| ^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
|
= help: the trait `Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
= note: [closure@$DIR/issue-62009-1.rs:12:5: 12:15] must be a future or must implement `IntoFuture` to be awaited
help: do not `.await` the expression
|
LL - (|_| 2333).await;
LL + (|_| 2333);
|
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0277, E0728. Some errors have detailed explanations: E0277, E0728.
For more information about an error, try `rustc --explain E0277`. For more information about an error, try `rustc --explain E0277`.

View File

@ -1,10 +1,10 @@
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/issue-62009-2.rs:8:5 --> $DIR/issue-62009-2.rs:8:23
| |
LL | fn main() { LL | fn main() {
| ---- this is not `async` | ---- this is not `async`
LL | (async || 2333)().await; LL | (async || 2333)().await;
| ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error: aborting due to previous error error: aborting due to previous error

View File

@ -6,16 +6,12 @@ LL | assert_send(async {
| |
= help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*const u8` = help: within `impl Future<Output = [async output]>`, the trait `Send` is not implemented for `*const u8`
note: future is not `Send` as this value is used across an await note: future is not `Send` as this value is used across an await
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:9 --> $DIR/issue-65436-raw-ptr-not-send.rs:14:35
| |
LL | bar(Foo(std::ptr::null())).await; LL | bar(Foo(std::ptr::null())).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ first, await occurs here, with `std::ptr::null()` maybe used later... | ---------------- ^^^^^^- `std::ptr::null()` is later dropped here
note: `std::ptr::null()` is later dropped here | | |
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:41 | | await occurs here, with `std::ptr::null()` maybe used later
|
LL | bar(Foo(std::ptr::null())).await;
| ---------------- ^
| |
| has type `*const u8` which is not `Send` | has type `*const u8` which is not `Send`
help: consider moving this into a `let` binding to create a shorter lived borrow help: consider moving this into a `let` binding to create a shorter lived borrow
--> $DIR/issue-65436-raw-ptr-not-send.rs:14:13 --> $DIR/issue-65436-raw-ptr-not-send.rs:14:13

View File

@ -1,11 +1,11 @@
error[E0728]: `await` is only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks
--> $DIR/non-async-enclosing-span.rs:9:13 --> $DIR/non-async-enclosing-span.rs:9:28
| |
LL | fn main() { LL | fn main() {
| ---- this is not `async` | ---- this is not `async`
LL | let x = move || {}; LL | let x = move || {};
LL | let y = do_the_thing().await; LL | let y = do_the_thing().await;
| ^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks | ^^^^^ only allowed inside `async` functions and blocks
error: aborting due to previous error error: aborting due to previous error

View File

@ -39,7 +39,7 @@ LL | dummy();
| + | +
error[E0308]: `if` and `else` have incompatible types error[E0308]: `if` and `else` have incompatible types
--> $DIR/suggest-missing-await.rs:35:9 --> $DIR/suggest-missing-await.rs:35:17
| |
LL | let _x = if true { LL | let _x = if true {
| ______________- | ______________-
@ -48,7 +48,7 @@ LL | | dummy()
LL | | LL | |
LL | | } else { LL | | } else {
LL | | dummy().await LL | | dummy().await
| | ^^^^^^^^^^^^^ expected opaque type, found `()` | | ^^^^^ expected opaque type, found `()`
LL | | LL | |
LL | | }; LL | | };
| |_____- `if` and `else` have incompatible types | |_____- `if` and `else` have incompatible types
@ -61,7 +61,7 @@ LL | dummy().await
| ++++++ | ++++++
error[E0308]: `match` arms have incompatible types error[E0308]: `match` arms have incompatible types
--> $DIR/suggest-missing-await.rs:45:14 --> $DIR/suggest-missing-await.rs:45:22
| |
LL | let _x = match 0usize { LL | let _x = match 0usize {
| ______________- | ______________-
@ -70,7 +70,7 @@ LL | | 0 => dummy(),
LL | | 1 => dummy(), LL | | 1 => dummy(),
| | ------- this is found to be of type `impl Future<Output = ()>` | | ------- this is found to be of type `impl Future<Output = ()>`
LL | | 2 => dummy().await, LL | | 2 => dummy().await,
| | ^^^^^^^^^^^^^ expected opaque type, found `()` | | ^^^^^ expected opaque type, found `()`
LL | | LL | |
LL | | }; LL | | };
| |_____- `match` arms have incompatible types | |_____- `match` arms have incompatible types

View File

@ -5,10 +5,10 @@ LL | bar().await;
| ^^^ cannot infer type for type parameter `T` declared on the function `bar` | ^^^ cannot infer type for type parameter `T` declared on the function `bar`
| |
note: the type is part of the `async fn` body because of this `await` note: the type is part of the `async fn` body because of this `await`
--> $DIR/unresolved_type_param.rs:9:5 --> $DIR/unresolved_type_param.rs:9:10
| |
LL | bar().await; LL | bar().await;
| ^^^^^^^^^^^ | ^^^^^^
error[E0698]: type inside `async fn` body must be known in this context error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/unresolved_type_param.rs:9:5 --> $DIR/unresolved_type_param.rs:9:5
@ -17,10 +17,10 @@ LL | bar().await;
| ^^^ cannot infer type for type parameter `T` declared on the function `bar` | ^^^ cannot infer type for type parameter `T` declared on the function `bar`
| |
note: the type is part of the `async fn` body because of this `await` note: the type is part of the `async fn` body because of this `await`
--> $DIR/unresolved_type_param.rs:9:5 --> $DIR/unresolved_type_param.rs:9:10
| |
LL | bar().await; LL | bar().await;
| ^^^^^^^^^^^ | ^^^^^^
error[E0698]: type inside `async fn` body must be known in this context error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/unresolved_type_param.rs:9:5 --> $DIR/unresolved_type_param.rs:9:5
@ -29,10 +29,10 @@ LL | bar().await;
| ^^^ cannot infer type for type parameter `T` declared on the function `bar` | ^^^ cannot infer type for type parameter `T` declared on the function `bar`
| |
note: the type is part of the `async fn` body because of this `await` note: the type is part of the `async fn` body because of this `await`
--> $DIR/unresolved_type_param.rs:9:5 --> $DIR/unresolved_type_param.rs:9:10
| |
LL | bar().await; LL | bar().await;
| ^^^^^^^^^^^ | ^^^^^^
error[E0698]: type inside `async fn` body must be known in this context error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/unresolved_type_param.rs:9:5 --> $DIR/unresolved_type_param.rs:9:5
@ -41,10 +41,10 @@ LL | bar().await;
| ^^^ cannot infer type for type parameter `T` declared on the function `bar` | ^^^ cannot infer type for type parameter `T` declared on the function `bar`
| |
note: the type is part of the `async fn` body because of this `await` note: the type is part of the `async fn` body because of this `await`
--> $DIR/unresolved_type_param.rs:9:5 --> $DIR/unresolved_type_param.rs:9:10
| |
LL | bar().await; LL | bar().await;
| ^^^^^^^^^^^ | ^^^^^^
error[E0698]: type inside `async fn` body must be known in this context error[E0698]: type inside `async fn` body must be known in this context
--> $DIR/unresolved_type_param.rs:9:5 --> $DIR/unresolved_type_param.rs:9:5
@ -53,10 +53,10 @@ LL | bar().await;
| ^^^ cannot infer type for type parameter `T` declared on the function `bar` | ^^^ cannot infer type for type parameter `T` declared on the function `bar`
| |
note: the type is part of the `async fn` body because of this `await` note: the type is part of the `async fn` body because of this `await`
--> $DIR/unresolved_type_param.rs:9:5 --> $DIR/unresolved_type_param.rs:9:10
| |
LL | bar().await; LL | bar().await;
| ^^^^^^^^^^^ | ^^^^^^
error: aborting due to 5 previous errors error: aborting due to 5 previous errors

View File

@ -4,7 +4,7 @@ error: boxed `Umm` held across a suspend point, but should not be
LL | let _guard = bar(); LL | let _guard = bar();
| ^^^^^^ | ^^^^^^
LL | other().await; LL | other().await;
| ------------- the value is held across this suspend point | ------ the value is held across this suspend point
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/boxed.rs:3:9 --> $DIR/boxed.rs:3:9

View File

@ -2,7 +2,7 @@ error: `No` held across a suspend point, but should not be
--> $DIR/dedup.rs:16:12 --> $DIR/dedup.rs:16:12
| |
LL | wheeee(No {}).await; LL | wheeee(No {}).await;
| -------^^^^^------- the value is held across this suspend point | ^^^^^ ------ the value is held across this suspend point
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/dedup.rs:3:9 --> $DIR/dedup.rs:3:9

View File

@ -31,7 +31,7 @@ error: `MutexGuard` held across a suspend point, but should not be
LL | let _guard = m.lock().unwrap(); LL | let _guard = m.lock().unwrap();
| ^^^^^^ | ^^^^^^
LL | other().await; LL | other().await;
| ------------- the value is held across this suspend point | ------ the value is held across this suspend point
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/gated.rs:2:9 --> $DIR/gated.rs:2:9

View File

@ -4,7 +4,7 @@ error: `MutexGuard` held across a suspend point, but should not be
LL | let _guard = m.lock().unwrap(); LL | let _guard = m.lock().unwrap();
| ^^^^^^ | ^^^^^^
LL | other().await; LL | other().await;
| ------------- the value is held across this suspend point | ------ the value is held across this suspend point
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/mutex.rs:3:9 --> $DIR/mutex.rs:3:9

View File

@ -5,7 +5,7 @@ LL | let guard = &mut self.u;
| ^^^^^^ | ^^^^^^
LL | LL |
LL | other().await; LL | other().await;
| ------------- the value is held across this suspend point | ------ the value is held across this suspend point
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/ref.rs:3:9 --> $DIR/ref.rs:3:9

View File

@ -5,7 +5,7 @@ LL | let _guard1 = r#impl();
| ^^^^^^^ | ^^^^^^^
... ...
LL | other().await; LL | other().await;
| ------------- the value is held across this suspend point | ------ the value is held across this suspend point
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/trait.rs:3:9 --> $DIR/trait.rs:3:9
@ -25,7 +25,7 @@ LL | let _guard2 = r#dyn();
| ^^^^^^^ | ^^^^^^^
LL | LL |
LL | other().await; LL | other().await;
| ------------- the value is held across this suspend point | ------ the value is held across this suspend point
| |
help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
--> $DIR/trait.rs:22:9 --> $DIR/trait.rs:22:9

View File

@ -4,7 +4,7 @@ error: `Umm` held across a suspend point, but should not be
LL | let _guard = bar(); LL | let _guard = bar();
| ^^^^^^ | ^^^^^^
LL | other().await; LL | other().await;
| ------------- the value is held across this suspend point | ------ the value is held across this suspend point
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/unit.rs:3:9 --> $DIR/unit.rs:3:9

View File

@ -4,7 +4,7 @@ warning: `Umm` held across a suspend point, but should not be
LL | let _guard = bar(); LL | let _guard = bar();
| ^^^^^^ | ^^^^^^
LL | other().await; LL | other().await;
| ------------- the value is held across this suspend point | ------ the value is held across this suspend point
| |
note: the lint level is defined here note: the lint level is defined here
--> $DIR/warn.rs:4:9 --> $DIR/warn.rs:4:9