1
1
use {
2
- crate :: { Aligned , AlignedMut , Destructure , Restructure , StructuralPinning } ,
2
+ crate :: { Destructure , Restructure , StructuralPinning } ,
3
3
:: core:: {
4
4
cell:: { Cell , UnsafeCell } ,
5
5
mem:: { ManuallyDrop , MaybeUninit } ,
6
6
pin:: Pin ,
7
7
} ,
8
8
} ;
9
9
10
- // Aligned<T>
10
+ // *const T
11
11
12
- impl < T : ?Sized > Destructure for Aligned < T > {
12
+ // SAFETY: Destructuring `*const T` is safe if and only if destructuring `T` with the same pattern
13
+ // is also safe.
14
+ unsafe impl < T > Destructure for * const T {
13
15
type Underlying = T ;
16
+ type Test = T ;
14
17
15
18
fn as_mut_ptr ( & mut self ) -> * mut Self :: Underlying {
16
- * * self as * mut T
19
+ * self as * mut T
17
20
}
18
21
}
19
22
20
- unsafe impl < T : ?Sized , U : ?Sized > Restructure < & Aligned < T > > for U {
21
- type Restructured = Aligned < Self > ;
23
+ // SAFETY: `restructure` returns a valid `*const U` that upholds the same invariants as a mutably
24
+ // borrowed subfield of some `T`.
25
+ unsafe impl < T : ?Sized , U : ?Sized > Restructure < & * const T > for U {
26
+ type Restructured = * const U ;
22
27
23
28
unsafe fn restructure ( ptr : * mut Self ) -> Self :: Restructured {
24
- // SAFETY: The caller has guaranteed that `ptr` is properly aligned.
25
- unsafe { Aligned :: new_unchecked ( ptr as * const Self ) }
29
+ ptr as * const Self
26
30
}
27
31
}
28
32
29
- // AlignedMut<T>
33
+ // *mut T
30
34
31
- impl < T : ?Sized > Destructure for AlignedMut < T > {
35
+ // SAFETY: Destructuring `*mut T` is safe if and only if destructuring `T` with the same pattern is
36
+ // also safe.
37
+ unsafe impl < T > Destructure for * mut T {
32
38
type Underlying = T ;
39
+ type Test = T ;
33
40
34
41
fn as_mut_ptr ( & mut self ) -> * mut Self :: Underlying {
35
- * * self
42
+ * self
36
43
}
37
44
}
38
45
39
- unsafe impl < T : ?Sized , U : ?Sized > Restructure < & AlignedMut < T > > for U {
40
- type Restructured = AlignedMut < Self > ;
46
+ // SAFETY: `restructure` returns a valid `*mut U` that upholds the same invariants as a mutably
47
+ // borrowed subfield of some `T`.
48
+ unsafe impl < T : ?Sized , U : ?Sized > Restructure < & * mut T > for U {
49
+ type Restructured = * mut U ;
41
50
42
51
unsafe fn restructure ( ptr : * mut Self ) -> Self :: Restructured {
43
- // SAFETY: The caller has guaranteed that `ptr` is properly aligned.
44
- unsafe { AlignedMut :: new_unchecked ( ptr) }
52
+ ptr
45
53
}
46
54
}
47
55
48
- // &MaybeUninit
56
+ // &MaybeUninit<T>
49
57
50
- impl < ' a , T > Destructure for & ' a MaybeUninit < T > {
58
+ // SAFETY: Destructuring `&'a MaybeUninit<T>` is safe if and only if destructuring `&'a T` with the
59
+ // same pattern is also safe.
60
+ unsafe impl < ' a , T > Destructure for & ' a MaybeUninit < T > {
51
61
type Underlying = T ;
62
+ type Test = & ' a T ;
52
63
53
64
fn as_mut_ptr ( & mut self ) -> * mut Self :: Underlying {
54
65
self . as_ptr ( ) as * mut Self :: Underlying
55
66
}
56
67
}
57
68
69
+ // SAFETY: `restructure` returns a valid `MaybeUninit` reference that upholds the same invariants as
70
+ // a mutably borrowed subfield of some `T`.
58
71
unsafe impl < ' a : ' b , ' b , T , U : ' b > Restructure < & ' b & ' a MaybeUninit < T > > for U {
59
72
type Restructured = & ' b MaybeUninit < U > ;
60
73
@@ -65,16 +78,21 @@ unsafe impl<'a: 'b, 'b, T, U: 'b> Restructure<&'b &'a MaybeUninit<T>> for U {
65
78
}
66
79
}
67
80
68
- // &mut MaybeUninit
81
+ // &mut MaybeUninit<T>
69
82
70
- impl < ' a , T > Destructure for & ' a mut MaybeUninit < T > {
83
+ // SAFETY: Destructuring `&'a mut MaybeUninit<T>` is safe if and only if destructuring `&'a mut T`
84
+ // with the same pattern is also safe.
85
+ unsafe impl < ' a , T > Destructure for & ' a mut MaybeUninit < T > {
71
86
type Underlying = T ;
87
+ type Test = & ' a T ;
72
88
73
89
fn as_mut_ptr ( & mut self ) -> * mut Self :: Underlying {
74
90
MaybeUninit :: as_mut_ptr ( self )
75
91
}
76
92
}
77
93
94
+ // SAFETY: `restructure` returns a valid `MaybeUninit` reference that upholds the same invariants as
95
+ // a mutably borrowed subfield of some `T`.
78
96
unsafe impl < ' a : ' b , ' b , T , U : ' b > Restructure < & ' b & ' a mut MaybeUninit < T > > for U {
79
97
type Restructured = & ' b mut MaybeUninit < U > ;
80
98
@@ -87,56 +105,78 @@ unsafe impl<'a: 'b, 'b, T, U: 'b> Restructure<&'b &'a mut MaybeUninit<T>> for U
87
105
88
106
// &Cell<T>
89
107
90
- impl < ' a , T > Destructure for & ' a Cell < T > {
108
+ // SAFETY: Destructuring `&'a Cell<T>` is safe if and only if destructuring `&'a T` with the same
109
+ // pattern is also safe.
110
+ unsafe impl < ' a , T : ?Sized > Destructure for & ' a Cell < T > {
91
111
type Underlying = T ;
112
+ type Test = & ' a T ;
92
113
93
114
fn as_mut_ptr ( & mut self ) -> * mut Self :: Underlying {
94
115
self . as_ptr ( )
95
116
}
96
117
}
97
118
98
- unsafe impl < ' a : ' b , ' b , T , U : ' b > Restructure < & ' b & ' a Cell < T > > for U {
119
+ // SAFETY: `restructure` returns a valid `Cell` reference that upholds the same invariants as a
120
+ // mutably borrowed subfield of some `T`.
121
+ unsafe impl < ' a : ' b , ' b , T : ?Sized , U : ' b + ?Sized > Restructure < & ' b & ' a Cell < T > > for U {
99
122
type Restructured = & ' b Cell < U > ;
100
123
101
124
unsafe fn restructure ( ptr : * mut Self ) -> Self :: Restructured {
102
125
// SAFETY: The caller has guaranteed that `ptr` points to a subfield of some
103
- // `&'b &'a Cell<T>`, so it's safe to dereference for the `'b` lifetime.
104
- unsafe { & * ptr. cast ( ) }
126
+ // `&'b &'a Cell<T>`, so it's safe to dereference for the `'b` lifetime. Additionally, `ptr`
127
+ // is guaranteed to have the same pointer metadata as a pointer to `Cell<U>`.
128
+ unsafe { & * :: core:: mem:: transmute :: < * mut Self , * const Cell < U > > ( ptr) }
105
129
}
106
130
}
107
131
108
132
// &UnsafeCell<T>
109
133
110
- impl < ' a , T > Destructure for & ' a UnsafeCell < T > {
134
+ // SAFETY: Destructuring `&'a UnsafeCell<T>` is safe if and only if destructuring `&'a T` with the
135
+ // same pattern is also safe.
136
+ unsafe impl < ' a , T : ?Sized > Destructure for & ' a UnsafeCell < T > {
111
137
type Underlying = T ;
138
+ type Test = & ' a T ;
112
139
113
140
fn as_mut_ptr ( & mut self ) -> * mut Self :: Underlying {
114
141
self . get ( )
115
142
}
116
143
}
117
144
118
- unsafe impl < ' a : ' b , ' b , T , U : ' b > Restructure < & ' b & ' a UnsafeCell < T > > for U {
145
+ // SAFETY: `restructure` returns a valid `UnsafeCell` reference that upholds the same invariants as
146
+ // a mutably borrowed subfield of some `T`.
147
+ unsafe impl < ' a : ' b , ' b , T : ?Sized , U : ' b + ?Sized > Restructure < & ' b & ' a UnsafeCell < T > > for U {
119
148
type Restructured = & ' b UnsafeCell < U > ;
120
149
121
150
unsafe fn restructure ( ptr : * mut Self ) -> Self :: Restructured {
122
151
// SAFETY: The caller has guaranteed that `ptr` points to a subfield of some
123
- // `&'b &'a UnsafeCell<T>`, so it's safe to dereference for the `'b` lifetime.
124
- unsafe { & * ptr. cast ( ) }
152
+ // `&'b &'a UnsafeCell<T>`, so it's safe to dereference for the `'b` lifetime. Additionally,
153
+ // `ptr` is guaranteed to have the same pointer metadata as a pointer to `UnsafeCell<U>`.
154
+ unsafe { & * :: core:: mem:: transmute :: < * mut Self , * const UnsafeCell < U > > ( ptr) }
125
155
}
126
156
}
127
157
128
158
// Pin<&T> where T: StructuralPinning
129
159
130
- impl < ' a , T : StructuralPinning > Destructure for Pin < & ' a T > {
160
+ // SAFETY: Destructuring `Pin<&'a T>` is safe if and only if destructuring `&'a T` with the same
161
+ // pattern is also safe.
162
+ unsafe impl < ' a , T : StructuralPinning + ?Sized > Destructure for Pin < & ' a T > {
131
163
type Underlying = T ;
164
+ type Test = & ' a T ;
132
165
133
166
fn as_mut_ptr ( & mut self ) -> * mut Self :: Underlying {
134
167
// SAFETY: The value pointed to by `self` will continue to be treated as pinned.
135
168
unsafe { Pin :: into_inner_unchecked ( self . as_ref ( ) ) as * const T as * mut T }
136
169
}
137
170
}
138
171
139
- unsafe impl < ' a : ' b , ' b , T : StructuralPinning , U : ' b > Restructure < & ' b Pin < & ' a T > > for U {
172
+ // SAFETY: `restructure` returns a valid `Pin<&'a T>` that upholds the same invariants as a mutably
173
+ // borrowed subfield of some `T`.
174
+ unsafe impl < ' a , ' b , T , U > Restructure < & ' b Pin < & ' a T > > for U
175
+ where
176
+ ' a : ' b ,
177
+ T : StructuralPinning + ?Sized ,
178
+ U : ' b + ?Sized ,
179
+ {
140
180
type Restructured = Pin < & ' b U > ;
141
181
142
182
unsafe fn restructure ( ptr : * mut Self ) -> Self :: Restructured {
@@ -149,16 +189,26 @@ unsafe impl<'a: 'b, 'b, T: StructuralPinning, U: 'b> Restructure<&'b Pin<&'a T>>
149
189
150
190
// Pin<&mut T> where T: StructuralPinning
151
191
152
- impl < ' a , T : StructuralPinning > Destructure for Pin < & ' a mut T > {
192
+ // SAFETY: Destructuring `Pin<&'a mut T>` is safe if and only if destructuring `&'a T` with the same
193
+ // pattern is also safe.
194
+ unsafe impl < ' a , T : StructuralPinning + ?Sized > Destructure for Pin < & ' a mut T > {
153
195
type Underlying = T ;
196
+ type Test = & ' a T ;
154
197
155
198
fn as_mut_ptr ( & mut self ) -> * mut Self :: Underlying {
156
199
// SAFETY: The value pointed to by `self` will continue to be treated as pinned.
157
200
unsafe { Pin :: into_inner_unchecked ( self . as_mut ( ) ) as * mut T }
158
201
}
159
202
}
160
203
161
- unsafe impl < ' a : ' b , ' b , T : StructuralPinning , U : ' b > Restructure < & ' b Pin < & ' a mut T > > for U {
204
+ // SAFETY: `restructure` returns a valid `Pin<&'a mut T>` that upholds the same invariants as a
205
+ // mutably borrowed subfield of some `T`.
206
+ unsafe impl < ' a , ' b , T , U > Restructure < & ' b Pin < & ' a mut T > > for U
207
+ where
208
+ ' a : ' b ,
209
+ T : StructuralPinning + ?Sized ,
210
+ U : ' b + ?Sized ,
211
+ {
162
212
type Restructured = Pin < & ' b mut U > ;
163
213
164
214
unsafe fn restructure ( ptr : * mut Self ) -> Self :: Restructured {
@@ -171,14 +221,19 @@ unsafe impl<'a: 'b, 'b, T: StructuralPinning, U: 'b> Restructure<&'b Pin<&'a mut
171
221
172
222
// ManuallyDrop<T>
173
223
174
- impl < ' a , T > Destructure for ManuallyDrop < T > {
224
+ // SAFETY: Destructuring `ManuallyDrop<T>` is safe if and only if destructuring `T` with the same
225
+ // pattern is also safe.
226
+ unsafe impl < ' a , T > Destructure for ManuallyDrop < T > {
175
227
type Underlying = T ;
228
+ type Test = T ;
176
229
177
230
fn as_mut_ptr ( & mut self ) -> * mut Self :: Underlying {
178
231
& mut * * self as * mut Self :: Underlying
179
232
}
180
233
}
181
234
235
+ // SAFETY: `restructure` returns a valid `ManuallyDrop<T>` that upholds the same invariants as a
236
+ // mutably borrowed subfield of some `T`.
182
237
unsafe impl < T , U > Restructure < & ManuallyDrop < T > > for U {
183
238
type Restructured = ManuallyDrop < U > ;
184
239
0 commit comments