Skip to content

Commit

Permalink
Auto merge of #79606 - ThePuzzlemaker:issue-79458-fix, r=scottmcm
Browse files Browse the repository at this point in the history
Do not show negative polarity trait implementations in diagnostic messages for similar implementations

This fixes #79458.

Previously, this code:
```rust
#[derive(Clone)]
struct Foo<'a, T> {
    x: &'a mut T,
}
```
would have suggested that `<&mut T as Clone>` was an implementation that was found. This is due to the fact that the standard library now has `impl<'_, T> !Clone for &'_ mut T`, and explicit negative polarity implementations were not filtered out in diagnostic output when suggesting similar implementations.

This PR fixes this issue by filtering out negative polarity trait implementations in `find_similar_impl_candidates` within `rustc_trait_selection::traits::error_reporting::InferCtxtPrivExt<'tcx>`. It also adds a UI regression test for this issue and fixes UI tests that had incorrectly been modified to expect the invalid output.

r? `@scottmcm`
  • Loading branch information
bors committed Dec 2, 2020
2 parents 92e4fb0 + b287806 commit d37afad
Show file tree
Hide file tree
Showing 15 changed files with 36 additions and 27 deletions.
12 changes: 11 additions & 1 deletion compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1310,10 +1310,20 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
return None;
}
}
if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative {
return None;
}
Some(imp)
})
.collect(),
None => all_impls.map(|def_id| self.tcx.impl_trait_ref(def_id).unwrap()).collect(),
None => all_impls
.filter_map(|def_id| {
if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative {
return None;
}
self.tcx.impl_trait_ref(def_id)
})
.collect(),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ LL | type U = str;
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) {
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ LL | type V = str;
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ LL | for<'b> <T as Z<'b, u16>>::W: Clone,
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error[E0277]: the trait bound `for<'b> <u16 as Z<'b, u16>>::W: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-2.rs:16:14
Expand All @@ -28,7 +27,6 @@ LL | type W = str;
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error[E0277]: the trait bound `for<'b> <u16 as Z<'b, u16>>::W: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-2.rs:4:8
Expand All @@ -44,7 +42,6 @@ LL | for<'b> <T as Z<'b, u16>>::W: Clone,
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error: aborting due to 3 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ LL | type U = str;
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ LL | type U = str;
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ LL | type U = str;
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error[E0277]: the trait bound `for<'b> <Vec<T> as X<'b, Vec<T>>>::U: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-5.rs:27:14
Expand All @@ -28,7 +27,6 @@ LL | type U = str;
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error[E0277]: the trait bound `for<'b> <Vec<T> as X<'b, Vec<T>>>::U: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-5.rs:33:14
Expand All @@ -44,7 +42,6 @@ LL | type U = str;
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error[E0277]: the trait bound `for<'b> <Box<T> as X<'b, Box<T>>>::U: Clone` is not satisfied
--> $DIR/hr-associated-type-bound-param-5.rs:33:14
Expand All @@ -60,7 +57,6 @@ LL | type U = str;
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error: aborting due to 4 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ LL | type U = str;
|
= help: the following implementations were found:
<&T as Clone>
<&mut T as Clone>

error[E0277]: the trait bound `for<'b> T: X<'b, T>` is not satisfied
--> $DIR/hr-associated-type-bound-param-6.rs:12:12
Expand Down
2 changes: 0 additions & 2 deletions src/test/ui/async-await/issue-64130-3-other.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ LL | async fn bar() {
LL | is_qux(bar());
| ^^^^^^ within `impl Future`, the trait `Qux` is not implemented for `Foo`
|
= help: the following implementations were found:
<Foo as Qux>
note: future does not implement `Qux` as this value is used across an await
--> $DIR/issue-64130-3-other.rs:18:5
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ LL | fn is_mytrait<T: MyTrait>() {}
LL | is_mytrait::<(MyS2, MyS)>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2`
|
= help: the following implementations were found:
<MyS2 as MyTrait>
= note: required because it appears within the type `(MyS2, MyS)`

error: aborting due to previous error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ LL | fn is_mytrait<T: MyTrait>() {}
...
LL | is_mytrait::<MyS2>();
| ^^^^ the trait `MyTrait` is not implemented for `MyS2`
|
= help: the following implementations were found:
<MyS2 as MyTrait>

error: aborting due to previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ LL | fn is_my_trait<T: MyTrait>() {}
...
LL | is_my_trait::<ThisImplsUnsafeTrait>();
| ^^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `ThisImplsUnsafeTrait`
|
= help: the following implementations were found:
<ThisImplsUnsafeTrait as MyTrait>

error[E0277]: the trait bound `ThisImplsTrait: MyUnsafeTrait` is not satisfied
--> $DIR/typeck-default-trait-impl-negation.rs:25:26
Expand All @@ -18,9 +15,6 @@ LL | fn is_my_unsafe_trait<T: MyUnsafeTrait>() {}
...
LL | is_my_unsafe_trait::<ThisImplsTrait>();
| ^^^^^^^^^^^^^^ the trait `MyUnsafeTrait` is not implemented for `ThisImplsTrait`
|
= help: the following implementations were found:
<ThisImplsTrait as MyUnsafeTrait>

error: aborting due to 2 previous errors

Expand Down
10 changes: 10 additions & 0 deletions src/test/ui/traits/issue-79458.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Negative implementations should not be shown in trait suggestions.
// This is a regression test of #79458.

#[derive(Clone)]
struct Foo<'a, T> {
bar: &'a mut T
//~^ ERROR the trait bound `&mut T: Clone` is not satisfied
}

fn main() {}
15 changes: 15 additions & 0 deletions src/test/ui/traits/issue-79458.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0277]: the trait bound `&mut T: Clone` is not satisfied
--> $DIR/issue-79458.rs:6:5
|
LL | bar: &'a mut T
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `&mut T`
|
= help: the following implementations were found:
<&T as Clone>
= note: `Clone` is implemented for `&T`, but not for `&mut T`
= note: required by `clone`
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.

0 comments on commit d37afad

Please sign in to comment.