From 397972f5b032b848dd8ba2d13e851be0bf9c1ffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 3 Jun 2017 17:06:46 -0700 Subject: [PATCH] Separate suggestion in a `help` and a `note` --- src/librustc_typeck/check/method/suggest.rs | 12 ++--- src/test/compile-fail/method-call-err-msg.rs | 1 + ...e-21659-show-relevant-trait-impls-3.stderr | 3 +- .../method-suggestion-no-duplication.stderr | 3 +- .../no-method-suggested-traits.stderr | 54 ++++++++++++------- src/test/ui/span/issue-7575.stderr | 6 ++- 6 files changed, 51 insertions(+), 28 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 51f16f8a49f4e..22479f9ae3d24 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -315,8 +315,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut candidates = valid_out_of_scope_traits; candidates.sort(); candidates.dedup(); - let mut msg = format!("items from traits can only be used if the trait is in scope; \ - the following {traits_are} implemented but not in scope, \ + err.help("items from traits can only be used if the trait is in scope"); + let mut msg = format!("the following {traits_are} implemented but not in scope, \ perhaps add a `use` for {one_of_them}:", traits_are = if candidates.len() == 1 { "trait is" @@ -338,7 +338,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if candidates.len() > limit { msg.push_str(&format!("\nand {} others", candidates.len() - limit)); } - err.help(&msg[..]); + err.note(&msg[..]); return; } @@ -369,8 +369,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // FIXME #21673 this help message could be tuned to the case // of a type parameter: suggest adding a trait bound rather // than implementing. - let mut msg = format!("items from traits can only be used if the trait is implemented \ - and in scope; the following {traits_define} an item `{name}`, \ + err.help("items from traits can only be used if the trait is implemented and in scope"); + let mut msg = format!("the following {traits_define} an item `{name}`, \ perhaps you need to implement {one_of_them}:", traits_define = if candidates.len() == 1 { "trait defines" @@ -389,7 +389,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { i + 1, self.tcx.item_path_str(trait_info.def_id))); } - err.help(&msg[..]); + err.note(&msg[..]); } } diff --git a/src/test/compile-fail/method-call-err-msg.rs b/src/test/compile-fail/method-call-err-msg.rs index b8eb8434b3506..14fa74d1f32e5 100644 --- a/src/test/compile-fail/method-call-err-msg.rs +++ b/src/test/compile-fail/method-call-err-msg.rs @@ -33,5 +33,6 @@ fn main() { y.zero() .take() //~ ERROR no method named `take` found for type `Foo` in the current scope //~^ NOTE the method `take` exists but the following trait bounds were not satisfied + //~| NOTE the following traits define an item `take`, perhaps you need to implement one of them .one(0); } diff --git a/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr b/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr index 38a1337c9b9ce..1b1e0eaf2039a 100644 --- a/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr +++ b/src/test/ui/impl-trait/issue-21659-show-relevant-trait-impls-3.stderr @@ -4,7 +4,8 @@ error[E0599]: no method named `foo` found for type `Bar` in the current scope 30 | f1.foo(1usize); | ^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `foo`, perhaps you need to implement it: + = 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(s) diff --git a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr index a548924815a6a..fa08c3bee9cf3 100644 --- a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr +++ b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr @@ -4,7 +4,8 @@ error[E0599]: no method named `is_empty` found for type `Foo` in the current sco 19 | foo(|s| s.is_empty()); | ^^^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item `is_empty`, perhaps you need to implement one of them: + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following traits define an item `is_empty`, perhaps you need to implement one of them: candidate #1: `std::iter::ExactSizeIterator` candidate #2: `core::slice::SliceExt` candidate #3: `core::str::StrExt` 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 ab5f6b6c6c87b..95d3007a4fb21 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -4,7 +4,8 @@ error[E0599]: no method named `method` found for type `u32` in the current scope 33 | 1u32.method(); | ^^^^^^ | - = help: items from traits can only be used if the trait is in scope; the following traits are implemented but not in scope, perhaps add a `use` for one of them: + = help: items from traits can only be used if the trait is in scope + = note: the following traits are implemented but not in scope, perhaps add a `use` for one of them: candidate #1: `use foo::Bar;` candidate #2: `use no_method_suggested_traits::foo::PubPub;` @@ -14,7 +15,8 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box 38 | std::rc::Rc::new(&mut Box::new(&1u32)).method(); | ^^^^^^ | - = help: items from traits can only be used if the trait is in scope; the following traits are implemented but not in scope, perhaps add a `use` for one of them: + = help: items from traits can only be used if the trait is in scope + = note: the following traits are implemented but not in scope, perhaps add a `use` for one of them: candidate #1: `use foo::Bar;` candidate #2: `use no_method_suggested_traits::foo::PubPub;` @@ -24,7 +26,8 @@ error[E0599]: no method named `method` found for type `char` in the current scop 44 | 'a'.method(); | ^^^^^^ | - = help: items from traits can only be used if the trait is in scope; the following trait is implemented but not in scope, perhaps add a `use` for it: + = help: items from traits can only be used if the trait is in scope + = note: the following trait is implemented but not in scope, perhaps add a `use` for it: candidate #1: `use foo::Bar;` error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&char>>` in the current scope @@ -33,7 +36,8 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box 48 | std::rc::Rc::new(&mut Box::new(&'a')).method(); | ^^^^^^ | - = help: items from traits can only be used if the trait is in scope; the following trait is implemented but not in scope, perhaps add a `use` for it: + = help: items from traits can only be used if the trait is in scope + = note: the following trait is implemented but not in scope, perhaps add a `use` for it: candidate #1: `use foo::Bar;` error[E0599]: no method named `method` found for type `i32` in the current scope @@ -42,7 +46,8 @@ error[E0599]: no method named `method` found for type `i32` in the current scope 53 | 1i32.method(); | ^^^^^^ | - = help: items from traits can only be used if the trait is in scope; the following trait is implemented but not in scope, perhaps add a `use` for it: + = help: items from traits can only be used if the trait is in scope + = note: the following trait is implemented but not in scope, perhaps add a `use` for it: candidate #1: `use no_method_suggested_traits::foo::PubPub;` error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&i32>>` in the current scope @@ -51,7 +56,8 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box 57 | std::rc::Rc::new(&mut Box::new(&1i32)).method(); | ^^^^^^ | - = help: items from traits can only be used if the trait is in scope; the following trait is implemented but not in scope, perhaps add a `use` for it: + = help: items from traits can only be used if the trait is in scope + = note: the following trait is implemented but not in scope, perhaps add a `use` for it: candidate #1: `use no_method_suggested_traits::foo::PubPub;` error[E0599]: no method named `method` found for type `Foo` in the current scope @@ -60,7 +66,8 @@ error[E0599]: no method named `method` found for type `Foo` in the current scope 62 | Foo.method(); | ^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item `method`, perhaps you need to implement one of them: + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following traits define an item `method`, perhaps you need to implement one of them: candidate #1: `foo::Bar` candidate #2: `no_method_suggested_traits::foo::PubPub` candidate #3: `no_method_suggested_traits::bar::PubPriv` @@ -74,7 +81,8 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box 71 | std::rc::Rc::new(&mut Box::new(&Foo)).method(); | ^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item `method`, perhaps you need to implement one of them: + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following traits define an item `method`, perhaps you need to implement one of them: candidate #1: `foo::Bar` candidate #2: `no_method_suggested_traits::foo::PubPub` candidate #3: `no_method_suggested_traits::bar::PubPriv` @@ -88,7 +96,8 @@ error[E0599]: no method named `method2` found for type `u64` in the current scop 81 | 1u64.method2(); | ^^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `method2`, perhaps you need to implement it: + = 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 type `std::rc::Rc<&mut std::boxed::Box<&u64>>` in the current scope @@ -97,7 +106,8 @@ error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::bo 85 | std::rc::Rc::new(&mut Box::new(&1u64)).method2(); | ^^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `method2`, perhaps you need to implement it: + = 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 type `no_method_suggested_traits::Foo` in the current scope @@ -106,7 +116,8 @@ error[E0599]: no method named `method2` found for type `no_method_suggested_trai 90 | no_method_suggested_traits::Foo.method2(); | ^^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `method2`, perhaps you need to implement it: + = 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 type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` in the current scope @@ -115,7 +126,8 @@ error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::bo 94 | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2(); | ^^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `method2`, perhaps you need to implement it: + = 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 type `no_method_suggested_traits::Bar` in the current scope @@ -124,7 +136,8 @@ error[E0599]: no method named `method2` found for type `no_method_suggested_trai 98 | no_method_suggested_traits::Bar::X.method2(); | ^^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `method2`, perhaps you need to implement it: + = 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 type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>` in the current scope @@ -133,7 +146,8 @@ error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::bo 102 | std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2(); | ^^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `method2`, perhaps you need to implement it: + = 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 type `Foo` in the current scope @@ -142,7 +156,8 @@ error[E0599]: no method named `method3` found for type `Foo` in the current scop 107 | Foo.method3(); | ^^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `method3`, perhaps you need to implement it: + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `no_method_suggested_traits::foo::PubPub` error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&Foo>>` in the current scope @@ -151,7 +166,8 @@ error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::bo 111 | std::rc::Rc::new(&mut Box::new(&Foo)).method3(); | ^^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `method3`, perhaps you need to implement it: + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `no_method_suggested_traits::foo::PubPub` error[E0599]: no method named `method3` found for type `Bar` in the current scope @@ -160,7 +176,8 @@ error[E0599]: no method named `method3` found for type `Bar` in the current scop 115 | Bar::X.method3(); | ^^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `method3`, perhaps you need to implement it: + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `no_method_suggested_traits::foo::PubPub` error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&Bar>>` in the current scope @@ -169,7 +186,8 @@ error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::bo 119 | std::rc::Rc::new(&mut Box::new(&Bar::X)).method3(); | ^^^^^^^ | - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `method3`, perhaps you need to implement it: + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `method3`, perhaps you need to implement it: candidate #1: `no_method_suggested_traits::foo::PubPub` error[E0599]: no method named `method3` found for type `usize` in the current scope diff --git a/src/test/ui/span/issue-7575.stderr b/src/test/ui/span/issue-7575.stderr index 249dfb15b49a9..9bf00b1b5749a 100644 --- a/src/test/ui/span/issue-7575.stderr +++ b/src/test/ui/span/issue-7575.stderr @@ -23,7 +23,8 @@ note: candidate #3 is defined in the trait `UnusedTrait` 29 | fn f9(usize) -> usize; //~ NOTE candidate | ^^^^^^^^^^^^^^^^^^^^^^ = help: to disambiguate the method call, write `UnusedTrait::f9(u, 342)` instead - = help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item `f9`, perhaps you need to implement one of them: + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following traits define an item `f9`, perhaps you need to implement one of them: candidate #1: `CtxtFn` candidate #2: `OtherTrait` candidate #3: `UnusedTrait` @@ -58,7 +59,8 @@ note: candidate #1 is defined in the trait `ManyImplTrait` 59 | | } | |_____^ = help: to disambiguate the method call, write `ManyImplTrait::is_str(t)` instead - = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `is_str`, perhaps you need to implement it: + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `is_str`, perhaps you need to implement it: candidate #1: `ManyImplTrait` error: aborting due to previous error(s)