For a language that prioritizes safety, there are a surprising number of gotchas in Rust (another example is the large number of partial functions in the standard library).
For a language that prioritizes safety, there are a surprising number of gotchas in Rust (another example is the large number of partial functions in the standard library).
> In my opinion, the convenience of auto-dereferencing "as much as possible" to make method call syntax magically work through the indirection of references is not worth the lack of stability guarantees that it causes.
Auto-deref is just one way of many that the dot operator can resolve to an unintended method. This problem would still exist even if auto-deref were removed. What you're really objecting to is the existence of the dot operator at all. I think the dot operator pulls its weight, given how often it's used: I encourage you to check out Simon Peyton-Jones' thoughts on "the power of the dot" [1].
[1]: https://www.microsoft.com/en-us/research/wp-content/uploads/...
Same with the array change, the failure mode was breakage. While in this case, the method's names, arguments, and argument types are identical, the return type is different, which means other code expecting a certain type now has a different type. For that to silently change behavior, it would also need to match up on everything on the return type as well.
(To be clear, what's happening with `array.into_iter()` is unsize coercion, not auto-dereferencing. `[T; N]` does not impl `Deref<Target = [T]>`. But the point is the same.)
struct S;
impl S {
fn foo(&self) { }
}
let s = S;
s.foo();
That compiles today. Your proposal would require it to be `(&s).foo()` 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.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.
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.
EDIT: hilariously exactly this happened three minutes after my post…