0

Why would mut not be required here

#[allow(dead_code)]
fn addo2(v: Vec<u64>, oi: Option<u64>) -> Vec<u64> {
    oi.into_iter().fold(v, |mut v, i| add(v, i)) //warning: variable does not need to be mutable
}

#[allow(dead_code)]
fn add(mut v: Vec<u64>, i: u64) -> Vec<u64> {
    v.push(i);
    v
}

when it is, as expected, required in this code

fn addo(v: Vec<u64>, oi: Option<u64>) -> Vec<u64> {
    oi.into_iter().fold(v, |mut v, i| {
        v.push(i);
        v
    })
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=097bb3c3cd5c8cd7aa69c5bfafd177fc

nicolas
  • 9,549
  • 3
  • 39
  • 83
  • See also: [Why does the compiler not complain that an iterator moved to a for loop is immutable?](https://stackoverflow.com/q/47760006) – E_net4 Jan 12 '21 at 11:01
  • See also https://stackoverflow.com/questions/65682724/why-immutable-string-can-call-stringaddmut-self-other-str – Jmb Jan 12 '21 at 11:31
  • I don't see why the first link is relevant (why does.. ) but the other two are, thanks. to rephrase the mechanism in short, the `mut` qualifier applies wherever ownership is transferred. not declaring `mut` in the chain of ownership does not constrain further owners to not require `mut` on their own. – nicolas Jan 12 '21 at 11:36

1 Answers1

1

The difference between v.push(i); v and add(v, i) is that the former modifies v in-place, whereas the latter passes v into add, and receives a (possibly unrelated) value back. mut refers to modifying something you own, so it doesn't apply when passing ownership to someone else.

user4815162342
  • 141,790
  • 18
  • 296
  • 355
  • rephrasing to make sure I got it : the `mut` modifier applies wherever ownership is transferred. not having mutability before a move (here in the caller's `v` ) does not restrict the ability for a subsequent owner (here `v` in the callee `add` ) to require mutability. – nicolas Jan 12 '21 at 11:30
  • 1
    @nicolas Correct - when you own something, you can always choose to mutate it regardless of the wishes of the previous owner. This is best illustrated by the snippet from the answer linked by E_net4: `let v = vec![1, 2, 3]; let mut x = v; x.push(0);` – user4815162342 Jan 12 '21 at 11:51