No error for two traits implementing the same method

1.7k views Asked by At

According to the docs, Rust should complain if I try to call a method provided by two different traits like this:

trait Foo {
    fn f(&self);
}

trait Bar {
    fn f(&self);
}

struct Baz;

impl Foo for Baz {
    fn f(&self) { println!("Baz’s impl of Foo"); }
}

impl Bar for Baz {
    fn f(&self) { println!("Baz’s impl of Bar"); }
}

fn main(){
    let b = Baz;
    b.f();
}

Running this results in the expected error: multiple applicable methods in scope error.

However I get no error for this:

extern crate mio;
use mio::buf::RingBuf;
use mio::buf::Buf;
use std::io::Read;

fn main() {
    let buf = RingBuf::new(10);
    let bytes = buf.bytes();
    println!("{:?}", bytes);
}

mio::buf::RingBuf implements both Buf and Read. Both traits provide a bytes method.

I would expect Rust to complain with the same error as above. Instead it silently chooses the "wrong" implementation and later println complains about the wrong type.

Any idea why I don't get an error here?

If I remove use std::io::Read; everything works fine. But with that trait in scope suddenly the implementation of Read is used and bytes has the "wrong" type.

(I am using Rust 1.0.0)

1

There are 1 answers

1
michas On BEST ANSWER

@bluss found the problem:

struct Type;

trait A {
    fn foo(&self) -> bool { false }
}

trait B : Sized {
    fn foo(self) -> bool { true }
}

impl A for Type { }
impl B for Type { }

fn main() {
    println!("{}", Type.foo());   // This will call B::foo -- it will prefer `self`.
}

If both types use a slightly different self type, Rust treats them as different and calling the method simply prefers one of them.

This is probably a bug in Rust. For details have a look at the corresponding Rust issue.