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

Inconsistency in Send/Sync requirements for async/await #59245

Open
Ekleog opened this Issue Mar 16, 2019 · 7 comments

Comments

Projects
None yet
5 participants
@Ekleog
Copy link

Ekleog commented Mar 16, 2019

The following code, when switching between lines 14 and 15 (the two versions of the for line), oscillates between compiling and not compiling because it requires Sync for the dyn Send items:

#![feature(async_await, await_macro, futures_api)]

use std::collections::VecDeque;
use std::future::Future;

pub async fn receive<HandleFn, Fut, Ret>(handle: HandleFn) -> Ret
where
    Fut: Future<Output = ()>,
    HandleFn: Fn() -> Fut,
{
    let v: VecDeque<Box<dyn Send>> = VecDeque::new();

    let l = v.len();
    for _i in 0..v.len() {
    //for _i in 0..l {
        await!(handle());
    }
    
    loop {}
}

fn do_stuff<F: Future + Send>(_f: F) {}

pub fn showcase() {
    do_stuff(async {
        match await!(receive(async move || ())) {
            true => "test",
            false => "test",
        };
    });
}

(playground)

(Note: this is a simplification of the failure that occurs on Ekleog/erlust@98c6cbc when running cargo test)

@Ekleog Ekleog referenced this issue Mar 16, 2019

Open

Tracking issue for async/await (RFC 2394) #50547

4 of 11 tasks complete
@cramertj

This comment has been minimized.

Copy link
Member

cramertj commented Mar 18, 2019

I think this is working as intended-- I'd expect that in order for the future to be Send, all references held across await! points must be Send, which means the data they reference must be Sync. In the for loop here, a reference to v is being held across the await!. cc @nikomatsakis for another unfortunate side-effect of temporary references becoming extraordinarily visible under async/await!.

@cramertj

This comment has been minimized.

Copy link
Member

cramertj commented Mar 18, 2019

I guess it's also worth pointing out that what isn't "working as intended" here is that the reference in question shouldn't need to be held across the await!, since it's only being used to produce a new temporary (the range).

@Ekleog

This comment has been minimized.

Copy link
Author

Ekleog commented Mar 18, 2019

Actually, if the reference points to inside the future itself, I think that the pointed-to stuff might only need to be Send, as there would at any point in time be only a single thread referring to them. But that is another issue (or another feature request, actually -- and I'm not even sure yet it'd be sound), and here what I wanted to point out was that the temporary borrow is propagated further than would be expected.

@earthengine

This comment has been minimized.

Copy link

earthengine commented Mar 18, 2019

FYI, I was posted in internals for a similar issue regarding pattern matches.

Playground

#![feature(
    await_macro,
    async_await,
    futures_api,
    optin_builtin_traits
)]
use std::future::Future;

struct Foo;
impl Foo {
    fn foo(&self) -> Option<()> { Some(()) }
}
impl !Sync for Foo{}

async fn bar() {
    let f = Foo;
    if let Some(v) = f.foo() {
        await!(async{})
    }
}

async fn buz(f: impl Future<Output=()> + Send) {
    await!(f)
}

fn main(){
    buz(bar());
}
@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Apr 16, 2019

I believe this is a duplicate of #57017.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Apr 16, 2019

I've marked this as deferred because of how #57017 is triaged, but I tend to think we should take some action here -- at least trying to get more precise.

question: If others agree this is a dup, maybe we can close this issue? (Perhaps move the examples over to #57017)

@Ekleog

This comment has been minimized.

Copy link
Author

Ekleog commented Apr 16, 2019

I'm not sure this is the same as #57017, but it does look similar -- will let someone more knowledgeable than me about compiler internals choose whether to close this :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.