> and &T can be converted to T,

This isn't possible in general. A `&Vec<T>` cannot "become" a `Vec<T>` (no copy constructors). Also "converting" from a `&T` to `T` is not always cheap even when it is possible (for `T: Copy`). Specifically, it is a `memcpy` of the `T` value, which can be large: `[u8, .. 100000]`.

(For `==` specifically this isn't quite true, since `a == b` is (basicalyl) equivalent to `(&a).eq(&b)`, so an implicitly inserted "dereference" won't actually cause any memory traffic, due to being immediately ref'd again.)

> To elaborate my own point, if we wanted to (and I think this can be not implemented at all), we could make rustc aware of "deeper" implicit conversions so that e.g. (&u8, &u8) can be considered to be (not converted to) (u8, &u8), (&u8, u8) and (u8, u8) because the inner &u8 can be converted to u8, so any code that actually uses the other types "reachable" from (&u8, &u8) can do so (possibly only in certain situations like comparisons).

I... don't understand how this can work.

Imagine `fn foo(x: (u8, u8))` defined in some crate, then, in a different crate, `foo((&1u8, &2u8))`. This is impossible without doing some actual conversion (i.e. you cannot just abstractly "consider" the types to be the same): the `foo` function is compiled to machine code that expects to be receiving exactly 2 bytes directly, but handling `(&u8, &u8)` requires receiving 2 pointers and then dereferencing them to retrieve the value, a very different operation.

---

I think, in summary, that the only thing that makes sense for this behaviour is going from `&T` to `T` at the top level, that is

```rust
let x: &T = ...;
let y: T = x;

y == x;

fn foo(_: T) {}
foo(x)
```

will implicitly "rewrite" each use of `x` to `*x` (and this may then fail due to non-`Copy`/movement restrictions).