2
2
3
3
use crate :: fmt;
4
4
use crate :: hash:: { Hash , Hasher } ;
5
- use crate :: ptr:: NonNull ;
6
5
7
6
/// FIXME docs
8
7
#[ lang = "pointee_trait" ]
@@ -62,17 +61,48 @@ impl<T: ?Sized> Clone for PtrComponents<T> {
62
61
/// The metadata for a `dyn SomeTrait` trait object type.
63
62
#[ lang = "dyn_metadata" ]
64
63
pub struct DynMetadata < Dyn : ?Sized > {
65
- #[ allow( unused) ]
66
- vtable_ptr : NonNull < ( ) > ,
64
+ vtable_ptr : & ' static VTable ,
67
65
phantom : crate :: marker:: PhantomData < Dyn > ,
68
66
}
69
67
68
+ /// The common prefix of all vtables. It is followed by function pointers for trait methods.
69
+ ///
70
+ /// Private implementation detail of `DynMetadata::size_of` etc.
71
+ #[ repr( C ) ]
72
+ struct VTable {
73
+ drop_in_place : fn ( * mut ( ) ) ,
74
+ size_of : usize ,
75
+ align_of : usize ,
76
+ }
77
+
78
+ impl < Dyn : ?Sized > DynMetadata < Dyn > {
79
+ /// Returns the size of the type associated with this vtable.
80
+ #[ inline]
81
+ pub fn size_of ( self ) -> usize {
82
+ self . vtable_ptr . size_of
83
+ }
84
+
85
+ /// Returns the alignment of the type associated with this vtable.
86
+ #[ inline]
87
+ pub fn align_of ( self ) -> usize {
88
+ self . vtable_ptr . align_of
89
+ }
90
+
91
+ /// Returns the size and alignment together as a `Layout`
92
+ #[ inline]
93
+ pub fn layout ( self ) -> crate :: alloc:: Layout {
94
+ // SAFETY: the compiler emitted this vtable for a concrete Rust type which
95
+ // is known to have a valid layout. Same rationale as in `Layout::for_value`.
96
+ unsafe { crate :: alloc:: Layout :: from_size_align_unchecked ( self . size_of ( ) , self . align_of ( ) ) }
97
+ }
98
+ }
99
+
70
100
unsafe impl < Dyn : ?Sized > Send for DynMetadata < Dyn > { }
71
101
unsafe impl < Dyn : ?Sized > Sync for DynMetadata < Dyn > { }
72
102
73
103
impl < Dyn : ?Sized > fmt:: Debug for DynMetadata < Dyn > {
74
104
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
75
- f. write_str ( "DynMetadata { … }" )
105
+ f. debug_tuple ( "DynMetadata" ) . field ( & ( self . vtable_ptr as * const VTable ) ) . finish ( )
76
106
}
77
107
}
78
108
@@ -94,27 +124,27 @@ impl<Dyn: ?Sized> Eq for DynMetadata<Dyn> {}
94
124
impl < Dyn : ?Sized > PartialEq for DynMetadata < Dyn > {
95
125
#[ inline]
96
126
fn eq ( & self , other : & Self ) -> bool {
97
- self . vtable_ptr == other. vtable_ptr
127
+ crate :: ptr :: eq :: < VTable > ( self . vtable_ptr , other. vtable_ptr )
98
128
}
99
129
}
100
130
101
131
impl < Dyn : ?Sized > Ord for DynMetadata < Dyn > {
102
132
#[ inline]
103
133
fn cmp ( & self , other : & Self ) -> crate :: cmp:: Ordering {
104
- self . vtable_ptr . cmp ( & other. vtable_ptr )
134
+ ( self . vtable_ptr as * const VTable ) . cmp ( & ( other. vtable_ptr as * const VTable ) )
105
135
}
106
136
}
107
137
108
138
impl < Dyn : ?Sized > PartialOrd for DynMetadata < Dyn > {
109
139
#[ inline]
110
140
fn partial_cmp ( & self , other : & Self ) -> Option < crate :: cmp:: Ordering > {
111
- Some ( self . vtable_ptr . cmp ( & other. vtable_ptr ) )
141
+ Some ( self . cmp ( other) )
112
142
}
113
143
}
114
144
115
145
impl < Dyn : ?Sized > Hash for DynMetadata < Dyn > {
116
146
#[ inline]
117
147
fn hash < H : Hasher > ( & self , hasher : & mut H ) {
118
- self . vtable_ptr . hash ( hasher)
148
+ crate :: ptr :: hash :: < VTable , _ > ( self . vtable_ptr , hasher)
119
149
}
120
150
}
0 commit comments