4

I am trying to run this

use std::collections::BTreeSet;

pub struct IntoIter<T> {
    iter: BTreeSet<T>::IntoIter,
}

fn main() {}

Playground

This fails with

error[E0223]: ambiguous associated type
 --> src/main.rs:4:11
  |
4 |     iter: BTreeSet<T>::IntoIter,
  |           ^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
  |

Why is the associated type ambiguous?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
ACC
  • 2,488
  • 6
  • 35
  • 61
  • Ah thanks, I did extract out this bit from my codebase. Did not realize this could be further reduced. I will update the snippet. – ACC Feb 08 '16 at 03:35

2 Answers2

5

"Ambiguous" seems like a bit of misleading wording here. This example produces the same error message:

struct Foo;

pub struct Bar {
    iter: Foo::Baz,
}

fn main() {}

I'm not certain, but I'd find it unlikely that there is an associated type named Baz in the standard library, much less likely that there are two to make it ambiguous!

What's more likely is that this syntax is simply not specific enough. It's completely plausible that there could be multiple traits that could have a Baz associated type. Because of that, you have to specify which trait you want to use the associated type from:

struct Foo;

pub struct Bar {
    iter: <Vec<u8> as IntoIterator>::IntoIter,
}

fn main() {}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 5
    Another way of expressing it: Rust objects to the concept of adding a `use` statement breaking code. If you had a `trait Trait { type IntoIter; }` implemented for `BTreeSet`, then importing `Trait` would suddenly break code if it permitted `BTreeSet::IntoIter`, because then it would indubitably be ambiguous. – Chris Morgan Feb 08 '16 at 04:41
  • Why "unlikely"? Everyone keeps writing their own version of `Foo`, `Bar` and `Baz`, it would be high time for them to be standardized! :) – Paolo Falabella Feb 08 '16 at 09:16
2

it's ambiguous because it could be associated constants. You need to tell the compiler you are referring to an associated type through ::, not a constant.

This is the same as the C++ typename, which is used to disambiguate type and constant of generic parameters.

Izana
  • 2,537
  • 27
  • 33