Change:
Currently, E0221 can give an error like: This isn't terribly helpful. Ideally, we'd like to show where these associated types that cause ambiguity are coming from: cc
I'd be up to mentor this. The message is reported by some code in , which has the job of converting the HIR representation of a type into the compiler's internal representation. The challenge here is that the HIR types have spans (because they are basically the things that the user wrote) whereas the internal representations do not. Right now, the routine in question, , only has access to a list of the representations in internal form (. To give better spans, we have to trace those spans in (so e.g. we want ). What this routine does is, given a type like , it selects what traits the associated type might have been defined in, and tries to pick one. The list is the list of traits that implements. So e.g. it might include something like , which would suggest that could be expanded to . But if there was another bound, say , that also defines an associated type , that'd be an amiguity. If you look at the callers, there aren't that many (3, I think). Two of those are for trait objects, I think, where the bounds come from the supertraits of the trait object. Probably we could give those the spans of the trait type itself, though we may want to get the spans out of the trait definition where the supertraits come from (but that could be in another crate). That last part is a bit tricky because we'd have to extend the . Let's assume we're not doing that for now, and we're willing to give a span referring to a trait when in fact the item lies in a supertrait where . The other is the more general case of a type parameter. I think the major piece of work then is to augment this routine in the trait: so that it returns a , where we would thread through the spans whence each bound was derived. Anyway, this is non-trivial, but seems to me to be achievable if anyone wants to dig in. If so, ping me (either on IRC, , or here) and I'll try to give more hints. :)
I'll try, I need some time to look around
gettypeparameterbounds in callerbounds contains vec of Predicate w/o spans. May be is it easy only for error case in oneboundforassociatedtype get spans from astmap (hir::map) by DefId extracted from TypeTraitItems like traitdefinesassociatedtype_named do?
I've updated it But what do you think about trait from extern crate?

Discussion:
} if bounds.len() > 1 { <ins> let spans = bounds.iter().map(|b| { self.tcx().impl_or_trait_items(b.def_id()).iter() .find(|&&def_id| { match self.tcx().impl_or_trait_item(def_id) { ty::TypeTraitItem(ref item) => item.name.as_str() == assoc_name, _ => false } }) .and_then(|&def_id| self.tcx().map.as_local_node_id(def_id)) .and_then(|node_id| self.tcx().map.opt_span(node_id)) }); </ins> let mut err = struct_span_err!( self.tcx().sess, span, E0221, "ambiguous associated type `{}` in bounds of `{}`",

ty_param_name); err.span_label(span, &format!("ambiguous associated type `{}`", assoc_name)); <del> for bound in &bounds { span_note!(&mut err, span, "associated type `{}` could derive from `{}`", ty_param_name, bound); </del> <ins> for span_and_bound in spans.zip(&bounds) { if let Some(span) = span_and_bound.0 { err.span_label(span, &format!("ambiguous `{}` from `{}`", assoc_name, span_and_bound.1)); } else { span_note!(&mut err, span, "associated type `{}` could derive from `{}`", ty_param_name, span_and_bound.1); } </ins> } err.emit(); }

trait T2 {} trait Foo { <del> type A: T1; </del> <ins> type A: T1; //~ NOTE: ambiguous `A` from `Foo` </ins> } trait Bar : Foo { <del> type A: T2; </del> <ins> type A: T2; //~ NOTE: ambiguous `A` from `Bar` </ins> fn do_something() { let _: Self::A; //~^ ERROR E0221 //~| NOTE ambiguous associated type `A` <del> //~| NOTE associated type `Self` could derive from `Foo` //~| NOTE associated type `Self` could derive from `Bar` </del> <ins> } } trait T3 {} trait My : std::str::FromStr { type Err: T3; //~ NOTE: ambiguous `Err` from `My` fn test() { let _: Self::Err; //~^ ERROR E0221 //~| NOTE ambiguous associated type `Err` //~| NOTE associated type `Self` could derive from `std::str::FromStr` </ins> } }

pub trait Vehicle { type Color; <ins> //~^ NOTE ambiguous `Color` from `Vehicle` //~| NOTE ambiguous `Color` from `Vehicle` //~| NOTE ambiguous `Color` from `Vehicle` </ins> fn go(&self) {  } } pub trait Box { type Color; <ins> //~^ NOTE ambiguous `Color` from `Box` //~| NOTE ambiguous `Color` from `Box` //~| NOTE ambiguous `Color` from `Box` // </ins> fn mail(&self) {  } }

fn dent<C:BoxCar>(c: C, color: C::Color) { //~^ ERROR ambiguous associated type `Color` in bounds of `C` //~| NOTE ambiguous associated type `Color` <del> //~| NOTE could derive from `Vehicle` //~| NOTE could derive from `Box` </del> } fn dent_object<COLOR>(c: BoxCar<Color=COLOR>) { //~^ ERROR ambiguous associated type //~| ERROR the value of the associated type `Color` (from the trait `Vehicle`) must be specified //~| NOTE ambiguous associated type `Color` <del> //~| NOTE could derive from `Vehicle` //~| NOTE could derive from `Box` </del> //~| NOTE missing associated type `Color` value } fn paint<C:BoxCar>(c: C, d: C::Color) { //~^ ERROR ambiguous associated type `Color` in bounds of `C` //~| NOTE ambiguous associated type `Color` <del> //~| NOTE could derive from `Vehicle` //~| NOTE could derive from `Box` </del> } pub fn main() { }