Change:
The docs for  state: And include an example which uses to copy the value from an unaligned pointer into an aligned one. However, the docs for  state: Either the docs for are wrong, and does not need to be aligned, or the example for invokes UB and should be updated to use
cc (It's also notable that the example in is wrong when it uses as is seen if you move the statement out of the block; we should fix that ASAP)
Good catch! What we'd really want is , I think... we don't want an intermediate value on the stack. Feel free to suggest code that we can use instead. We have several doctests that need They have been there since 1.0 and longer, probably. But nobody listens to me when I say that there is existing code that we need to support ASAP.
The example given is just using to put it on the stack anyway. If you're having to copy the value at all, there's really no reason to use at that point, since the only reason to use it instead of is to avoid the copy (which is optimized out in release mode anyway). I think we can probably just remove the unaligned example entirely and change the documentation to read: I think we should probably mention the caveat WRT the optimizer eliminating the copy (or can it even do that in this case? The docs mention that the drop glue generated for packed structs does this copy automatically, I'm curious if it's doing so in a way that is UB or if the copy is just the price you have to pay here. It's also worth noting that there's no way to an unsized value through an unaligned pointer, but I'm not sure that's worth bringing up at all in the docs, since there's no reasonable way to actually get that pointer in the first place.
Oh, good point. Yeah then you can basically just make it , right? I wonder why / ever got used here? Well but wouldn't it make sense for that text to come with an example? It cannot, because then it would be introducing alignment errors. Uh... yeah. With it could work. Doesn't seem like a reasonable thing to have either way?
Presumably because they wanted the example to continue to use Sure, we could -- it just wouldn't ever call the function being documented. Yes, it's just unrelated to dropping unaligned pointers since the only place you can reasonably copy them to is the stack. Unless you happen to already have an valid pointer of the proper size and alignment sitting around
I'm not actually sure unalgined DSTs are so unreasonable. For example, is only stopped by this rule: Which could be solved if we had e.g. a way to express "does not have drop glue" as a bound ( doesn't work for obvious reasons). In any case, I think "copy unaligned" functions make sense but we might want to consider multiple variants for src only / dest only / both unaligned. This can be expressed in LLVM IR though in a brief test I couldn't demonstrate that it currently makes a codegen difference (but I could only try on x86_64, where alignment rarely matters for codegen).
:rofl: fair. I guess all of this is basically saying an in-place drop of unaligned data is just not possible. Do an "out-of-place" drop instead.
Actually looks like the use of an unaligned pointer in the doctest just caused to fail to land. ;)
Proposed fix at

Discussion:
///   as the compiler doesn't need to prove that it's sound to elide the ///   copy. /// <ins> /// Unaligned values cannot be dropped in place, they must be copied to an aligned /// location first using [`ptr::read_unaligned`]. /// </ins> /// [`ptr::read`]: ../ptr/fn.read.html <ins> /// [`ptr::read_unaligned`]: ../ptr/fn.read_unaligned.html </ins> /// /// # Safety ///

/// /// * `to_drop` must be [valid] for reads. /// <del> /// * `to_drop` must be properly aligned. See the example below for how to drop ///   an unaligned pointer. </del> <ins> /// * `to_drop` must be properly aligned. </ins> /// /// Additionally, if `T` is not [`Copy`], using the pointed-to value after /// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =

/// assert!(weak.upgrade().is_none()); /// ``` /// <del> /// Unaligned values cannot be dropped in place, they must be copied to an aligned /// location first: /// ``` /// use std::ptr; /// use std::mem::{self, MaybeUninit}; /// /// unsafe fn drop_after_copy<T>(to_drop: *mut T) { ///     let mut copy: MaybeUninit<T> = MaybeUninit::uninit(); ///     ptr::copy(to_drop, copy.as_mut_ptr(), 1); ///     drop(copy.assume_init()); /// } /// /// #[repr(packed, C)] /// struct Packed { ///     _padding: u8, ///     unaligned: Vec<i32>, /// } /// /// let mut p = Packed { _padding: 0, unaligned: vec![42] }; /// unsafe { ///     drop_after_copy(&mut p.unaligned as *mut _); ///     mem::forget(p); /// } /// ``` /// </del> /// Notice that the compiler performs this copy automatically when dropping packed structs, /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place` /// manually.