owned this note
owned this note
Published
Linked with GitHub
# 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