Discussing some aspects of Method Calls
⚓ Rust 📅 2025-06-26 👤 surdeus 👁️ 18Chapter 5 of the book talks about Automatic Dereferencing with the notable example of method calls.
Call Expressions have a search-process to find the method in an instance.method() call. This algorithm enables ergonomic read and use since (*instance).method(), (&instance).method() and such are later added by the compiler.
For example in instance.method() the compiler will know the type of instance but the guessing-feature (par above) doesn't know whether it's for instance, *instance, &instance, &mut instance...
So it creates candidates until the it matches, say fn method(&mut self).
A complete example of that process is given in the reference:
For instance, if the receiver has type
Box<[i32;2]>, then the candidate types will beBox<[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].
- My first question is: Are the candidate types independent of the type of the instance ? In other words, do
instance,&instace,&&instanceall generate the same candidate list? I assume so, or that one is a subset of the others, but I'm unsure. - PS: What happens if 2 of the types in the list have the same method? Like
xand&x? (or it could be that the sentence below is correct, I am hesitating now.)
From that candidate list only one matches the receiver's type (that in the method signature.)
Case 1: No traits
Expectedly so, this fails to compile:
However, this overloading of foo is actually allowed for traits (and compounded by A's foo as well):
Case 2: Default Traits
Snippet 2: Default Implementations (click for more details)I think this is error prone. If you Derive a trait, or simply implement an external trait with a default {} that could lead to bugs since a.foo() could be choosing methods from any implemented traits.
Some of the rules I found
- Compiler only complains when they resolve to the same method and the same receiver; a name+method like
foo(&self)inBandCclashes, but won't if one is not&self.- When they clash, one needs to disambiguate the code with a full path
B::foo(&c)orC::..
- When they clash, one needs to disambiguate the code with a full path
- Compiler takes first
selfthen&selfthen&mut self; this is important for homonymous methods.
There isn't much of a question for this last part, but it is just very confusing, so any notes, remarks or corrections are welcome.
3 posts - 2 participants
🏷️ rust_feed