3 ms·
I think you have it reversed. `expr.expr` would need to become `(*expr).expr` if we didn't have auto-dereferencing.
by ebingdom 5y ago
I think you have it reversed. `expr.expr` would need to become `(*expr).expr` if we didn't have auto-dereferencing.
- Arnavion 5y agostruct S; impl S { fn foo(&self) { } } let s = S; s.foo(); That compiles today. Your proposal would require it to be `(&s).foo()`
- pcwalton 5y agoIn other words, there is auto-ref in addition to auto-deref, and auto-ref causes the same issues of possibly-surprising method resolution. As I mention above, auto-deref is just one way that methods could resolve to the "wrong" implementation, and there would be no solution that I can see other than to remove dot entirely, which isn't viable.
- a1369209993 5y agoNo, IIUC, the sematics is (approximately): a.foo(b,c); vvvv typeof(a)::foo (??? a,b,c); vvvv A::foo /* takes &A */ (/*so this is:*/& a,b,c); vvvv A::foo(&a,b,c); Auto-derefencing is: a.foo(b,c) vvvv // a is &X, so replace it with (*a) (*a).foo(b,c) // wrong; should be a.foo(b,c); we called vvvv // a method on the pointer, not what it points to X::foo(???(*a),b,c) // should be A::foo(???a,b,c) // continue as above Auto-derefencing changes which type the method is looked up relative to, not just how the object is passed to it.
- Arnavion 5y agoYes yes, there's auto-ref, auto-deref, deref coercion, unsize coercion, ... All of them are forms of "`lhs.rhs` tries to look up a different type to apply the `rhs` to vs what type `lhs` actually has," or more generally "I wrote an expr of type T but the compiler treats it as an expr of type U for :reasons:" I called it "auto-dereferencing" because that's what OP used when talking about `[].into_iter()`, and then clarified that it's actually an unsize coercion, not auto-deref.
- a1369209993 5y ago> All of them are forms of "`lhs.rhs` tries to look up a different type to apply the `rhs` to vs what type `lhs` actually has," Nope, it uses the same type (A), just blindly adds a operator to the argument based on which method is called. You could just as easily have `a.foo()` -> `A::foo(++a)` instead; it's just[0] that adding `++` would be largely useless. 0: You'd also need a explict annotation on the declaration of foo, but that's a convenience issue.