Skip to content

Commit 585f835

Browse files
committed
Make error E0221 more helpful
1 parent 7bccb82 commit 585f835

File tree

3 files changed

+44
-16
lines changed

3 files changed

+44
-16
lines changed

src/librustc_typeck/astconv.rs

+23-5
Original file line numberDiff line numberDiff line change
@@ -1261,18 +1261,36 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
12611261
}
12621262

12631263
if bounds.len() > 1 {
1264+
let spans = bounds.iter().map(|b| {
1265+
self.tcx().impl_or_trait_items(b.def_id()).iter()
1266+
.find(|&&def_id| {
1267+
match self.tcx().impl_or_trait_item(def_id) {
1268+
ty::TypeTraitItem(ref item) => item.name.as_str() == assoc_name,
1269+
_ => false
1270+
}
1271+
})
1272+
.and_then(|&def_id| self.tcx().map.as_local_node_id(def_id))
1273+
.and_then(|node_id| self.tcx().map.opt_span(node_id))
1274+
});
1275+
12641276
let mut err = struct_span_err!(
12651277
self.tcx().sess, span, E0221,
12661278
"ambiguous associated type `{}` in bounds of `{}`",
12671279
assoc_name,
12681280
ty_param_name);
12691281
err.span_label(span, &format!("ambiguous associated type `{}`", assoc_name));
12701282

1271-
for bound in &bounds {
1272-
span_note!(&mut err, span,
1273-
"associated type `{}` could derive from `{}`",
1274-
ty_param_name,
1275-
bound);
1283+
for span_and_bound in spans.zip(&bounds) {
1284+
if let Some(span) = span_and_bound.0 {
1285+
err.span_label(span, &format!("ambiguous `{}` from `{}`",
1286+
assoc_name,
1287+
span_and_bound.1));
1288+
} else {
1289+
span_note!(&mut err, span,
1290+
"associated type `{}` could derive from `{}`",
1291+
ty_param_name,
1292+
span_and_bound.1);
1293+
}
12761294
}
12771295
err.emit();
12781296
}

src/test/compile-fail/E0221.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,27 @@ trait T1 {}
1212
trait T2 {}
1313

1414
trait Foo {
15-
type A: T1;
15+
type A: T1; //~ NOTE: ambiguous `A` from `Foo`
1616
}
1717

1818
trait Bar : Foo {
19-
type A: T2;
19+
type A: T2; //~ NOTE: ambiguous `A` from `Bar`
2020
fn do_something() {
2121
let _: Self::A;
2222
//~^ ERROR E0221
2323
//~| NOTE ambiguous associated type `A`
24-
//~| NOTE associated type `Self` could derive from `Foo`
25-
//~| NOTE associated type `Self` could derive from `Bar`
24+
}
25+
}
26+
27+
trait T3 {}
28+
29+
trait My : std::str::FromStr {
30+
type Err: T3; //~ NOTE: ambiguous `Err` from `My`
31+
fn test() {
32+
let _: Self::Err;
33+
//~^ ERROR E0221
34+
//~| NOTE ambiguous associated type `Err`
35+
//~| NOTE associated type `Self` could derive from `std::str::FromStr`
2636
}
2737
}
2838

src/test/compile-fail/associated-type-projection-from-multiple-supertraits.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,19 @@
1313

1414
pub trait Vehicle {
1515
type Color;
16+
//~^ NOTE ambiguous `Color` from `Vehicle`
17+
//~| NOTE ambiguous `Color` from `Vehicle`
18+
//~| NOTE ambiguous `Color` from `Vehicle`
1619

1720
fn go(&self) { }
1821
}
1922

2023
pub trait Box {
2124
type Color;
22-
25+
//~^ NOTE ambiguous `Color` from `Box`
26+
//~| NOTE ambiguous `Color` from `Box`
27+
//~| NOTE ambiguous `Color` from `Box`
28+
//
2329
fn mail(&self) { }
2430
}
2531

@@ -29,24 +35,18 @@ pub trait BoxCar : Box + Vehicle {
2935
fn dent<C:BoxCar>(c: C, color: C::Color) {
3036
//~^ ERROR ambiguous associated type `Color` in bounds of `C`
3137
//~| NOTE ambiguous associated type `Color`
32-
//~| NOTE could derive from `Vehicle`
33-
//~| NOTE could derive from `Box`
3438
}
3539

3640
fn dent_object<COLOR>(c: BoxCar<Color=COLOR>) {
3741
//~^ ERROR ambiguous associated type
3842
//~| ERROR the value of the associated type `Color` (from the trait `Vehicle`) must be specified
3943
//~| NOTE ambiguous associated type `Color`
40-
//~| NOTE could derive from `Vehicle`
41-
//~| NOTE could derive from `Box`
4244
//~| NOTE missing associated type `Color` value
4345
}
4446

4547
fn paint<C:BoxCar>(c: C, d: C::Color) {
4648
//~^ ERROR ambiguous associated type `Color` in bounds of `C`
4749
//~| NOTE ambiguous associated type `Color`
48-
//~| NOTE could derive from `Vehicle`
49-
//~| NOTE could derive from `Box`
5050
}
5151

5252
pub fn main() { }

0 commit comments

Comments
 (0)