{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreih53lp24zrzosd5fpzlqvsdtcyewslv2gsy4cnsjv2n5uwjkfi24e",
    "uri": "at://did:plc:25rdn5elo5izoxrmtis34zuk/app.bsky.feed.post/3mp73p6srxnf2"
  },
  "coverImage": {
    "$type": "blob",
    "ref": {
      "$link": "bafkreifiui2l7jzcazeoujqgtyurofvemfk757punphd7gwsezlnmrtbli"
    },
    "mimeType": "image/webp",
    "size": 59712
  },
  "path": "/jazz_thumyat/understanding-mut-self-calls-on-temporaries-in-rust-5bm2",
  "publishedAt": "2026-06-26T13:25:04.000Z",
  "site": "https://dev.to",
  "tags": [
    "rust",
    "learningrust"
  ],
  "textContent": "`[T]` has the following `split_off` method. Notice that its receiver type is `&mut &'a Self`:\n\n\n\n    pub fn split_off<'a, R: OneSidedRange<usize>>(\n        self: &mut &'a Self,\n        range: R,\n    ) -> Option<&'a Self> {\n        // ...\n    }\n\n\nNow look at this code:\n\n\n\n    let v = vec![1, 2, 3, 4, 5];\n    let head = v.as_slice().split_off(..2);\n\n    assert_eq!(head, Some([1, 2].as_slice()));\n\n\nThis may look confusing at first.\n\n`v.as_slice()` returns `&[i32]`, but `split_off()` expects `&mut &[i32]`. So where does the mutable reference come from?\n\nThe answer is that `v.as_slice()` creates a **temporary** value. In Rust, a temporary is a mutable place, so the compiler can automatically borrow it as `&mut`.\n\nYou can think of the code as if the compiler had written this:\n\n\n\n    let mut temp = v.as_slice();\n    temp.split_off(..2);\n\n\nThe mutable reference is taken to the temporary variable (`temp`), not to the original vector or slice. The vector `v` and the slice it produces are never mutated. Only the temporary variable is.\n\n##  Proof that temporaries are mutable places\n\nA normal `let` binding is **immutable** unless you write `mut`. Because of that, the following code does **not** compile:\n\n\n\n    let s: &[i32] = v.as_slice(); // no `mut`\n    let _ = s.split_off(..2);     // compiler error here\n\n\nThe compiler reports:\n\n\n\n    error[E0596]: cannot borrow `s` as mutable, as it is not declared as mutable\n    13 |     let _ = s.split_off(..2);\n       |             ^ cannot borrow as mutable\n    help: consider changing this to be mutable\n    12 |     let mut s: &[i32] = v.as_slice();\n\n\nThis shows the difference:\n\n  * `let s: &[i32] = v.as_slice()` creates an immutable place, so Rust cannot take `&mut s`.\n  * `v.as_slice()` creates a temporary, and a temporary is a mutable place, so Rust can automatically take `&mut` to call `split_off()`.\n\n\n\nThat is why `v.as_slice().split_off(..2)` compiles, while `s.split_off(..2)` does not unless `s` is declared with `mut`.",
  "title": "Understanding `&mut &'a self` Calls on Temporaries in Rust"
}