Change:
Rust 1.51 was released yesterday and included the  macro. Its documentation talks about its usage in creating pointers to unaligned fields without the need for an intermediate reference: Despite that, the documentation of [] states the following: The documentation of [] should be updated to reflect the new changes in the language. : and modify labels: T-doc claim []: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOT_END --

Discussion:
/// As a result, using `&packed.unaligned as *const FieldType` causes immediate /// *undefined behavior* in your program. /// <ins> /// Instead you must use the [`ptr::addr_of!`](addr_of) macro to /// create the pointer. You may use that returned pointer together with this /// function. /// </ins> /// An example of what not to do and how this relates to `read_unaligned` is: /// <del> /// ```no_run </del> <ins> /// ``` </ins> /// #[repr(packed, C)] /// struct Packed { ///     _padding: u8,

///     unaligned: 0x01020304, /// }; /// <del> /// #[allow(unaligned_references)] /// let v = unsafe { ///     // Here we attempt to take the address of a 32-bit integer which is not aligned. ///     let unaligned = ///         // A temporary unaligned reference is created here which results in ///         // undefined behavior regardless of whether the reference is used or not. ///         &packed.unaligned ///         // Casting to a raw pointer doesn't help; the mistake already happened. ///         as *const u32; </del> <ins> /// // Take the address of a 32-bit integer which is not aligned. /// // In contrast to `&packed.unaligned as *const _`, this has no undefined behavior. /// let unaligned = std::ptr::addr_of!(packed.unaligned); </ins> /// <del> ///     let v = std::ptr::read_unaligned(unaligned); /// ///     v /// }; </del> <ins> /// let v = unsafe { std::ptr::read_unaligned(unaligned) }; /// assert_eq!(v, 0x01020304); </ins> /// ``` /// /// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however. <del> // FIXME: Update docs based on outcome of RFC #2582 and friends. </del> /// /// # Examples ///

/// /// ## On `packed` structs /// <del> /// It is currently impossible to create raw pointers to unaligned fields /// of a packed struct. /// </del> /// Attempting to create a raw pointer to an `unaligned` struct field with /// an expression such as `&packed.unaligned as *const FieldType` creates an /// intermediate unaligned reference before converting that to a raw pointer.

/// As a result, using `&packed.unaligned as *const FieldType` causes immediate /// *undefined behavior* in your program. /// <del> /// An example of what not to do and how this relates to `write_unaligned` is: </del> <ins> /// Instead you must use the [`ptr::addr_of_mut!`](addr_of_mut) /// macro to create the pointer. You may use that returned pointer together with /// this function. /// /// An example of how to do it and how this relates to `write_unaligned` is: </ins> /// <del> /// ```no_run </del> <ins> /// ``` </ins> /// #[repr(packed, C)] /// struct Packed { ///     _padding: u8, ///     unaligned: u32, /// } /// <del> /// let v = 0x01020304; </del> /// let mut packed: Packed = unsafe { std::mem::zeroed() }; /// <del> /// #[allow(unaligned_references)] /// let v = unsafe { ///     // Here we attempt to take the address of a 32-bit integer which is not aligned. ///     let unaligned = ///         // A temporary unaligned reference is created here which results in ///         // undefined behavior regardless of whether the reference is used or not. ///         &mut packed.unaligned ///         // Casting to a raw pointer doesn't help; the mistake already happened. ///         as *mut u32; </del> <ins> /// // Take the address of a 32-bit integer which is not aligned. /// // In contrast to `&packed.unaligned as *mut _`, this has no undefined behavior. /// let unaligned = std::ptr::addr_of_mut!(packed.unaligned); </ins> /// <del> ///     std::ptr::write_unaligned(unaligned, v); </del> <ins> /// unsafe { std::ptr::write_unaligned(unaligned, 42) }; </ins> /// <del> ///     v /// }; </del> <ins> /// assert_eq!({packed.unaligned}, 42); // `{...}` forces copying the field instead of creating a reference. </ins> /// ``` /// <del> /// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however. // FIXME: Update docs based on outcome of RFC #2582 and friends. </del> <ins> /// Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however /// (as can be seen in the `assert_eq!` above). </ins> /// /// # Examples ///

/// Note that here the call to [`drop`] is for clarity - it indicates /// that we are done with the given value and it should be destroyed. /// <del> /// ## 3. Get it from C. </del> <ins> /// ## 3. Create it using `ptr::addr_of!` /// /// Instead of coercing a reference to a raw pointer, you can use the macros /// [`ptr::addr_of!`] (for `*const T`) and [`ptr::addr_of_mut!`] (for `*mut T`). /// These macros allow you to create raw pointers to fields to which you cannot /// create a reference (without causing undefined behaviour), such as an /// unaligned field. This might be necessary if packed structs or uninitialized /// memory is involved. /// /// ``` /// #[derive(Debug, Default, Copy, Clone)] /// #[repr(C, packed)] /// struct S { ///     aligned: u8, ///     unaligned: u32, /// } /// let s = S::default(); /// let p = std::ptr::addr_of!(s.unaligned); // not allowed with coercion /// ``` /// /// ## 4. Get it from C. </ins> /// /// ``` /// # #![feature(rustc_private)]