1#![feature(maybe_uninit_ref)]
2#![feature(new_uninit)]
3#![feature(specialization)]
4
5use std::mem::MaybeUninit;
6
7pub trait PartialUninit: Sized {
9 fn partial_uninit() -> MaybeUninit<Self> {
10 let mut uninit = MaybeUninit::<Self>::uninit();
11 unsafe {
12 uninit.get_mut().partial_init();
13 }
14 uninit
15 }
16
17 fn boxed_partial_uninit() -> Box<MaybeUninit<Self>> {
18 let mut uninit = Box::<Self>::new_uninit();
19 unsafe {
20 uninit.get_mut().partial_init();
21 }
22 uninit
23 }
24
25 fn partial_init(&mut self);
26}
27
28impl<T> PartialUninit for T {
29 default fn partial_init(&mut self) {}
30}
31
32#[cfg(test)]
33mod tests {
34 use super::PartialUninit;
35 use std::mem::MaybeUninit;
36
37 #[test]
38 fn it_works() {
39 struct Struct {
40 a: u8,
41 b: u8,
42 }
43
44 impl PartialUninit for Struct {
45 fn partial_init(&mut self) {
46 self.a = 9;
47 }
48 }
49
50 let mut uninit: MaybeUninit<Struct> = PartialUninit::partial_uninit();
51 unsafe {
52 uninit.get_mut().b = 9;
53 }
54 let init = unsafe { uninit.assume_init() };
55 assert_eq!(init.a, 9);
56 assert_eq!(init.b, 9);
57 }
58}