[rust-dev] Removing some autoref magic

Alex Crichton alex at crichton.co
Tue Nov 19 14:08:06 PST 2013

Hello rust-dev!

Everyone's had their fair share of issues with autoref and autoderef,
and it's worth considering removing certain portions of it from the
compiler. The discussion around this has been rooted in the past, but
has recently been brought up as part of

The current proposal is to remove all autoref except for function
invocations and indexing operations. The method of creating &T from ~T
would be `let foo: &T = foo` or `&*foo`. Vectors and strings can't
currently benefit from the `&*foo` syntax, but they will hopefully be
able to do such once DST lands. In the meantime coercion via type
ascription will work and they also have `as_slice` methods.

There are a few reasons backing this proposal:

1. It's inconsistent to have magical autoref in some places, but not
in other places.
2. The camp of "less compiler magic is better" can fly their flag over
this change.
3. Code readability does not necessarily benefit from autoref on arguments:

  let a = ~Foo;
  foo(a); // reading this code looks like it moves `a`
  fn foo(_: &Foo) {} // ah, nevermind, it doesn't move `a`!

  let mut a = ~[ ... ];
  sort(a); // not only does this not move `a`, but it mutates it!

The basic idea is that reasoning about code is no longer a local
function decision, but rather you must understand all the pointer-ness
of the called signatures to understand when a move happens or not.
With no autoref, the code would look like

  let a = ~Foo;
  foo(&*a); // clearly not passing by value

  let mut a = ~[ ... ];
  sort(a.as_mut_slice()); // clearly loaning a mutable reference

That being said, this proposal is not yet set in stone. I don't think
that there are many people that are fans of `&*foo` or `&mut *foo`;
both cases look fairly ugly. So far the general agreement is that
local small ugliness is the price we pay for local readability, and
the discussions have been unable to unearth a better system.

I'm curious if others have a better idea of how to go about doing
this, or if others just think it's a terrible idea in the first place.

More information about the Rust-dev mailing list