Don't ICE on item in .await expression

This commit is contained in:
Nathan Corbyn 2019-06-26 13:48:41 +01:00
parent d3e2cec292
commit 5cb841d72e
7 changed files with 89 additions and 9 deletions

View File

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

View File

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

View File

@ -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();
}

View File

@ -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() {}

View File

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

View 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
}

View 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`.