Skip to content

Commit a9a99df

Browse files
committed
Do not suggest implementing traits if present in predicates
1 parent 61bc7a3 commit a9a99df

File tree

4 files changed

+11
-10
lines changed

4 files changed

+11
-10
lines changed

src/librustc_typeck/check/method/suggest.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
696696
item_name,
697697
source,
698698
out_of_scope_traits,
699+
&unsatisfied_predicates,
699700
);
700701
}
701702

@@ -895,6 +896,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
895896
item_name: ast::Ident,
896897
source: SelfSource<'b>,
897898
valid_out_of_scope_traits: Vec<DefId>,
899+
unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option<ty::Predicate<'tcx>>)],
898900
) {
899901
if self.suggest_valid_traits(err, valid_out_of_scope_traits) {
900902
return;
@@ -915,7 +917,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
915917
// this isn't perfect (that is, there are cases when
916918
// implementing a trait would be legal but is rejected
917919
// here).
918-
(type_is_local || info.def_id.is_local())
920+
!unsatisfied_predicates.iter().any(|(p, _)| match p {
921+
// Hide traits if they are present in predicates as they can be fixed without
922+
// having to implement them.
923+
ty::Predicate::Trait(t, _) => t.def_id() != info.def_id,
924+
ty::Predicate::Projection(p) => p.item_def_id() != info.def_id,
925+
_ => true,
926+
}) && (type_is_local || info.def_id.is_local())
919927
&& self
920928
.associated_item(info.def_id, item_name, Namespace::ValueNS)
921929
.filter(|item| {

src/test/ui/methods/method-call-err-msg.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,8 @@ LL | .take()
4747
`Foo: std::iter::Iterator`
4848
which is required by `&mut Foo: std::iter::Iterator`
4949
= help: items from traits can only be used if the trait is implemented and in scope
50-
= note: the following traits define an item `take`, perhaps you need to implement one of them:
51-
candidate #1: `std::io::Read`
52-
candidate #2: `std::iter::Iterator`
50+
= note: the following trait defines an item `take`, perhaps you need to implement it:
51+
candidate #1: `std::iter::Iterator`
5352

5453
error[E0061]: this function takes 3 arguments but 0 arguments were supplied
5554
--> $DIR/method-call-err-msg.rs:21:7

src/test/ui/union/union-derive-clone.stderr

-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ LL | let w = u.clone();
2525
= note: the method `clone` exists but the following trait bounds were not satisfied:
2626
`CloneNoCopy: std::marker::Copy`
2727
which is required by `U5<CloneNoCopy>: std::clone::Clone`
28-
= help: items from traits can only be used if the trait is implemented and in scope
29-
= note: the following trait defines an item `clone`, perhaps you need to implement it:
30-
candidate #1: `std::clone::Clone`
3128

3229
error: aborting due to 2 previous errors
3330

src/test/ui/unique-object-noncopyable.stderr

-3
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ LL | pub struct Box<T: ?Sized>(Unique<T>);
2020
which is required by `std::boxed::Box<dyn Foo>: std::clone::Clone`
2121
`dyn Foo: std::clone::Clone`
2222
which is required by `std::boxed::Box<dyn Foo>: std::clone::Clone`
23-
= help: items from traits can only be used if the trait is implemented and in scope
24-
= note: the following trait defines an item `clone`, perhaps you need to implement it:
25-
candidate #1: `std::clone::Clone`
2623

2724
error: aborting due to previous error
2825

0 commit comments

Comments
 (0)