Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilize async closures (RFC 3668) #132706

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,9 +511,9 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
);
gate_all!(let_chains, "`let` expressions in this position are unstable");
gate_all!(
async_closure,
"async closures are unstable",
"to use an async block, remove the `||`: `async {`"
async_trait_bounds,
"`async` trait bounds are unstable",
"use the desugared name of the async trait, such as `AsyncFn`"
);
gate_all!(async_for_loop, "`for await` loops are experimental");
gate_all!(
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_error_codes/src/error_codes/E0708.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
Erroneous code example:

```edition2018
#![feature(async_closure)]
fn main() {
let add_one = async |num: u8| {
num + 1
Expand All @@ -18,8 +16,6 @@ fn main() {
version, you can use successfully by using move:

```edition2018
#![feature(async_closure)]
fn main() {
let add_one = async move |num: u8| { // ok!
num + 1
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ declare_features! (
(accepted, associated_types, "1.0.0", None),
/// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
(accepted, async_await, "1.39.0", Some(50547)),
/// Allows `async || body` closures.
(accepted, async_closure, "CURRENT_RUSTC_VERSION", Some(62290)),
/// Allows async functions to be declared, implemented, and used in traits.
(accepted, async_fn_in_trait, "1.75.0", Some(91611)),
/// Allows all literals in attribute lists and values of key-value pairs.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,12 +381,12 @@ declare_features! (
(unstable, associated_const_equality, "1.58.0", Some(92827)),
/// Allows associated type defaults.
(unstable, associated_type_defaults, "1.2.0", Some(29661)),
/// Allows `async || body` closures.
(unstable, async_closure, "1.37.0", Some(62290)),
/// Allows `#[track_caller]` on async functions.
(unstable, async_fn_track_caller, "1.73.0", Some(110011)),
/// Allows `for await` loops.
(unstable, async_for_loop, "1.77.0", Some(118898)),
/// Allows `async` trait bound modifier.
(unstable, async_trait_bounds, "CURRENT_RUSTC_VERSION", Some(62290)),
/// Allows using C-variadics.
(unstable, c_variadic, "1.34.0", Some(44930)),
/// Allows the use of `#[cfg(<true/false>)]`.
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_hir_typeck/src/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1826,7 +1826,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// captured by move.
///
/// ```rust
/// #![feature(async_closure)]
/// let x = &1i32; // Let's call this lifetime `'1`.
/// let c = async move || {
/// println!("{:?}", *x);
Expand All @@ -1841,7 +1840,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// child capture with the lifetime of the parent coroutine-closure's env.
///
/// ```rust
/// #![feature(async_closure)]
/// let mut x = 1i32;
/// let c = async || {
/// x = 1;
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_lint/src/async_closures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ declare_lint! {
/// ### Example
///
/// ```rust
/// #![feature(async_closure)]
/// #![warn(closure_returning_async_block)]
/// let c = |x: &str| async {};
/// ```
Expand Down Expand Up @@ -40,8 +39,6 @@ declare_lint! {
/// But it does work with async closures:
///
/// ```rust
/// #![feature(async_closure)]
///
/// async fn callback(x: &str) {}
///
/// let captured_str = String::new();
Expand All @@ -52,7 +49,6 @@ declare_lint! {
pub CLOSURE_RETURNING_ASYNC_BLOCK,
Allow,
"closure that returns `async {}` could be rewritten as an async closure",
@feature_gate = async_closure;
}

declare_lint_pass!(
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
//!
//! Consider an async closure like:
//! ```rust
//! #![feature(async_closure)]
//!
//! let x = vec![1, 2, 3];
//!
//! let closure = async move || {
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2362,10 +2362,7 @@ impl<'a> Parser<'a> {
};

match coroutine_kind {
Some(CoroutineKind::Async { span, .. }) => {
// Feature-gate `async ||` closures.
self.psess.gated_spans.gate(sym::async_closure, span);
}
Some(CoroutineKind::Async { .. }) => {}
Some(CoroutineKind::Gen { span, .. }) | Some(CoroutineKind::AsyncGen { span, .. }) => {
// Feature-gate `gen ||` and `async gen ||` closures.
// FIXME(gen_blocks): This perhaps should be a different gate.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,7 @@ impl<'a> Parser<'a> {
let asyncness = if self.token.uninterpolated_span().at_least_rust_2018()
&& self.eat_keyword(kw::Async)
{
self.psess.gated_spans.gate(sym::async_closure, self.prev_token.span);
self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
BoundAsyncness::Async(self.prev_token.span)
} else if self.may_recover()
&& self.token.uninterpolated_span().is_rust_2015()
Expand All @@ -954,7 +954,7 @@ impl<'a> Parser<'a> {
span: self.prev_token.span,
help: HelpUseLatestEdition::new(),
});
self.psess.gated_spans.gate(sym::async_closure, self.prev_token.span);
self.psess.gated_spans.gate(sym::async_trait_bounds, self.prev_token.span);
BoundAsyncness::Async(self.prev_token.span)
} else {
BoundAsyncness::Normal
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ symbols! {
async_for_loop,
async_iterator,
async_iterator_poll_next,
async_trait_bounds,
atomic,
atomic_mod,
atomics,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
closure_def_id,
found_kind,
expected_kind,
"async ",
"Async",
);
self.note_obligation_cause(&mut err, &obligation);
self.point_at_returns_when_relevant(&mut err, &obligation);
Expand Down
9 changes: 6 additions & 3 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1982,7 +1982,8 @@ impl<Args: Tuple, F: Fn<Args> + ?Sized, A: Allocator> Fn<Args> for Box<F, A> {
}
}

#[unstable(feature = "async_fn_traits", issue = "none")]
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
impl<Args: Tuple, F: AsyncFnOnce<Args> + ?Sized, A: Allocator> AsyncFnOnce<Args> for Box<F, A> {
type Output = F::Output;
type CallOnceFuture = F::CallOnceFuture;
Expand All @@ -1992,7 +1993,8 @@ impl<Args: Tuple, F: AsyncFnOnce<Args> + ?Sized, A: Allocator> AsyncFnOnce<Args>
}
}

#[unstable(feature = "async_fn_traits", issue = "none")]
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
impl<Args: Tuple, F: AsyncFnMut<Args> + ?Sized, A: Allocator> AsyncFnMut<Args> for Box<F, A> {
type CallRefFuture<'a>
= F::CallRefFuture<'a>
Expand All @@ -2004,7 +2006,8 @@ impl<Args: Tuple, F: AsyncFnMut<Args> + ?Sized, A: Allocator> AsyncFnMut<Args> f
}
}

#[unstable(feature = "async_fn_traits", issue = "none")]
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
impl<Args: Tuple, F: AsyncFn<Args> + ?Sized, A: Allocator> AsyncFn<Args> for Box<F, A> {
extern "rust-call" fn async_call(&self, args: Args) -> Self::CallRefFuture<'_> {
F::async_call(self, args)
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
//
// Library features:
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(async_closure))]
#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_len))]
#![cfg_attr(test, feature(str_as_str))]
Expand All @@ -101,7 +102,6 @@
#![feature(array_windows)]
#![feature(ascii_char)]
#![feature(assert_matches)]
#![feature(async_closure)]
#![feature(async_fn_traits)]
#![feature(async_iterator)]
#![feature(box_uninit_write)]
Expand Down
24 changes: 16 additions & 8 deletions library/core/src/ops/async_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use crate::marker::Tuple;
/// An async-aware version of the [`Fn`](crate::ops::Fn) trait.
///
/// All `async fn` and functions returning futures implement this trait.
#[unstable(feature = "async_closure", issue = "62290")]
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
#[rustc_paren_sugar]
#[fundamental]
#[must_use = "async closures are lazy and do nothing unless called"]
Expand All @@ -18,7 +19,8 @@ pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
/// An async-aware version of the [`FnMut`](crate::ops::FnMut) trait.
///
/// All `async fn` and functions returning futures implement this trait.
#[unstable(feature = "async_closure", issue = "62290")]
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
#[rustc_paren_sugar]
#[fundamental]
#[must_use = "async closures are lazy and do nothing unless called"]
Expand All @@ -39,7 +41,8 @@ pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
/// An async-aware version of the [`FnOnce`](crate::ops::FnOnce) trait.
///
/// All `async fn` and functions returning futures implement this trait.
#[unstable(feature = "async_closure", issue = "62290")]
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
#[rustc_paren_sugar]
#[fundamental]
#[must_use = "async closures are lazy and do nothing unless called"]
Expand All @@ -64,7 +67,8 @@ mod impls {
use super::{AsyncFn, AsyncFnMut, AsyncFnOnce};
use crate::marker::Tuple;

#[unstable(feature = "async_fn_traits", issue = "none")]
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
impl<A: Tuple, F: ?Sized> AsyncFn<A> for &F
where
F: AsyncFn<A>,
Expand All @@ -74,7 +78,8 @@ mod impls {
}
}

#[unstable(feature = "async_fn_traits", issue = "none")]
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
impl<A: Tuple, F: ?Sized> AsyncFnMut<A> for &F
where
F: AsyncFn<A>,
Expand All @@ -89,7 +94,8 @@ mod impls {
}
}

#[unstable(feature = "async_fn_traits", issue = "none")]
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce<A> for &'a F
where
F: AsyncFn<A>,
Expand All @@ -102,7 +108,8 @@ mod impls {
}
}

#[unstable(feature = "async_fn_traits", issue = "none")]
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
impl<A: Tuple, F: ?Sized> AsyncFnMut<A> for &mut F
where
F: AsyncFnMut<A>,
Expand All @@ -117,7 +124,8 @@ mod impls {
}
}

#[unstable(feature = "async_fn_traits", issue = "none")]
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
impl<'a, A: Tuple, F: ?Sized> AsyncFnOnce<A> for &'a mut F
where
F: AsyncFnMut<A>,
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/prelude/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ pub use crate::marker::{Send, Sized, Sync, Unpin};
#[stable(feature = "rust1", since = "1.0.0")]
#[doc(no_inline)]
pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
#[cfg_attr(bootstrap, unstable(feature = "async_closure", issue = "62290"))]
#[cfg_attr(not(bootstrap), stable(feature = "async_closure", since = "CURRENT_RUSTC_VERSION"))]
#[doc(no_inline)]
pub use crate::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce};

// Re-exported functions
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui-internal/author/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#![allow(redundant_semicolons, clippy::no_effect)]
#![feature(stmt_expr_attributes)]
#![feature(async_closure)]

#[rustfmt::skip]
fn main() {
Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/async_yields_async.fixed
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(async_closure)]
#![warn(clippy::async_yields_async)]
#![allow(clippy::redundant_async_block)]

Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/async_yields_async.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(async_closure)]
#![warn(clippy::async_yields_async)]
#![allow(clippy::redundant_async_block)]

Expand Down
12 changes: 6 additions & 6 deletions src/tools/clippy/tests/ui/async_yields_async.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: an async construct yields a type which is itself awaitable
--> tests/ui/async_yields_async.rs:38:9
--> tests/ui/async_yields_async.rs:37:9
|
LL | let _h = async {
| _____________________-
Expand All @@ -20,7 +20,7 @@ LL + }.await
|

error: an async construct yields a type which is itself awaitable
--> tests/ui/async_yields_async.rs:43:9
--> tests/ui/async_yields_async.rs:42:9
|
LL | let _i = async {
| ____________________-
Expand All @@ -33,7 +33,7 @@ LL | | };
| |_____- outer async construct

error: an async construct yields a type which is itself awaitable
--> tests/ui/async_yields_async.rs:49:9
--> tests/ui/async_yields_async.rs:48:9
|
LL | let _j = async || {
| ________________________-
Expand All @@ -52,7 +52,7 @@ LL + }.await
|

error: an async construct yields a type which is itself awaitable
--> tests/ui/async_yields_async.rs:54:9
--> tests/ui/async_yields_async.rs:53:9
|
LL | let _k = async || {
| _______________________-
Expand All @@ -65,7 +65,7 @@ LL | | };
| |_____- outer async construct

error: an async construct yields a type which is itself awaitable
--> tests/ui/async_yields_async.rs:56:23
--> tests/ui/async_yields_async.rs:55:23
|
LL | let _l = async || CustomFutureType;
| ^^^^^^^^^^^^^^^^
Expand All @@ -75,7 +75,7 @@ LL | let _l = async || CustomFutureType;
| help: consider awaiting this value: `CustomFutureType.await`

error: an async construct yields a type which is itself awaitable
--> tests/ui/async_yields_async.rs:62:9
--> tests/ui/async_yields_async.rs:61:9
|
LL | let _m = async || {
| _______________________-
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(async_closure)]
#![warn(clippy::redundant_closure_call)]
#![allow(clippy::redundant_async_block)]
#![allow(clippy::type_complexity)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(async_closure)]
#![warn(clippy::redundant_closure_call)]
#![allow(clippy::redundant_async_block)]
#![allow(clippy::type_complexity)]
Expand Down
Loading