@@ -1399,3 +1399,70 @@ fnptr_impls_args! { A, B, C, D, E, F, G, H, I }
13991399fnptr_impls_args ! { A , B , C , D , E , F , G , H , I , J }
14001400fnptr_impls_args ! { A , B , C , D , E , F , G , H , I , J , K }
14011401fnptr_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