Skip to content

Method call resolution documentation is wrong #1321

Closed as not planned
Closed as not planned
@tczajka

Description

@tczajka

I am looking at the algorithm for method call resolution.

The first step is to build a list of candidate receiver types. Obtain these by repeatedly dereferencing the receiver expression's type, adding each type encountered to the list, then finally attempting an unsized coercion at the end, and adding the result type if that is successful. Then, for each candidate T, add &T and &mut T to the list immediately after T.

For instance, if the receiver has type Box<[i32;2]>, then the candidate types will be Box<[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].

Then, for each candidate type T, search for a visible method with a receiver of that type in the following places:

  1. T's inherent methods (methods implemented directly on T).
  2. Any of the methods provided by a visible trait implemented by T. If T is a type parameter, methods provided by trait bounds on T are looked up first. Then all remaining methods in scope are looked up.

Let's follow this algorithm for this method call:

struct Foo;

impl Foo {
    fn foo(&self) {}
}

fn main() {
    let a = Foo;
    a.foo();
}

First, build the list of candidate types:

  1. Foo
  2. &Foo
  3. &mut Foo

Then for each candidate type, search for methods with a receiver of that type in the places listed:

  1. Foo: There are no methods with receiver type of Foo
  2. &Foo:
    2.1. Search &Foo's inherent methods (methods implemented directly on &Foo). There are none because there is no impl &Foo.
    2.2. Search methods provided by traits implemented by &Foo. There are none.
  3. &mut Foo: no methods with receiver type of &mut Foo

So according to the reference, the a.foo() method call shouldn't work.

Another example is with a trait:

struct Foo;

trait Trait {
    fn foo(&self);
}

impl Trait for Foo {
    fn foo(&self) {}
}

fn main() {
    let a = Foo;
    a.foo();
}

The reference says to look for methods with the receiver type of &Foo in traits implemented by &Foo, but Trait is not implemented by &Foo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions