Rollup merge of #129091 - RalfJung:box_as_ptr, r=Amanieu · patricklam/verify-rust-std@3a8de95 (original) (raw)

`@@ -1254,6 +1254,95 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {

`

1254

1254

`unsafe { (Unique::from(&mut *ptr), alloc) }

`

1255

1255

`}

`

1256

1256

``

``

1257

`` +

/// Returns a raw mutable pointer to the Box's contents.

``

``

1258

`+

///

`

``

1259

`` +

/// The caller must ensure that the Box outlives the pointer this

``

``

1260

`+

/// function returns, or else it will end up dangling.

`

``

1261

`+

///

`

``

1262

`+

/// This method guarantees that for the purpose of the aliasing model, this method

`

``

1263

`+

/// does not materialize a reference to the underlying memory, and thus the returned pointer

`

``

1264

`` +

/// will remain valid when mixed with other calls to [as_ptr] and [as_mut_ptr].

``

``

1265

`+

/// Note that calling other methods that materialize references to the memory

`

``

1266

`+

/// may still invalidate this pointer.

`

``

1267

`+

/// See the example below for how this guarantee can be used.

`

``

1268

`+

///

`

``

1269

`+

/// # Examples

`

``

1270

`+

///

`

``

1271

`+

/// Due to the aliasing guarantee, the following code is legal:

`

``

1272

`+

///

`

``

1273


/// ```rust

``

1274

`+

/// #![feature(box_as_ptr)]

`

``

1275

`+

///

`

``

1276

`+

/// unsafe {

`

``

1277

`+

/// let mut b = Box::new(0);

`

``

1278

`+

/// let ptr1 = Box::as_mut_ptr(&mut b);

`

``

1279

`+

/// ptr1.write(1);

`

``

1280

`+

/// let ptr2 = Box::as_mut_ptr(&mut b);

`

``

1281

`+

/// ptr2.write(2);

`

``

1282

`` +

/// // Notably, the write to ptr2 did not invalidate ptr1:

``

``

1283

`+

/// ptr1.write(3);

`

``

1284

`+

/// }

`

``

1285


/// ```

``

1286

`+

///

`

``

1287

`` +

/// [as_mut_ptr]: Self::as_mut_ptr

``

``

1288

`` +

/// [as_ptr]: Self::as_ptr

``

``

1289

`+

#[unstable(feature = "box_as_ptr", issue = "129090")]

`

``

1290

`+

#[rustc_never_returns_null_ptr]

`

``

1291

`+

#[inline]

`

``

1292

`+

pub fn as_mut_ptr(b: &mut Self) -> *mut T {

`

``

1293

`` +

// This is a primitive deref, not going through DerefMut, and therefore not materializing

``

``

1294

`+

// any references.

`

``

1295

`+

ptr::addr_of_mut!(**b)

`

``

1296

`+

}

`

``

1297

+

``

1298

`` +

/// Returns a raw pointer to the Box's contents.

``

``

1299

`+

///

`

``

1300

`` +

/// The caller must ensure that the Box outlives the pointer this

``

``

1301

`+

/// function returns, or else it will end up dangling.

`

``

1302

`+

///

`

``

1303

`+

/// The caller must also ensure that the memory the pointer (non-transitively) points to

`

``

1304

`` +

/// is never written to (except inside an UnsafeCell) using this pointer or any pointer

``

``

1305

`` +

/// derived from it. If you need to mutate the contents of the Box, use [as_mut_ptr].

``

``

1306

`+

///

`

``

1307

`+

/// This method guarantees that for the purpose of the aliasing model, this method

`

``

1308

`+

/// does not materialize a reference to the underlying memory, and thus the returned pointer

`

``

1309

`` +

/// will remain valid when mixed with other calls to [as_ptr] and [as_mut_ptr].

``

``

1310

`+

/// Note that calling other methods that materialize mutable references to the memory,

`

``

1311

`+

/// as well as writing to this memory, may still invalidate this pointer.

`

``

1312

`+

/// See the example below for how this guarantee can be used.

`

``

1313

`+

///

`

``

1314

`+

/// # Examples

`

``

1315

`+

///

`

``

1316

`+

/// Due to the aliasing guarantee, the following code is legal:

`

``

1317

`+

///

`

``

1318


/// ```rust

``

1319

`+

/// #![feature(box_as_ptr)]

`

``

1320

`+

///

`

``

1321

`+

/// unsafe {

`

``

1322

`+

/// let mut v = Box::new(0);

`

``

1323

`+

/// let ptr1 = Box::as_ptr(&v);

`

``

1324

`+

/// let ptr2 = Box::as_mut_ptr(&mut v);

`

``

1325

`+

/// let _val = ptr2.read();

`

``

1326

`` +

/// // No write to this memory has happened yet, so ptr1 is still valid.

``

``

1327

`+

/// let _val = ptr1.read();

`

``

1328

`+

/// // However, once we do a write...

`

``

1329

`+

/// ptr2.write(1);

`

``

1330

`` +

/// // ... ptr1 is no longer valid.

``

``

1331

`+

/// // This would be UB: let _val = ptr1.read();

`

``

1332

`+

/// }

`

``

1333


/// ```

``

1334

`+

///

`

``

1335

`` +

/// [as_mut_ptr]: Self::as_mut_ptr

``

``

1336

`` +

/// [as_ptr]: Self::as_ptr

``

``

1337

`+

#[unstable(feature = "box_as_ptr", issue = "129090")]

`

``

1338

`+

#[rustc_never_returns_null_ptr]

`

``

1339

`+

#[inline]

`

``

1340

`+

pub fn as_ptr(b: &Self) -> *const T {

`

``

1341

`` +

// This is a primitive deref, not going through DerefMut, and therefore not materializing

``

``

1342

`+

// any references.

`

``

1343

`+

ptr::addr_of!(**b)

`

``

1344

`+

}

`

``

1345

+

1257

1346

`/// Returns a reference to the underlying allocator.

`

1258

1347

`///

`

1259

1348

`/// Note: this is an associated function, which means that you have

`