@@ -1399,3 +1399,70 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I }
1399
1399
fnptr_impls_args ! { A , B , C , D , E , F , G , H , I , J }
1400
1400
fnptr_impls_args ! { A , B , C , D , E , F , G , H , I , J , K }
1401
1401
fnptr_impls_args ! { A , B , C , D , E , F , G , H , I , J , K , L }
1402
+
1403
+ /// Create a `const` raw pointer to a place, without creating an intermediate reference.
1404
+ ///
1405
+ /// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
1406
+ /// and points to initialized data. For cases where those requirements do not hold,
1407
+ /// raw pointers should be used instead. However, `&expr as *const _` creates a reference
1408
+ /// before casting it to a raw pointer, and that reference is subject to the same rules
1409
+ /// as all other references. This macro can create a raw pointer *without* creating
1410
+ /// a reference first.
1411
+ ///
1412
+ /// # Example
1413
+ ///
1414
+ /// ```
1415
+ /// #![feature(raw_ref_macros)]
1416
+ /// use std::ptr;
1417
+ ///
1418
+ /// #[repr(packed)]
1419
+ /// struct Packed {
1420
+ /// f1: u8,
1421
+ /// f2: u16,
1422
+ /// }
1423
+ ///
1424
+ /// let packed = Packed { f1: 1, f2: 2 };
1425
+ /// // `&packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
1426
+ /// let raw_f2 = ptr::raw_const!(packed.f2);
1427
+ /// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
1428
+ /// ```
1429
+ #[ unstable( feature = "raw_ref_macros" , issue = "73394" ) ]
1430
+ #[ rustc_macro_transparency = "semitransparent" ]
1431
+ #[ allow_internal_unstable( raw_ref_op) ]
1432
+ pub macro raw_const ( $e: expr) {
1433
+ & raw const $e
1434
+ }
1435
+
1436
+ /// Create a `mut` raw pointer to a place, without creating an intermediate reference.
1437
+ ///
1438
+ /// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
1439
+ /// and points to initialized data. For cases where those requirements do not hold,
1440
+ /// raw pointers should be used instead. However, `&mut expr as *mut _` creates a reference
1441
+ /// before casting it to a raw pointer, and that reference is subject to the same rules
1442
+ /// as all other references. This macro can create a raw pointer *without* creating
1443
+ /// a reference first.
1444
+ ///
1445
+ /// # Example
1446
+ ///
1447
+ /// ```
1448
+ /// #![feature(raw_ref_macros)]
1449
+ /// use std::ptr;
1450
+ ///
1451
+ /// #[repr(packed)]
1452
+ /// struct Packed {
1453
+ /// f1: u8,
1454
+ /// f2: u16,
1455
+ /// }
1456
+ ///
1457
+ /// let mut packed = Packed { f1: 1, f2: 2 };
1458
+ /// // `&mut packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
1459
+ /// let raw_f2 = ptr::raw_mut!(packed.f2);
1460
+ /// unsafe { raw_f2.write_unaligned(42); }
1461
+ /// assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference.
1462
+ /// ```
1463
+ #[ unstable( feature = "raw_ref_macros" , issue = "73394" ) ]
1464
+ #[ rustc_macro_transparency = "semitransparent" ]
1465
+ #[ allow_internal_unstable( raw_ref_op) ]
1466
+ pub macro raw_mut ( $e: expr) {
1467
+ & raw mut $e
1468
+ }
0 commit comments