Skip to content

Commit 083d70f

Browse files
committed
Account for negative bounds in E0277 note and suggestion
Do not suggest `#[derive(Copy)]` when we wanted a `!Copy` type. Do not say "`Copy` is not implemented for `T` but `Copy` is". Do not talk about `Trait` having no implementations when `!Trait` was desired.
1 parent a019c39 commit 083d70f

File tree

4 files changed

+8
-19
lines changed

4 files changed

+8
-19
lines changed

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2540,12 +2540,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
25402540
&& self.tcx.trait_impls_of(trait_def_id).is_empty()
25412541
&& !self.tcx.trait_is_auto(trait_def_id)
25422542
&& !self.tcx.trait_is_alias(trait_def_id)
2543+
&& trait_predicate.polarity() == ty::PredicatePolarity::Positive
25432544
{
25442545
err.span_help(
25452546
self.tcx.def_span(trait_def_id),
25462547
crate::fluent_generated::trait_selection_trait_has_no_impls,
25472548
);
2548-
} else if !suggested && !unsatisfied_const {
2549+
} else if !suggested
2550+
&& !unsatisfied_const
2551+
&& trait_predicate.polarity() == ty::PredicatePolarity::Positive
2552+
{
25492553
// Can't show anything else useful, try to find similar impls.
25502554
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
25512555
if !self.report_similar_impl_candidates(

compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

+3
Original file line numberDiff line numberDiff line change
@@ -3697,6 +3697,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
36973697
err: &mut Diag<'_>,
36983698
trait_pred: ty::PolyTraitPredicate<'tcx>,
36993699
) {
3700+
if trait_pred.polarity() == ty::PredicatePolarity::Negative {
3701+
return;
3702+
}
37003703
let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) else {
37013704
return;
37023705
};

tests/ui/traits/negative-bounds/on-unimplemented.stderr

-6
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@ LL | fn hello() -> impl !Foo {
66
LL |
77
LL | NotFoo
88
| ------ return type was inferred to be `NotFoo` here
9-
|
10-
help: this trait has no implementations, consider adding one
11-
--> $DIR/on-unimplemented.rs:4:1
12-
|
13-
LL | trait Foo {}
14-
| ^^^^^^^^^
159

1610
error: aborting due to 1 previous error
1711

tests/ui/traits/negative-bounds/simple.stderr

-12
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,11 @@ error[E0277]: the trait bound `Copyable: !Copy` is not satisfied
2828
LL | not_copy::<Copyable>();
2929
| ^^^^^^^^ the trait bound `Copyable: !Copy` is not satisfied
3030
|
31-
= help: the trait `Copy` is not implemented for `Copyable`
32-
but trait `Copy` is implemented for it
3331
note: required by a bound in `not_copy`
3432
--> $DIR/simple.rs:3:16
3533
|
3634
LL | fn not_copy<T: !Copy>() {}
3735
| ^^^^^ required by this bound in `not_copy`
38-
help: consider annotating `Copyable` with `#[derive(Copy)]`
39-
|
40-
LL + #[derive(Copy)]
41-
LL | struct Copyable;
42-
|
4336

4437
error[E0277]: the trait bound `NotNecessarilyCopyable: !Copy` is not satisfied
4538
--> $DIR/simple.rs:37:16
@@ -52,11 +45,6 @@ note: required by a bound in `not_copy`
5245
|
5346
LL | fn not_copy<T: !Copy>() {}
5447
| ^^^^^ required by this bound in `not_copy`
55-
help: consider annotating `NotNecessarilyCopyable` with `#[derive(Copy)]`
56-
|
57-
LL + #[derive(Copy)]
58-
LL | struct NotNecessarilyCopyable;
59-
|
6048

6149
error: aborting due to 4 previous errors
6250

0 commit comments

Comments
 (0)