Add future::pinned combinator#1023
Conversation
| /// Created by the `borrowed` function. | ||
| #[must_use = "futures do nothing unless polled"] | ||
| #[allow(missing_debug_implementations)] | ||
| pub struct PinnedFut<'any, Data: 'any, Output, F: PinnedFn<Data, Output> + 'any> { |
There was a problem hiding this comment.
I can't actually make this work because I get stuck on that PinnedFut isn't allowed to outlive 'any no matter what I do. This seems like I need #[may_dangle], but somehow stronger. I don't even need a lifetime to be part of the type-- I just need a lifetime that does not outlive Data (can't always use 'static) but which will unify with other lifetimes.
There was a problem hiding this comment.
Even using 'static doesn't work-- then the implied WF checks for HRTB aren't kicking in for some reason: i get errors that T: for<'a> PinnedFnLt<'a, Data, Output> isn't satisfied if I add a where Self: 'a bound to PinnedFnLt.
|
Okay, I've got a minimal reproduction of the issue here. It seems like higher ranked bounds for traits implemented by closures like this don't work. |
|
Opened an issue: rust-lang/rust#51004 |
| // TODO: | ||
| // marker: Pinned, | ||
| // Data, which may be borrowed by `fn_or_fut`, must be dropped last | ||
| data: Data, |
There was a problem hiding this comment.
Maybe this should use ManuallyDrop so as to not rely on drop order?
(AFAIK drop order is actually "first field is dropped last", so this may even be wrong right now.)
|
I don't think I really understand what is going on here... what is the crazy stuff that's going on here, other than some funny shenanigans with |
|
@RalfJung One of the fields is being allowed to hold a |
|
Well, you can get a little bit further with this nowadays on nightly, but still the actual usage fails due to the way elision inside closures works: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=b480eb854734a23aa525cf60dc71a40d |
|
☔ The latest upstream changes (possibly #3001) made this pull request unmergeable. Please resolve the merge conflicts. |
This is a preliminary attempt at a massively unsafe manual self-borrowing future to allow working with borrowing
futurescombinators without relying onasync/await. I'm uncomfortable about the number of different crazy hacks happening here-- hopefully we can whittle those down. Ideally this wouldn't be replaced entirely by async/await someday, at which point we can remove this, but it could allow moving stable code over to the new borrowing versions of e.g.Stream::nextandAsyncRead::read.I'm not even sure that this is possible to express correctly in Rust's surface syntax, since the
Selftype contains a value as well as a live field with a live&mutinside of it.UnsafeCellisn't enough here, and I don't know what is. Perhaps it's enough to know that we never create an&mutreference toself.datawhileself.fn_or_futholds a future containing a reference toself.data? I wouldn't have thought so, but I don't know what to do otherwise. cc @Zoxc and @alexcrichton, who know how self-referential generators are implemented-- do they rely on special magic for this? cc also @RalfJung, primarily so they're aware of the crazy pinning shenanigans happening here.