futures-rs
futures-rs copied to clipboard
Add future::pinned combinator
This is a preliminary attempt at a massively unsafe manual self-borrowing future to allow working with borrowing futures combinators without relying on async/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::next and AsyncRead::read.
I'm not even sure that this is possible to express correctly in Rust's surface syntax, since the Self type contains a value as well as a live field with a live &mut inside of it. UnsafeCell isn't enough here, and I don't know what is. Perhaps it's enough to know that we never create an &mut reference to self.data while self.fn_or_fut holds a future containing a reference to self.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.
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: https://github.com/rust-lang/rust/issues/51004
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 for<'a> ... as a super trait bound?
@RalfJung One of the fields is being allowed to hold a PinMut reference into another field, and it may mutate that field.
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