Don't ICE on item in .await
expression
This commit is contained in:
parent
d3e2cec292
commit
5cb841d72e
@ -5795,7 +5795,6 @@ impl<'a> LoweringContext<'a> {
|
||||
err.span_label(item_sp, "this is not `async`");
|
||||
}
|
||||
err.emit();
|
||||
return hir::ExprKind::Err;
|
||||
}
|
||||
}
|
||||
let span = self.mark_span_with_reason(
|
||||
|
@ -1713,7 +1713,7 @@ pub enum GeneratorMovability {
|
||||
}
|
||||
|
||||
/// The yield kind that caused an `ExprKind::Yield`.
|
||||
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub enum YieldSource {
|
||||
/// An `<expr>.await`.
|
||||
Await,
|
||||
|
@ -295,8 +295,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ExprKind::Index(ref base, ref idx) => {
|
||||
self.check_expr_index(base, idx, needs, expr)
|
||||
}
|
||||
ExprKind::Yield(ref value, _) => {
|
||||
self.check_expr_yield(value, expr)
|
||||
ExprKind::Yield(ref value, ref src) => {
|
||||
self.check_expr_yield(value, expr, src)
|
||||
}
|
||||
hir::ExprKind::Err => {
|
||||
tcx.types.err
|
||||
@ -1541,12 +1541,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr_yield(&self, value: &'tcx hir::Expr, expr: &'tcx hir::Expr) -> Ty<'tcx> {
|
||||
fn check_expr_yield(
|
||||
&self,
|
||||
value: &'tcx hir::Expr,
|
||||
expr: &'tcx hir::Expr,
|
||||
src: &'tcx hir::YieldSource
|
||||
) -> Ty<'tcx> {
|
||||
match self.yield_ty {
|
||||
Some(ty) => {
|
||||
self.check_expr_coercable_to_type(&value, ty);
|
||||
}
|
||||
None => {
|
||||
// Given that this `yield` expression was generated as a result of lowering a `.await`,
|
||||
// we know that the yield type must be `()`; however, the context won't contain this
|
||||
// information. Hence, we check the source of the yield expression here and check its
|
||||
// value's type against `()` (this check should always hold).
|
||||
None if src == &hir::YieldSource::Await => {
|
||||
self.check_expr_coercable_to_type(&value, self.tcx.mk_unit());
|
||||
}
|
||||
_ => {
|
||||
struct_span_err!(self.tcx.sess, expr.span, E0627,
|
||||
"yield statement outside of generator literal").emit();
|
||||
}
|
||||
|
@ -7,7 +7,8 @@
|
||||
async fn foo() {}
|
||||
|
||||
fn make_generator() {
|
||||
let _gen = || foo.await; //~ ERROR `await` is only allowed inside `async` functions and blocks
|
||||
let _gen = || foo().await;
|
||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||
--> $DIR/issue-51719.rs:10:19
|
||||
|
|
||||
LL | let _gen = || foo.await;
|
||||
| -- ^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||
LL | let _gen = || foo().await;
|
||||
| -- ^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||
| |
|
||||
| this is not `async`
|
||||
|
||||
|
19
src/test/ui/async-await/issues/issue-62009.rs
Normal file
19
src/test/ui/async-await/issues/issue-62009.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// edition:2018
|
||||
|
||||
#![feature(async_await)]
|
||||
|
||||
async fn print_dur() {}
|
||||
|
||||
fn main() {
|
||||
async { let (); }.await;
|
||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||
async {
|
||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||
let task1 = print_dur().await;
|
||||
}.await;
|
||||
(async || 2333)().await;
|
||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||
(|_| 2333).await;
|
||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||
//~^^ ERROR
|
||||
}
|
49
src/test/ui/async-await/issues/issue-62009.stderr
Normal file
49
src/test/ui/async-await/issues/issue-62009.stderr
Normal file
@ -0,0 +1,49 @@
|
||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||
--> $DIR/issue-62009.rs:8:5
|
||||
|
|
||||
LL | fn main() {
|
||||
| ---- this is not `async`
|
||||
LL | async { let (); }.await;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||
|
||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||
--> $DIR/issue-62009.rs:10:5
|
||||
|
|
||||
LL | fn main() {
|
||||
| ---- this is not `async`
|
||||
...
|
||||
LL | / async {
|
||||
LL | |
|
||||
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
|
||||
--> $DIR/issue-62009.rs:14:5
|
||||
|
|
||||
LL | fn main() {
|
||||
| ---- this is not `async`
|
||||
...
|
||||
LL | (async || 2333)().await;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||
|
||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||
--> $DIR/issue-62009.rs:16:5
|
||||
|
|
||||
LL | fn main() {
|
||||
| ---- this is not `async`
|
||||
...
|
||||
LL | (|_| 2333).await;
|
||||
| ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||
|
||||
error[E0277]: the trait bound `[closure@$DIR/issue-62009.rs:16:5: 16:15]: std::future::Future` is not satisfied
|
||||
--> $DIR/issue-62009.rs:16:5
|
||||
|
|
||||
LL | (|_| 2333).await;
|
||||
| ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009.rs:16:5: 16:15]`
|
||||
|
|
||||
= note: required by `std::future::poll_with_tls_context`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
Loading…
x
Reference in New Issue
Block a user