Associated Types and Advanced Traits

Disambiguating Trait Methods

Nothing prevents two different traits—or a trait and an inherent impl block—from defining methods with the exact same name on the same type. When method names collide, Rust provides explicit call syntax to select the intended implementation.

Precedence Rule: Inherent Methods Win Over Trait Methods

When a type defines an inherent method with the same name as an in-scope trait method, dot syntax (value.method()) always calls the inherent method:

trait Pilot {
    fn fly(&self);
}

trait Wizard {
    fn fly(&self);
}

struct Human;

impl Human {
    fn fly(&self) {
        println!("*waving arms furiously* (Human inherent)");
    }
}

impl Pilot for Human {
    fn fly(&self) {
        println!("This is your captain speaking. (Pilot)");
    }
}

impl Wizard for Human {
    fn fly(&self) {
        println!("Up! (Wizard)");
    }
}

fn main() {
    let person = Human;

    // 1. Dot syntax calls the inherent method on Human:
    person.fly();

    // 2. Trait::method(&receiver) selects the specific trait implementation:
    Pilot::fly(&person);
    Wizard::fly(&person);
}
*waving arms furiously* (Human inherent)
This is your captain speaking. (Pilot)
Up! (Wizard)

Collision Between Two In-Scope Traits (E0034)

If a type does not have an inherent method of that name, and two traits that are both in scope provide a method with the same name, calling value.method() is rejected with E0034:

// ❌ does not compile
trait PrettyPrint {
    fn render(&self) -> String;
}

trait CompactPrint {
    fn render(&self) -> String;
}

struct Record(u32);

impl PrettyPrint for Record {
    fn render(&self) -> String {
        format!("Record {{ id: {} }}", self.0)
    }
}

impl CompactPrint for Record {
    fn render(&self) -> String {
        format!("#{}", self.0)
    }
}

fn main() {
    let rec = Record(7);
    println!("{}", rec.render());
}
error[E0034]: multiple applicable items in scope
  --> src/main.rs:25:24
   |
25 |     println!("{}", rec.render());
   |                        ^^^^^^ multiple `render` found
   |
note: candidate #1 is defined in an impl of the trait `PrettyPrint` for the type `Record`
  --> src/main.rs:11:5
   |
11 |     fn render(&self) -> String {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `CompactPrint` for the type `Record`
  --> src/main.rs:17:5
   |
17 |     fn render(&self) -> String {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
help: disambiguate the method for candidate #1
   |
25 |     println!("{}", PrettyPrint::render(&rec));
   |                    ~~~~~~~~~~~~~~~~~~~~~~~~~
help: disambiguate the method for candidate #2
   |
25 |     println!("{}", CompactPrint::render(&rec));
   |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~

Summary of Method Disambiguation Forms

Scenario Call Syntax
Call inherent method when trait methods share the name value.method() or Type::method(&value)
Call a specific trait's method (&self receiver) Trait::method(&value)
Call a specific trait's method (&mut self receiver) Trait::method(&mut value)
Call a specific trait's associated function (no self) <Type as Trait>::function()