Self-referencing struct w/ minimum of unsafe

While trying to figure out a way to eliminate a seemingly-redundant lifetime parameter, I had the realization that Rust already has support for one kind of self-referential struct: async blocks.

I wasn’t able to remove the parameter, but I did succeed in making something that looks like it might be able to solve the case where you want to keep an RAII guard long-term: I define a future that acquires whatever guards are necessary and then give an &mut T to a future that will never be ready. As long as that future isn’t cancelled, the borrow checker will make sure that the async code doesn’t violate the &mut guarantees and we can exfiltrate the reference via a raw pointer.

I’m curious if this general approach seems viable, and how it compares to the existing solutions in terms of safety. I also wanted to put this idea out there in case someone else wants to run with it— I don’t have the time to take this from a proof-of-concept to a production-ready crate.


Haven't looked at this stuff in detail yet, but the idea does sound similar to that of the crate mentioned in the last This Week In Rust blog post:



Thanks; I was not aware of this crate. It appears that we both came up with the same basic concept— nolife has more capabilities, and a correspondingly more-complicated API, but the core self-referencing code is strikingly similar to what I’ve written here.

Edit: Apparently, nolife originally had an API similar to this, and some of the complications are there to fix soundness holes. So, in order to keep things simple, Capsule::new will have to remain unsafe, only to ever be used with trusted futures.

That makes mine a building block that crates can build on for specific uses more than a general user-facing solution, which I’m OK with.

1 Like