{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreig5hm3jdrvko27zl7f7747p2ddxjmk2kfckhtw7fkm5cuy42ok63e",
    "uri": "at://did:plc:ivbknywyskln22er3nkssdhl/app.bsky.feed.post/3mkjddp6mcba2"
  },
  "path": "/t/pre-rfc-a-tiny-internal-change-to-reverse-copy-from-slice-swap-with-slice/24189#post_5",
  "publishedAt": "2026-04-27T22:47:27.000Z",
  "site": "https://internals.rust-lang.org",
  "textContent": "Lysxia:\n\n> Indeed, even outside of formal verification, one could argue that `self.as_mut_ptr()` \"morally borrows\" from `self`, so calling `self.len()` while the raw pointer `self.as_mut_ptr()` is still in use is kinda smelly.\n\nI realised a while ago that raw pointers conceptually have a lifetime (which is the lifetime of their provenance, not the lifetime of the thing they point to). Under that model, you would indeed have to copy the length out of a slice reference before convering it to a pointer, if you wanted to use it at the same time as the pointer.\n\nWith current (and all likely future) Rust operational semantics, Rust code is allowed to violate the mutable borrow rules as long as they don't access any bytes of memory that the mutable reference is also used to access. As such, the following is sound (although it can't be written using safe Rust):\n\n\n    fn f(s: &mut [u8;2]) -> u8 {\n        let p = s.as_mut_ptr();\n        s[1] = 4;\n        unsafe { p.write(5); }\n        s[1]\n    }\n\n\nbut if you wrote `s[0]` twice rather than `s[1]`, it would be undefined behaviour.\n\nThe current Rust code for `swap_with_slice` is effectively doing the same thing: it's creating what are conceptually overlapping mutable references, but they're accessing disjoint memory (the length and the slice contents) and thus no actual breach of unsafe Rust's rules has occurred.\n\nIn general, I'd be in favour of rewriting it to put the `len()` first, because (as you say) it makes the soundness analysis vastly simpler – there's no longer a need to rely on a somewhat obscure rule that is specific to unsafe Rust, meaning that proof tools that think along safe-Rust lines will be much better at understanding what is going on. (On the other hand, code like the existing code is to many programmers \"obviously correct\", so it's important that unsafe Rust's operational semantics permits it: there would be too much of a chance of people writing undefined code by mistake otherwise.)\n\nI don't make the decisions, but if I did, I would probably move the len() call first with a comment saying something like \"it is easier for automated proof tools to prove this code correct if it doesn't attempt to read the length through a mutable reference while a pointer derived from it is currently in use\" (but ideally with better / more succinct wording).",
  "title": "[Pre-RFC] A tiny internal change to `reverse`, `copy_from_slice`, `swap_with_slice`"
}