forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#128201 - compiler-errors:closure-clone, r=oli-obk Implement `Copy`/`Clone` for async closures We can do so in the same cases that regular closures do. For the purposes of cloning, coroutine-closures are actually precisely the same as regular closures, specifically in the aspect that `Clone` impls care about which is the upvars. The only difference b/w coroutine-closures and regular closures is the type that they *return*, but this type has not been *created* yet, so we don't really have a problem. IDK why I didn't add this impl initially -- I went back and forth a bit on the internal representation for coroutine-closures before settling on a design which largely models regular closures. Previous (not published) iterations of coroutine-closures used to be represented as a special (read: cursed) kind of coroutine, which would probably suffer from the pitfalls that coroutines have that oli mentioned below in rust-lang#128201 (comment). r? oli-obk
- Loading branch information
Showing
11 changed files
with
120 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
//@ aux-build:block-on.rs | ||
//@ edition:2021 | ||
//@ run-pass | ||
//@ check-run-results | ||
|
||
#![feature(async_closure)] | ||
|
||
extern crate block_on; | ||
|
||
async fn for_each(f: impl async FnOnce(&str) + Clone) { | ||
f.clone()("world").await; | ||
f.clone()("world2").await; | ||
} | ||
|
||
fn main() { | ||
block_on::block_on(async_main()); | ||
} | ||
|
||
async fn async_main() { | ||
let x = String::from("Hello,"); | ||
for_each(async move |s| { | ||
println!("{x} {s}"); | ||
}).await; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Hello, world | ||
Hello, world2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
//@ edition: 2021 | ||
|
||
#![feature(async_closure)] | ||
|
||
struct NotClonableArg; | ||
#[derive(Default)] | ||
struct NotClonableReturnType; | ||
|
||
// Verify that the only components that we care about are the upvars, not the signature. | ||
fn we_are_okay_with_not_clonable_signature() { | ||
let x = async |x: NotClonableArg| -> NotClonableReturnType { Default::default() }; | ||
x.clone(); // Okay | ||
} | ||
|
||
#[derive(Debug)] | ||
struct NotClonableUpvar; | ||
|
||
fn we_only_care_about_clonable_upvars() { | ||
let x = NotClonableUpvar; | ||
// Notably, this is clone because we capture `&x`. | ||
let yes_clone = async || { | ||
println!("{x:?}"); | ||
}; | ||
yes_clone.clone(); // Okay | ||
|
||
let z = NotClonableUpvar; | ||
// However, this is not because the closure captures `z` by move. | ||
// (Even though the future that is lent out captures `z by ref!) | ||
let not_clone = async move || { | ||
println!("{z:?}"); | ||
}; | ||
not_clone.clone(); | ||
//~^ ERROR the trait bound `NotClonableUpvar: Clone` is not satisfied | ||
} | ||
|
||
fn main() {} |
20 changes: 20 additions & 0 deletions
20
tests/ui/async-await/async-closures/not-clone-closure.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
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 | ||
| | ||
LL | not_clone.clone(); | ||
| ^^^^^ within `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}`, the trait `Clone` is not implemented for `NotClonableUpvar`, which is required by `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}: Clone` | ||
| | ||
note: required because it's used within this closure | ||
--> $DIR/not-clone-closure.rs:29:21 | ||
| | ||
LL | let not_clone = async move || { | ||
| ^^^^^^^^^^^^^ | ||
help: consider annotating `NotClonableUpvar` with `#[derive(Clone)]` | ||
| | ||
LL + #[derive(Clone)] | ||
LL | struct NotClonableUpvar; | ||
| | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0277`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters