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.

`