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 toT. 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:
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) {}
| ^^^^^^^^^^^^^^^^
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
*x is either a builtin operation (e.g. for references), or *Deref::deref(&x).[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. ↩︎