Is this undefined behaviour?

Maybe we can get an answer here


Well, read is a convenience wrapper around copy_nonoverlapping:

So what I'd say is that it absolutely breaks safety invariants (unless T was Copy). And it's up to the unsafe code writer to unsure that those invariants are restored before returning control to safe code.

Typical uses would restore the invariant using write (such as doing swap as 2 reads then 2 writes), though there are other ways -- one trivial way is that forget(read(ptr::addr_of!(x))) is always sound (albeit useless). That code does, however, need to be incredibly careful of panics, as they can easily cause UB by leaving the block before the cleanup is finished. Arguably it may be been better for read to return ManuallyDrop<T> instead of just T, as that way such mistakes are more likely to "just" leak memory instead of being UB.

Well, any potentially-unaware safe code, because the tootsie pop boundary isn't just the unsafe block.