Нет ошибки для двух признаков, реализующих один и тот же метод

В соответствии с документами, Rust должен жаловаться, если я попытаюсь вызвать метод, предоставляемый двумя разными признаками, такими как:

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();
}

Запуск этого результата приводит к ожидаемой ошибке error: multiple applicable methods in scope.

Однако я не получаю ошибки для этого:

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 реализует как Buf, так и Read. Обе характеристики предоставляют метод bytes.

Я ожидаю, что Rust будет жаловаться на ту же ошибку, что и выше. Вместо этого он тихо выбирает "неправильную" реализацию, а позже println жалуется на неправильный тип.

Любая идея, почему я не получаю ошибку здесь?

Если я удалю use std::io::Read;, все будет хорошо. Но с этой чертой в области внезапно используется реализация Read, а байты имеют "неправильный" тип.

(Я использую Rust 1.0.0)

Ответы

Ответ 1

@bluss нашел проблему:

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`.
}

Если оба типа используют несколько другой тип self, Rust рассматривает их как разные, и вызов метода просто предпочитает один из них.

Вероятно, это ошибка в Rust. Для получения дополнительной информации см. Соответствующую проблему ржавчины.