|
| 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