@@ -178,8 +178,8 @@ impl<T: ?Sized> Clone for PtrComponents<T> {
178178/// compare equal (since identical vtables can be deduplicated within a codegen unit).
179179#[ lang = "dyn_metadata" ]
180180pub 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 > ,
183183}
184184
185185extern "C" {
@@ -191,6 +191,17 @@ extern "C" {
191191}
192192
193193impl < 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+
194205 /// Returns the size of the type associated with this vtable.
195206 #[ inline]
196207 pub fn size_of ( self ) -> usize {
@@ -199,7 +210,7 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> {
199210 // `Send` part!
200211 // SAFETY: DynMetadata always contains a valid vtable pointer
201212 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 ( ) )
203214 } ;
204215 }
205216
@@ -208,7 +219,7 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> {
208219 pub fn align_of ( self ) -> usize {
209220 // SAFETY: DynMetadata always contains a valid vtable pointer
210221 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 ( ) )
212223 } ;
213224 }
214225
@@ -226,7 +237,7 @@ unsafe impl<Dyn: ?Sized> Sync for DynMetadata<Dyn> {}
226237
227238impl < Dyn : ?Sized > fmt:: Debug for DynMetadata < Dyn > {
228239 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 ( )
230241 }
231242}
232243
@@ -248,15 +259,15 @@ impl<Dyn: ?Sized> Eq for DynMetadata<Dyn> {}
248259impl < Dyn : ?Sized > PartialEq for DynMetadata < Dyn > {
249260 #[ inline]
250261 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 ( ) )
252263 }
253264}
254265
255266impl < Dyn : ?Sized > Ord for DynMetadata < Dyn > {
256267 #[ inline]
257268 #[ allow( ambiguous_wide_pointer_comparisons) ]
258269 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 ( ) )
260271 }
261272}
262273
@@ -270,6 +281,6 @@ impl<Dyn: ?Sized> PartialOrd for DynMetadata<Dyn> {
270281impl < Dyn : ?Sized > Hash for DynMetadata < Dyn > {
271282 #[ inline]
272283 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)
274285 }
275286}
0 commit comments