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

Are blanket Future impls necessary? #60645

Open
stjepang opened this issue May 8, 2019 · 7 comments

Comments

Projects
None yet
6 participants
@stjepang
Copy link
Contributor

commented May 8, 2019

We currently have the following blanket impls:

impl<F: ?Sized + Future + Unpin> Future for &mut F
{ ... }

impl<F: ?Sized + Future + Unpin> Future for Box<F>
{ ... }

impl<F: Future> Future for AssertUnwindSafe<F>
{ ... }

impl<P> Future for Pin<P>
where
    P: Unpin + ops::DerefMut,
    P::Target: Future,
{ ... }

All of these blanket impls are on types that deref to something that implements Future. But then there are similar types that don't have a blanket Future implementation - for example, MutexGuard.

I wonder if these impls are necessary in practice if fut.await will auto-deref fut to a value that implements Future. I'm opening this issue just to double-check whether we really want to stabilize those blanket impls.

@Nemo157

This comment has been minimized.

Copy link
Contributor

commented May 8, 2019

The final impl is very important for non .await usecases, it is what allows you to take a Future + !Unpin, pin it in your stack frame, then call a generic function like future::select which requires a Future + Unpin.

To get a similar impl for MutexGuard maybe the first two implementations could be merged into something generic over reference types (although this seems likely to run into coherence issues)?

impl<P> Future for P
where
    P: Unpin + ops::DerefMut,
    P::Target: Future + Unpin,
{ ... }
@mark-i-m

This comment has been minimized.

Copy link
Contributor

commented May 8, 2019

@cramertj

This comment has been minimized.

Copy link
Member

commented May 8, 2019

Yes, the last impl especially is critically important, and the others are nice conveniences. fut.await will not auto-deref.

@stjepang

This comment has been minimized.

Copy link
Contributor Author

commented May 8, 2019

fut.await will not auto-deref.

Do we explicitly not want it to auto-deref or is that something we'll think about in the future? Will .await auto-deref when we introduce DerefMove?

@cramertj

This comment has been minimized.

Copy link
Member

commented May 8, 2019

I mean, never say never, but I certainly wouldn't expect the thing we stabilize to perform auto-deref, and I don't personally have plans to introduce this. The logic around deref is quite complicated, and the interactions with pinning here are especially unclear.

@stjepang

This comment has been minimized.

Copy link
Contributor Author

commented May 8, 2019

I see, thanks. My last question would then be: does foo.await consume (i.e. drop) foo or not?

Also feel free to close this issue if you think it's been resolved.

@cramertj

This comment has been minimized.

Copy link
Member

commented May 8, 2019

@stjepang foo.await consumes the expression foo. If foo is an &mut T, for example, it'll act just as if you passed an &mut T into a function as an argument (i.e. you'll still be able to use it). If foo was a non-Copy value, it will be consumed.

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.