Common method overlaps method in trait

Hello!

Right now I am confused: why this code compiles without even a warning? Why compiler prefer metod from impl and not from trait?

struct Type;

impl Type {
    fn f(&self) -> bool { true }
}

trait F {
    fn f(&self) -> bool { false }
}

impl F for Type {}

fn main() {
    println!("{}", Type.f()); // why this even compile  and print "true"?
    //println!("{}", (&Type as &F).f()); // print "false"
}

(Playground)

I wasted too much time right now, investigating one error, before I realized, that method from trait overlapped by method, generated from macros.

As it is shown, the code compiles because Type.f() is defined as an inherent method of the Type struct. This takes precedence over any traits that may or may not be defined and in scope.

If you want to force the usage of the trait method, you can do this:

// the rest is the same as earlier

fn main() {
    // Create a `Type` instance, borrow it, and then use it as a trait object: 
    let trait_obj: &F = &Type as &F;
    println!("{}", trait_obj.f()); // false
}

You can also use fully qualified method syntax to disambiguate instead of making a trait object.

https://play.rust-lang.org/?gist=c029bb462d1cbfa02def70eb6a1eb25b&version=stable&mode=debug&edition=2015

2 Likes

And you don’t even need a projection -
F::f(&t) would be enough.

1 Like