Another question on trait and method call

According to the reference method-call-expr.html:

Then, for each candidate type T , search for a method with a receiver of that type in the following places:
... 2. Any of the methods provided by a trait implemented by T

If I understand this correctly, this simple code will not work: (But it works.)

trait Barkable {
    fn bark(&self);
}

struct Dog{}

impl Barkable for Dog {
    fn bark(&self) {
        println!("woof!");
    }
}

fn main() {
    let d = Dog{};
    d.bark();
}

Let's follow the logic:

  1. d is of type Dog. Build a candidate type list: [Dog, &Dog, ...];
  2. For each candidate type:
    2.1. Dog: there is no method with receiver type Dog.
    2.2. &Dog: There is a method with receiver type &Dog, however, it is provided by an impl on Dog, not &Dog. This violates point 2 in the reference.
    2.3. Method not found in the rest of candidate list. Thus, the method call fails.

Point 2 in the reference requires the method with receiver type T be provided by an implementation on T, which in this case is &Dog. However, type &Dog does not implement the trait.

I suppose it falls into:

Then all remaining methods in scope are looked up.

The trait isn't implemented for &Dog but the method is visible and has the right receiver type so it's valid.

1 Like

Thanks! That makes sense. However, I guess most methods have receiver type &Self, which makes the following rule for the most time not applicable.

Any of the methods provided by a visible trait implemented by T

Then, the rule that is applicable to most cases is "casually" mentioned at the end of the paragraph. I think this is pretty weird.

The reference is a work in progress, I think this chapter will be rewritten to include (a lot) more information making it clearer. Here's the issue.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.