Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Safe placement new as a library #46

@crlf0710

Description

@crlf0710

Assume we have

struct S{ a: u32 }
struct T { s: S, t: [u32; 5] }
fn foo(x: bool) -> u32 { ... }

and let mut v = MaybeUninit::uninit();
design a macro called init, when invoked as
init!(v, T { s: S { a: f1 }, t: [f2; 5] }, f1 = foo(true), f2 = foo(false));, it gets expanded into:

{
   let f1 = foo(true);
   let f2 = foo(false);
   let v_mut_ptr = v.as_mut_ptr();
   unsafe {
       // FIXME: static assert T can be initialized by initializing "s" and "t"
       let s_mut_ptr = &mut (*v_mut_ptr).s as * mut S;
       // FIXME: static assert S can be initialized by initializing "a"
       std::ptr::write(&mut (*s_mut_ptr).a, f1);
       std::ptr::write(&mut (*v_mut_ptr).t, [f2; 5]);
   }
}

The key points is that there's no panicking possibility within the unsafe region. And compiler will properly check about the Copy-ability of f2.

This serves as basis of higher-level macros like boxed , boxed!(S {a: f1}, f1 = foo(true)) get expanded into:

{
    let mut b = Box::new_uninit();
    init!(b.as_mut(), S {a: f1}, f1 = foo(true));
    unsafe { b.assume_init() }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions