Rollup merge of #37396 - mikhail-m1:e0221, r=jonathandturner

Make error E0221 more helpful

fix #35970 as part of #35233
r? @jonathandturner
This commit is contained in:
Guillaume Gomez 2016-10-26 23:49:27 +02:00 committed by GitHub
commit 46c5c6ccfd
3 changed files with 44 additions and 16 deletions

View file

@ -1261,6 +1261,18 @@ fn one_bound_for_assoc_type(&self,
}
if bounds.len() > 1 {
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))
});
let mut err = struct_span_err!(
self.tcx().sess, span, E0221,
"ambiguous associated type `{}` in bounds of `{}`",
@ -1268,11 +1280,17 @@ fn one_bound_for_assoc_type(&self,
ty_param_name);
err.span_label(span, &format!("ambiguous associated type `{}`", assoc_name));
for bound in &bounds {
span_note!(&mut err, span,
"associated type `{}` could derive from `{}`",
ty_param_name,
bound);
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);
}
}
err.emit();
}

View file

@ -12,17 +12,27 @@ trait T1 {}
trait T2 {}
trait Foo {
type A: T1;
type A: T1; //~ NOTE: ambiguous `A` from `Foo`
}
trait Bar : Foo {
type A: T2;
type A: T2; //~ NOTE: ambiguous `A` from `Bar`
fn do_something() {
let _: Self::A;
//~^ ERROR E0221
//~| NOTE ambiguous associated type `A`
//~| NOTE associated type `Self` could derive from `Foo`
//~| NOTE associated type `Self` could derive from `Bar`
}
}
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`
}
}

View file

@ -13,13 +13,19 @@
pub trait Vehicle {
type Color;
//~^ NOTE ambiguous `Color` from `Vehicle`
//~| NOTE ambiguous `Color` from `Vehicle`
//~| NOTE ambiguous `Color` from `Vehicle`
fn go(&self) { }
}
pub trait Box {
type Color;
//~^ NOTE ambiguous `Color` from `Box`
//~| NOTE ambiguous `Color` from `Box`
//~| NOTE ambiguous `Color` from `Box`
//
fn mail(&self) { }
}
@ -29,24 +35,18 @@ pub trait BoxCar : Box + Vehicle {
fn dent<C:BoxCar>(c: C, color: C::Color) {
//~^ ERROR ambiguous associated type `Color` in bounds of `C`
//~| NOTE ambiguous associated type `Color`
//~| NOTE could derive from `Vehicle`
//~| NOTE could derive from `Box`
}
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`
//~| NOTE could derive from `Vehicle`
//~| NOTE could derive from `Box`
//~| 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`
//~| NOTE could derive from `Vehicle`
//~| NOTE could derive from `Box`
}
pub fn main() { }