Repository: rust
Issue: Automatic dereferencing or borrowing on methods that exist behind a blanket (generic) trait implementation
Labels: T-lang,C-discussion

I wrote a recent StackOverflow question where I asked: [Why do I need to implement `From` for both a value and a reference? Shouldn't methods be automatically dereferenced or borrowed?](https://stackoverflow.com/questions/76478569/why-do-i-need-to-implement-from-for-both-a-value-and-a-reference-shouldnt-me)

### What is the problem?

The behaviour of a Rust method call is described in [The Rust Reference](https://doc.rust-lang.org/reference/expressions/method-call-expr.html), whereby it states that "when looking up a method call, the receiver may be automatically dereferenced or borrowed in order to call a method." The exact specification of this behaviour is explained in more detail in the chapter.

As an example `&usize` would first through repeated dereferences and becomes: `&usize, usize`. It has no unsized coercion, therefore the list is unchanged. Then, through each type is referenced and becomes: `&usize, &&usize, &mut &usize, usize, &usize, &mut usize`. Any "visible method with a receiver of that type" is discovered. In the event that multiple matches are discovered, then this is an error and the exact method must be disambiguated.

Now, given a type `T` where `From<T> for U` is implemented and thus `Into<U> for T` is also implemented. Therefore, we should have the method `U::from(T)` and `T::into(U)`. When I call `T::into(U)` it should and does work.

But, now when I call `&T::into(U)`, it does not find a match. Since `From<&T> for U` is not implemented therefore `Into<U> for &T` is not implemented. But, it should still be possible to find a match through the automatic dereference and borrow procedure that was described above, but it does not.

### Why is it a problem?

As explained in [the answer on StackOverflow](https://stackoverflow.com/a/76480443/7349225) the reason for this is [the blanket implementation of the `Into` trait](https://doc.rust-lang.org/stable/std/convert/trait.Into.html#impl-Into%3CU%3E-for-T). Due to the current way Rust attempts to resolve methods it appears to match the blanket implementation, but before it is fully resolved, therefore when the generic types are filled in there is actually no match.

I have created [this reproduction on the Rust playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=1ff58178f7a0b9c9e5a7a15d38dde93f) whereby you can uncomment section `(A), (B), (C) or (D)` to see the different behaviours.

### How can it be fixed?

I don't know if this can be fixed, but I believe the lookup routine could be adjusted to fix this specific issue. I expect there are other cases where this could be a problem, however the `From` and `Into` traits are the only place I have discovered this issue so far...

*If it can be fixed, should it? Would this be a breaking change that requires a new edition of Rust?*

I would be interested in attempting to fix this issue, although I have not contributed to the Rust compiler before... First, I would like know what people have to say on this issue, and see whether there is something that would block an adjustment like this being implemented.