Open eeff opened 3 years ago
Yea, the method call documentation could use some improvement. Niko recently mentioned this at https://rust-lang.zulipchat.com/#narrow/stream/237824-t-lang.2Fdoc/topic/documentation.20for.20method.20dispatch.
I think in your example, the key part is the type of the receiver. In the example, the method
receiver is &Foo
for both the inherent impl and the trait impl. Since inherent impls always take precedence over trait impls, the inherent impl is called.
To explain it in more detail, algorithm is more like:
&Foo
and Foo
.In this case, the search finds the inherent impl during the first step in 3.1, since it finds an &Foo
receiver in the inherent impl.
There's a little more information in the rustc-dev-guide: https://rustc-dev-guide.rust-lang.org/method-lookup.html#method-lookup
And the actual code is here: rustc_typeck/src/check/method/probe.rs
(Note: I am no expert on this, this is just my understanding of how it works, this isn't any sort of authoritative explanation.)
See also https://github.com/rust-lang/rust/issues/26007#issuecomment-270484928
@ehuss thanks for the explanation. I also posed a question in the user forum
@ehuss I think I misunderstand the concept inherent impl
. As you said
In this case, the search finds the inherent impl during the first step in 3.1, since it finds an &Foo receiver in the inherent impl.
But isn't the inherent impl is for type Foo
, not &Foo
?
It's not when the type the impl
is declared for. It is the type of the receiver, which in this case is &Foo
.
To reiterate the key part of #1321 over here, it is currently worded that
Then, for each candidate type
T
, search [...]
T
's inherent methods [...]- visible trait[s] implemented by
T
And the factual error is that it's not just the candidate's implementations that are considered.
I believe it's any visible implementation where candidate T
is a valid receiver. Also, inherent implementations can conflict with each other. This is especially true under #![feature(arbitrary_self_types)]
, but is already true on stable today:
impl S {
fn get_ref(self: Pin<&Self>) {}
}
fn error_e0034_multiple_applicable_items_in_scope(p: Pin<&S>) {
p.get_ref();
}
After reading the Method Call Expression section, I am still confused about the method resolution. For example, the following code outputs
in inherent impl
instead ofin trait impl
. But according to the reference, shouldn't the type candidate list be&Foo, &&Foo, &mut &Foo, Foo, &Foo, &mut Foo
? And so the traitmethod
would be found first? Could somebody shed more light on this ?The output is:
Found a related StackOverflow, but I still don't understand why this is so.