@@ -178,8 +178,8 @@ impl<T: ?Sized> Clone for PtrComponents<T> {
178
178
/// compare equal (since identical vtables can be deduplicated within a codegen unit).
179
179
#[ lang = "dyn_metadata" ]
180
180
pub struct DynMetadata < Dyn : ?Sized > {
181
- vtable_ptr : & ' static VTable ,
182
- phantom : crate :: marker:: PhantomData < Dyn > ,
181
+ _vtable_ptr : & ' static VTable ,
182
+ _phantom : crate :: marker:: PhantomData < Dyn > ,
183
183
}
184
184
185
185
extern "C" {
@@ -191,6 +191,17 @@ extern "C" {
191
191
}
192
192
193
193
impl < Dyn : ?Sized > DynMetadata < Dyn > {
194
+ /// One of the things that rustc_middle does with this being a lang item is
195
+ /// give it `FieldsShape::Primitive`, which means that as far as codegen can
196
+ /// tell, it *is* a reference, and thus doesn't have any fields.
197
+ /// That means we can't use field access, and have to transmute it instead.
198
+ #[ inline]
199
+ fn vtable_ptr ( self ) -> * const VTable {
200
+ // SAFETY: this layout assumption is hard-coded into the compiler.
201
+ // If it's somehow not a size match, the transmute will error.
202
+ unsafe { crate :: mem:: transmute :: < Self , & ' static VTable > ( self ) }
203
+ }
204
+
194
205
/// Returns the size of the type associated with this vtable.
195
206
#[ inline]
196
207
pub fn size_of ( self ) -> usize {
@@ -199,7 +210,7 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> {
199
210
// `Send` part!
200
211
// SAFETY: DynMetadata always contains a valid vtable pointer
201
212
return unsafe {
202
- crate :: intrinsics:: vtable_size ( self . vtable_ptr as * const VTable as * const ( ) )
213
+ crate :: intrinsics:: vtable_size ( self . vtable_ptr ( ) as * const ( ) )
203
214
} ;
204
215
}
205
216
@@ -208,7 +219,7 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> {
208
219
pub fn align_of ( self ) -> usize {
209
220
// SAFETY: DynMetadata always contains a valid vtable pointer
210
221
return unsafe {
211
- crate :: intrinsics:: vtable_align ( self . vtable_ptr as * const VTable as * const ( ) )
222
+ crate :: intrinsics:: vtable_align ( self . vtable_ptr ( ) as * const ( ) )
212
223
} ;
213
224
}
214
225
@@ -226,7 +237,7 @@ unsafe impl<Dyn: ?Sized> Sync for DynMetadata<Dyn> {}
226
237
227
238
impl < Dyn : ?Sized > fmt:: Debug for DynMetadata < Dyn > {
228
239
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
229
- f. debug_tuple ( "DynMetadata" ) . field ( & ( self . vtable_ptr as * const VTable ) ) . finish ( )
240
+ f. debug_tuple ( "DynMetadata" ) . field ( & self . vtable_ptr ( ) ) . finish ( )
230
241
}
231
242
}
232
243
@@ -248,15 +259,15 @@ impl<Dyn: ?Sized> Eq for DynMetadata<Dyn> {}
248
259
impl < Dyn : ?Sized > PartialEq for DynMetadata < Dyn > {
249
260
#[ inline]
250
261
fn eq ( & self , other : & Self ) -> bool {
251
- crate :: ptr:: eq :: < VTable > ( self . vtable_ptr , other. vtable_ptr )
262
+ crate :: ptr:: eq :: < VTable > ( self . vtable_ptr ( ) , other. vtable_ptr ( ) )
252
263
}
253
264
}
254
265
255
266
impl < Dyn : ?Sized > Ord for DynMetadata < Dyn > {
256
267
#[ inline]
257
268
#[ allow( ambiguous_wide_pointer_comparisons) ]
258
269
fn cmp ( & self , other : & Self ) -> crate :: cmp:: Ordering {
259
- ( self . vtable_ptr as * const VTable ) . cmp ( & ( other. vtable_ptr as * const VTable ) )
270
+ < * const VTable > :: cmp ( & self . vtable_ptr ( ) , & other. vtable_ptr ( ) )
260
271
}
261
272
}
262
273
@@ -270,6 +281,6 @@ impl<Dyn: ?Sized> PartialOrd for DynMetadata<Dyn> {
270
281
impl < Dyn : ?Sized > Hash for DynMetadata < Dyn > {
271
282
#[ inline]
272
283
fn hash < H : Hasher > ( & self , hasher : & mut H ) {
273
- crate :: ptr:: hash :: < VTable , _ > ( self . vtable_ptr , hasher)
284
+ crate :: ptr:: hash :: < VTable , _ > ( self . vtable_ptr ( ) , hasher)
274
285
}
275
286
}
0 commit comments