From a9a99df0a2976f1fd0dfc146f818778e5fdd635e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Esteban=20K=C3=BCber?= Date: Tue, 25 Feb 2020 12:10:48 -0800 Subject: [PATCH] Do not suggest implementing traits if present in predicates --- src/librustc_typeck/check/method/suggest.rs | 10 +++++++++- src/test/ui/methods/method-call-err-msg.stderr | 5 ++--- src/test/ui/union/union-derive-clone.stderr | 3 --- src/test/ui/unique-object-noncopyable.stderr | 3 --- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 5528895ad03..44f87319ebf 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -696,6 +696,7 @@ trait bound{s}", item_name, source, out_of_scope_traits, + &unsatisfied_predicates, ); } @@ -895,6 +896,7 @@ fn suggest_traits_to_import<'b>( item_name: ast::Ident, source: SelfSource<'b>, valid_out_of_scope_traits: Vec, + unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option>)], ) { if self.suggest_valid_traits(err, valid_out_of_scope_traits) { return; @@ -915,7 +917,13 @@ fn suggest_traits_to_import<'b>( // this isn't perfect (that is, there are cases when // implementing a trait would be legal but is rejected // here). - (type_is_local || info.def_id.is_local()) + !unsatisfied_predicates.iter().any(|(p, _)| match p { + // Hide traits if they are present in predicates as they can be fixed without + // having to implement them. + ty::Predicate::Trait(t, _) => t.def_id() != info.def_id, + ty::Predicate::Projection(p) => p.item_def_id() != info.def_id, + _ => true, + }) && (type_is_local || info.def_id.is_local()) && self .associated_item(info.def_id, item_name, Namespace::ValueNS) .filter(|item| { diff --git a/src/test/ui/methods/method-call-err-msg.stderr b/src/test/ui/methods/method-call-err-msg.stderr index ecb69506157..4678642dd6d 100644 --- a/src/test/ui/methods/method-call-err-msg.stderr +++ b/src/test/ui/methods/method-call-err-msg.stderr @@ -47,9 +47,8 @@ LL | .take() `Foo: std::iter::Iterator` which is required by `&mut Foo: std::iter::Iterator` = help: items from traits can only be used if the trait is implemented and in scope - = note: the following traits define an item `take`, perhaps you need to implement one of them: - candidate #1: `std::io::Read` - candidate #2: `std::iter::Iterator` + = note: the following trait defines an item `take`, perhaps you need to implement it: + candidate #1: `std::iter::Iterator` error[E0061]: this function takes 3 arguments but 0 arguments were supplied --> $DIR/method-call-err-msg.rs:21:7 diff --git a/src/test/ui/union/union-derive-clone.stderr b/src/test/ui/union/union-derive-clone.stderr index fdf2393656e..01c8e8471aa 100644 --- a/src/test/ui/union/union-derive-clone.stderr +++ b/src/test/ui/union/union-derive-clone.stderr @@ -25,9 +25,6 @@ LL | let w = u.clone(); = note: the method `clone` exists but the following trait bounds were not satisfied: `CloneNoCopy: std::marker::Copy` which is required by `U5: std::clone::Clone` - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `clone`, perhaps you need to implement it: - candidate #1: `std::clone::Clone` error: aborting due to 2 previous errors diff --git a/src/test/ui/unique-object-noncopyable.stderr b/src/test/ui/unique-object-noncopyable.stderr index 1c5fed2c33b..286008188fc 100644 --- a/src/test/ui/unique-object-noncopyable.stderr +++ b/src/test/ui/unique-object-noncopyable.stderr @@ -20,9 +20,6 @@ LL | pub struct Box(Unique); which is required by `std::boxed::Box: std::clone::Clone` `dyn Foo: std::clone::Clone` which is required by `std::boxed::Box: std::clone::Clone` - = help: items from traits can only be used if the trait is implemented and in scope - = note: the following trait defines an item `clone`, perhaps you need to implement it: - candidate #1: `std::clone::Clone` error: aborting due to previous error -- 2.44.0