Method lookup doubt

I was going through the Rust Reference for the Method Call expression section here Method Call Expr

And I wanted to ask about this part specifically
Then, for each candidate T, add &T and &mut T to the list immediately after T.

For instance, if the receiver has type Box<[i32;2]>, then the candidate types will be Box<[i32;2]>, &Box<[i32;2]>, &mut Box<[i32;2]>, [i32; 2] (by dereferencing), &[i32; 2], &mut [i32; 2], [i32] (by unsized coercion), &[i32], and finally &mut [i32].

Shouldn’t the dereferencing produce &[i32;2] instead if [i32;2]?

Also another question, if I have a function on some type T that takes &self and I have the same function on &T that takes self, which one gets priority in the lookup

No. Dereferencing is called dereferencing because the result has one less “reference” (pointer, in Rust terminology); dereferencing Box<[i32; 2]> gets you exactly [i32; 2].

let b: Box<[i32; 2]> = Box::new([1, 2]);
let d: [i32; 2] = *b; // dereferenced

This is sometimes confusing in Rust because of how Deref::deref() works, but if you ignore the method and look at the type, the implementation still spells out exactly what is going on:

impl<T, A> Deref for Box<T, A>
where ...
{
    type Target = T;
    ...
}

This tells you that Box<T> dereferences to T. And even Deref::deref() is still removing a pointer type, just in a slightly more complicated way: it takes in &Box<T> and gives you &T — you had two levels of pointers and now you have one.

But, in general, to see what dereferencing means, look at what the * operator does.

If one of them is an inherent method and the other is a trait method, inherent methods always get priority. If they are both trait methods, they have equal priority and you will get an ambiguity error. For example:

trait Tr1 {
    fn method(&self);
}
trait Tr2 {
    fn method(self);
}

struct Foo;
impl Tr1 for Foo {
    fn method(&self) {}
}
impl Tr2 for &Foo {
    fn method(self) {}
}

fn main() {
    Foo.method();
}
error[E0034]: multiple applicable items in scope
  --> src/main.rs:17:9
   |
17 |     Foo.method();
   |         ^^^^^^ multiple `method` found
   |
note: candidate #1 is defined in an impl of the trait `Tr2` for the type `&Foo`
  --> src/main.rs:13:5
   |
13 |     fn method(self) {}
   |     ^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `Tr1` for the type `Foo`
  --> src/main.rs:10:5
   |
10 |     fn method(&self) {}
   |     ^^^^^^^^^^^^^^^^
3 Likes

Thanks. So the compiler does this dereferencing via the indirection operator instead of calling the deref function. since deref returns &Self::Target?
Am I correct in my understanding?
Here is the rust analyser inference for the types

The operation of "dereferencing" is equivalent to *x, and also equivalent to *x.deref().

You can think of the compiler as inserting *.

*x is either a builtin operation (e.g. for references), or *Deref::deref(&x).[1]


  1. There may be minor differences. There are various operator lowerings documented as "equivalent" to some syntax which have slight differences in reality, as the lowering is not actually syntactical. ↩︎