Rollup merge of #127859 - RalfJung:ptr-dyn-metadata, r=scottmcm · model-checking/verify-rust-std@3d50720 (original) (raw)
`@@ -5,6 +5,7 @@ use crate::hash::{Hash, Hasher};
`
5
5
`use crate::intrinsics::aggregate_raw_ptr;
`
6
6
`use crate::intrinsics::ptr_metadata;
`
7
7
`use crate:📑:Freeze;
`
``
8
`+
use crate::ptr::NonNull;
`
8
9
``
9
10
`/// Provides the pointer metadata type of any pointed-to type.
`
10
11
`///
`
`@@ -153,7 +154,7 @@ pub const fn from_raw_parts_mut<T: ?Sized>(
`
153
154
`/// compare equal (since identical vtables can be deduplicated within a codegen unit).
`
154
155
`#[lang = "dyn_metadata"]
`
155
156
`pub struct DynMetadata<Dyn: ?Sized> {
`
156
``
`-
_vtable_ptr: &'static VTable,
`
``
157
`+
_vtable_ptr: NonNull,
`
157
158
`_phantom: crate:📑:PhantomData,
`
158
159
`}
`
159
160
``
`@@ -166,15 +167,18 @@ extern "C" {
`
166
167
`}
`
167
168
``
168
169
`impl<Dyn: ?Sized> DynMetadata {
`
169
``
`-
/// One of the things that rustc_middle does with this being a lang item is
`
170
``
`` -
/// give it FieldsShape::Primitive
, which means that as far as codegen can
``
171
``
`-
/// tell, it is a reference, and thus doesn't have any fields.
`
172
``
`-
/// That means we can't use field access, and have to transmute it instead.
`
``
170
`` +
/// When DynMetadata
appears as the metadata field of a wide pointer, the rustc_middle layout
``
``
171
`` +
/// computation does magic and the resulting layout is not a FieldsShape::Aggregate
, instead
``
``
172
`` +
/// it is a FieldsShape::Primitive
. This means that the same type can have different layout
``
``
173
`+
/// depending on whether it appears as the metadata field of a wide pointer or as a stand-alone
`
``
174
`+
/// type, which understandably confuses codegen and leads to ICEs when trying to project to a
`
``
175
`` +
/// field of DynMetadata
. To work around that issue, we use transmute
instead of using a
``
``
176
`+
/// field projection.
`
173
177
`#[inline]
`
174
178
`fn vtable_ptr(self) -> *const VTable {
`
175
179
`// SAFETY: this layout assumption is hard-coded into the compiler.
`
176
180
`// If it's somehow not a size match, the transmute will error.
`
177
``
`-
unsafe { crate::mem::transmute::<Self, &'static VTable>(self) }
`
``
181
`+
unsafe { crate::mem::transmute::<Self, *const VTable>(self) }
`
178
182
`}
`
179
183
``
180
184
`/// Returns the size of the type associated with this vtable.
`