Is a `mut` on a moved function parameter leaking implementation details to the function's API?

Viewed 81

I am new to Rust, just reading the 2nd edition of the programming in Rust book. I was wondering about the below but couldn't find an answer so far.

When defining a function, you can move some of the parameters. You can also declare them mut (without a reference) if you intend to mutate them within the function.

For the caller, this mut does not seem to have any significance, however. They have just moved ownership, and what happens to the data after that point is not their concern, is it?

So, is it right to say that a mut along with a moved parameter is actually not part of the function's API? Instead, it is leaking implementation details of that function to its signature.

Thanks for helping me understand this better.

Regards, Alex

1 Answers

You are right that the mut does not change the interface in any way. The function pointer types of these two functions

fn foo(s: String);
fn bar(mut s: String);

is fn(String) – whether the binding is mutable is not part of the function type. Since the types are considered identical with and without the mut, the mut isn't any meaningful part of the API.

Also note that a function can mutate any value that it receives ownership of, regardless of whether the corresponding paramter is marked as mut. If you have an immutable variable binding, you can always move it into a mutable binding, e.g.

fn foo(s: String) {
    let mut s = s;
    s.push_str("glonk");
}

So the mut in the signature is neither part of the API, nor does it actually tell you much about what the function is doing.

Related