[rust-dev] Why doesn't rust require "mut" param prefix at call site?

Patrick Walton pcwalton at mozilla.com
Wed Jan 1 22:18:02 PST 2014


On 1/1/14 10:06 PM, Vadim wrote:
> Well, since requiring '&' at the original borrow site doesn't really
> prevent the "unexpected mutability" problem, why not drop it and
> eliminate a bunch of noise from Rust sources?

But it does eliminate mutation of lvalues.

> And, again, if
> "unexpected mutability" is what concerns people, "mut" annotation is the
> better way to fix that, IMHO.

I don't know if it's a coherent proposal. Consider these four function 
signatures, each of which might mutate their arguments:

     fn f(x: &mut int) { ... }

     fn g(x: (&mut int, &mut int)) { ... }

     struct S<'a> {
         a: &'a mut int,
         b: &'a mut uint,
     }
     fn h(x: S) { ... }

     fn i<T>(x: T, f: |T|) { f(x) }

How might `i` mutate its argument? Consider function `j`:

     fn j() {
         let mut x = 3;
         i(&mut x, |ptr| *ptr = 5);
     }

So `i` mutated its argument. So how should you be forced to notate that? 
Should you have to write:

     fn i<T>(x: T, f: |T|) { f(mut x) }

     ... i(&mut x, |ptr| *ptr = 5);

Or:

     fn i<T>(x: T, f: |T|) { f(x) }

     ... i(mut &mut x, |ptr| *ptr = 5);

Or:

     fn i<T>(x: T, f: |T|) { f(mut x) }

     ... i(mut &mut x, |ptr| *ptr = 5);

And that's just a simple example: start throwing in existential types 
like traits and it becomes clear that you really can't tell from the 
program where mutation could possibly happen, because the types are 
hiding mutability from you. And that's fine--existential types and 
generics deliberately permit that abstraction. But it does mean, I 
think, that we can't meaningfully talk about a sound and complete "mut" 
annotation at call sites.

Patrick



More information about the Rust-dev mailing list