If autoref still happens on methods, does this mean that you'd be able to
get around the need to do:

    sort(&mut *foo);

...by turning it into a method?

    foo.sort();


On Tue, Nov 19, 2013 at 6:10 PM, Kevin Ballard <ke...@sb.org> wrote:

> In general, I’m not a fan of &*, and I like auto-borrowing (autoref sounds
> like it turns T into &T, not ~T into &T). I understand the arguments to get
> rid of it though.
>
> BTW, you said that the current proposal still includes autoref for
> function invocation. That sounds to me like autoref would still apply to x
> in foo(x). Is there something else you mean by that?
>
> As I see it, the two interesting cases to consider for removing it are:
>
> 1. let x = ~Foo; foo(x); // looks like it moves x when it just borrows it
>
> 2. let mut a = ~[ … ]; sort(a); // mutates a
>
> To me, the second case seems pretty clear that it shouldn’t auto-borrow a
> ~T to a &mut T, and instead require sort(&mut *a). It’s pretty ugly, but it
> makes it clear what’s going on. This case isn’t particularly common, which
> is why losing autoref isn’t very tragic.
>
> The first case is the most common case, and it seems a shame to require
> &*x everywhere. I understand the argument that it looks like x is moved
> until you read the function signature of foo(), but I’m not convinced
> that’s important enough to uglify the code. Arguably, you already have to
> know what foo() does to understand what the code is doing.
>
> The basic argument, as I see it, is that the type signature of foo()
> shouldn’t change how the calling code treats its argument. If foo() changed
> from `fn foo(_: &T)` to `fn foo(_: ~T)` then `x` would start being moved
> instead of borrowed, which could cause errors in subsequent code in the
> caller.
>
> But the problem with this argument is that the type signature of foo()
> *already* changes how the calling code treats its argument, in a fashion
> that will surface errors in later code rather than at the call site.
> Notably, if the argument is not fully constrained to a specific type by the
> time foo(x) is called, it will further constrain the type that may not
> cause a problem until later. For example:
>
> fn foo(_: uint);
> fn bar(_: uint);
>
> let x = 1;
> foo(x);
> bar(x);
>
> This compiles just fine, but if foo() changes its argument to `int`, then
> the call to bar() will fail with a type error. More complex situations can
> be created using generic functions as well.
>
> In the case of autoref, the question is whether the value will be moved,
> rather than the type of the value, which is a slightly different issue but
> I’m not convinced it’s different enough that it needs to be specially
> addressed.
>
> The other problem with this is that, even with autoref removed, you can
> still hit the same problem of a seemingly-benign change elsewhere causing a
> compiler error in your code. Namely, if a struct has no destructor, and you
> rely on the ability to implicitly copy it (e.g. calling bar(x) where foo is
> fn bar(_: T)), then adding a destructor to the struct will cause your code
> to fail to compile, in just the same way that foo changing from `fn foo(_:
> &T)` to `fn foo(_: ~T)` will today.
>
> Overall, there just doesn’t seem to me to be a compelling reason to remove
> the ability to auto-borrow ~T into &T. Removing the ability to auto-borrow
> ~T into &mut T is more sensible though.
>
> FWIW, a lot of why I like auto-borrowing is actually due to auto-slicing
> of ~[T] into &[T] and ~str into &str. But I assume that when (if) DST
> happens, auto-slicing will just be a case of auto-borrowing. And until that
> happens I’d really like to avoiding having to say foo(v.as_slice()).
>
> -Kevin
>
> On Nov 19, 2013, at 2:08 PM, Alex Crichton <a...@crichton.co> wrote:
>
> 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
> https://github.com/mozilla/rust/issues/10504.
>
> 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.
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
>
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev
>
>
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to