Skip to content

Commit 46d74a9

Browse files
committed
Add in-place initialization goal
1 parent 0d0f95d commit 46d74a9

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

src/2025h2/in-place-initialization.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# In-place initialization
2+
3+
| Metadata | |
4+
|:-----------------|----------------------------------------------------------------------------------|
5+
| Point of contact | @Darksonn |
6+
| Teams | <!-- TEAMS WITH ASKS --> |
7+
| Task owners | <!-- TASK OWNERS --> |
8+
| Status | Proposed |
9+
| Tracking issue | |
10+
| Zulip channel | [#t-lang][channel] |
11+
12+
[channel]: https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang
13+
14+
## Summary
15+
16+
Evaluate approaches for in-place initialization and pick one.
17+
18+
## Motivation
19+
20+
This project goal aims to find an ergonomic mechanism for in-place
21+
initialization so that we can add it to the language.
22+
23+
### The status quo
24+
25+
There are multiple projects that are running into various problems that can only
26+
be solved using a mechanism for in-place initialization. Each project has
27+
implemented their own independent and slightly different solution in external
28+
crates relying on complex macros at the cost of ergonomics.
29+
30+
It's time to learn from the extensive amount of experimentation in the ecosystem
31+
and create a language feature that provides a shared solution that can be more
32+
ergonomic than what is possible in an external crate.
33+
34+
#### Current proposals and implementations
35+
36+
* [Init expressions] were proposed by [Alice Ryhl] based on work originally by
37+
[Benno Lossin] and [Gary Guo].
38+
* [Initialization via out-ptrs] was proposed by [Taylor Cramer].
39+
* [Placing functions] were proposed by [Yoshua Wuyts].
40+
* The [Placement by return] RFC was opened in 2020 by [Olivier Faure].
41+
* For the Linux Kernel, there is the [pin-init] crate.
42+
* For C++ interop, there is the [moveit] crate, and the descendent [Ctor] trait
43+
from Crubit.
44+
* There is already an [open lang experiement][lang-experiment] on init
45+
expressions and supporting async fn in dyn trait, which is being implemented
46+
by [Michael Goulet] and [Ding Xiang Fei].
47+
48+
[Init expressions]: https://hackmd.io/@aliceryhl/BJutRcPblx
49+
[Initialization via out-ptrs]: https://hackmd.io/awB-GOYJRlua9Cuc0a3G-Q
50+
[Placing functions]: https://blog.yoshuawuyts.com/placing-functions/
51+
[Placement by return]: https://github.com/rust-lang/rfcs/pull/2884
52+
[Alice Ryhl]: https://github.com/Darksonn
53+
[Benno Lossin]: https://github.com/BennoLossin
54+
[Gary Guo]: https://github.com/nbdd0121
55+
[Taylor Cramer]: https://github.com/cramertj
56+
[Yoshua Wuyts]: https://github.com/yoshuawuyts
57+
[Olivier Faure]: https://github.com/PoignardAzur
58+
[pin-init]: https://github.com/rust-for-linux/pin-init
59+
[moveit]: https://docs.rs/moveit/latest/moveit/new/trait.New.html
60+
[Ctor]: https://github.com/google/crubit/blob/c65afa7b2923a2d4c9528f16f7bfd4aef6c80b86/support/ctor.rs#L189-L226
61+
[lang-experiment]: https://github.com/rust-lang/lang-team/issues/336
62+
[Michael Goulet]: https://github.com/compiler-errors
63+
[Ding Xiang Fei]: https://github.com/dingxiangfei2009
64+
65+
### The next 6 months
66+
67+
Today, there are multiple different competing proposals for how in-place
68+
initialization should work. For the next 6 months, the primary aim of this goal
69+
is to figure out which proposal (or combination of proposals!) is best and pick
70+
one.
71+
72+
There may also be some amount of experimentation with the proposals as part of
73+
the lang experiment. This may also involve experiments to refactor e.g. the
74+
Linux Kernel or Crubit to use a proposal to see how well it works in the real
75+
world. Actually attempting to land the feature is out of scope for the next six
76+
months.
77+
78+
### The "shiny future" we are working towards
79+
80+
In the shiny future, Rust will be a language that supports in-place
81+
initialization in a way that is efficient, ergonomic, easy-to-use. The language
82+
may utilize in-place initialization to provide the following five features:
83+
84+
#### Avoid stack overflow when creating values on the heap
85+
86+
When creating a boxed value, in-place initialization allows you to construct the
87+
value in-place directly in the location on the heap. This avoids stack overflow
88+
crashes when the value is large.
89+
90+
#### C++ interop
91+
92+
Most values in C++ are not trivially relocatable. This means that you must run
93+
user-defined code (the move constructor) to move them from one address to
94+
another. Pinned in-place initialization provides a natural way to translate C++
95+
constructors into Rust.
96+
97+
#### Constructors returning pinned values
98+
99+
When interacting with C code such as the Linux kernel, constructors for C types
100+
often take an out pointer to initialize the value in. It's usually not safe to
101+
memcpy the resulting C value to a different location, which means that the value
102+
must be pinned immediately on creation. By using pinned in-place initialization,
103+
it is natural to work with this kind of value in Rust.
104+
105+
For this to be ergonomic, it's important that you can embed these values as
106+
fields in your own Rust structs, and that initialization can be fallible.
107+
108+
#### Async fn in dyn Trait
109+
110+
Trait objects can have async functions. When an async function is called, the
111+
future is initialized in-place into a user-provided location. The same feature
112+
also extends to other `-> impl Trait` return types in trait objects.
113+
114+
The same feature could potentially extend to any function returning an unsized
115+
type.
116+
117+
#### Custom self-referential types
118+
119+
In the constructor for your custom struct, you know the final address of each
120+
field, so you can safely create a situation where one field borrows from another
121+
field. Since the struct being initialized is immediately pinned, there is no
122+
risk that the caller will memcpy the value to a different location and
123+
invalidate internal references.
124+
125+
## Design axioms
126+
127+
We must remember to **take advantage of the language**. It has already been
128+
proven multiple times that in-place initialization can be implemented in an
129+
external crate with macros. Are there any possible ergonomics wins that are
130+
possible only by adding a real language feature?
131+
132+
## Ownership and team asks
133+
134+
Since the primary objective of this project goal is to choose a solution, this
135+
project goals asks the lang-team for *two* design meetings. There is already [a
136+
meeting scheduled on July 30th][design-meeting], which is at the beginning of
137+
the goal period. This project goal asks the lang team for a second meeting near
138+
the end of the goal period, in addition to the one that has already been
139+
scheduled.
140+
141+
[design-meeting]: https://github.com/rust-lang/lang-team/issues/332
142+
143+
| Task | Owner(s) or team(s) | Notes |
144+
|------------------------------|---------------------------------------|-------|
145+
| Discussion and moral support | ![Team][] [lang] | |
146+
| Two design meetings | ![Team][] [lang] | |
147+
| Be the main author of an RFC | @Darksonn | |
148+
| Contribute to the RFC | @cramertj, @yoshuawuyts, @BennoLossin, @nbdd0121 | |
149+
| Lang-team liason | @joshtriplett | |
150+
| Dedicated reviewer | @compiler-errors | Of lang experiments |
151+

0 commit comments

Comments
 (0)