Problem with &self in method call

Why is the follow code not compiling?

trait Trait {
    fn foo(&mut self, x: i32);

struct Foo;

impl Foo {
    fn foo(&self) {

impl Trait for Foo {
    fn foo(&mut self, x: i32) {; // (&*self).foo();
        println!("Trait::foo {}", x);

The error message:

error[E0061]: this function takes 1 parameter but 0 parameters were supplied
  --> src/
2  |     fn foo(&mut self, x: i32);
   |     -------------------------- defined here
15 |; // (&*self).foo();
   |              ^^^ expected 1 parameter

But if I change call to (&*self).foo() or Self::foo(self), then program compiles successfuly.

Method resolution uses very simple rules. The compiler looks at the method "receiver" (the thing before the dot, in this case self, which has type &mut Foo) and checks it if has a method called foo. If it doesn't, then it tries either borrowing or dereferencing the receiver and checks again. It continues this process until it finds a matching method or reaches its recursion limit. As soon as it finds a method with a matching name, it stops.

This system is dumb but predictable. It has the disadvantage that sometimes it doesn't find the right method when there is a name conflict, and you need to be more explicit, as in your example. But it also has advantages over a "smarter" system that continues searching and looking for "better" matches after finding a possibly-incorrect one. Some of these advantages are on the implementation side; smarter searching would be slower and more complex, and could create circular dependencies between compiler passes. Deeper searching could also make type inference fail more often (requiring additional type annotations) or cause method resolution to change in surprising ways when code changes.


This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.