Change:
The  function allows passed pointers to overlap, and its safety section is as follows: It says that both pointers must be "valid," but IIUC, the definition of validity becomes unclear under Stacked Borrows. Consider the following program (all code in this comment is checked using Miri with ): and are both "valid" at in the sense that this program is safe. is invalidated when we perform a write using , but it's ok because we don't use anymore. However, the following program exhibits UB in spite of the validity of and , because first reads from and the read invalidates . Note that the intermediate unique reference () is crucial for "separating" the two pointers. If we remove the intermediate reference, those pointers have the same capabilities. In other words, the following program does not exhibit UB: The difference between the two examples is so subtle that I'm not sure how to spell out the exact safety conditions for . This issue is found while formalizing the safety of in the Rustv project.
By the way, of contains unrelated UB. The example calls  twice, which accidentally invalidates the first pointer .
possibly related:
cc
The same argument seems to apply to . Miri (tracking raw pointers) reported undefined behavior for the following code: When I set the argument of the to 1, Miri did not report any undefined behavior. This may be an implementation detail. <details</detailsNote that the pointers are valid individually but not simultaneously in these examples. I found this distinction very interesting, but I don't know how to explain this without being too scholarly
Well, they are valid individually, but they are not "both valid at the same time". In separation logic terms, we have but we do not have . The issue is to find a way to express that without using separation logic terminology.^^ is entirely unrelated, as it concerns the safety invariant of and the soundness of its method in ways other than aliasing. is an example of code that uses* the wrong way, at least wrong under Stacked Borrows. So it is the dual issue -- it is a consumer if the spec which this issue points could needs to be made more precise.

Discussion:
/// /// Behavior is undefined if any of the following conditions are violated: /// <del> /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes. </del> <ins> /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes, and must remain valid even ///   when `dst` is written for `count * size_of::<T>()` bytes. (This means if the memory ranges ///   overlap, the two pointers must not be subject to aliasing restrictions relative to each ///   other.) </ins> /// <del> /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes. </del> <ins> /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes, and must remain valid even ///   when `src` is read for `count * size_of::<T>()` bytes. </ins> /// /// * Both `src` and `dst` must be properly aligned. ///

/// /// Behavior is undefined if any of the following conditions are violated: /// <del> /// * Both `x` and `y` must be [valid] for both reads and writes. </del> <ins> /// * Both `x` and `y` must be [valid] for both reads and writes. They must remain valid even when the ///   other pointer is written. (This means if the memory ranges overlap, the two pointers must not ///   be subject to aliasing restrictions relative to each other.) </ins> /// /// * Both `x` and `y` must be properly aligned. ///