-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make the computation of coroutine_captures_by_ref_ty more sophisticated
- Loading branch information
1 parent
8af94ce
commit 7dbc68b
Showing
7 changed files
with
376 additions
and
34 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
//@ check-pass | ||
//@ edition: 2021 | ||
|
||
#![feature(async_closure)] | ||
|
||
use std::future::Future; | ||
use std::pin::Pin; | ||
use std::{marker::PhantomData, sync::Mutex}; | ||
|
||
type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>; | ||
|
||
pub struct Scope<'scope, 'env: 'scope> { | ||
enqueued: Mutex<Vec<BoxFuture<'scope, ()>>>, | ||
phantom: PhantomData<&'env ()>, | ||
} | ||
|
||
impl<'scope, 'env: 'scope> Scope<'scope, 'env> { | ||
pub fn spawn(&'scope self, future: impl Future<Output = ()> + Send + 'scope) { | ||
self.enqueued.lock().unwrap().push(Box::pin(future)); | ||
} | ||
} | ||
|
||
fn scope_with_closure<'env, B>(_body: B) -> BoxFuture<'env, ()> | ||
where | ||
for<'scope> B: async FnOnce(&'scope Scope<'scope, 'env>), | ||
{ | ||
todo!() | ||
} | ||
|
||
type ScopeRef<'scope, 'env> = &'scope Scope<'scope, 'env>; | ||
|
||
async fn go<'a>(value: &'a i32) { | ||
let closure = async |scope: ScopeRef<'_, 'a>| { | ||
let _future1 = scope.spawn(async { | ||
// Make sure that `*value` is immutably borrowed with lifetime of | ||
// `'a` and not with the lifetime of the containing coroutine-closure. | ||
let _v = *value; | ||
}); | ||
}; | ||
scope_with_closure(closure).await; | ||
} | ||
|
||
fn main() {} |
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,44 @@ | ||
//@ edition: 2021 | ||
//@ check-pass | ||
|
||
#![feature(async_closure)] | ||
|
||
fn outlives<'a>(_: impl Sized + 'a) {} | ||
|
||
async fn call_once(f: impl async FnOnce()) { | ||
f().await; | ||
} | ||
|
||
fn simple<'a>(x: &'a i32) { | ||
let c = async || { println!("{}", *x); }; | ||
outlives::<'a>(c()); | ||
outlives::<'a>(call_once(c)); | ||
|
||
let c = async move || { println!("{}", *x); }; | ||
outlives::<'a>(c()); | ||
outlives::<'a>(call_once(c)); | ||
} | ||
|
||
struct S<'a>(&'a i32); | ||
|
||
fn through_field<'a>(x: S<'a>) { | ||
let c = async || { println!("{}", *x.0); }; | ||
outlives::<'a>(c()); | ||
outlives::<'a>(call_once(c)); | ||
|
||
let c = async move || { println!("{}", *x.0); }; | ||
outlives::<'a>(c()); | ||
outlives::<'a>(call_once(c)); | ||
} | ||
|
||
fn through_field_and_ref<'a>(x: &S<'a>) { | ||
let c = async || { println!("{}", *x.0); }; | ||
outlives::<'a>(c()); | ||
outlives::<'a>(call_once(c)); | ||
|
||
let c = async move || { println!("{}", *x.0); }; | ||
outlives::<'a>(c()); | ||
// outlives::<'a>(call_once(c)); // FIXME(async_closures): Figure out why this fails | ||
} | ||
|
||
fn main() {} |
47 changes: 47 additions & 0 deletions
47
tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
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,47 @@ | ||
//@ edition: 2018 | ||
|
||
// This is `no-borrow-from-env.rs`, but under edition 2018 we still want to make | ||
// sure that we don't ICE or anything, even if precise closure captures means | ||
// that we can't actually borrowck successfully. | ||
|
||
#![feature(async_closure)] | ||
|
||
fn outlives<'a>(_: impl Sized + 'a) {} | ||
|
||
async fn call_once(f: impl async FnOnce()) { | ||
f().await; | ||
} | ||
|
||
fn simple<'a>(x: &'a i32) { | ||
let c = async || { println!("{}", *x); }; //~ ERROR `x` does not live long enough | ||
outlives::<'a>(c()); | ||
outlives::<'a>(call_once(c)); | ||
|
||
let c = async move || { println!("{}", *x); }; | ||
outlives::<'a>(c()); //~ ERROR `c` does not live long enough | ||
outlives::<'a>(call_once(c)); //~ ERROR cannot move out of `c` | ||
} | ||
|
||
struct S<'a>(&'a i32); | ||
|
||
fn through_field<'a>(x: S<'a>) { | ||
let c = async || { println!("{}", *x.0); }; //~ ERROR `x` does not live long enough | ||
outlives::<'a>(c()); | ||
outlives::<'a>(call_once(c)); | ||
|
||
let c = async move || { println!("{}", *x.0); }; //~ ERROR cannot move out of `x` | ||
outlives::<'a>(c()); //~ ERROR `c` does not live long enough | ||
outlives::<'a>(call_once(c)); //~ ERROR cannot move out of `c` | ||
} | ||
|
||
fn through_field_and_ref<'a>(x: &S<'a>) { | ||
let c = async || { println!("{}", *x.0); }; //~ ERROR `x` does not live long enough | ||
outlives::<'a>(c()); | ||
outlives::<'a>(call_once(c)); //~ ERROR explicit lifetime required in the type of `x` | ||
|
||
let c = async move || { println!("{}", *x.0); }; | ||
outlives::<'a>(c()); //~ ERROR `c` does not live long enough | ||
// outlives::<'a>(call_once(c)); // FIXME(async_closures): Figure out why this fails | ||
} | ||
|
||
fn main() {} |
Oops, something went wrong.