# Reading notes: Language feature: in-place construction Link to document: https://y86-dev.github.io/blog/safe-pinned-initialization/in-place.html ###### tags: `reading-club` Leave questions, observations, discussion topics below. --- ## Topic name: prompt --- ### Are in-place constructors similar to `alloca`? Yosh: my knowledge of C / C++ is limited, but this seems to give similar vibes as alloca does? Instead of constructing a new thing and returning it, you take a reference to a location and construct the thing there - meaning you never have to move it. - (eholk) It's more like [placement new](https://www.cs.technion.ac.il/users/yechiel/c++-faq/placement-new.html) in C++. (I don't know if that link is actually good, it was just one that came up relatively high after searching :) ) How is this different from move constructors as well? mcyoung showed this on twitter recently: alloca in rust using const generics: ```rust fn static_alloca<const N: usize, R>(f: impl FnOnce(&mut [u8]) -> R) -> R { let mut buf = [0; N]; f(&mut buf) } ``` eholk: alloca is like malloc for the stack instead of the heap. This is for when you have memory already and want to turn it into a value of type T. eholk: Big benefit of in-place construction is that it gives you access to your self pointer before it's created. vincenzo: Main reason is to remove unsafe code in kernel crate. eholk: Is this removing unsafe, or shuffling it around? tmandry: Encapsulates unsafe in a macro and `Box` constructors. ### Follow-up question: don't we already have established ways of doing placement-new? Yosh: I think I was talking with Mara last week who mentioned something like that? My memory is a bit hazy, but I believe there should be ways of achieving placement-new already as well without using `unsafe`? Or am I completely off? tmandry: There's [`Box::new_in`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#method.new_in), not stable. tmandry: If you want to construct self-referential types you need in-place construction. We skipped past the [overview](https://y86-dev.github.io/blog/safe-pinned-initialization/overview.html) post that explains this, oops. eholk: The only way to do self-references is with raw pointers. No way to talk about this using e.g. `'self` in Rust. tmandry: I've seen in a talk about Polonius how we could use the "origins" framing to work toward something like this: ```rust struct Foo { data: String, subset: &'data str, } ``` (To be clear we don't get this with Polonius today!) Eric was trying to do this yesterday: ```rust struct Foo<F> where F: 'data { data: String, subset: F } ``` (the idea is `F` is a future that references `data`, but `data` can also be accessed outside the future) tmandry: Sounds a little like what the [yoke](https://docs.rs/yoke/latest/yoke/) crate does. ### Details Yosh: I remember reading [their previous post](https://github.com/y86-dev/blog/blob/main/safe-pinned-initialization/overview.md) a while back. It didn't make note of any of the problems relating to pin-projections such as what to do about `Drop`, or `#[repr(packed)]`, or `unsafe trait Unpin {}`. Idk, it feels like at least from the outset there are important details left unaddressed? Oh yeah, here's their "safe pin projections" RFC: https://github.com/rust-lang/rfcs/pull/3318. We should probably read this in a future session. tmandry: Agreed with reading the RFC ### PhantomData Tyler: Why PhantomData here? ```rust pub struct InitClosure<F, T, E>(F, PhantomData<fn(T, E) -> (T, E)>); ``` Eric: I think it's just because otherwise `T` and `E` wouldn't appear in the type. tmandry: Something something variance... putting T and E in both argument and return position makes those type parameters have invariant lifetimes. So if you have an initializer for `Foo<'a>` you can't pass it to something that expects you to initialize `Foo<'static>`, for example. ## New syntax Is it justified? Don't want to spend language complexity budget on niche use case. Start with macros, then usage can make the case. ## Appendix Rust-for-linux PR: https://github.com/Rust-for-Linux/linux/pull/909 (should be this) RustConf 2021 talk by Miguel Young de la Sota: https://youtube.com/watch?v=UrDhMWISR3w&feature=share - Was that the move constructors talk? - yes (: RFCs by the same author - [Field projection RFC](https://github.com/rust-lang/rfcs/pull/3318) More discussions on Zulip: https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/safe.20initialization