I haven't found quite the answer I'm looking for, but I apologize in advance if it's out there and I just haven't located it.
Could someone explain to me in excruciating detail how, in code such as
let v = vec![1,2,3];
let i = vec.iter();
how exactly does vec.iter()
get resolved to the method fn iter(&self)
for the slice type. I'm looking for explicit details on when the Deref trait and implicit borrowing kicks in during the process of method resolution.
Thanks,
Matt
Well I can't provide specific details, but I can tell you this:
vec.iter()
comes from [T].iter()
because the compiler looks for the following:
- A method in
Vec<T>
given what T
implements
- I'm not sure about the order on this one: method that
<Vec as Deref>
(or in this case [T]
) implements or a trait method that Vec<T>
implements
- A trait method that
[T]
implements.
The Deref
trait for Vec<T>
In the references for rust, when the process for coming up with candidate receiver types for resolution, it uses a Box<T>
as an example. One of the steps involves dereferencing Box<T>
to come up with T
. But here, one wouldn't dereference Vec<T>
- at some point in the process it would have to look at applying deref(&self)
on the &Vec<T>
to come up with &[T]
(I think?) and then start looking at methods on [T]
. I'm unclear though what the compiler would be doing exactly. Would it say "ok, I see Vec<T>
implements Deref<Target=[T]>
. So I'll start looking for methods on [T]
. I see [T]
has implements iter(&self)
. So I will borrow a reference and apply iter(&self)
".
I feel like I'm being very hand waving, though. I want to pretend to be the compiler and lay out all the steps for myself. This is purely for my own edification.
I just know that it works, I basically haven't touched rustc's source code so I'm not the one to ask.