@@ -23,51 +23,56 @@ pub struct Arena {
23
23
}
24
24
25
25
/// A pointer to an uninitialized region of memory.
26
- pub struct Uninitialized < ' arena , T : ' arena > {
27
- pointer : & ' arena mut T ,
26
+ pub struct Uninitialized < ' arena , T : Copy + ' arena > {
27
+ pointer : & ' arena mut MaybeUninit < T > ,
28
28
}
29
29
30
- impl < ' arena , T : ' arena > Uninitialized < ' arena , T > {
30
+ /// Almost a copy of https://github.com/rust-lang/rust/issues/53491
31
+ union MaybeUninit < T : Copy > {
32
+ value : T ,
33
+ _uninit : ( ) ,
34
+ }
35
+
36
+ impl < ' arena , T : Copy + ' arena > Uninitialized < ' arena , T > {
31
37
/// Initialize the memory at the pointer with a given value.
32
38
#[ inline]
33
39
pub fn init ( self , value : T ) -> & ' arena mut T {
34
- * self . pointer = value;
35
-
36
- self . pointer
40
+ unsafe {
41
+ self . pointer . value = value;
42
+ & mut self . pointer . value
43
+ }
37
44
}
38
45
39
46
/// Get a reference to the pointer without writing to it.
40
47
///
41
- /// **Reading from this reference without calling `init` is undefined behavior.**
48
+ /// **Calling this method without calling `init` is undefined behavior.**
42
49
#[ inline]
43
50
pub unsafe fn as_ref ( & self ) -> & ' arena T {
44
- & * ( self . pointer as * const T )
51
+ & * ( & self . pointer . value as * const T )
45
52
}
46
53
47
54
/// Convert the `Uninitialized` to a regular mutable reference.
48
55
///
49
- /// **Reading from this reference without calling `init` is undefined behavior.**
56
+ /// **Calling this method without calling `init` is undefined behavior.**
50
57
#[ inline]
51
58
pub unsafe fn as_mut_ref ( self ) -> & ' arena mut T {
52
- self . pointer
59
+ & mut self . pointer . value
53
60
}
54
61
55
62
/// Convert a raw pointer to an `Uninitialized`. This method is unsafe since it can
56
63
/// bind to arbitrary lifetimes.
57
64
#[ inline]
58
65
pub unsafe fn from_raw ( pointer : * mut T ) -> Self {
59
66
Uninitialized {
60
- pointer : & mut * pointer,
67
+ pointer : & mut * ( pointer as * mut MaybeUninit < T > ) ,
61
68
}
62
69
}
63
70
}
64
71
65
- impl < ' arena , T : ' arena > From < & ' arena mut T > for Uninitialized < ' arena , T > {
72
+ impl < ' arena , T : Copy + ' arena > From < & ' arena mut T > for Uninitialized < ' arena , T > {
66
73
#[ inline]
67
74
fn from ( pointer : & ' arena mut T ) -> Self {
68
- Uninitialized {
69
- pointer
70
- }
75
+ unsafe { Self :: from_raw ( pointer) }
71
76
}
72
77
}
73
78
@@ -167,7 +172,7 @@ impl Arena {
167
172
#[ inline]
168
173
pub fn alloc_uninitialized < ' arena , T : Sized + Copy > ( & ' arena self ) -> Uninitialized < ' arena , T > {
169
174
Uninitialized {
170
- pointer : unsafe { & mut * ( self . require ( size_of :: < T > ( ) ) as * mut T ) }
175
+ pointer : unsafe { & mut * ( self . require ( size_of :: < T > ( ) ) as * mut MaybeUninit < T > ) } ,
171
176
}
172
177
}
173
178
0 commit comments