What's the point of arguments with mutable ownership


#1

Here is an example I found really weird:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ea5fdeca43404cf531251a1f989953b0

I am wondering why you are allowed to convert from “non mutable owned” to “mutable owned”.

It might seem a dumb question since anyway when you call this method, you’ve lost ownership, so it shouldn’t matter whether it modifies it or not, but I feel like it does.
The keyword mut on owned variable is to me causing more confusions than anything.


#2

You own the value - you can do whatever you want with it. The mut there applies to the binding (i.e. s), not to the type (i.e. MyStruct).

It’s no different from

fn change_it_3(s: MyStruct) -> MyStruct {
    let mut s2 = s;
    s2.myval = 2;
    s2
}

#3

I get it, I am questioning the value of the mut keyword here.
What the point of having the mut keyword here if anyway you can do whatever you want?

While for references it has a strong meaning, for owned variables it just seems unnecessary. (It just tells us that till it’s binded like that, you can’t edit it, but you can change the binding anytime…)


#4

I think in general, Rust likes to be explicit when a value is mutable. I agree that mut on owned function parameters can be confusing because it looks like it’s changing the function signature, even though the function signature is essentially the same as when the parameter is not marked as mut.

Think of it as just being symmeric with variable bindings requiring mut to modify the value that is bound. I think Rust could change the default for bindings from immutable to mutable tomorrow and no existing code would break, but it’s more of a design choice to encourage better code that avoids excessive mutability.


#5

It’s more or less a convenience, and it’s the internal business of the function. Rustdoc doesn’t show this mut, because it doesn’t make a difference.


#6

I recently described some of my feelings on mut in this comment on internals.

tl;dr: The existence of mut bindings leads to a very helpful “unused mut” lint, but no more than that.

The fact that you can “circumvent” it by moving a value is immaterial. All temporaries in Rust are mutable, as immutability (other than of references) is not part of the type.


#7

I should add: the reason you can do this in function arguments is because function arguments are (irrefutable) patterns, the same as let statements.

// if you can do it in 'let'...
let Thing(a, mut b) = thing;

// ...you can do it in 'fn'
fn foo(Thing(a, mut b): Thing<i32>)  {
    ...
}

#8

2 posts were split to a new topic: Immutable Frozen type


#10

[Moved some posts to a new topic since they were getting away from the original question here.]


#11

By my thinking the value of mut is for the reader of the code. Once they locate where a variable is bound, if it’s not mut they know what the value is. That’s really convenient. I use const on local variables in C++ for the same reason.