Skip to content

Commit 95c531a

Browse files
dingxiangfei2009BennoLossinDarksonn
committed
[lib] in-place initialization infrastructure
This is the initial design of the in-place initialization interface, without the `PinInit` part. Signed-off-by: Xiangfei Ding <[email protected]> Co-authored-by: Benno Lossin <[email protected]> Co-authored-by: Alice Ryhl <[email protected]>
1 parent cc87afd commit 95c531a

File tree

4 files changed

+66
-0
lines changed

4 files changed

+66
-0
lines changed

compiler/rustc_hir/src/lang_items.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,11 @@ language_item_table! {
350350

351351
MaybeUninit, sym::maybe_uninit, maybe_uninit, Target::Union, GenericRequirement::None;
352352

353+
Init, sym::init_trait, init_trait, Target::Trait, GenericRequirement::Exact(1);
354+
InitError, sym::init_error, init_error, Target::AssocTy, GenericRequirement::Exact(1);
355+
InitLayout, sym::init_layout, init_layout, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1);
356+
InitInit, sym::init_init, init_init, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::Exact(1);
357+
353358
Termination, sym::termination, termination, Target::Trait, GenericRequirement::None;
354359

355360
Try, sym::Try, try_trait, Target::Trait, GenericRequirement::None;

compiler/rustc_span/src/symbol.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,11 @@ symbols! {
12001200
infer_static_outlives_requirements,
12011201
inherent_associated_types,
12021202
inherit,
1203+
init,
1204+
init_error,
1205+
init_init,
1206+
init_layout,
1207+
init_trait,
12031208
inlateout,
12041209
inline,
12051210
inline_const,

library/core/src/init.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//! In-place initialization
2+
//!
3+
//! This module describes the interface through which types supporting in-place initialization
4+
//! interact with allocation mechanism to ensure correct and safe initialization of values
5+
//! within the memory slots provided by the allocation.
6+
7+
use crate::ptr::Pointee;
8+
9+
/// # Safety
10+
///
11+
/// Implementers must ensure that if `init` returns `Ok(metadata)`, then
12+
/// `core::ptr::from_raw_parts_mut(slot, metadata)` must reference a valid
13+
/// value owned by the caller. Furthermore, the layout returned by using
14+
/// `size_of` and `align_of` on this pointer must match what `Self::layout()`
15+
/// returns exactly.
16+
///
17+
/// Implementers must ensure that the implementation of `init()` does not rely
18+
/// on the value being pinned.
19+
#[unstable(feature = "in_place_initialization", issue = "999999")]
20+
#[lang = "init_trait"]
21+
pub unsafe trait Init<T: ?Sized + Pointee> {
22+
/// Error type upon initialization failure during the actual
23+
/// in-place initialization procedure.
24+
#[lang = "init_error"]
25+
type Error;
26+
27+
/// The layout needed by this initializer, which the allocation
28+
/// should arrange the destination memory slot accordingly.
29+
#[lang = "init_layout"]
30+
fn layout(&self) -> crate::alloc::Layout;
31+
32+
/// Writes a valid value of type `T` to `slot` or fails.
33+
///
34+
/// If this call returns [`Ok`], then `slot` is guaranteed to contain a valid
35+
/// value of type `T`. If `T` is unsized, then `slot` may be combined with
36+
/// the metadata to obtain a valid pointer to the value.
37+
///
38+
/// Note that `slot` should be thought of as a `*mut T`. A unit type is used
39+
/// so that the pointer is thin even if `T` is unsized.
40+
///
41+
/// # Safety
42+
///
43+
/// The caller must provide a pointer that references a location that `init`
44+
/// may write to, and the location must have at least the size and alignment
45+
/// specified by [`Init::layout`].
46+
///
47+
/// If this call returns `Ok` and the initializer does not implement
48+
/// `Init<T>`, then `slot` contains a pinned value, and the caller must
49+
/// respect the usual pinning requirements for `slot`.
50+
#[lang = "init_init"]
51+
unsafe fn init(self, slot: *mut ()) -> Result<T::Metadata, Self::Error>;
52+
}

library/core/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,10 @@ pub mod task;
363363
#[allow(missing_docs)]
364364
pub mod alloc;
365365

366+
/* In-place initialization */
367+
#[unstable(feature = "in_place_initialization", issue = "999999")]
368+
pub mod init;
369+
366370
// note: does not need to be public
367371
mod bool;
368372
mod escape;

0 commit comments

Comments
 (0)