Skip to content

If two traits provide a method with the same name, and said method is used in an "unambiguous" way, the compiler picks the "wrong" trait #16949

Description

@japaric

Worth noting, that the traits are implemented for "non-overlapping" types. (Hence, I said "unambiguous" in the title)

STR

use std::iter::AdditiveIterator;

// I can't reuse the trait defined in the stdlib, create a new one
trait MyAdditiveIterator<T> {
    fn sum(self) -> Option<Row<Vec<T>>>;
}

// newtype to represent the row of a matrix
struct Row<D> {
    data: D,
}

// consume a "row-by-row" iterator, and return the sum of the rows
impl<T, D, I: Iterator<Row<D>>> MyAdditiveIterator<T> for I {
    fn sum(self) -> Option<Row<Vec<T>>> {
        unimplemented!();
    }
}

fn main() {
    // Clearly `range` is *not* an iterator over rows (`u8` != `Row<D>` for any `D`),
    // so the compiler should *not* pick `MyAdditiveIterator` but it does
    range(0u8, 3).sum();
}

Output

rows.rs:23:5: 23:24 error: expected core::iter::Iterator<Row<<generic #519>>>, found core::iter::Iterator<u8> (expected struct Row, found u8) [E0095]
rows.rs:23     range(0u8, 3).sum();
               ^~~~~~~~~~~~~~~~~~~
rows.rs:23:5: 23:24 error: expected core::iter::Iterator<Row<<generic #519>>>, found core::iter::Iterator<u8> (expected struct Row, found u8) [E0095]
rows.rs:23     range(0u8, 3).sum();
               ^~~~~~~~~~~~~~~~~~~
rows.rs:23:5: 23:24 error: expected core::iter::Iterator<Row<<generic #519>>>, found core::iter::Iterator<u8> (expected struct Row, found u8) [E0095]
rows.rs:23     range(0u8, 3).sum();
               ^~~~~~~~~~~~~~~~~~~
rows.rs:23:5: 23:24 error: expected core::iter::Iterator<Row<<generic #519>>>, found core::iter::Iterator<u8> (expected struct Row, found u8) [E0095]
rows.rs:23     range(0u8, 3).sum();
               ^~~~~~~~~~~~~~~~~~~
error: aborting due to 4 previous errors

(Off-topic: Same error 4 times?)

Version

rustc 0.12.0-pre (dfbd4669c 2014-09-02 10:31:04 +0000)

For completeness sake, here's the definition/impl of std::iter::AdditiveIterator:

pub trait AdditiveIterator<A> {
    fn sum(&mut self) -> A;
}

impl<A: Zero + Add<A, A>, T: Iterator<A>> AdditiveIterator<A> for T {}

Altough I can work around this issue, I get the feeling that the compiler should be able to handle this case (but I could be wrong).

cc @nikomatsakis

EDIT: Added rustc version

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions