From 8993b99ae28a1f8e3c11231a17e645feee66ea2f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Esteban=20K=C3=BCber?= Date: Tue, 18 Feb 2020 01:35:18 -0800 Subject: [PATCH] On single local candidate, use span label --- src/librustc_typeck/check/method/suggest.rs | 33 +++++++++++++------ .../associated-const-no-item.stderr | 5 +-- src/test/ui/auto-ref-slice-plus-ref.stderr | 20 ++++++----- ...e-21659-show-relevant-trait-impls-3.stderr | 5 +-- .../no-method-suggested-traits.stderr | 30 ++++++++++------- src/test/ui/issues/issue-5153.stderr | 5 +-- src/test/ui/issues/issue-57362-1.stderr | 5 +-- src/test/ui/issues/issue-57362-2.stderr | 5 +-- src/test/ui/never_type/issue-2149.stderr | 5 +-- src/test/ui/object-pointer-types.stderr | 10 +++--- ...at-arbitrary-self-type-trait-method.stderr | 6 ++-- ...pecialization-trait-not-implemented.stderr | 5 +-- src/test/ui/traits/trait-item-privacy.stderr | 15 +++++---- .../trivial-bounds/trivial-bounds-leak.stderr | 5 +-- 14 files changed, 95 insertions(+), 59 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index c6c404c5c78..3fa5d4baa76 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -846,7 +846,7 @@ fn suggest_traits_to_import<'b>( let message = |action| { format!( "the following {traits_define} an item `{name}`, perhaps you need to {action} \ - {one_of_them}:", + {one_of_them}:", traits_define = if candidates.len() == 1 { "trait defines" } else { "traits define" }, action = action, @@ -944,19 +944,32 @@ fn suggest_traits_to_import<'b>( } if !suggested { - let mut msg = message(if let Some(param) = param_type { + let action = if let Some(param) = param_type { format!("restrict type parameter `{}` with", param) } else { "implement".to_string() - }); - for (i, trait_info) in candidates.iter().enumerate() { - msg.push_str(&format!( - "\ncandidate #{}: `{}`", - i + 1, - self.tcx.def_path_str(trait_info.def_id), - )); + }; + let mut use_note = true; + if let [trait_info] = &candidates[..] { + if let Some(span) = self.tcx.hir().span_if_local(trait_info.def_id) { + err.span_label( + self.tcx.sess.source_map().def_span(span), + &format!("this trait defines an item `{}`", item_name), + ); + use_note = false + } + } + if use_note { + let mut msg = message(action); + for (i, trait_info) in candidates.iter().enumerate() { + msg.push_str(&format!( + "\ncandidate #{}: `{}`", + i + 1, + self.tcx.def_path_str(trait_info.def_id), + )); + } + err.note(&msg[..]); } - err.note(&msg[..]); } } } diff --git a/src/test/ui/associated-const/associated-const-no-item.stderr b/src/test/ui/associated-const/associated-const-no-item.stderr index d96cf67b875..e6765bc3dd6 100644 --- a/src/test/ui/associated-const/associated-const-no-item.stderr +++ b/src/test/ui/associated-const/associated-const-no-item.stderr @@ -1,12 +1,13 @@ error[E0599]: no associated item named `ID` found for type `i32` in the current scope --> $DIR/associated-const-no-item.rs:5:23 | +LL | trait Foo { + | --------- this trait defines an item `ID` +... LL | const X: i32 = ::ID; | ^^ associated item not found in `i32` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `ID`, perhaps you need to implement it: - candidate #1: `Foo` error: aborting due to previous error diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr index a0739a7a90b..3e14dc80122 100644 --- a/src/test/ui/auto-ref-slice-plus-ref.stderr +++ b/src/test/ui/auto-ref-slice-plus-ref.stderr @@ -3,40 +3,44 @@ error[E0599]: no method named `test_mut` found for struct `std::vec::Vec<{intege | LL | a.test_mut(); | ^^^^^^^^ help: there is a method with a similar name: `get_mut` +... +LL | trait MyIter { + | ------------ this trait defines an item `test_mut` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `test_mut`, perhaps you need to implement it: - candidate #1: `MyIter` error[E0599]: no method named `test` found for struct `std::vec::Vec<{integer}>` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:8:7 | LL | a.test(); | ^^^^ method not found in `std::vec::Vec<{integer}>` +... +LL | trait MyIter { + | ------------ this trait defines an item `test` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `test`, perhaps you need to implement it: - candidate #1: `MyIter` error[E0599]: no method named `test` found for array `[{integer}; 1]` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:10:11 | LL | ([1]).test(); | ^^^^ method not found in `[{integer}; 1]` +... +LL | trait MyIter { + | ------------ this trait defines an item `test` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `test`, perhaps you need to implement it: - candidate #1: `MyIter` error[E0599]: no method named `test` found for reference `&[{integer}; 1]` in the current scope --> $DIR/auto-ref-slice-plus-ref.rs:11:12 | LL | (&[1]).test(); | ^^^^ method not found in `&[{integer}; 1]` +... +LL | trait MyIter { + | ------------ this trait defines an item `test` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `test`, perhaps you need to implement it: - candidate #1: `MyIter` error: aborting due to 4 previous errors diff --git a/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr b/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr index 57417975474..32a677a7d7f 100644 --- a/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr +++ b/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr @@ -1,6 +1,9 @@ error[E0599]: no method named `foo` found for struct `Bar` in the current scope --> $DIR/issue-21659-show-relevant-trait-impls-3.rs:20:8 | +LL | trait Foo { + | ------------ this trait defines an item `foo` +... LL | struct Bar; | ----------- method `foo` not found for this ... @@ -8,8 +11,6 @@ LL | f1.foo(1usize); | ^^^ method not found in `Bar` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `foo`, perhaps you need to implement it: - candidate #1: `Foo` error: aborting due to previous error diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index da25617e187..8025c12047f 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -122,62 +122,68 @@ LL | std::rc::Rc::new(&mut Box::new(&Foo)).method(); error[E0599]: no method named `method2` found for type `u64` in the current scope --> $DIR/no-method-suggested-traits.rs:45:10 | +LL | pub trait Bar { + | ------------- this trait defines an item `method2` +... LL | 1u64.method2(); | ^^^^^^^ method not found in `u64` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `method2`, perhaps you need to implement it: - candidate #1: `foo::Bar` error[E0599]: no method named `method2` found for struct `std::rc::Rc<&mut std::boxed::Box<&u64>>` in the current scope --> $DIR/no-method-suggested-traits.rs:47:44 | +LL | pub trait Bar { + | ------------- this trait defines an item `method2` +... LL | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); | ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&u64>>` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `method2`, perhaps you need to implement it: - candidate #1: `foo::Bar` error[E0599]: no method named `method2` found for struct `no_method_suggested_traits::Foo` in the current scope --> $DIR/no-method-suggested-traits.rs:50:37 | +LL | pub trait Bar { + | ------------- this trait defines an item `method2` +... LL | no_method_suggested_traits::Foo.method2(); | ^^^^^^^ method not found in `no_method_suggested_traits::Foo` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `method2`, perhaps you need to implement it: - candidate #1: `foo::Bar` error[E0599]: no method named `method2` found for struct `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` in the current scope --> $DIR/no-method-suggested-traits.rs:52:71 | +LL | pub trait Bar { + | ------------- this trait defines an item `method2` +... LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); | ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `method2`, perhaps you need to implement it: - candidate #1: `foo::Bar` error[E0599]: no method named `method2` found for enum `no_method_suggested_traits::Bar` in the current scope --> $DIR/no-method-suggested-traits.rs:54:40 | +LL | pub trait Bar { + | ------------- this trait defines an item `method2` +... LL | no_method_suggested_traits::Bar::X.method2(); | ^^^^^^^ method not found in `no_method_suggested_traits::Bar` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `method2`, perhaps you need to implement it: - candidate #1: `foo::Bar` error[E0599]: no method named `method2` found for struct `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>` in the current scope --> $DIR/no-method-suggested-traits.rs:56:74 | +LL | pub trait Bar { + | ------------- this trait defines an item `method2` +... LL | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); | ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `method2`, perhaps you need to implement it: - candidate #1: `foo::Bar` error[E0599]: no method named `method3` found for struct `Foo` in the current scope --> $DIR/no-method-suggested-traits.rs:59:9 diff --git a/src/test/ui/issues/issue-5153.stderr b/src/test/ui/issues/issue-5153.stderr index 4680c8b131c..730da21ddf5 100644 --- a/src/test/ui/issues/issue-5153.stderr +++ b/src/test/ui/issues/issue-5153.stderr @@ -1,12 +1,13 @@ error[E0599]: no method named `foo` found for reference `&dyn Foo` in the current scope --> $DIR/issue-5153.rs:10:27 | +LL | trait Foo { + | --------- this trait defines an item `foo` +... LL | (&5isize as &dyn Foo).foo(); | ^^^ method not found in `&dyn Foo` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `foo`, perhaps you need to implement it: - candidate #1: `Foo` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57362-1.stderr b/src/test/ui/issues/issue-57362-1.stderr index ad596db13cc..3a5189b132d 100644 --- a/src/test/ui/issues/issue-57362-1.stderr +++ b/src/test/ui/issues/issue-57362-1.stderr @@ -1,13 +1,14 @@ error[E0599]: no method named `f` found for fn pointer `fn(&u8)` in the current scope --> $DIR/issue-57362-1.rs:20:7 | +LL | trait Trait { + | ----------- this trait defines an item `f` +... LL | a.f(); | ^ method not found in `fn(&u8)` | = note: `a` is a function, perhaps you wish to call it = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `f`, perhaps you need to implement it: - candidate #1: `Trait` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57362-2.stderr b/src/test/ui/issues/issue-57362-2.stderr index 3528084f6ce..e2d80b3b4df 100644 --- a/src/test/ui/issues/issue-57362-2.stderr +++ b/src/test/ui/issues/issue-57362-2.stderr @@ -1,12 +1,13 @@ error[E0599]: no function or associated item named `make_g` found for fn pointer `for<'r> fn(&'r ())` in the current scope --> $DIR/issue-57362-2.rs:22:25 | +LL | trait X { + | ------- this trait defines an item `make_g` +... LL | let x = ::make_g(); | ^^^^^^ function or associated item not found in `for<'r> fn(&'r ())` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `make_g`, perhaps you need to implement it: - candidate #1: `X` error: aborting due to previous error diff --git a/src/test/ui/never_type/issue-2149.stderr b/src/test/ui/never_type/issue-2149.stderr index 9645244751d..4fadf49bd6d 100644 --- a/src/test/ui/never_type/issue-2149.stderr +++ b/src/test/ui/never_type/issue-2149.stderr @@ -9,12 +9,13 @@ LL | for elt in self { r = r + f(*elt); } error[E0599]: no method named `bind` found for array `[&str; 1]` in the current scope --> $DIR/issue-2149.rs:13:12 | +LL | trait VecMonad { + | ----------------- this trait defines an item `bind` +... LL | ["hi"].bind(|x| [x] ); | ^^^^ method not found in `[&str; 1]` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `bind`, perhaps you need to implement it: - candidate #1: `VecMonad` error: aborting due to 2 previous errors diff --git a/src/test/ui/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr index 855894b4495..5ca326bca31 100644 --- a/src/test/ui/object-pointer-types.stderr +++ b/src/test/ui/object-pointer-types.stderr @@ -1,22 +1,24 @@ error[E0599]: no method named `owned` found for reference `&dyn Foo` in the current scope --> $DIR/object-pointer-types.rs:11:7 | +LL | trait Foo { + | --------- this trait defines an item `owned` +... LL | x.owned(); | ^^^^^ method not found in `&dyn Foo` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `owned`, perhaps you need to implement it: - candidate #1: `Foo` error[E0599]: no method named `owned` found for mutable reference `&mut dyn Foo` in the current scope --> $DIR/object-pointer-types.rs:17:7 | +LL | trait Foo { + | --------- this trait defines an item `owned` +... LL | x.owned(); | ^^^^^ method not found in `&mut dyn Foo` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `owned`, perhaps you need to implement it: - candidate #1: `Foo` error[E0599]: no method named `managed` found for struct `std::boxed::Box<(dyn Foo + 'static)>` in the current scope --> $DIR/object-pointer-types.rs:23:7 diff --git a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr index 28a7b68a682..8ed2b8b5c95 100644 --- a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr +++ b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr @@ -2,7 +2,9 @@ error[E0599]: no method named `foo` found for struct `A` in the current scope --> $DIR/point-at-arbitrary-self-type-trait-method.rs:9:7 | LL | trait B { fn foo(self: Box); } - | --- the method is available for `std::boxed::Box` here + | ------- --- the method is available for `std::boxed::Box` here + | | + | this trait defines an item `foo` LL | struct A; | --------- method `foo` not found for this ... @@ -10,8 +12,6 @@ LL | A.foo() | ^^^ method not found in `A` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `foo`, perhaps you need to implement it: - candidate #1: `B` error: aborting due to previous error diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr index 2d0caf1dd87..ccbb2aae05d 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr @@ -1,6 +1,9 @@ error[E0599]: no method named `foo_one` found for struct `MyStruct` in the current scope --> $DIR/specialization-trait-not-implemented.rs:22:29 | +LL | trait Foo { + | --------- this trait defines an item `foo_one` +... LL | struct MyStruct; | ---------------- | | @@ -13,8 +16,6 @@ LL | println!("{}", MyStruct.foo_one()); = note: the method `foo_one` exists but the following trait bounds were not satisfied: `MyStruct: Foo` = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `foo_one`, perhaps you need to implement it: - candidate #1: `Foo` error: aborting due to previous error diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr index 072328ab50c..5b7f0a8ce5f 100644 --- a/src/test/ui/traits/trait-item-privacy.stderr +++ b/src/test/ui/traits/trait-item-privacy.stderr @@ -4,12 +4,13 @@ error[E0599]: no method named `a` found for struct `S` in the current scope LL | struct S; | --------- method `a` not found for this ... +LL | trait A { + | ------- this trait defines an item `a` +... LL | S.a(); | ^ method not found in `S` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `a`, perhaps you need to implement it: - candidate #1: `method::A` error[E0599]: no method named `b` found for struct `S` in the current scope --> $DIR/trait-item-privacy.rs:68:7 @@ -45,12 +46,13 @@ error[E0599]: no function or associated item named `a` found for struct `S` in t LL | struct S; | --------- function or associated item `a` not found for this ... +LL | trait A { + | ------- this trait defines an item `a` +... LL | S::a(&S); | ^ function or associated item not found in `S` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `a`, perhaps you need to implement it: - candidate #1: `method::A` error[E0599]: no function or associated item named `b` found for struct `S` in the current scope --> $DIR/trait-item-privacy.rs:80:8 @@ -79,12 +81,13 @@ error[E0599]: no associated item named `A` found for struct `S` in the current s LL | struct S; | --------- associated item `A` not found for this ... +LL | trait A { + | ------- this trait defines an item `A` +... LL | S::A; | ^ associated item not found in `S` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `A`, perhaps you need to implement it: - candidate #1: `assoc_const::A` error[E0599]: no associated item named `B` found for struct `S` in the current scope --> $DIR/trait-item-privacy.rs:98:8 diff --git a/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr index acf309ac608..7ed24591e66 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr @@ -11,12 +11,13 @@ LL | fn cant_return_str() -> str { error[E0599]: no method named `test` found for type `i32` in the current scope --> $DIR/trivial-bounds-leak.rs:24:10 | +LL | pub trait Foo { + | ------------- this trait defines an item `test` +... LL | 3i32.test(); | ^^^^ method not found in `i32` | = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `test`, perhaps you need to implement it: - candidate #1: `Foo` error[E0277]: the trait bound `i32: Foo` is not satisfied --> $DIR/trivial-bounds-leak.rs:25:15 -- 2.44.0