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

Closed
@japaric

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

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