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