Auto merge of #132706 - compiler-errors:async-closures, r=oli-obk
Stabilize async closures (RFC 3668)
# Async Closures Stabilization Report
This report proposes the stabilization of `#![feature(async_closure)]` ([RFC 3668](https://rust-lang.github.io/rfcs/3668-async-closures.html)). This is a long-awaited feature that increases the expressiveness of the Rust language and fills a pressing gap in the async ecosystem.
## Stabilization summary
* You can write async closures like `async || {}` which return futures that can borrow from their captures and can be higher-ranked in their argument lifetimes.
* You can express trait bounds for these async closures using the `AsyncFn` family of traits, analogous to the `Fn` family.
```rust
async fn takes_an_async_fn(f: impl AsyncFn(&str)) {
futures::join(f("hello"), f("world")).await;
}
takes_an_async_fn(async |s| { other_fn(s).await }).await;
```
## Motivation
Without this feature, users hit two major obstacles when writing async code that uses closures and `Fn` trait bounds:
- The inability to express higher-ranked async function signatures.
- That closures cannot return futures that borrow from the closure captures.
That is, for the first, we cannot write:
```rust
// We cannot express higher-ranked async function signatures.
async fn f<Fut>(_: impl for<'a> Fn(&'a u8) -> Fut)
where
Fut: Future<Output = ()>,
{ todo!() }
async fn main() {
async fn g(_: &u8) { todo!() }
f(g).await;
//~^ ERROR mismatched types
//~| ERROR one type is more general than the other
}
```
And for the second, we cannot write:
```rust
// Closures cannot return futures that borrow closure captures.
async fn f<Fut: Future<Output = ()>>(_: impl FnMut() -> Fut)
{ todo!() }
async fn main() {
let mut xs = vec![];
f(|| async {
async fn g() -> u8 { todo!() }
xs.push(g().await);
});
//~^ ERROR captured variable cannot escape `FnMut` closure body
}
```
Async closures provide a first-class solution to these problems.
For further background, please refer to the [motivation section](https://rust-lang.github.io/rfcs/3668-async-closures.html#motivation) of the RFC.
## Major design decisions since RFC
The RFC had left open the question of whether we would spell the bounds syntax for async closures...
```rust
// ...as this...
fn f() -> impl AsyncFn() -> u8 { todo!() }
// ...or as this:
fn f() -> impl async Fn() -> u8 { todo!() }
```
We've decided to spell this as `AsyncFn{,Mut,Once}`.
The `Fn` family of traits is special in many ways. We had originally argued that, due to this specialness, that perhaps the `async Fn` syntax could be adopted without having to decide whether a general `async Trait` mechanism would ever be adopted. However, concerns have been raised that we may not want to use `async Fn` syntax unless we would pursue more general trait modifiers. Since there remain substantial open questions on those -- and we don't want to rush any design work there -- it makes sense to ship this needed feature using the `AsyncFn`-style bounds syntax.
Since we would, in no case, be shipping a generalized trait modifier system anytime soon, we'll be continuing to see `AsyncFoo` traits appear across the ecosystem regardless. If we were to ever later ship some general mechanism, we could at that time manage the migration from `AsyncFn` to `async Fn`, just as we'd be enabling and managing the migration of many other traits.
Note that, as specified in RFC 3668, the details of the `AsyncFn*` traits are not exposed and they can only be named via the "parentheses sugar". That is, we can write `T: AsyncFn() -> u8` but not `T: AsyncFn<Output = u8>`.
Unlike the `Fn` traits, we cannot project to the `Output` associated type of the `AsyncFn` traits. That is, while we can write...
```rust
fn f<F: Fn() -> u8>(_: F::Output) {}
```
...we cannot write:
```rust
fn f<F: AsyncFn() -> u8>(_: F::Output) {}
//~^ ERROR
```
The choice of `AsyncFn{,Mut,Once}` bounds syntax obviates, for our purposes here, another question decided after that RFC, which was how to order bound modifiers such as `for<'a> async Fn()`.
Other than answering the open question in the RFC on syntax, nothing has changed about the design of this feature between RFC 3668 and this stabilization.
## What is stabilized
For those interested in the technical details, please see [the dev guide section](https://rustc-dev-guide.rust-lang.org/coroutine-closures.html) I authored.
#### Async closures
Other than in how they solve the problems described above, async closures act similarly to closures that return async blocks, and can have parts of their signatures specified:
```rust
// They can have arguments annotated with types:
let _ = async |_: u8| { todo!() };
// They can have their return types annotated:
let _ = async || -> u8 { todo!() };
// They can be higher-ranked:
let _ = async |_: &str| { todo!() };
// They can capture values by move:
let x = String::from("hello, world");
let _ = async move || do_something(&x).await };
```
When called, they return an anonymous future type corresponding to the (not-yet-executed) body of the closure. These can be awaited like any other future.
What distinguishes async closures is that, unlike closures that return async blocks, the futures returned from the async closure can capture state from the async closure. For example:
```rust
let vec: Vec<String> = vec![];
let closure = async || {
vec.push(ready(String::from("")).await);
};
```
The async closure captures `vec` with some `&'closure mut Vec<String>` which lives until the closure is dropped. Every call to `closure()` returns a future which reborrows that mutable reference `&'call mut Vec<String>` which lives until the future is dropped (e.g. it is `await`ed).
As another example:
```rust
let string: String = "Hello, world".into();
let closure = async move || {
ready(&string).await;
};
```
The closure is marked with `move`, which means it takes ownership of the string by *value*. The future that is returned by calling `closure()` returns a future which borrows a reference `&'call String` which lives until the future is dropped (e.g. it is `await`ed).
#### Async fn trait family
To support the lending capability of async closures, and to provide a first-class way to express higher-ranked async closures, we introduce the `AsyncFn*` family of traits. See the [corresponding section](https://rust-lang.github.io/rfcs/3668-async-closures.html#asyncfn) of the RFC.
We stabilize naming `AsyncFn*` via the "parenthesized sugar" syntax that normal `Fn*` traits can be named. The `AsyncFn*` trait can be used anywhere a `Fn*` trait bound is allowed, such as:
```rust
/// In return-position impl trait:
fn closure() -> impl AsyncFn() { async || {} }
/// In trait bounds:
trait Foo<F>: Sized
where
F: AsyncFn()
{
fn new(f: F) -> Self;
}
/// in GATs:
trait Gat {
type AsyncHasher<T>: AsyncFn(T) -> i32;
}
```
Other than using them in trait bounds, the definitions of these traits are not directly observable, but certain aspects of their behavior can be indirectly observed such as the fact that:
* `AsyncFn::async_call` and `AsyncFnMut::async_call_mut` return a future which is *lending*, and therefore borrows the `&self` lifetime of the callee.
```rust
fn by_ref_call(c: impl AsyncFn()) {
let fut = c();
drop(c);
// ^ Cannot drop `c` since it is borrowed by `fut`.
}
```
* `AsyncFnOnce::async_call_once` returns a future that takes ownership of the callee.
```rust
fn by_ref_call(c: impl AsyncFnOnce()) {
let fut = c();
let _ = c();
// ^ Cannot call `c` since calling it takes ownership the callee.
}
```
* All currently-stable callable types (i.e., closures, function items, function pointers, and `dyn Fn*` trait objects) automatically implement `AsyncFn*() -> T` if they implement `Fn*() -> Fut` for some output type `Fut`, and `Fut` implements `Future<Output = T>`.
* This is to make sure that `AsyncFn*()` trait bounds have maximum compatibility with existing callable types which return futures, such as async function items and closures which return boxed futures.
* For now, this only works currently for *concrete* callable types -- for example, a argument-position impl trait like `impl Fn() -> impl Future<Output = ()>` does not implement `AsyncFn()`, due to the fact that a `AsyncFn`-if-`Fn` blanket impl does not exist in reality. This may be relaxed in the future. Users can work around this by wrapping their type in an async closure and calling it. I expect this to not matter much in practice, as users are encouraged to write `AsyncFn` bounds directly.
```rust
fn is_async_fn(_: impl AsyncFn(&str)) {}
async fn async_fn_item(s: &str) { todo!() }
is_async_fn(s);
// ^^^ This works.
fn generic(f: impl Fn() -> impl Future<Output = ()>) {
is_async_fn(f);
// ^^^ This does not work (yet).
}
```
#### The by-move future
When async closures are called with `AsyncFn`/`AsyncFnMut`, they return a coroutine that borrows from the closure. However, when they are called via `AsyncFnOnce`, we consume that closure, and cannot return a coroutine that borrows from data that is now dropped.
To work around around this limitation, we synthesize a separate future type for calling the async closure via `AsyncFnOnce`.
This future executes identically to the by-ref future returned from calling the async closure, except for the fact that it has a different set of captures, since we must *move* the captures from the parent async into the child future.
#### Interactions between async closures and the `Fn*` family of traits
Async closures always implement `FnOnce`, since they always can be called once. They may also implement `Fn` or `FnMut` if their body is compatible with the calling mode (i.e. if they do not mutate their captures, or they do not capture their captures, respectively) and if the future returned by the async closure is not *lending*.
```rust
let id = String::new();
let mapped: Vec</* impl Future */> =
[/* elements */]
.into_iter()
// `Iterator::map` takes an `impl FnMut`
.map(async |element| {
do_something(&id, element).await;
})
.collect();
```
See [the dev guide](https://rustc-dev-guide.rust-lang.org/coroutine-closures.html#follow-up-when-do-async-closures-implement-the-regular-fn-traits) for a detailed explanation for the situations where this may not be possible due to the lending nature of async closures.
#### Other notable features of async closures shared with synchronous closures
* Async closures are `Copy` and/or `Clone` if their captures are `Copy`/`Clone`.
* Async closures do closure signature inference: If an async closure is passed to a function with a `AsyncFn` or `Fn` trait bound, we can eagerly infer the argument types of the closure. More details are provided in [the dev guide](https://rustc-dev-guide.rust-lang.org/coroutine-closures.html#closure-signature-inference).
#### Lints
This PR also stabilizes the `CLOSURE_RETURNING_ASYNC_BLOCK` lint as an `allow` lint. This lints on "old-style" async closures:
```rust
#![warn(closure_returning_async_block)]
let c = |x: &str| async {};
```
We should encourage users to use `async || {}` where possible. This lint remains `allow` and may be refined in the future because it has a few false positives (namely, see: "Where do we expect rewriting `|| async {}` into `async || {}` to fail?")
An alternative that could be made at the time of stabilization is to put this lint behind another gate, so we can decide to stabilize it later.
## What isn't stabilized (aka, potential future work)
#### `async Fn*()` bound syntax
We decided to stabilize async closures without the `async Fn*()` bound modifier syntax. The general direction of this syntax and how it fits is still being considered by T-lang (e.g. in [RFC 3710](https://github.com/rust-lang/rfcs/pull/3710)).
#### Naming the futures returned by async closures
This stabilization PR does not provide a way of naming the futures returned by calling `AsyncFn*`.
Exposing a stable way to refer to these futures is important for building async-closure-aware combinators, and will be an important future step.
#### Return type notation-style bounds for async closures
The RFC described an RTN-like syntax for putting bounds on the future returned by an async closure:
```rust
async fn foo(x: F) -> Result<()>
where
F: AsyncFn(&str) -> Result<()>,
// The future from calling `F` is `Send` and `'static`.
F(..): Send + 'static,
{}
```
This stabilization PR does not stabilize that syntax yet, which remains unimplemented (though will be soon).
#### `dyn AsyncFn*()`
`AsyncFn*` are not dyn-compatible yet. This will likely be implemented in the future along with the dyn-compatibility of async fn in trait, since the same issue (dealing with the future returned by a call) applies there.
## Tests
Tests exist for this feature in [`tests/ui/async-await/async-closures`](5b54286640/tests/ui/async-await/async-closures
).
<details>
<summary>A selected set of tests:</summary>
* Lending behavior of async closures
* `tests/ui/async-await/async-closures/mutate.rs`
* `tests/ui/async-await/async-closures/captures.rs`
* `tests/ui/async-await/async-closures/precise-captures.rs`
* `tests/ui/async-await/async-closures/no-borrow-from-env.rs`
* Async closures may be higher-ranked
* `tests/ui/async-await/async-closures/higher-ranked.rs`
* `tests/ui/async-await/async-closures/higher-ranked-return.rs`
* Async closures may implement `Fn*` traits
* `tests/ui/async-await/async-closures/is-fn.rs`
* `tests/ui/async-await/async-closures/implements-fnmut.rs`
* Async closures may be cloned
* `tests/ui/async-await/async-closures/clone-closure.rs`
* Ownership of the upvars when `AsyncFnOnce` is called
* `tests/ui/async-await/async-closures/drop.rs`
* `tests/ui/async-await/async-closures/move-is-async-fn.rs`
* `tests/ui/async-await/async-closures/force-move-due-to-inferred-kind.rs`
* `tests/ui/async-await/async-closures/force-move-due-to-actually-fnonce.rs`
* Closure signature inference
* `tests/ui/async-await/async-closures/signature-deduction.rs`
* `tests/ui/async-await/async-closures/sig-from-bare-fn.rs`
* `tests/ui/async-await/async-closures/signature-inference-from-two-part-bound.rs`
</details>
## Remaining bugs and open issues
* https://github.com/rust-lang/rust/issues/120694 tracks moving onto more general `LendingFn*` traits. No action needed, since it's not observable.
* https://github.com/rust-lang/rust/issues/124020 - Polymorphization ICE. Polymorphization needs to be heavily reworked. No action needed.
* https://github.com/rust-lang/rust/issues/127227 - Tracking reworking the way that rustdoc re-sugars bounds.
* The part relevant to to `AsyncFn` is fixed by https://github.com/rust-lang/rust/pull/132697.
## Where do we expect rewriting `|| async {}` into `async || {}` to fail?
* Fn pointer coercions
* Currently, it is not possible to coerce an async closure to an fn pointer like regular closures can be. This functionality may be implemented in the future.
```rust
let x: fn() -> _ = async || {};
```
* Argument capture
* Like async functions, async closures always capture their input arguments. This is in contrast to something like `|t: T| async {}`, which doesn't capture `t` unless it is used in the async block. This may affect the `Send`-ness of the future or affect its outlives.
```rust
fn needs_send_future(_: impl Fn(NotSendArg) -> Fut)
where
Fut: Future<Output = ()>,
{}
needs_send_future(async |_| {});
```
## History
#### Important feature history
- https://github.com/rust-lang/rust/pull/51580
- https://github.com/rust-lang/rust/pull/62292
- https://github.com/rust-lang/rust/pull/120361
- https://github.com/rust-lang/rust/pull/120712
- https://github.com/rust-lang/rust/pull/121857
- https://github.com/rust-lang/rust/pull/123660
- https://github.com/rust-lang/rust/pull/125259
- https://github.com/rust-lang/rust/pull/128506
- https://github.com/rust-lang/rust/pull/127482
## Acknowledgements
Thanks to `@oli-obk` for reviewing the bulk of the work for this feature. Thanks to `@nikomatsakis` for his design blog posts which generated interest for this feature, `@traviscross` for feedback and additions to this stabilization report. All errors are my own.
r? `@ghost`
This commit is contained in:
commit
f4f0fafd0c
185 changed files with 314 additions and 555 deletions
|
@ -511,11 +511,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
|||
"you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`"
|
||||
);
|
||||
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 {`"
|
||||
);
|
||||
gate_all!(
|
||||
async_trait_bounds,
|
||||
"`async` trait bounds are unstable",
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
Erroneous code example:
|
||||
|
||||
```edition2018
|
||||
#![feature(async_closure)]
|
||||
|
||||
fn main() {
|
||||
let add_one = async |num: u8| {
|
||||
num + 1
|
||||
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -388,8 +388,6 @@ 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 async functions to be called from `dyn Trait`.
|
||||
(incomplete, async_fn_in_dyn_trait, "CURRENT_RUSTC_VERSION", Some(133119)),
|
||||
/// Allows `#[track_caller]` on async functions.
|
||||
|
|
|
@ -1840,7 +1840,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);
|
||||
|
@ -1855,7 +1854,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;
|
||||
|
|
|
@ -12,7 +12,6 @@ declare_lint! {
|
|||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(async_closure)]
|
||||
/// #![warn(closure_returning_async_block)]
|
||||
/// let c = |x: &str| async {};
|
||||
/// ```
|
||||
|
@ -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();
|
||||
|
@ -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!(
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
//!
|
||||
//! Consider an async closure like:
|
||||
//! ```rust
|
||||
//! #![feature(async_closure)]
|
||||
//!
|
||||
//! let x = vec![1, 2, 3];
|
||||
//!
|
||||
//! let closure = async move || {
|
||||
|
|
|
@ -2366,10 +2366,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.
|
||||
|
|
|
@ -1985,7 +1985,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;
|
||||
|
@ -1995,7 +1996,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>
|
||||
|
@ -2007,7 +2009,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)
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
//
|
||||
// Library features:
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(bootstrap, feature(async_closure))]
|
||||
#![cfg_attr(test, feature(str_as_str))]
|
||||
#![feature(alloc_layout_extra)]
|
||||
#![feature(allocator_api)]
|
||||
|
@ -99,7 +100,6 @@
|
|||
#![feature(array_windows)]
|
||||
#![feature(ascii_char)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(async_closure)]
|
||||
#![feature(async_fn_traits)]
|
||||
#![feature(async_iterator)]
|
||||
#![feature(box_uninit_write)]
|
||||
|
|
|
@ -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"]
|
||||
|
@ -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"]
|
||||
|
@ -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"]
|
||||
|
@ -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>,
|
||||
|
@ -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>,
|
||||
|
@ -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>,
|
||||
|
@ -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>,
|
||||
|
@ -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>,
|
||||
|
|
|
@ -12,7 +12,8 @@ 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};
|
||||
#[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"))]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::ops::{AsyncFn, AsyncFnMut, AsyncFnOnce};
|
||||
|
||||
|
|
|
@ -33,8 +33,9 @@
|
|||
//!
|
||||
//! * <code>[std::marker]::{[Copy], [Send], [Sized], [Sync], [Unpin]}</code>,
|
||||
//! marker traits that indicate fundamental properties of types.
|
||||
//! * <code>[std::ops]::{[Drop], [Fn], [FnMut], [FnOnce]}</code>, various
|
||||
//! operations for both destructors and overloading `()`.
|
||||
//! * <code>[std::ops]::{[Fn], [FnMut], [FnOnce]}</code>, and their analogous
|
||||
//! async traits, <code>[std::ops]::{[AsyncFn], [AsyncFnMut], [AsyncFnOnce]}</code>.
|
||||
//! * <code>[std::ops]::[Drop]</code>, for implementing destructors.
|
||||
//! * <code>[std::mem]::[drop]</code>, a convenience function for explicitly
|
||||
//! dropping a value.
|
||||
//! * <code>[std::mem]::{[size_of], [size_of_val]}</code>, to get the size of
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(async_closure)]
|
||||
#![warn(clippy::async_yields_async)]
|
||||
#![allow(clippy::redundant_async_block)]
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(async_closure)]
|
||||
#![warn(clippy::async_yields_async)]
|
||||
#![allow(clippy::redundant_async_block)]
|
||||
|
||||
|
|
|
@ -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 {
|
||||
| _____________________-
|
||||
|
@ -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 {
|
||||
| ____________________-
|
||||
|
@ -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 || {
|
||||
| ________________________-
|
||||
|
@ -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 || {
|
||||
| _______________________-
|
||||
|
@ -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;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
@ -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 || {
|
||||
| _______________________-
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#![allow(redundant_semicolons, clippy::no_effect)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(async_closure)]
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn main() {
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#![allow(clippy::never_loop)]
|
||||
#![warn(clippy::infinite_loop)]
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate proc_macros;
|
||||
use proc_macros::{external, with_span};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:14:5
|
||||
--> tests/ui/infinite_loops.rs:13:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -15,7 +15,7 @@ LL | fn no_break() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:21:5
|
||||
--> tests/ui/infinite_loops.rs:20:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -32,7 +32,7 @@ LL | fn all_inf() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:23:9
|
||||
--> tests/ui/infinite_loops.rs:22:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -49,7 +49,7 @@ LL | fn all_inf() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:25:13
|
||||
--> tests/ui/infinite_loops.rs:24:13
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -63,7 +63,7 @@ LL | fn all_inf() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:39:5
|
||||
--> tests/ui/infinite_loops.rs:38:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -74,7 +74,7 @@ LL | | }
|
|||
= help: if this is not intended, try adding a `break` or `return` condition in the loop
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:52:5
|
||||
--> tests/ui/infinite_loops.rs:51:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | | fn inner_fn() -> ! {
|
||||
|
@ -90,7 +90,7 @@ LL | fn no_break_never_ret_noise() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:95:5
|
||||
--> tests/ui/infinite_loops.rs:94:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -107,7 +107,7 @@ LL | fn break_inner_but_not_outer_1(cond: bool) -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:106:5
|
||||
--> tests/ui/infinite_loops.rs:105:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -124,7 +124,7 @@ LL | fn break_inner_but_not_outer_2(cond: bool) -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:120:9
|
||||
--> tests/ui/infinite_loops.rs:119:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -138,7 +138,7 @@ LL | fn break_outer_but_not_inner() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:143:9
|
||||
--> tests/ui/infinite_loops.rs:142:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -155,7 +155,7 @@ LL | fn break_wrong_loop(cond: bool) -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:183:5
|
||||
--> tests/ui/infinite_loops.rs:182:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -172,7 +172,7 @@ LL | fn match_like() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:224:5
|
||||
--> tests/ui/infinite_loops.rs:223:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -186,7 +186,7 @@ LL | fn match_like() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:229:5
|
||||
--> tests/ui/infinite_loops.rs:228:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -203,7 +203,7 @@ LL | fn match_like() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:334:9
|
||||
--> tests/ui/infinite_loops.rs:333:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -217,7 +217,7 @@ LL | fn problematic_trait_method() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:344:9
|
||||
--> tests/ui/infinite_loops.rs:343:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -231,7 +231,7 @@ LL | fn could_be_problematic() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:353:9
|
||||
--> tests/ui/infinite_loops.rs:352:9
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -245,7 +245,7 @@ LL | let _loop_forever = || -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:367:8
|
||||
--> tests/ui/infinite_loops.rs:366:8
|
||||
|
|
||||
LL | Ok(loop {
|
||||
| ________^
|
||||
|
@ -256,7 +256,7 @@ LL | | })
|
|||
= help: if this is not intended, try adding a `break` or `return` condition in the loop
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:409:5
|
||||
--> tests/ui/infinite_loops.rs:408:5
|
||||
|
|
||||
LL | / 'infinite: loop {
|
||||
LL | |
|
||||
|
@ -272,7 +272,7 @@ LL | fn continue_outer() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:416:5
|
||||
--> tests/ui/infinite_loops.rs:415:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
@ -289,7 +289,7 @@ LL | fn continue_outer() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:418:9
|
||||
--> tests/ui/infinite_loops.rs:417:9
|
||||
|
|
||||
LL | / 'inner: loop {
|
||||
LL | | loop {
|
||||
|
@ -304,7 +304,7 @@ LL | fn continue_outer() -> ! {
|
|||
| ++++
|
||||
|
||||
error: infinite loop detected
|
||||
--> tests/ui/infinite_loops.rs:426:5
|
||||
--> tests/ui/infinite_loops.rs:425:5
|
||||
|
|
||||
LL | / loop {
|
||||
LL | |
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(async_closure)]
|
||||
#![warn(clippy::redundant_closure_call)]
|
||||
#![allow(clippy::redundant_async_block)]
|
||||
#![allow(clippy::type_complexity)]
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(async_closure)]
|
||||
#![warn(clippy::redundant_closure_call)]
|
||||
#![allow(clippy::redundant_async_block)]
|
||||
#![allow(clippy::type_complexity)]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:16:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:15:13
|
||||
|
|
||||
LL | let a = (|| 42)();
|
||||
| ^^^^^^^^^ help: try doing something like: `42`
|
||||
|
@ -8,7 +8,7 @@ LL | let a = (|| 42)();
|
|||
= help: to override `-D warnings` add `#[allow(clippy::redundant_closure_call)]`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:17:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:16:13
|
||||
|
|
||||
LL | let b = (async || {
|
||||
| _____________^
|
||||
|
@ -28,7 +28,7 @@ LL ~ };
|
|||
|
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:22:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:21:13
|
||||
|
|
||||
LL | let c = (|| {
|
||||
| _____________^
|
||||
|
@ -48,13 +48,13 @@ LL ~ };
|
|||
|
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:27:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:26:13
|
||||
|
|
||||
LL | let d = (async || something().await)();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:36:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:35:13
|
||||
|
|
||||
LL | (|| m!())()
|
||||
| ^^^^^^^^^^^ help: try doing something like: `m!()`
|
||||
|
@ -65,7 +65,7 @@ LL | m2!();
|
|||
= note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:31:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:30:13
|
||||
|
|
||||
LL | (|| 0)()
|
||||
| ^^^^^^^^ help: try doing something like: `0`
|
||||
|
@ -76,67 +76,67 @@ LL | m2!();
|
|||
= note: this error originates in the macro `m` which comes from the expansion of the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:44:16
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:43:16
|
||||
|
|
||||
LL | assert_eq!((|| || 43)()(), 42);
|
||||
| ^^^^^^^^^^^^^^ help: try doing something like: `43`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:53:10
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:52:10
|
||||
|
|
||||
LL | dbg!((|| 42)());
|
||||
| ^^^^^^^^^ help: try doing something like: `42`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:56:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:55:13
|
||||
|
|
||||
LL | let a = (|| || || 123)();
|
||||
| ^^^^^^^^^^^^^^^^ help: try doing something like: `(|| || 123)`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:60:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:59:13
|
||||
|
|
||||
LL | let a = (|| || || || async || 1)()()()()();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { 1 }`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:69:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:68:13
|
||||
|
|
||||
LL | let a = (|| echo!(|| echo!(|| 1)))()()();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `1`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:71:13
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:70:13
|
||||
|
|
||||
LL | let a = (|| echo!((|| 123)))()();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `123`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:84:11
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:83:11
|
||||
|
|
||||
LL | bar()((|| || 42)()(), 5);
|
||||
| ^^^^^^^^^^^^^^ help: try doing something like: `42`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:85:9
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:84:9
|
||||
|
|
||||
LL | foo((|| || 42)()(), 5);
|
||||
| ^^^^^^^^^^^^^^ help: try doing something like: `42`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:89:5
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:88:5
|
||||
|
|
||||
LL | (|| async {})().await;
|
||||
| ^^^^^^^^^^^^^^^ help: try doing something like: `async {}`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:98:18
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:97:18
|
||||
|
|
||||
LL | spawn_on((|| async move {})());
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async move {}`
|
||||
|
||||
error: try not to call a closure in the expression where it is declared
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:103:28
|
||||
--> tests/ui/redundant_closure_call_fixable.rs:102:28
|
||||
|
|
||||
LL | std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `13_i32 + 36_i32`
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//@aux-build:proc_macros.rs
|
||||
#![allow(unused, clippy::no_effect, clippy::needless_pass_by_ref_mut)]
|
||||
#![warn(clippy::redundant_locals)]
|
||||
#![feature(async_closure, coroutines, stmt_expr_attributes)]
|
||||
#![feature(coroutines, stmt_expr_attributes)]
|
||||
|
||||
extern crate proc_macros;
|
||||
use proc_macros::{external, with_span};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Same as rustc's `tests/ui/async-await/async-closures/captures.rs`, keep in sync
|
||||
|
||||
#![feature(async_closure, async_trait_bounds)]
|
||||
#![feature(async_trait_bounds)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::pin;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(async_closure, async_trait_bounds)]
|
||||
#![feature(async_fn_traits, async_trait_bounds)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::pin;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(async_closure, async_fn_traits)]
|
||||
#![feature(async_fn_traits)]
|
||||
#![allow(unused)]
|
||||
|
||||
use std::future::Future;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// please consider modifying rustc's async drop test at
|
||||
// `tests/ui/async-await/async-drop.rs`.
|
||||
|
||||
#![feature(async_drop, impl_trait_in_assoc_type, async_closure)]
|
||||
#![feature(async_drop, impl_trait_in_assoc_type)]
|
||||
#![allow(incomplete_features, dead_code)]
|
||||
|
||||
// FIXME(zetanumbers): consider AsyncDestruct::async_drop cleanup tests
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
// CHECK-DAG: [[CLOSURE:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: [[GEN_FN]]
|
||||
// CHECK-DAG: [[UPVAR:!.*]] = !DIDerivedType(tag: DW_TAG_member, name: "upvar", scope: [[CLOSURE]]
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
fn async_closure_test(upvar: &str) -> impl AsyncFn() + '_ {
|
||||
async move || {
|
||||
let hello = String::from("hello");
|
||||
|
|
|
@ -1,56 +1,56 @@
|
|||
Function name: async_closure::call_once::<async_closure::main::{closure#0}>
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 07, 01, 00, 2b]
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 06, 01, 00, 2b]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 1
|
||||
- Code(Counter(0)) at (prev + 7, 1) to (start + 0, 43)
|
||||
- Code(Counter(0)) at (prev + 6, 1) to (start + 0, 43)
|
||||
Highest counter ID seen: c0
|
||||
|
||||
Function name: async_closure::call_once::<async_closure::main::{closure#0}>::{closure#0}
|
||||
Raw bytes (14): 0x[01, 01, 00, 02, 01, 07, 2b, 01, 0e, 05, 02, 01, 00, 02]
|
||||
Raw bytes (14): 0x[01, 01, 00, 02, 01, 06, 2b, 01, 0e, 05, 02, 01, 00, 02]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 2
|
||||
- Code(Counter(0)) at (prev + 7, 43) to (start + 1, 14)
|
||||
- Code(Counter(0)) at (prev + 6, 43) to (start + 1, 14)
|
||||
- Code(Counter(1)) at (prev + 2, 1) to (start + 0, 2)
|
||||
Highest counter ID seen: c1
|
||||
|
||||
Function name: async_closure::main
|
||||
Raw bytes (14): 0x[01, 01, 00, 02, 01, 0b, 01, 01, 16, 01, 02, 05, 02, 02]
|
||||
Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 01, 01, 16, 01, 02, 05, 02, 02]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 2
|
||||
- Code(Counter(0)) at (prev + 11, 1) to (start + 1, 22)
|
||||
- Code(Counter(0)) at (prev + 10, 1) to (start + 1, 22)
|
||||
- Code(Counter(0)) at (prev + 2, 5) to (start + 2, 2)
|
||||
Highest counter ID seen: c0
|
||||
|
||||
Function name: async_closure::main::{closure#0}
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 23, 00, 24]
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 23, 00, 24]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 1
|
||||
- Code(Counter(0)) at (prev + 12, 35) to (start + 0, 36)
|
||||
- Code(Counter(0)) at (prev + 11, 35) to (start + 0, 36)
|
||||
Highest counter ID seen: c0
|
||||
|
||||
Function name: async_closure::main::{closure#0}::{closure#0}::<i16>
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 22, 00, 24]
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 22, 00, 24]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 1
|
||||
- Code(Counter(0)) at (prev + 12, 34) to (start + 0, 36)
|
||||
- Code(Counter(0)) at (prev + 11, 34) to (start + 0, 36)
|
||||
Highest counter ID seen: c0
|
||||
|
||||
Function name: async_closure::main::{closure#0}::{closure#1}::<i32>
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 23, 00, 24]
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 23, 00, 24]
|
||||
Number of files: 1
|
||||
- file 0 => global file 1
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 1
|
||||
- Code(Counter(0)) at (prev + 12, 35) to (start + 0, 36)
|
||||
- Code(Counter(0)) at (prev + 11, 35) to (start + 0, 36)
|
||||
Highest counter ID seen: c0
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
LL| |#![feature(async_closure)]
|
||||
LL| |//@ edition: 2021
|
||||
LL| |
|
||||
LL| |//@ aux-build: executor.rs
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(async_closure)]
|
||||
//@ edition: 2021
|
||||
|
||||
//@ aux-build: executor.rs
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// MIR for `main::{closure#0}::{closure#0}::{closure#0}` after built
|
||||
|
||||
fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10}, _2: ResumeTy) -> ()
|
||||
fn main::{closure#0}::{closure#0}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> ()
|
||||
yields ()
|
||||
{
|
||||
debug _task_context => _2;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// MIR for `main::{closure#0}::{closure#0}::{closure#1}` after built
|
||||
|
||||
fn main::{closure#0}::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10}, _2: ResumeTy) -> ()
|
||||
fn main::{closure#0}::{closure#0}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10}, _2: ResumeTy) -> ()
|
||||
yields ()
|
||||
{
|
||||
debug _task_context => _2;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// MIR for `main::{closure#0}::{closure#0}` 0 coroutine_closure_by_move
|
||||
|
||||
fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:54:33: 54:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10} {
|
||||
let mut _0: {async closure body@$DIR/async_closure_shims.rs:54:53: 57:10};
|
||||
fn main::{closure#0}::{closure#0}(_1: {async closure@$DIR/async_closure_shims.rs:53:33: 53:52}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10} {
|
||||
let mut _0: {async closure body@$DIR/async_closure_shims.rs:53:53: 56:10};
|
||||
|
||||
bb0: {
|
||||
_0 = {coroutine@$DIR/async_closure_shims.rs:54:53: 57:10 (#0)} { a: move _2, b: move (_1.0: i32) };
|
||||
_0 = {coroutine@$DIR/async_closure_shims.rs:53:53: 56:10 (#0)} { a: move _2, b: move (_1.0: i32) };
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// MIR for `main::{closure#0}::{closure#1}::{closure#0}` after built
|
||||
|
||||
fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10}, _2: ResumeTy) -> ()
|
||||
fn main::{closure#0}::{closure#1}::{closure#0}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> ()
|
||||
yields ()
|
||||
{
|
||||
debug _task_context => _2;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// MIR for `main::{closure#0}::{closure#1}::{closure#1}` after built
|
||||
|
||||
fn main::{closure#0}::{closure#1}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10}, _2: ResumeTy) -> ()
|
||||
fn main::{closure#0}::{closure#1}::{closure#1}(_1: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10}, _2: ResumeTy) -> ()
|
||||
yields ()
|
||||
{
|
||||
debug _task_context => _2;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_move
|
||||
|
||||
fn main::{closure#0}::{closure#1}(_1: {async closure@$DIR/async_closure_shims.rs:63:33: 63:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10} {
|
||||
let mut _0: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10};
|
||||
fn main::{closure#0}::{closure#1}(_1: {async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} {
|
||||
let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10};
|
||||
|
||||
bb0: {
|
||||
_0 = {coroutine@$DIR/async_closure_shims.rs:63:48: 66:10 (#0)} { a: move _2, b: move (_1.0: &i32) };
|
||||
_0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: move (_1.0: &i32) };
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// MIR for `main::{closure#0}::{closure#1}` 0 coroutine_closure_by_ref
|
||||
|
||||
fn main::{closure#0}::{closure#1}(_1: &{async closure@$DIR/async_closure_shims.rs:63:33: 63:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10} {
|
||||
let mut _0: {async closure body@$DIR/async_closure_shims.rs:63:48: 66:10};
|
||||
fn main::{closure#0}::{closure#1}(_1: &{async closure@$DIR/async_closure_shims.rs:62:33: 62:47}, _2: i32) -> {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10} {
|
||||
let mut _0: {async closure body@$DIR/async_closure_shims.rs:62:48: 65:10};
|
||||
|
||||
bb0: {
|
||||
_0 = {coroutine@$DIR/async_closure_shims.rs:63:48: 66:10 (#0)} { a: move _2, b: copy ((*_1).0: &i32) };
|
||||
_0 = {coroutine@$DIR/async_closure_shims.rs:62:48: 65:10 (#0)} { a: move _2, b: copy ((*_1).0: &i32) };
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
//@ edition:2021
|
||||
// skip-filecheck
|
||||
|
||||
#![feature(async_closure, async_fn_traits)]
|
||||
#![allow(unused)]
|
||||
|
||||
use std::future::Future;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(async_closure)]
|
||||
|
||||
use std::ops::AsyncFnMut;
|
||||
|
||||
pub trait Main {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//@ edition:2018
|
||||
|
||||
#![feature(async_closure)]
|
||||
fn foo() -> Box<dyn std::future::Future<Output = u32>> {
|
||||
let x = 0u32;
|
||||
Box::new((async || x)())
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0515]: cannot return value referencing local variable `x`
|
||||
--> $DIR/async-borrowck-escaping-closure-error.rs:6:5
|
||||
--> $DIR/async-borrowck-escaping-closure-error.rs:5:5
|
||||
|
|
||||
LL | Box::new((async || x)())
|
||||
| ^^^^^^^^^------------^^^
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
//@ build-pass
|
||||
//@ edition:2018
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
macro_rules! match_expr {
|
||||
($x:expr) => {}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
//@ edition:2018
|
||||
//@ aux-build:arc_wake.rs
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate arc_wake;
|
||||
|
||||
use std::pin::Pin;
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
// Regression test for #123901. We previously ICE'd as we silently
|
||||
// swallowed an in the `ExprUseVisitor`.
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
pub fn test(test: &u64, temp: &u64) {
|
||||
async |check, a, b| {
|
||||
//~^ ERROR type annotations needed
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0282]: type annotations needed
|
||||
--> $DIR/ambiguous-arg.rs:9:25
|
||||
--> $DIR/ambiguous-arg.rs:7:25
|
||||
|
|
||||
LL | async |check, a, b| {
|
||||
| _________________________^
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
//@ aux-build:block-on.rs
|
||||
//@ edition:2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/arg-mismatch.rs:12:11
|
||||
--> $DIR/arg-mismatch.rs:10:11
|
||||
|
|
||||
LL | c(2usize).await;
|
||||
| - ^^^^^^ expected `i32`, found `usize`
|
||||
|
@ -7,7 +7,7 @@ LL | c(2usize).await;
|
|||
| arguments to this function are incorrect
|
||||
|
|
||||
note: closure parameter defined here
|
||||
--> $DIR/arg-mismatch.rs:10:24
|
||||
--> $DIR/arg-mismatch.rs:8:24
|
||||
|
|
||||
LL | let c = async |x| {};
|
||||
| ^
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition:2021
|
||||
//@ run-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition:2021
|
||||
//@ run-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
//@ edition: 2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::pin;
|
||||
use std::task::*;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
//@ edition:2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
pub fn closure() -> impl AsyncFn() {
|
||||
async || { /* Don't really need to do anything here. */ }
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition:2021
|
||||
//@ run-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition:2021
|
||||
//@ build-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
// Make sure that we don't call `coroutine_by_move_body_def_id` query
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition:2021
|
||||
//@ run-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
pub trait Trait {
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition:2021
|
||||
//@ build-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
use std::future::Future;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//@ edition: 2021
|
||||
//@ check-pass
|
||||
|
||||
#![feature(async_closure, async_fn_traits, unboxed_closures)]
|
||||
#![feature(async_fn_traits, unboxed_closures)]
|
||||
|
||||
fn bar<F, O>(_: F)
|
||||
where
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
// Same as miri's `tests/pass/async-closure-captures.rs`, keep in sync
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
//@ run-pass
|
||||
//@ check-run-results
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
async fn for_each(f: impl AsyncFnOnce(&str) + Clone) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
//@ compile-flags: -Zvalidate-mir --edition=2018 --crate-type=lib -Copt-level=3
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
fn needs_fn_mut<T>(mut x: impl FnMut() -> T) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0507]: cannot move out of `x` which is behind a mutable reference
|
||||
--> $DIR/closure-shim-borrowck-error.rs:12:18
|
||||
--> $DIR/closure-shim-borrowck-error.rs:10:18
|
||||
|
|
||||
LL | needs_fn_mut(async || {
|
||||
| ^^^^^^^^ `x` is moved here
|
||||
|
@ -11,7 +11,7 @@ LL | x.hello();
|
|||
| move occurs because `x` has type `Ty`, which does not implement the `Copy` trait
|
||||
|
|
||||
note: if `Ty` implemented `Clone`, you could clone the value
|
||||
--> $DIR/closure-shim-borrowck-error.rs:18:1
|
||||
--> $DIR/closure-shim-borrowck-error.rs:16:1
|
||||
|
|
||||
LL | x.hello();
|
||||
| - you could clone this value
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
fn constrain<T: AsyncFnOnce()>(t: T) -> T {
|
||||
t
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
//@ build-pass
|
||||
//@ compile-flags: -Cdebuginfo=2
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
async fn call_once(f: impl AsyncFnOnce()) {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
//@ compile-flags: -Zverbose-internals
|
||||
//@ edition:2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
fn main() {
|
||||
let x = async || {};
|
||||
//~^ NOTE the expected `async` closure body
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/def-path.rs:9:9
|
||||
--> $DIR/def-path.rs:7:9
|
||||
|
|
||||
LL | let x = async || {};
|
||||
| -- the expected `async` closure body
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition: 2021
|
||||
// issue: rust-lang/rust#123697
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
struct S { t: i32 }
|
||||
|
||||
fn test(s: &S, t: &i32) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
//@ edition: 2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
struct DropMe;
|
||||
|
||||
trait Impossible {}
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
error[E0277]: the trait bound `(): Impossible` is not satisfied
|
||||
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:19:23
|
||||
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:17:23
|
||||
|
|
||||
LL | trait_error::<()>();
|
||||
| ^^ the trait `Impossible` is not implemented for `()`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:7:1
|
||||
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:5:1
|
||||
|
|
||||
LL | trait Impossible {}
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `trait_error`
|
||||
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:8:19
|
||||
--> $DIR/dont-ice-when-body-tainted-by-errors.rs:6:19
|
||||
|
|
||||
LL | fn trait_error<T: Impossible>() {}
|
||||
| ^^^^^^^^^^ required by this bound in `trait_error`
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
//@ run-pass
|
||||
//@ check-run-results
|
||||
|
||||
#![feature(async_closure)]
|
||||
#![allow(unused)]
|
||||
|
||||
extern crate block_on;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//@ edition: 2021
|
||||
//@ only-x86_64
|
||||
|
||||
#![feature(async_closure, target_feature_11)]
|
||||
#![feature(target_feature_11)]
|
||||
// `target_feature_11` just to test safe functions w/ target features.
|
||||
|
||||
use std::pin::Pin;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
//@ edition: 2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
use std::pin::Pin;
|
||||
use std::future::Future;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0277]: the trait bound `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}: AsyncFn()` is not satisfied
|
||||
--> $DIR/fn-exception.rs:19:10
|
||||
--> $DIR/fn-exception.rs:17:10
|
||||
|
|
||||
LL | test(unsafety);
|
||||
| ---- ^^^^^^^^ the trait `AsyncFn()` is not implemented for fn item `unsafe fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {unsafety}`
|
||||
|
@ -7,13 +7,13 @@ LL | test(unsafety);
|
|||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `test`
|
||||
--> $DIR/fn-exception.rs:16:17
|
||||
--> $DIR/fn-exception.rs:14:17
|
||||
|
|
||||
LL | fn test(f: impl AsyncFn()) {}
|
||||
| ^^^^^^^^^ required by this bound in `test`
|
||||
|
||||
error[E0277]: the trait bound `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}: AsyncFn()` is not satisfied
|
||||
--> $DIR/fn-exception.rs:20:10
|
||||
--> $DIR/fn-exception.rs:18:10
|
||||
|
|
||||
LL | test(abi);
|
||||
| ---- ^^^ the trait `AsyncFn()` is not implemented for fn item `extern "C" fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {abi}`
|
||||
|
@ -21,7 +21,7 @@ LL | test(abi);
|
|||
| required by a bound introduced by this call
|
||||
|
|
||||
note: required by a bound in `test`
|
||||
--> $DIR/fn-exception.rs:16:17
|
||||
--> $DIR/fn-exception.rs:14:17
|
||||
|
|
||||
LL | fn test(f: impl AsyncFn()) {}
|
||||
| ^^^^^^^^^ required by this bound in `test`
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition:2021
|
||||
//@ build-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
fn consume(_: String) {}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition:2021
|
||||
//@ build-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
fn force_fnonce<T: AsyncFnOnce()>(t: T) -> T { t }
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
//@ edition:2021
|
||||
//@ build-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
extern crate block_on;
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
//@ known-bug: unknown
|
||||
// Borrow checking doesn't like that higher-ranked output...
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error: lifetime may not live long enough
|
||||
--> $DIR/higher-ranked-return.rs:13:46
|
||||
--> $DIR/higher-ranked-return.rs:11:46
|
||||
|
|
||||
LL | let x = async move |x: &str| -> &str {
|
||||
| ________________________________-________----_^
|
||||
| | | |
|
||||
| | | return type of async closure `{async closure body@$DIR/higher-ranked-return.rs:13:46: 15:10}` contains a lifetime `'2`
|
||||
| | | return type of async closure `{async closure body@$DIR/higher-ranked-return.rs:11:46: 13:10}` contains a lifetime `'2`
|
||||
| | let's call the lifetime of this reference `'1`
|
||||
LL | | x
|
||||
LL | | };
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition:2021
|
||||
//@ build-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
// `should_reborrow_from_env_of_parent_coroutine_closure` for more detail for when we
|
||||
// must borrow from the closure env.
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
fn main() {
|
||||
hello(&Ty);
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
// `mir_inliner_callees` for the synthetic by-move coroutine body since
|
||||
// its def-id wasn't previously being considered.
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::pin;
|
||||
use std::task::*;
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
extern crate block_on;
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
//@ edition:2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
fn main() {
|
||||
fn needs_fn(x: impl FnOnce()) {}
|
||||
needs_fn(async || {});
|
||||
//~^ ERROR expected `{async closure@is-not-fn.rs:7:14}` to be a closure that returns `()`
|
||||
//~^ ERROR expected `{async closure@is-not-fn.rs:5:14}` to be a closure that returns `()`
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0271]: expected `{async closure@is-not-fn.rs:7:14}` to be a closure that returns `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:7:23: 7:25}`
|
||||
--> $DIR/is-not-fn.rs:7:14
|
||||
error[E0271]: expected `{async closure@is-not-fn.rs:5:14}` to be a closure that returns `()`, but it returns `{async closure body@$DIR/is-not-fn.rs:5:23: 5:25}`
|
||||
--> $DIR/is-not-fn.rs:5:14
|
||||
|
|
||||
LL | needs_fn(async || {});
|
||||
| -------- ^^^^^^^^^^^ expected `()`, found `async` closure body
|
||||
|
@ -7,9 +7,9 @@ LL | needs_fn(async || {});
|
|||
| required by a bound introduced by this call
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found `async` closure body `{async closure body@$DIR/is-not-fn.rs:7:23: 7:25}`
|
||||
found `async` closure body `{async closure body@$DIR/is-not-fn.rs:5:23: 5:25}`
|
||||
note: required by a bound in `needs_fn`
|
||||
--> $DIR/is-not-fn.rs:6:25
|
||||
--> $DIR/is-not-fn.rs:4:25
|
||||
|
|
||||
LL | fn needs_fn(x: impl FnOnce()) {}
|
||||
| ^^^^^^^^ required by this bound in `needs_fn`
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//@ edition: 2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
#![deny(closure_returning_async_block)]
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error: closure returning async block can be made into an async closure
|
||||
--> $DIR/lint-closure-returning-async-block.rs:7:13
|
||||
--> $DIR/lint-closure-returning-async-block.rs:6:13
|
||||
|
|
||||
LL | let x = || async {};
|
||||
| ^^ ----- this async block can be removed, and the closure can be turned into an async closure
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-closure-returning-async-block.rs:4:9
|
||||
--> $DIR/lint-closure-returning-async-block.rs:3:9
|
||||
|
|
||||
LL | #![deny(closure_returning_async_block)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -16,7 +16,7 @@ LL + let x = async || {};
|
|||
|
|
||||
|
||||
error: closure returning async block can be made into an async closure
|
||||
--> $DIR/lint-closure-returning-async-block.rs:10:13
|
||||
--> $DIR/lint-closure-returning-async-block.rs:9:13
|
||||
|
|
||||
LL | let x = || async move {};
|
||||
| ^^ ---------- this async block can be removed, and the closure can be turned into an async closure
|
||||
|
@ -28,7 +28,7 @@ LL + let x = async || {};
|
|||
|
|
||||
|
||||
error: closure returning async block can be made into an async closure
|
||||
--> $DIR/lint-closure-returning-async-block.rs:13:13
|
||||
--> $DIR/lint-closure-returning-async-block.rs:12:13
|
||||
|
|
||||
LL | let x = move || async move {};
|
||||
| ^^^^^^^ ---------- this async block can be removed, and the closure can be turned into an async closure
|
||||
|
@ -40,7 +40,7 @@ LL + let x = async move || {};
|
|||
|
|
||||
|
||||
error: closure returning async block can be made into an async closure
|
||||
--> $DIR/lint-closure-returning-async-block.rs:16:13
|
||||
--> $DIR/lint-closure-returning-async-block.rs:15:13
|
||||
|
|
||||
LL | let x = move || async {};
|
||||
| ^^^^^^^ ----- this async block can be removed, and the closure can be turned into an async closure
|
||||
|
@ -52,7 +52,7 @@ LL + let x = async move || {};
|
|||
|
|
||||
|
||||
error: closure returning async block can be made into an async closure
|
||||
--> $DIR/lint-closure-returning-async-block.rs:19:13
|
||||
--> $DIR/lint-closure-returning-async-block.rs:18:13
|
||||
|
|
||||
LL | let x = || {{ async {} }};
|
||||
| ^^ ----- this async block can be removed, and the closure can be turned into an async closure
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
//@ edition: 2021
|
||||
//@ check-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
// Make sure we don't ICE if an async closure has a macro body.
|
||||
// This happened because we were calling walk instead of visit
|
||||
// in the def collector, oops!
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
//@[v0] compile-flags: -Csymbol-mangling-version=v0
|
||||
//@[legacy] compile-flags: -Csymbol-mangling-version=legacy -Zunstable-options
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
use std::future::Future;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
//@ check-pass
|
||||
//@ edition: 2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::{marker::PhantomData, sync::Mutex};
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
//@ aux-build:block-on.rs
|
||||
//@ edition:2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
struct NoCopy;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/move-consuming-capture.rs:17:9
|
||||
--> $DIR/move-consuming-capture.rs:15:9
|
||||
|
|
||||
LL | let x = async move || {
|
||||
| - move occurs because `x` has type `{async closure@$DIR/move-consuming-capture.rs:13:17: 13:30}`, which does not implement the `Copy` trait
|
||||
| - move occurs because `x` has type `{async closure@$DIR/move-consuming-capture.rs:11:17: 11:30}`, which does not implement the `Copy` trait
|
||||
...
|
||||
LL | x().await;
|
||||
| --- `x` moved due to this method call
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//@ edition:2021
|
||||
//@ build-pass
|
||||
|
||||
#![feature(async_closure, async_fn_traits)]
|
||||
#![feature(async_fn_traits)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
//@ compile-flags: -Zvalidate-mir
|
||||
//@ edition: 2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
// NOT copy.
|
||||
struct Ty;
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
error[E0507]: cannot move out of `*x` which is behind a shared reference
|
||||
--> $DIR/move-out-of-ref.rs:11:9
|
||||
--> $DIR/move-out-of-ref.rs:9:9
|
||||
|
|
||||
LL | *x;
|
||||
| ^^ move occurs because `*x` has type `Ty`, which does not implement the `Copy` trait
|
||||
|
|
||||
note: if `Ty` implemented `Clone`, you could clone the value
|
||||
--> $DIR/move-out-of-ref.rs:7:1
|
||||
--> $DIR/move-out-of-ref.rs:5:1
|
||||
|
|
||||
LL | struct Ty;
|
||||
| ^^^^^^^^^ consider implementing `Clone` for this type
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
//@[e2018] edition:2018
|
||||
//@[e2021] edition:2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
async fn call_once(f: impl AsyncFnOnce()) { f().await; }
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition:2021
|
||||
//@ run-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
//@ edition: 2021
|
||||
//@ check-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
fn outlives<'a>(_: impl Sized + 'a) {}
|
||||
|
||||
async fn call_once(f: impl AsyncFnOnce()) {
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
//@ edition:2021
|
||||
//@ build-pass
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
extern crate block_on;
|
||||
|
||||
fn wrapper(f: impl Fn(String)) -> impl AsyncFn(String) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
//@ edition: 2021
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
struct NotClonableArg;
|
||||
#[derive(Default)]
|
||||
struct NotClonableReturnType;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
error[E0277]: the trait bound `NotClonableUpvar: Clone` is not satisfied in `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}`
|
||||
--> $DIR/not-clone-closure.rs:32:15
|
||||
error[E0277]: the trait bound `NotClonableUpvar: Clone` is not satisfied in `{async closure@$DIR/not-clone-closure.rs:27:21: 27:34}`
|
||||
--> $DIR/not-clone-closure.rs:30:15
|
||||
|
|
||||
LL | not_clone.clone();
|
||||
| ^^^^^ unsatisfied trait bound
|
||||
|
|
||||
= help: within `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}`, the trait `Clone` is not implemented for `NotClonableUpvar`
|
||||
= help: within `{async closure@$DIR/not-clone-closure.rs:27:21: 27:34}`, the trait `Clone` is not implemented for `NotClonableUpvar`
|
||||
note: required because it's used within this closure
|
||||
--> $DIR/not-clone-closure.rs:29:21
|
||||
--> $DIR/not-clone-closure.rs:27:21
|
||||
|
|
||||
LL | let not_clone = async move || {
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
// FIXME(async_closures): This needs a better error message!
|
||||
|
||||
#![feature(async_closure)]
|
||||
|
||||
fn main() {
|
||||
fn needs_fn<T>(_: impl FnMut() -> T) {}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue