Rollup merge of #62292 - Centril:split-async-closures, r=cramertj
Move `async || ...` closures into `#![feature(async_closure)]` The `async || expr` syntax is moved out from `#![feature(async_await)]` into its own gate `#![feature(async_closure)]`. New tracking issue: https://github.com/rust-lang/rust/issues/62290 Closes https://github.com/rust-lang/rust/issues/62214. cc https://github.com/rust-lang/rust/issues/62149 r? @varkor
This commit is contained in:
commit
84527e4676
@ -31,6 +31,7 @@ use crate::tokenstream::TokenTree;
|
||||
|
||||
use errors::{Applicability, DiagnosticBuilder, Handler};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::Lock;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
|
||||
use log::debug;
|
||||
@ -573,6 +574,9 @@ declare_features! (
|
||||
// Allows `impl Trait` with multiple unrelated lifetimes.
|
||||
(active, member_constraints, "1.37.0", Some(61977), None),
|
||||
|
||||
// Allows `async || body` closures.
|
||||
(active, async_closure, "1.37.0", Some(62290), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: actual feature gates
|
||||
// -------------------------------------------------------------------------
|
||||
@ -2191,9 +2195,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
"labels on blocks are unstable");
|
||||
}
|
||||
}
|
||||
ast::ExprKind::Closure(_, ast::IsAsync::Async { .. }, ..) => {
|
||||
gate_feature_post!(&self, async_await, e.span, "async closures are unstable");
|
||||
}
|
||||
ast::ExprKind::Async(..) => {
|
||||
gate_feature_post!(&self, async_await, e.span, "async blocks are unstable");
|
||||
}
|
||||
@ -2527,6 +2528,10 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
|
||||
features
|
||||
}
|
||||
|
||||
fn for_each_in_lock<T>(vec: &Lock<Vec<T>>, f: impl Fn(&T)) {
|
||||
vec.borrow().iter().for_each(f);
|
||||
}
|
||||
|
||||
pub fn check_crate(krate: &ast::Crate,
|
||||
sess: &ParseSess,
|
||||
features: &Features,
|
||||
@ -2539,27 +2544,26 @@ pub fn check_crate(krate: &ast::Crate,
|
||||
plugin_attributes,
|
||||
};
|
||||
|
||||
sess
|
||||
.param_attr_spans
|
||||
.borrow()
|
||||
.iter()
|
||||
.for_each(|span| gate_feature!(
|
||||
&ctx,
|
||||
param_attrs,
|
||||
*span,
|
||||
"attributes on function parameters are unstable"
|
||||
));
|
||||
for_each_in_lock(&sess.param_attr_spans, |span| gate_feature!(
|
||||
&ctx,
|
||||
param_attrs,
|
||||
*span,
|
||||
"attributes on function parameters are unstable"
|
||||
));
|
||||
|
||||
sess
|
||||
.let_chains_spans
|
||||
.borrow()
|
||||
.iter()
|
||||
.for_each(|span| gate_feature!(
|
||||
&ctx,
|
||||
let_chains,
|
||||
*span,
|
||||
"`let` expressions in this position are experimental"
|
||||
));
|
||||
for_each_in_lock(&sess.let_chains_spans, |span| gate_feature!(
|
||||
&ctx,
|
||||
let_chains,
|
||||
*span,
|
||||
"`let` expressions in this position are experimental"
|
||||
));
|
||||
|
||||
for_each_in_lock(&sess.async_closure_spans, |span| gate_feature!(
|
||||
&ctx,
|
||||
async_closure,
|
||||
*span,
|
||||
"async closures are unstable"
|
||||
));
|
||||
|
||||
let visitor = &mut PostExpansionVisitor {
|
||||
context: &ctx,
|
||||
|
@ -1452,6 +1452,7 @@ mod tests {
|
||||
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
|
||||
param_attr_spans: Lock::new(Vec::new()),
|
||||
let_chains_spans: Lock::new(Vec::new()),
|
||||
async_closure_spans: Lock::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,8 @@ pub struct ParseSess {
|
||||
pub param_attr_spans: Lock<Vec<Span>>,
|
||||
// Places where `let` exprs were used and should be feature gated according to `let_chains`.
|
||||
pub let_chains_spans: Lock<Vec<Span>>,
|
||||
// Places where `async || ..` exprs were used and should be feature gated.
|
||||
pub async_closure_spans: Lock<Vec<Span>>,
|
||||
}
|
||||
|
||||
impl ParseSess {
|
||||
@ -84,6 +86,7 @@ impl ParseSess {
|
||||
ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
|
||||
param_attr_spans: Lock::new(Vec::new()),
|
||||
let_chains_spans: Lock::new(Vec::new()),
|
||||
async_closure_spans: Lock::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3221,21 +3221,24 @@ impl<'a> Parser<'a> {
|
||||
-> PResult<'a, P<Expr>>
|
||||
{
|
||||
let lo = self.token.span;
|
||||
|
||||
let movability = if self.eat_keyword(kw::Static) {
|
||||
Movability::Static
|
||||
} else {
|
||||
Movability::Movable
|
||||
};
|
||||
|
||||
let asyncness = if self.token.span.rust_2018() {
|
||||
self.parse_asyncness()
|
||||
} else {
|
||||
IsAsync::NotAsync
|
||||
};
|
||||
let capture_clause = if self.eat_keyword(kw::Move) {
|
||||
CaptureBy::Value
|
||||
} else {
|
||||
CaptureBy::Ref
|
||||
};
|
||||
if asyncness.is_async() {
|
||||
// Feature gate `async ||` closures.
|
||||
self.sess.async_closure_spans.borrow_mut().push(self.prev_span);
|
||||
}
|
||||
|
||||
let capture_clause = self.parse_capture_clause();
|
||||
let decl = self.parse_fn_block_decl()?;
|
||||
let decl_hi = self.prev_span;
|
||||
let body = match decl.output {
|
||||
@ -3257,7 +3260,7 @@ impl<'a> Parser<'a> {
|
||||
attrs))
|
||||
}
|
||||
|
||||
// `else` token already eaten
|
||||
/// `else` token already eaten
|
||||
fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
|
||||
if self.eat_keyword(kw::If) {
|
||||
return self.parse_if_expr(ThinVec::new());
|
||||
@ -3306,7 +3309,7 @@ impl<'a> Parser<'a> {
|
||||
Ok(self.mk_expr(span, ExprKind::While(cond, body, opt_label), attrs))
|
||||
}
|
||||
|
||||
// parse `loop {...}`, `loop` token already eaten
|
||||
/// Parse `loop {...}`, `loop` token already eaten.
|
||||
fn parse_loop_expr(&mut self, opt_label: Option<Label>,
|
||||
span_lo: Span,
|
||||
mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
|
||||
@ -3316,17 +3319,20 @@ impl<'a> Parser<'a> {
|
||||
Ok(self.mk_expr(span, ExprKind::Loop(body, opt_label), attrs))
|
||||
}
|
||||
|
||||
/// Parses an `async move {...}` expression.
|
||||
pub fn parse_async_block(&mut self, mut attrs: ThinVec<Attribute>)
|
||||
-> PResult<'a, P<Expr>>
|
||||
{
|
||||
let span_lo = self.token.span;
|
||||
self.expect_keyword(kw::Async)?;
|
||||
let capture_clause = if self.eat_keyword(kw::Move) {
|
||||
/// Parse an optional `move` prefix to a closure lke construct.
|
||||
fn parse_capture_clause(&mut self) -> CaptureBy {
|
||||
if self.eat_keyword(kw::Move) {
|
||||
CaptureBy::Value
|
||||
} else {
|
||||
CaptureBy::Ref
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses an `async move? {...}` expression.
|
||||
pub fn parse_async_block(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
|
||||
let span_lo = self.token.span;
|
||||
self.expect_keyword(kw::Async)?;
|
||||
let capture_clause = self.parse_capture_clause();
|
||||
let (iattrs, body) = self.parse_inner_attrs_and_block()?;
|
||||
attrs.extend(iattrs);
|
||||
Ok(self.mk_expr(
|
||||
|
@ -146,6 +146,7 @@ symbols! {
|
||||
associated_type_defaults,
|
||||
associated_types,
|
||||
async_await,
|
||||
async_closure,
|
||||
attr,
|
||||
attributes,
|
||||
attr_literals,
|
||||
|
@ -70,13 +70,6 @@ fn async_nonmove_block(x: u8) -> impl Future<Output = u8> {
|
||||
}
|
||||
}
|
||||
|
||||
fn async_closure(x: u8) -> impl Future<Output = u8> {
|
||||
(async move |x: u8| -> u8 {
|
||||
wake_and_yield_once().await;
|
||||
x
|
||||
})(x)
|
||||
}
|
||||
|
||||
async fn async_fn(x: u8) -> u8 {
|
||||
wake_and_yield_once().await;
|
||||
x
|
||||
@ -180,7 +173,6 @@ fn main() {
|
||||
test! {
|
||||
async_block,
|
||||
async_nonmove_block,
|
||||
async_closure,
|
||||
async_fn,
|
||||
generic_async_fn,
|
||||
async_fn_with_internal_borrow,
|
||||
|
12
src/test/ui/async-await/async-closure-matches-expr.rs
Normal file
12
src/test/ui/async-await/async-closure-matches-expr.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// compile-pass
|
||||
// edition:2018
|
||||
|
||||
#![feature(async_await, async_closure)]
|
||||
|
||||
macro_rules! match_expr {
|
||||
($x:expr) => {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match_expr!(async || {});
|
||||
}
|
81
src/test/ui/async-await/async-closure.rs
Normal file
81
src/test/ui/async-await/async-closure.rs
Normal file
@ -0,0 +1,81 @@
|
||||
// run-pass
|
||||
|
||||
// edition:2018
|
||||
// aux-build:arc_wake.rs
|
||||
|
||||
#![feature(async_await, async_closure)]
|
||||
|
||||
extern crate arc_wake;
|
||||
|
||||
use std::pin::Pin;
|
||||
use std::future::Future;
|
||||
use std::sync::{
|
||||
Arc,
|
||||
atomic::{self, AtomicUsize},
|
||||
};
|
||||
use std::task::{Context, Poll};
|
||||
use arc_wake::ArcWake;
|
||||
|
||||
struct Counter {
|
||||
wakes: AtomicUsize,
|
||||
}
|
||||
|
||||
impl ArcWake for Counter {
|
||||
fn wake(self: Arc<Self>) {
|
||||
Self::wake_by_ref(&self)
|
||||
}
|
||||
fn wake_by_ref(arc_self: &Arc<Self>) {
|
||||
arc_self.wakes.fetch_add(1, atomic::Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
struct WakeOnceThenComplete(bool);
|
||||
|
||||
fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
|
||||
|
||||
impl Future for WakeOnceThenComplete {
|
||||
type Output = ();
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
|
||||
if self.0 {
|
||||
Poll::Ready(())
|
||||
} else {
|
||||
cx.waker().wake_by_ref();
|
||||
self.0 = true;
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn async_closure(x: u8) -> impl Future<Output = u8> {
|
||||
(async move |x: u8| -> u8 {
|
||||
wake_and_yield_once().await;
|
||||
x
|
||||
})(x)
|
||||
}
|
||||
|
||||
fn test_future_yields_once_then_returns<F, Fut>(f: F)
|
||||
where
|
||||
F: FnOnce(u8) -> Fut,
|
||||
Fut: Future<Output = u8>,
|
||||
{
|
||||
let mut fut = Box::pin(f(9));
|
||||
let counter = Arc::new(Counter { wakes: AtomicUsize::new(0) });
|
||||
let waker = ArcWake::into_waker(counter.clone());
|
||||
let mut cx = Context::from_waker(&waker);
|
||||
assert_eq!(0, counter.wakes.load(atomic::Ordering::SeqCst));
|
||||
assert_eq!(Poll::Pending, fut.as_mut().poll(&mut cx));
|
||||
assert_eq!(1, counter.wakes.load(atomic::Ordering::SeqCst));
|
||||
assert_eq!(Poll::Ready(9), fut.as_mut().poll(&mut cx));
|
||||
}
|
||||
|
||||
fn main() {
|
||||
macro_rules! test {
|
||||
($($fn_name:expr,)*) => { $(
|
||||
test_future_yields_once_then_returns($fn_name);
|
||||
)* }
|
||||
}
|
||||
|
||||
test! {
|
||||
async_closure,
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// build-pass (FIXME(62277): could be check-pass?)
|
||||
// edition:2018
|
||||
|
||||
#![feature(async_await, await_macro)]
|
||||
#![feature(async_await)]
|
||||
|
||||
macro_rules! match_expr {
|
||||
($x:expr) => {}
|
||||
@ -9,5 +9,4 @@ macro_rules! match_expr {
|
||||
|
||||
fn main() {
|
||||
match_expr!(async {});
|
||||
match_expr!(async || {});
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// edition:2018
|
||||
// aux-build:arc_wake.rs
|
||||
|
||||
#![feature(async_await, await_macro)]
|
||||
#![feature(async_await, async_closure, await_macro)]
|
||||
|
||||
extern crate arc_wake;
|
||||
|
||||
|
8
src/test/ui/async-await/feature-async-closure.rs
Normal file
8
src/test/ui/async-await/feature-async-closure.rs
Normal file
@ -0,0 +1,8 @@
|
||||
// edition:2018
|
||||
// gate-test-async_closure
|
||||
|
||||
fn f() {
|
||||
let _ = async || {}; //~ ERROR async closures are unstable
|
||||
}
|
||||
|
||||
fn main() {}
|
12
src/test/ui/async-await/feature-async-closure.stderr
Normal file
12
src/test/ui/async-await/feature-async-closure.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0658]: async closures are unstable
|
||||
--> $DIR/feature-async-closure.rs:5:13
|
||||
|
|
||||
LL | let _ = async || {};
|
||||
| ^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/62290
|
||||
= help: add #![feature(async_closure)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -11,8 +11,6 @@ fn main() {
|
||||
//~^ 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
|
@ -1,5 +1,5 @@
|
||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||
--> $DIR/issue-62009.rs:8:5
|
||||
--> $DIR/issue-62009-1.rs:8:5
|
||||
|
|
||||
LL | fn main() {
|
||||
| ---- this is not `async`
|
||||
@ -7,7 +7,7 @@ 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
|
||||
--> $DIR/issue-62009-1.rs:10:5
|
||||
|
|
||||
LL | fn main() {
|
||||
| ---- this is not `async`
|
||||
@ -19,16 +19,7 @@ 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
|
||||
--> $DIR/issue-62009-1.rs:14:5
|
||||
|
|
||||
LL | fn main() {
|
||||
| ---- this is not `async`
|
||||
@ -36,14 +27,14 @@ LL | fn main() {
|
||||
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
|
||||
error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]: std::future::Future` is not satisfied
|
||||
--> $DIR/issue-62009-1.rs:14:5
|
||||
|
|
||||
LL | (|_| 2333).await;
|
||||
| ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009.rs:16:5: 16:15]`
|
||||
| ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]`
|
||||
|
|
||||
= note: required by `std::future::poll_with_tls_context`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
10
src/test/ui/async-await/issues/issue-62009-2.rs
Normal file
10
src/test/ui/async-await/issues/issue-62009-2.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// edition:2018
|
||||
|
||||
#![feature(async_await, async_closure)]
|
||||
|
||||
async fn print_dur() {}
|
||||
|
||||
fn main() {
|
||||
(async || 2333)().await;
|
||||
//~^ ERROR `await` is only allowed inside `async` functions and blocks
|
||||
}
|
10
src/test/ui/async-await/issues/issue-62009-2.stderr
Normal file
10
src/test/ui/async-await/issues/issue-62009-2.stderr
Normal file
@ -0,0 +1,10 @@
|
||||
error[E0728]: `await` is only allowed inside `async` functions and blocks
|
||||
--> $DIR/issue-62009-2.rs:8:5
|
||||
|
|
||||
LL | fn main() {
|
||||
| ---- this is not `async`
|
||||
LL | (async || 2333)().await;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,6 +1,6 @@
|
||||
// edition:2018
|
||||
|
||||
#![feature(async_await, await_macro)]
|
||||
#![feature(async_await, async_closure, await_macro)]
|
||||
|
||||
fn main() {
|
||||
let _ = async |x: u8| {};
|
||||
|
23
src/test/ui/async-await/suggest-missing-await-closure.fixed
Normal file
23
src/test/ui/async-await/suggest-missing-await-closure.fixed
Normal file
@ -0,0 +1,23 @@
|
||||
// edition:2018
|
||||
// run-rustfix
|
||||
|
||||
#![feature(async_await, async_closure)]
|
||||
|
||||
fn take_u32(_x: u32) {}
|
||||
|
||||
async fn make_u32() -> u32 {
|
||||
22
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
async fn suggest_await_in_async_closure() {
|
||||
async || {
|
||||
let x = make_u32();
|
||||
take_u32(x.await)
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~| HELP consider using `.await` here
|
||||
//~| SUGGESTION x.await
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
23
src/test/ui/async-await/suggest-missing-await-closure.rs
Normal file
23
src/test/ui/async-await/suggest-missing-await-closure.rs
Normal file
@ -0,0 +1,23 @@
|
||||
// edition:2018
|
||||
// run-rustfix
|
||||
|
||||
#![feature(async_await, async_closure)]
|
||||
|
||||
fn take_u32(_x: u32) {}
|
||||
|
||||
async fn make_u32() -> u32 {
|
||||
22
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
async fn suggest_await_in_async_closure() {
|
||||
async || {
|
||||
let x = make_u32();
|
||||
take_u32(x)
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~| HELP consider using `.await` here
|
||||
//~| SUGGESTION x.await
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
15
src/test/ui/async-await/suggest-missing-await-closure.stderr
Normal file
15
src/test/ui/async-await/suggest-missing-await-closure.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/suggest-missing-await-closure.rs:16:18
|
||||
|
|
||||
LL | take_u32(x)
|
||||
| ^
|
||||
| |
|
||||
| expected u32, found opaque type
|
||||
| help: consider using `.await` here: `x.await`
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found type `impl std::future::Future`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -18,15 +18,4 @@ async fn suggest_await_in_async_fn() {
|
||||
//~| SUGGESTION x.await
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
async fn suggest_await_in_async_closure() {
|
||||
async || {
|
||||
let x = make_u32();
|
||||
take_u32(x.await)
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~| HELP consider using `.await` here
|
||||
//~| SUGGESTION x.await
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -18,15 +18,4 @@ async fn suggest_await_in_async_fn() {
|
||||
//~| SUGGESTION x.await
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
async fn suggest_await_in_async_closure() {
|
||||
async || {
|
||||
let x = make_u32();
|
||||
take_u32(x)
|
||||
//~^ ERROR mismatched types [E0308]
|
||||
//~| HELP consider using `.await` here
|
||||
//~| SUGGESTION x.await
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -10,18 +10,6 @@ LL | take_u32(x)
|
||||
= note: expected type `u32`
|
||||
found type `impl std::future::Future`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/suggest-missing-await.rs:25:18
|
||||
|
|
||||
LL | take_u32(x)
|
||||
| ^
|
||||
| |
|
||||
| expected u32, found opaque type
|
||||
| help: consider using `.await` here: `x.await`
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found type `impl std::future::Future`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -15,5 +15,4 @@ async fn foo() {} //~ ERROR async fn is unstable
|
||||
|
||||
fn main() {
|
||||
let _ = async {}; //~ ERROR async blocks are unstable
|
||||
let _ = async || {}; //~ ERROR async closures are unstable
|
||||
}
|
||||
|
@ -40,15 +40,6 @@ LL | let _ = async {};
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/50547
|
||||
= help: add #![feature(async_await)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: async closures are unstable
|
||||
--> $DIR/feature-gate-async-await.rs:18:13
|
||||
|
|
||||
LL | let _ = async || {};
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/50547
|
||||
= help: add #![feature(async_await)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user