From abdcb868ff69a5f6a96dd188ff845a1ec67335f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Nov 2018 17:51:13 -0800 Subject: [PATCH 1/6] Point at every unexpected lifetime and type argument in E0107 --- src/librustc_typeck/astconv.rs | 57 ++++++++++++++------------ src/test/ui/error-codes/E0107-b.rs | 8 ++++ src/test/ui/error-codes/E0107-b.stderr | 24 +++++++++++ src/test/ui/error-codes/E0107.rs | 3 +- src/test/ui/error-codes/E0107.stderr | 6 ++- 5 files changed, 69 insertions(+), 29 deletions(-) create mode 100644 src/test/ui/error-codes/E0107-b.rs create mode 100644 src/test/ui/error-codes/E0107-b.stderr diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d388d75643888..277f7d345462e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -338,33 +338,31 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { (required, "") }; - let mut span = span; - let label = if required == permitted && provided > permitted { - let diff = provided - permitted; - if diff == 1 { - // In the case when the user has provided too many arguments, - // we want to point to the first unexpected argument. - let first_superfluous_arg: &GenericArg = &args.args[offset + permitted]; - span = first_superfluous_arg.span(); - } - format!( - "{}unexpected {} argument{}", - if diff != 1 { format!("{} ", diff) } else { String::new() }, - kind, - if diff != 1 { "s" } else { "" }, + let (spans, label) = if required == permitted && provided > permitted { + // In the case when the user has provided too many arguments, + // we want to point to the unexpected arguments. + ( + args.args[offset+permitted .. offset+provided] + .iter() + .map(|arg| arg.span()) + .collect(), + format!( + "unexpected {} argument", + kind, + ), ) } else { - format!( + (vec![span], format!( "expected {}{} {} argument{}", quantifier, bound, kind, if bound != 1 { "s" } else { "" }, - ) + )) }; - tcx.sess.struct_span_err_with_code( - span, + let mut err = tcx.sess.struct_span_err_with_code( + spans.clone(), &format!( "wrong number of {} arguments: expected {}{}, found {}", kind, @@ -373,7 +371,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { provided, ), DiagnosticId::Error("E0107".into()) - ).span_label(span, label).emit(); + ); + for span in spans { + err.span_label(span, label.as_str()); + } + err.emit(); provided > required // `suppress_error` }; @@ -1030,13 +1032,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { for item_def_id in associated_types { let assoc_item = tcx.associated_item(item_def_id); let trait_def_id = assoc_item.container.id(); - struct_span_err!(tcx.sess, span, E0191, "the value of the associated type `{}` \ - (from the trait `{}`) must be specified", - assoc_item.ident, - tcx.item_path_str(trait_def_id)) - .span_label(span, format!("missing associated type `{}` value", - assoc_item.ident)) - .emit(); + let mut err = struct_span_err!( + tcx.sess, + span, + E0191, + "the value of the associated type `{}` (from the trait `{}`) must be specified", + assoc_item.ident, + tcx.item_path_str(trait_def_id), + ); + err.span_label(span, format!("missing associated type `{}` value", assoc_item.ident)); + err.emit(); } // Erase the `dummy_self` (`TRAIT_OBJECT_DUMMY_SELF`) used above. diff --git a/src/test/ui/error-codes/E0107-b.rs b/src/test/ui/error-codes/E0107-b.rs new file mode 100644 index 0000000000000..58e7718ba5bb4 --- /dev/null +++ b/src/test/ui/error-codes/E0107-b.rs @@ -0,0 +1,8 @@ +pub trait T { + type A; + type B; + type C; +} + pub struct Foo { i: Box> } + + fn main() {} diff --git a/src/test/ui/error-codes/E0107-b.stderr b/src/test/ui/error-codes/E0107-b.stderr new file mode 100644 index 0000000000000..28b957dc91e77 --- /dev/null +++ b/src/test/ui/error-codes/E0107-b.stderr @@ -0,0 +1,24 @@ +error[E0107]: wrong number of type arguments: expected 2, found 4 + --> $DIR/E0107-b.rs:6:42 + | +LL | pub struct Foo { i: Box> } + | ^^^^^ ^^^^^ unexpected type argument + | | + | unexpected type argument + +error[E0191]: the value of the associated type `A` (from the trait `T`) must be specified + --> $DIR/E0107-b.rs:6:26 + | +LL | pub struct Foo { i: Box> } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing associated type `A` value + +error[E0191]: the value of the associated type `C` (from the trait `T`) must be specified + --> $DIR/E0107-b.rs:6:26 + | +LL | pub struct Foo { i: Box> } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing associated type `C` value + +error: aborting due to 3 previous errors + +Some errors occurred: E0107, E0191. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/error-codes/E0107.rs b/src/test/ui/error-codes/E0107.rs index 815c7fefd2a96..87ac9e37853c0 100644 --- a/src/test/ui/error-codes/E0107.rs +++ b/src/test/ui/error-codes/E0107.rs @@ -26,7 +26,8 @@ struct Baz<'a, 'b, 'c> { //~| unexpected lifetime argument foo2: Foo<'a, 'b, 'c>, //~^ ERROR E0107 - //~| 2 unexpected lifetime arguments + //~| unexpected lifetime argument + //~| unexpected lifetime argument } fn main() {} diff --git a/src/test/ui/error-codes/E0107.stderr b/src/test/ui/error-codes/E0107.stderr index 497fa91bd4f39..a07c92cf26afb 100644 --- a/src/test/ui/error-codes/E0107.stderr +++ b/src/test/ui/error-codes/E0107.stderr @@ -11,10 +11,12 @@ LL | bar: Bar<'a>, | ^^ unexpected lifetime argument error[E0107]: wrong number of lifetime arguments: expected 1, found 3 - --> $DIR/E0107.rs:27:11 + --> $DIR/E0107.rs:27:19 | LL | foo2: Foo<'a, 'b, 'c>, - | ^^^^^^^^^^^^^^^ 2 unexpected lifetime arguments + | ^^ ^^ unexpected lifetime argument + | | + | unexpected lifetime argument error: aborting due to 3 previous errors From 286f7ae1dde03478fc0f36b7d1f3dc97cb47b730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Nov 2018 18:11:37 -0800 Subject: [PATCH 2/6] Join multiple E0191 errors in the same location under a single diagnostic --- src/librustc_typeck/astconv.rs | 27 ++++++++++++++----- .../associated-types-incomplete-object.rs | 3 +-- .../associated-types-incomplete-object.stderr | 15 +++++------ src/test/ui/error-codes/E0107-b.stderr | 15 +++++------ 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 277f7d345462e..906b800ee4472 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1029,18 +1029,31 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { associated_types.remove(&projection_bound.projection_def_id()); } - for item_def_id in associated_types { - let assoc_item = tcx.associated_item(item_def_id); - let trait_def_id = assoc_item.container.id(); + if !associated_types.is_empty() { + let names = associated_types.iter().map(|item_def_id| { + let assoc_item = tcx.associated_item(*item_def_id); + let trait_def_id = assoc_item.container.id(); + format!( + "`{}` (from the trait `{}`)", + assoc_item.ident, + tcx.item_path_str(trait_def_id), + ) + }).collect::>().join(", "); let mut err = struct_span_err!( tcx.sess, span, E0191, - "the value of the associated type `{}` (from the trait `{}`) must be specified", - assoc_item.ident, - tcx.item_path_str(trait_def_id), + "the value of the associated type{} {} must be specified", + if associated_types.len() == 1 { "" } else { "s" }, + names, ); - err.span_label(span, format!("missing associated type `{}` value", assoc_item.ident)); + for item_def_id in associated_types { + let assoc_item = tcx.associated_item(item_def_id); + err.span_label( + span, + format!("missing associated type `{}` value", assoc_item.ident), + ); + } err.emit(); } diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.rs b/src/test/ui/associated-types/associated-types-incomplete-object.rs index 9f1df14605b69..e575fd695b2db 100644 --- a/src/test/ui/associated-types/associated-types-incomplete-object.rs +++ b/src/test/ui/associated-types/associated-types-incomplete-object.rs @@ -37,6 +37,5 @@ pub fn main() { //~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified let d = &42isize as &Foo; - //~^ ERROR the value of the associated type `A` (from the trait `Foo`) must be specified - //~| ERROR the value of the associated type `B` (from the trait `Foo`) must be specified + //~^ ERROR the value of the associated types `A` (from the trait `Foo`), `B` (from the trait } diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.stderr b/src/test/ui/associated-types/associated-types-incomplete-object.stderr index 95b1c63125005..5a3c243efd084 100644 --- a/src/test/ui/associated-types/associated-types-incomplete-object.stderr +++ b/src/test/ui/associated-types/associated-types-incomplete-object.stderr @@ -10,18 +10,15 @@ error[E0191]: the value of the associated type `A` (from the trait `Foo`) must b LL | let c = &42isize as &Foo; | ^^^^^^^^^^^ missing associated type `A` value -error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified - --> $DIR/associated-types-incomplete-object.rs:39:26 - | -LL | let d = &42isize as &Foo; - | ^^^ missing associated type `A` value - -error[E0191]: the value of the associated type `B` (from the trait `Foo`) must be specified +error[E0191]: the value of the associated types `A` (from the trait `Foo`), `B` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:39:26 | LL | let d = &42isize as &Foo; - | ^^^ missing associated type `B` value + | ^^^ + | | + | missing associated type `A` value + | missing associated type `B` value -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0191`. diff --git a/src/test/ui/error-codes/E0107-b.stderr b/src/test/ui/error-codes/E0107-b.stderr index 28b957dc91e77..f779ca1e0b131 100644 --- a/src/test/ui/error-codes/E0107-b.stderr +++ b/src/test/ui/error-codes/E0107-b.stderr @@ -6,19 +6,16 @@ LL | pub struct Foo { i: Box> } | | | unexpected type argument -error[E0191]: the value of the associated type `A` (from the trait `T`) must be specified +error[E0191]: the value of the associated types `A` (from the trait `T`), `C` (from the trait `T`) must be specified --> $DIR/E0107-b.rs:6:26 | LL | pub struct Foo { i: Box> } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing associated type `A` value + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | missing associated type `A` value + | missing associated type `C` value -error[E0191]: the value of the associated type `C` (from the trait `T`) must be specified - --> $DIR/E0107-b.rs:6:26 - | -LL | pub struct Foo { i: Box> } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing associated type `C` value - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors occurred: E0107, E0191. For more information about an error, try `rustc --explain E0107`. From b6f4b29c6df3fc78adbda9c915f01f8e354d9ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Nov 2018 18:14:41 -0800 Subject: [PATCH 3/6] Point at the associated type's def span --- src/librustc_typeck/astconv.rs | 4 ++++ ...d-type-projection-from-multiple-supertraits.stderr | 3 +++ .../associated-types-incomplete-object.stderr | 11 +++++++++++ src/test/ui/error-codes/E0107-b.stderr | 6 ++++++ src/test/ui/error-codes/E0191.stderr | 3 +++ src/test/ui/error-codes/E0220.stderr | 3 +++ src/test/ui/issues/issue-19482.stderr | 3 +++ src/test/ui/issues/issue-21950.stderr | 5 +++++ src/test/ui/issues/issue-22434.stderr | 3 +++ src/test/ui/issues/issue-22560.stderr | 5 +++++ src/test/ui/issues/issue-23024.stderr | 5 +++++ src/test/ui/issues/issue-28344.stderr | 10 ++++++++++ src/test/ui/traits/trait-alias-object.stderr | 5 +++++ 13 files changed, 66 insertions(+) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 906b800ee4472..173f7ababe364 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1053,6 +1053,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { span, format!("missing associated type `{}` value", assoc_item.ident), ); + err.span_label( + tcx.def_span(item_def_id), + format!("`{}` defined here", assoc_item.ident), + ); } err.emit(); } diff --git a/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr b/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr index 7a10b6d021f54..726078f44a7ea 100644 --- a/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr +++ b/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr @@ -25,6 +25,9 @@ LL | fn dent_object(c: BoxCar) { error[E0191]: the value of the associated type `Color` (from the trait `Vehicle`) must be specified --> $DIR/associated-type-projection-from-multiple-supertraits.rs:33:26 | +LL | type Color; + | ----------- `Color` defined here +... LL | fn dent_object(c: BoxCar) { | ^^^^^^^^^^^^^^^^^^^ missing associated type `Color` value diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.stderr b/src/test/ui/associated-types/associated-types-incomplete-object.stderr index 5a3c243efd084..933f059ebf483 100644 --- a/src/test/ui/associated-types/associated-types-incomplete-object.stderr +++ b/src/test/ui/associated-types/associated-types-incomplete-object.stderr @@ -1,18 +1,29 @@ error[E0191]: the value of the associated type `B` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:33:26 | +LL | type B; + | ------- `B` defined here +... LL | let b = &42isize as &Foo; | ^^^^^^^^^^^^ missing associated type `B` value error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:36:26 | +LL | type A; + | ------- `A` defined here +... LL | let c = &42isize as &Foo; | ^^^^^^^^^^^ missing associated type `A` value error[E0191]: the value of the associated types `A` (from the trait `Foo`), `B` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:39:26 | +LL | type A; + | ------- `A` defined here +LL | type B; + | ------- `B` defined here +... LL | let d = &42isize as &Foo; | ^^^ | | diff --git a/src/test/ui/error-codes/E0107-b.stderr b/src/test/ui/error-codes/E0107-b.stderr index f779ca1e0b131..1e8c683aff6a5 100644 --- a/src/test/ui/error-codes/E0107-b.stderr +++ b/src/test/ui/error-codes/E0107-b.stderr @@ -9,6 +9,12 @@ LL | pub struct Foo { i: Box> } error[E0191]: the value of the associated types `A` (from the trait `T`), `C` (from the trait `T`) must be specified --> $DIR/E0107-b.rs:6:26 | +LL | type A; + | ------- `A` defined here +LL | type B; +LL | type C; + | ------- `C` defined here +LL | } LL | pub struct Foo { i: Box> } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | diff --git a/src/test/ui/error-codes/E0191.stderr b/src/test/ui/error-codes/E0191.stderr index 08b0a845814d9..a1f7c935c4a45 100644 --- a/src/test/ui/error-codes/E0191.stderr +++ b/src/test/ui/error-codes/E0191.stderr @@ -1,6 +1,9 @@ error[E0191]: the value of the associated type `Bar` (from the trait `Trait`) must be specified --> $DIR/E0191.rs:15:12 | +LL | type Bar; + | --------- `Bar` defined here +... LL | type Foo = Trait; //~ ERROR E0191 | ^^^^^ missing associated type `Bar` value diff --git a/src/test/ui/error-codes/E0220.stderr b/src/test/ui/error-codes/E0220.stderr index c8a587f2b5351..7ddd912d4f2bf 100644 --- a/src/test/ui/error-codes/E0220.stderr +++ b/src/test/ui/error-codes/E0220.stderr @@ -7,6 +7,9 @@ LL | type Foo = Trait; //~ ERROR E0220 error[E0191]: the value of the associated type `Bar` (from the trait `Trait`) must be specified --> $DIR/E0220.rs:15:12 | +LL | type Bar; + | --------- `Bar` defined here +... LL | type Foo = Trait; //~ ERROR E0220 | ^^^^^^^^^^^^ missing associated type `Bar` value diff --git a/src/test/ui/issues/issue-19482.stderr b/src/test/ui/issues/issue-19482.stderr index 5e2d427ab7258..7e71b0bd2323b 100644 --- a/src/test/ui/issues/issue-19482.stderr +++ b/src/test/ui/issues/issue-19482.stderr @@ -1,6 +1,9 @@ error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified --> $DIR/issue-19482.rs:20:12 | +LL | type A; + | ------- `A` defined here +... LL | fn bar(x: &Foo) {} | ^^^ missing associated type `A` value diff --git a/src/test/ui/issues/issue-21950.stderr b/src/test/ui/issues/issue-21950.stderr index a2f74a29aab78..3359225ab6dbd 100644 --- a/src/test/ui/issues/issue-21950.stderr +++ b/src/test/ui/issues/issue-21950.stderr @@ -11,6 +11,11 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | &Add; | ^^^ missing associated type `Output` value + | + ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL + | +LL | type Output; + | ------------ `Output` defined here error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-22434.stderr b/src/test/ui/issues/issue-22434.stderr index 914da801ad4e7..d951d57444d0f 100644 --- a/src/test/ui/issues/issue-22434.stderr +++ b/src/test/ui/issues/issue-22434.stderr @@ -1,6 +1,9 @@ error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified --> $DIR/issue-22434.rs:15:19 | +LL | type A; + | ------- `A` defined here +... LL | type I<'a> = &'a (Foo + 'a); | ^^^^^^^^ missing associated type `A` value diff --git a/src/test/ui/issues/issue-22560.stderr b/src/test/ui/issues/issue-22560.stderr index b5524036fae9d..8f736aa034537 100644 --- a/src/test/ui/issues/issue-22560.stderr +++ b/src/test/ui/issues/issue-22560.stderr @@ -29,6 +29,11 @@ LL | | //~^ ERROR E0393 LL | | //~| ERROR E0191 LL | | Sub; | |_______________^ missing associated type `Output` value + | + ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL + | +LL | type Output; + | ------------ `Output` defined here error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr index 129d094530361..8a493468dbf9c 100644 --- a/src/test/ui/issues/issue-23024.stderr +++ b/src/test/ui/issues/issue-23024.stderr @@ -17,6 +17,11 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | println!("{:?}",(vfnfer[0] as Fn)(3)); | ^^ missing associated type `Output` value + | + ::: $SRC_DIR/libcore/ops/function.rs:LL:COL + | +LL | type Output; + | ------------ `Output` defined here error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index 7ef2e906422ed..67588ba46f2e5 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -3,6 +3,11 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); | ^^^^^^^^^^^^^ missing associated type `Output` value + | + ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL + | +LL | type Output; + | ------------ `Output` defined here error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:14:17 @@ -17,6 +22,11 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | let g = BitXor::bitor; | ^^^^^^^^^^^^^ missing associated type `Output` value + | + ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL + | +LL | type Output; + | ------------ `Output` defined here error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:18:13 diff --git a/src/test/ui/traits/trait-alias-object.stderr b/src/test/ui/traits/trait-alias-object.stderr index 6b7b322a53d9e..0ae9b0b886419 100644 --- a/src/test/ui/traits/trait-alias-object.stderr +++ b/src/test/ui/traits/trait-alias-object.stderr @@ -11,6 +11,11 @@ error[E0191]: the value of the associated type `Item` (from the trait `std::iter | LL | let _: &dyn IteratorAlias = &vec![123].into_iter(); | ^^^^^^^^^^^^^^^^^ missing associated type `Item` value + | + ::: $SRC_DIR/libcore/iter/iterator.rs:LL:COL + | +LL | type Item; + | ---------- `Item` defined here error: aborting due to 2 previous errors From 48fa974211990ec2dd2b8d8c6949d101fb51bb45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Nov 2018 18:54:34 -0800 Subject: [PATCH 4/6] Suggest correct syntax when writing type arg instead of assoc type When confusing an associated type with a type argument, suggest the appropriate syntax. Given `Iterator`, suggest `Iterator`. --- src/librustc_typeck/astconv.rs | 114 +++++++++++------- src/librustc_typeck/collect.rs | 11 +- src/librustc_typeck/lib.rs | 2 +- ...se-type-argument-instead-of-assoc-type.rs} | 0 ...ype-argument-instead-of-assoc-type.stderr} | 8 +- 5 files changed, 88 insertions(+), 47 deletions(-) rename src/test/ui/{error-codes/E0107-b.rs => suggestions/use-type-argument-instead-of-assoc-type.rs} (100%) rename src/test/ui/{error-codes/E0107-b.stderr => suggestions/use-type-argument-instead-of-assoc-type.stderr} (75%) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 173f7ababe364..f1192cf98ae1c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -182,7 +182,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { item_segment: &hir::PathSegment) -> &'tcx Substs<'tcx> { - let (substs, assoc_bindings) = item_segment.with_generic_args(|generic_args| { + let (substs, assoc_bindings, _) = item_segment.with_generic_args(|generic_args| { self.create_substs_for_ast_path( span, def_id, @@ -256,7 +256,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { }, def.parent.is_none() && def.has_self, // `has_self` seg.infer_types || suppress_mismatch, // `infer_types` - ) + ).0 } /// Check that the correct number of generic arguments have been provided. @@ -269,7 +269,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { position: GenericArgPosition, has_self: bool, infer_types: bool, - ) -> bool { + ) -> (bool, Option>) { // At this stage we are guaranteed that the generic arguments are in the correct order, e.g. // that lifetimes will proceed types. So it suffices to check the number of each generic // arguments in order to validate them with respect to the generic parameters. @@ -303,13 +303,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { let mut err = tcx.sess.struct_span_err(span, msg); err.span_note(span_late, note); err.emit(); - return true; + return (true, None); } else { let mut multispan = MultiSpan::from_span(span); multispan.push_span_label(span_late, note.to_string()); tcx.lint_node(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS, args.args[0].id(), multispan, msg); - return false; + return (false, None); } } } @@ -323,7 +323,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { // For kinds without defaults (i.e. lifetimes), `required == permitted`. // For other kinds (i.e. types), `permitted` may be greater than `required`. if required <= provided && provided <= permitted { - return false; + return (false, None); } // Unfortunately lifetime and type parameter mismatches are typically styled @@ -338,19 +338,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { (required, "") }; + let mut potential_assoc_types: Option> = None; let (spans, label) = if required == permitted && provided > permitted { // In the case when the user has provided too many arguments, // we want to point to the unexpected arguments. - ( - args.args[offset+permitted .. offset+provided] + let spans: Vec = args.args[offset+permitted .. offset+provided] .iter() .map(|arg| arg.span()) - .collect(), - format!( - "unexpected {} argument", - kind, - ), - ) + .collect(); + potential_assoc_types = Some(spans.clone()); + (spans, format!( "unexpected {} argument", kind)) } else { (vec![span], format!( "expected {}{} {} argument{}", @@ -377,7 +374,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { } err.emit(); - provided > required // `suppress_error` + (provided > required, // `suppress_error` + potential_assoc_types) }; if !infer_lifetimes || arg_counts.lifetimes > param_counts.lifetimes { @@ -399,7 +397,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { arg_counts.lifetimes, ) } else { - false + (false, None) } } @@ -557,7 +555,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { generic_args: &hir::GenericArgs, infer_types: bool, self_ty: Option>) - -> (&'tcx Substs<'tcx>, Vec>) + -> (&'tcx Substs<'tcx>, Vec>, Option>) { // If the type is parameterized by this region, then replace this // region with the current anon region binding (in other words, @@ -573,7 +571,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { assert_eq!(generic_params.has_self, self_ty.is_some()); let has_self = generic_params.has_self; - Self::check_generic_arg_count( + let (_, potential_assoc_types) = Self::check_generic_arg_count( self.tcx(), span, &generic_params, @@ -678,7 +676,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { debug!("create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}", generic_params, self_ty, substs); - (substs, assoc_bindings) + (substs, assoc_bindings, potential_assoc_types) } /// Instantiates the path for the given trait reference, assuming that it's @@ -720,7 +718,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { self_ty: Ty<'tcx>, poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>, speculative: bool) - -> ty::PolyTraitRef<'tcx> + -> (ty::PolyTraitRef<'tcx>, Option>) { let trait_def_id = self.trait_def_id(trait_ref); @@ -728,11 +726,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1); - let (substs, assoc_bindings) = - self.create_substs_for_ast_trait_ref(trait_ref.path.span, - trait_def_id, - self_ty, - trait_ref.path.segments.last().unwrap()); + let (substs, assoc_bindings, potential_assoc_types) = self.create_substs_for_ast_trait_ref( + trait_ref.path.span, + trait_def_id, + self_ty, + trait_ref.path.segments.last().unwrap(), + ); let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs)); let mut dup_bindings = FxHashMap::default(); @@ -747,14 +746,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { debug!("instantiate_poly_trait_ref({:?}, projections={:?}) -> {:?}", trait_ref, poly_projections, poly_trait_ref); - poly_trait_ref + (poly_trait_ref, potential_assoc_types) } pub fn instantiate_poly_trait_ref(&self, poly_trait_ref: &hir::PolyTraitRef, self_ty: Ty<'tcx>, poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>) - -> ty::PolyTraitRef<'tcx> + -> (ty::PolyTraitRef<'tcx>, Option>) { self.instantiate_poly_trait_ref_inner(&poly_trait_ref.trait_ref, self_ty, poly_projections, false) @@ -767,7 +766,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { trait_segment: &hir::PathSegment) -> ty::TraitRef<'tcx> { - let (substs, assoc_bindings) = + let (substs, assoc_bindings, _) = self.create_substs_for_ast_trait_ref(span, trait_def_id, self_ty, @@ -776,13 +775,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { ty::TraitRef::new(trait_def_id, substs) } - fn create_substs_for_ast_trait_ref(&self, - span: Span, - trait_def_id: DefId, - self_ty: Ty<'tcx>, - trait_segment: &hir::PathSegment) - -> (&'tcx Substs<'tcx>, Vec>) - { + fn create_substs_for_ast_trait_ref( + &self, + span: Span, + trait_def_id: DefId, + self_ty: Ty<'tcx>, + trait_segment: &hir::PathSegment, + ) -> (&'tcx Substs<'tcx>, Vec>, Option>) { debug!("create_substs_for_ast_trait_ref(trait_segment={:?})", trait_segment); @@ -972,9 +971,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { let mut projection_bounds = Vec::new(); let dummy_self = tcx.mk_ty(TRAIT_OBJECT_DUMMY_SELF); - let principal = self.instantiate_poly_trait_ref(&trait_bounds[0], - dummy_self, - &mut projection_bounds); + let (principal, potential_assoc_types) = self.instantiate_poly_trait_ref( + &trait_bounds[0], + dummy_self, + &mut projection_bounds, + ); debug!("principal: {:?}", principal); for trait_bound in trait_bounds[1..].iter() { @@ -1047,16 +1048,47 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { if associated_types.len() == 1 { "" } else { "s" }, names, ); - for item_def_id in associated_types { - let assoc_item = tcx.associated_item(item_def_id); + let mut suggest = false; + let mut potential_assoc_types_spans = vec![]; + if let Some(potential_assoc_types) = potential_assoc_types { + if potential_assoc_types.len() == associated_types.len() { + // Only suggest when the amount of missing associated types is equals to the + // extra type arguments present, as that gives us a relatively high confidence + // that the user forgot to give the associtated type's name. The canonical + // example would be trying to use `Iterator` instead of + // `Iterator`. + suggest = true; + potential_assoc_types_spans = potential_assoc_types; + } + } + let mut suggestions = vec![]; + for (i, item_def_id) in associated_types.iter().enumerate() { + let assoc_item = tcx.associated_item(*item_def_id); err.span_label( span, format!("missing associated type `{}` value", assoc_item.ident), ); err.span_label( - tcx.def_span(item_def_id), + tcx.def_span(*item_def_id), format!("`{}` defined here", assoc_item.ident), ); + if suggest { + if let Ok(snippet) = tcx.sess.source_map().span_to_snippet( + potential_assoc_types_spans[i], + ) { + suggestions.push(( + potential_assoc_types_spans[i], + format!("{} = {}", assoc_item.ident, snippet), + )); + } + } + } + if !suggestions.is_empty() { + err.multipart_suggestion_with_applicability( + "if you meant to assign the missing associated type, use the name", + suggestions, + Applicability::MaybeIncorrect, + ); } err.emit(); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index f3c570e84009b..a1bb0b53f1fce 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1892,7 +1892,7 @@ fn explicit_predicates_of<'a, 'tcx>( &hir::GenericBound::Trait(ref poly_trait_ref, _) => { let mut projections = Vec::new(); - let trait_ref = AstConv::instantiate_poly_trait_ref( + let (trait_ref, _) = AstConv::instantiate_poly_trait_ref( &icx, poly_trait_ref, ty, @@ -2016,7 +2016,12 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>( let mut projection_bounds = Vec::new(); let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| { - (astconv.instantiate_poly_trait_ref(bound, param_ty, &mut projection_bounds), bound.span) + let (poly_trait_ref, _) = astconv.instantiate_poly_trait_ref( + bound, + param_ty, + &mut projection_bounds, + ); + (poly_trait_ref, bound.span) }).collect(); let region_bounds = region_bounds @@ -2057,7 +2062,7 @@ fn predicates_from_bound<'tcx>( match *bound { hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => { let mut projections = Vec::new(); - let pred = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections); + let (pred, _) = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections); iter::once((pred.to_predicate(), tr.span)).chain( projections .into_iter() diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 1f5998d8ca395..0fba311d7f7d5 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -389,7 +389,7 @@ pub fn hir_trait_to_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_trait: let env_def_id = tcx.hir.local_def_id(env_node_id); let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id); let mut projections = Vec::new(); - let principal = astconv::AstConv::instantiate_poly_trait_ref_inner( + let (principal, _) = astconv::AstConv::instantiate_poly_trait_ref_inner( &item_cx, hir_trait, tcx.types.err, &mut projections, true ); diff --git a/src/test/ui/error-codes/E0107-b.rs b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.rs similarity index 100% rename from src/test/ui/error-codes/E0107-b.rs rename to src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.rs diff --git a/src/test/ui/error-codes/E0107-b.stderr b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr similarity index 75% rename from src/test/ui/error-codes/E0107-b.stderr rename to src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr index 1e8c683aff6a5..053f701042112 100644 --- a/src/test/ui/error-codes/E0107-b.stderr +++ b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr @@ -1,5 +1,5 @@ error[E0107]: wrong number of type arguments: expected 2, found 4 - --> $DIR/E0107-b.rs:6:42 + --> $DIR/use-type-argument-instead-of-assoc-type.rs:6:42 | LL | pub struct Foo { i: Box> } | ^^^^^ ^^^^^ unexpected type argument @@ -7,7 +7,7 @@ LL | pub struct Foo { i: Box> } | unexpected type argument error[E0191]: the value of the associated types `A` (from the trait `T`), `C` (from the trait `T`) must be specified - --> $DIR/E0107-b.rs:6:26 + --> $DIR/use-type-argument-instead-of-assoc-type.rs:6:26 | LL | type A; | ------- `A` defined here @@ -20,6 +20,10 @@ LL | pub struct Foo { i: Box> } | | | missing associated type `A` value | missing associated type `C` value +help: if you meant to assign the missing associated type, use the name + | +LL | pub struct Foo { i: Box> } + | ^^^^^^^^^ ^^^^^^^^^ error: aborting due to 2 previous errors From a5d35631febf78027e5dd7f741bb9f07897d4eda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 8 Nov 2018 21:43:08 -0800 Subject: [PATCH 5/6] Reword and fix test --- src/librustc_typeck/astconv.rs | 9 +++++++-- src/test/compile-fail/issue-23595-1.rs | 4 +--- ...ated-type-projection-from-multiple-supertraits.stderr | 2 +- .../associated-types-incomplete-object.stderr | 8 ++++---- src/test/ui/error-codes/E0191.stderr | 2 +- src/test/ui/error-codes/E0220.stderr | 2 +- src/test/ui/issues/issue-19482.stderr | 2 +- src/test/ui/issues/issue-21950.stderr | 2 +- src/test/ui/issues/issue-22434.stderr | 2 +- src/test/ui/issues/issue-22560.stderr | 2 +- src/test/ui/issues/issue-23024.stderr | 2 +- src/test/ui/issues/issue-28344.stderr | 4 ++-- .../use-type-argument-instead-of-assoc-type.stderr | 6 +++--- src/test/ui/traits/trait-alias-object.stderr | 2 +- 14 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f1192cf98ae1c..b583c0554e821 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1066,7 +1066,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { let assoc_item = tcx.associated_item(*item_def_id); err.span_label( span, - format!("missing associated type `{}` value", assoc_item.ident), + format!("associated type `{}` must be specified", assoc_item.ident), ); err.span_label( tcx.def_span(*item_def_id), @@ -1084,8 +1084,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { } } if !suggestions.is_empty() { + let msg = if suggestions.len() == 1 { + "if you meant to specify the associated type, write" + } else { + "if you meant to specify the associated types, write" + }; err.multipart_suggestion_with_applicability( - "if you meant to assign the missing associated type, use the name", + msg, suggestions, Applicability::MaybeIncorrect, ); diff --git a/src/test/compile-fail/issue-23595-1.rs b/src/test/compile-fail/issue-23595-1.rs index a3422d859c61f..1e615c4c0db80 100644 --- a/src/test/compile-fail/issue-23595-1.rs +++ b/src/test/compile-fail/issue-23595-1.rs @@ -16,9 +16,7 @@ trait Hierarchy { type Value; type ChildKey; type Children = Index; - //~^ ERROR: the value of the associated type `ChildKey` - //~^^ ERROR: the value of the associated type `Children` - //~^^^ ERROR: the value of the associated type `Value` + //~^ ERROR: the value of the associated types `Value` (from the trait `Hierarchy`), `ChildKey` fn data(&self) -> Option<(Self::Value, Self::Children)>; } diff --git a/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr b/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr index 726078f44a7ea..b4285c0de29d5 100644 --- a/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr +++ b/src/test/ui/associated-type/associated-type-projection-from-multiple-supertraits.stderr @@ -29,7 +29,7 @@ LL | type Color; | ----------- `Color` defined here ... LL | fn dent_object(c: BoxCar) { - | ^^^^^^^^^^^^^^^^^^^ missing associated type `Color` value + | ^^^^^^^^^^^^^^^^^^^ associated type `Color` must be specified error[E0221]: ambiguous associated type `Color` in bounds of `C` --> $DIR/associated-type-projection-from-multiple-supertraits.rs:38:29 diff --git a/src/test/ui/associated-types/associated-types-incomplete-object.stderr b/src/test/ui/associated-types/associated-types-incomplete-object.stderr index 933f059ebf483..eb8e6f998a534 100644 --- a/src/test/ui/associated-types/associated-types-incomplete-object.stderr +++ b/src/test/ui/associated-types/associated-types-incomplete-object.stderr @@ -5,7 +5,7 @@ LL | type B; | ------- `B` defined here ... LL | let b = &42isize as &Foo; - | ^^^^^^^^^^^^ missing associated type `B` value + | ^^^^^^^^^^^^ associated type `B` must be specified error[E0191]: the value of the associated type `A` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:36:26 @@ -14,7 +14,7 @@ LL | type A; | ------- `A` defined here ... LL | let c = &42isize as &Foo; - | ^^^^^^^^^^^ missing associated type `A` value + | ^^^^^^^^^^^ associated type `A` must be specified error[E0191]: the value of the associated types `A` (from the trait `Foo`), `B` (from the trait `Foo`) must be specified --> $DIR/associated-types-incomplete-object.rs:39:26 @@ -27,8 +27,8 @@ LL | type B; LL | let d = &42isize as &Foo; | ^^^ | | - | missing associated type `A` value - | missing associated type `B` value + | associated type `A` must be specified + | associated type `B` must be specified error: aborting due to 3 previous errors diff --git a/src/test/ui/error-codes/E0191.stderr b/src/test/ui/error-codes/E0191.stderr index a1f7c935c4a45..f07529e7e9e1d 100644 --- a/src/test/ui/error-codes/E0191.stderr +++ b/src/test/ui/error-codes/E0191.stderr @@ -5,7 +5,7 @@ LL | type Bar; | --------- `Bar` defined here ... LL | type Foo = Trait; //~ ERROR E0191 - | ^^^^^ missing associated type `Bar` value + | ^^^^^ associated type `Bar` must be specified error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0220.stderr b/src/test/ui/error-codes/E0220.stderr index 7ddd912d4f2bf..d26e61fba8c6b 100644 --- a/src/test/ui/error-codes/E0220.stderr +++ b/src/test/ui/error-codes/E0220.stderr @@ -11,7 +11,7 @@ LL | type Bar; | --------- `Bar` defined here ... LL | type Foo = Trait; //~ ERROR E0220 - | ^^^^^^^^^^^^ missing associated type `Bar` value + | ^^^^^^^^^^^^ associated type `Bar` must be specified error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-19482.stderr b/src/test/ui/issues/issue-19482.stderr index 7e71b0bd2323b..d125438b8517d 100644 --- a/src/test/ui/issues/issue-19482.stderr +++ b/src/test/ui/issues/issue-19482.stderr @@ -5,7 +5,7 @@ LL | type A; | ------- `A` defined here ... LL | fn bar(x: &Foo) {} - | ^^^ missing associated type `A` value + | ^^^ associated type `A` must be specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-21950.stderr b/src/test/ui/issues/issue-21950.stderr index 3359225ab6dbd..2cc064dad1b8d 100644 --- a/src/test/ui/issues/issue-21950.stderr +++ b/src/test/ui/issues/issue-21950.stderr @@ -10,7 +10,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-21950.rs:17:14 | LL | &Add; - | ^^^ missing associated type `Output` value + | ^^^ associated type `Output` must be specified | ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL | diff --git a/src/test/ui/issues/issue-22434.stderr b/src/test/ui/issues/issue-22434.stderr index d951d57444d0f..3ba77346a1f82 100644 --- a/src/test/ui/issues/issue-22434.stderr +++ b/src/test/ui/issues/issue-22434.stderr @@ -5,7 +5,7 @@ LL | type A; | ------- `A` defined here ... LL | type I<'a> = &'a (Foo + 'a); - | ^^^^^^^^ missing associated type `A` value + | ^^^^^^^^ associated type `A` must be specified error: aborting due to previous error diff --git a/src/test/ui/issues/issue-22560.stderr b/src/test/ui/issues/issue-22560.stderr index 8f736aa034537..bfce870196a8e 100644 --- a/src/test/ui/issues/issue-22560.stderr +++ b/src/test/ui/issues/issue-22560.stderr @@ -28,7 +28,7 @@ LL | type Test = Add + LL | | //~^ ERROR E0393 LL | | //~| ERROR E0191 LL | | Sub; - | |_______________^ missing associated type `Output` value + | |_______________^ associated type `Output` must be specified | ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL | diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr index 8a493468dbf9c..198469ca723d0 100644 --- a/src/test/ui/issues/issue-23024.stderr +++ b/src/test/ui/issues/issue-23024.stderr @@ -16,7 +16,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-23024.rs:19:35 | LL | println!("{:?}",(vfnfer[0] as Fn)(3)); - | ^^ missing associated type `Output` value + | ^^ associated type `Output` must be specified | ::: $SRC_DIR/libcore/ops/function.rs:LL:COL | diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index 67588ba46f2e5..824ba4b49cb46 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -2,7 +2,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-28344.rs:14:17 | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); - | ^^^^^^^^^^^^^ missing associated type `Output` value + | ^^^^^^^^^^^^^ associated type `Output` must be specified | ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL | @@ -21,7 +21,7 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op --> $DIR/issue-28344.rs:18:13 | LL | let g = BitXor::bitor; - | ^^^^^^^^^^^^^ missing associated type `Output` value + | ^^^^^^^^^^^^^ associated type `Output` must be specified | ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL | diff --git a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr index 053f701042112..b62b5d3b04ca0 100644 --- a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr +++ b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr @@ -18,9 +18,9 @@ LL | } LL | pub struct Foo { i: Box> } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | missing associated type `A` value - | missing associated type `C` value -help: if you meant to assign the missing associated type, use the name + | associated type `A` must be specified + | associated type `C` must be specified +help: if you meant to specify the associated types, write | LL | pub struct Foo { i: Box> } | ^^^^^^^^^ ^^^^^^^^^ diff --git a/src/test/ui/traits/trait-alias-object.stderr b/src/test/ui/traits/trait-alias-object.stderr index 0ae9b0b886419..c316c4a6beb7f 100644 --- a/src/test/ui/traits/trait-alias-object.stderr +++ b/src/test/ui/traits/trait-alias-object.stderr @@ -10,7 +10,7 @@ error[E0191]: the value of the associated type `Item` (from the trait `std::iter --> $DIR/trait-alias-object.rs:18:13 | LL | let _: &dyn IteratorAlias = &vec![123].into_iter(); - | ^^^^^^^^^^^^^^^^^ missing associated type `Item` value + | ^^^^^^^^^^^^^^^^^ associated type `Item` must be specified | ::: $SRC_DIR/libcore/iter/iterator.rs:LL:COL | From 510f836d2378bc9d7ec48e3c39ca83006aadb197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 22 Nov 2018 14:30:33 -0800 Subject: [PATCH 6/6] Do not point at associated types from other crates This is a somewhat arbitrary restriction in order to be consistent in the output of the tests regardless of target platform. --- src/librustc_typeck/astconv.rs | 10 ++++++---- src/test/ui/issues/issue-21950.stderr | 5 ----- src/test/ui/issues/issue-22560.stderr | 5 ----- src/test/ui/issues/issue-23024.stderr | 5 ----- src/test/ui/issues/issue-28344.stderr | 10 ---------- src/test/ui/traits/trait-alias-object.stderr | 5 ----- 6 files changed, 6 insertions(+), 34 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index b583c0554e821..a8164c85e821d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1068,10 +1068,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o { span, format!("associated type `{}` must be specified", assoc_item.ident), ); - err.span_label( - tcx.def_span(*item_def_id), - format!("`{}` defined here", assoc_item.ident), - ); + if item_def_id.is_local() { + err.span_label( + tcx.def_span(*item_def_id), + format!("`{}` defined here", assoc_item.ident), + ); + } if suggest { if let Ok(snippet) = tcx.sess.source_map().span_to_snippet( potential_assoc_types_spans[i], diff --git a/src/test/ui/issues/issue-21950.stderr b/src/test/ui/issues/issue-21950.stderr index 2cc064dad1b8d..33c89dd4994b7 100644 --- a/src/test/ui/issues/issue-21950.stderr +++ b/src/test/ui/issues/issue-21950.stderr @@ -11,11 +11,6 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | &Add; | ^^^ associated type `Output` must be specified - | - ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL - | -LL | type Output; - | ------------ `Output` defined here error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-22560.stderr b/src/test/ui/issues/issue-22560.stderr index bfce870196a8e..715f84011f64e 100644 --- a/src/test/ui/issues/issue-22560.stderr +++ b/src/test/ui/issues/issue-22560.stderr @@ -29,11 +29,6 @@ LL | | //~^ ERROR E0393 LL | | //~| ERROR E0191 LL | | Sub; | |_______________^ associated type `Output` must be specified - | - ::: $SRC_DIR/libcore/ops/arith.rs:LL:COL - | -LL | type Output; - | ------------ `Output` defined here error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-23024.stderr b/src/test/ui/issues/issue-23024.stderr index 198469ca723d0..adee12a36d31b 100644 --- a/src/test/ui/issues/issue-23024.stderr +++ b/src/test/ui/issues/issue-23024.stderr @@ -17,11 +17,6 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | println!("{:?}",(vfnfer[0] as Fn)(3)); | ^^ associated type `Output` must be specified - | - ::: $SRC_DIR/libcore/ops/function.rs:LL:COL - | -LL | type Output; - | ------------ `Output` defined here error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index 824ba4b49cb46..734c761d0b7bc 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -3,11 +3,6 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); | ^^^^^^^^^^^^^ associated type `Output` must be specified - | - ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL - | -LL | type Output; - | ------------ `Output` defined here error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:14:17 @@ -22,11 +17,6 @@ error[E0191]: the value of the associated type `Output` (from the trait `std::op | LL | let g = BitXor::bitor; | ^^^^^^^^^^^^^ associated type `Output` must be specified - | - ::: $SRC_DIR/libcore/ops/bit.rs:LL:COL - | -LL | type Output; - | ------------ `Output` defined here error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope --> $DIR/issue-28344.rs:18:13 diff --git a/src/test/ui/traits/trait-alias-object.stderr b/src/test/ui/traits/trait-alias-object.stderr index c316c4a6beb7f..fdb9427cba734 100644 --- a/src/test/ui/traits/trait-alias-object.stderr +++ b/src/test/ui/traits/trait-alias-object.stderr @@ -11,11 +11,6 @@ error[E0191]: the value of the associated type `Item` (from the trait `std::iter | LL | let _: &dyn IteratorAlias = &vec![123].into_iter(); | ^^^^^^^^^^^^^^^^^ associated type `Item` must be specified - | - ::: $SRC_DIR/libcore/iter/iterator.rs:LL:COL - | -LL | type Item; - | ---------- `Item` defined here error: aborting due to 2 previous errors