Skip to content

Commit f6e6d2a

Browse files
committed
Elaborate unmet obligations in E0599 for more context
1 parent 0b90256 commit f6e6d2a

File tree

4 files changed

+53
-12
lines changed

4 files changed

+53
-12
lines changed

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,11 +1587,29 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15871587
let o = self.resolve_vars_if_possible(o);
15881588
if !self.predicate_may_hold(&o) {
15891589
result = ProbeResult::NoMatch;
1590-
possibly_unsatisfied_predicates.push((
1591-
o.predicate,
1592-
None,
1593-
Some(o.cause),
1594-
));
1590+
let parent_o = o.clone();
1591+
let implied_obligations =
1592+
traits::elaborate_obligations(self.tcx, vec![o]);
1593+
for o in implied_obligations {
1594+
let parent = if o == parent_o {
1595+
None
1596+
} else {
1597+
if o.predicate.to_opt_poly_trait_pred().map(|p| p.def_id())
1598+
== self.tcx.lang_items().sized_trait()
1599+
{
1600+
// We don't care to talk about implicit `Sized` bounds.
1601+
continue;
1602+
}
1603+
Some(parent_o.predicate)
1604+
};
1605+
if !self.predicate_may_hold(&o) {
1606+
possibly_unsatisfied_predicates.push((
1607+
o.predicate,
1608+
parent,
1609+
Some(o.cause),
1610+
));
1611+
}
1612+
}
15951613
}
15961614
}
15971615
}

tests/ui/derives/issue-91550.stderr

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ LL | struct Value(u32);
66
| |
77
| doesn't satisfy `Value: Eq`
88
| doesn't satisfy `Value: Hash`
9+
| doesn't satisfy `Value: PartialEq`
910
...
1011
LL | hs.insert(Value(0));
1112
| ^^^^^^
1213
|
1314
= note: the following trait bounds were not satisfied:
1415
`Value: Eq`
16+
`Value: PartialEq`
17+
which is required by `Value: Eq`
1518
`Value: Hash`
1619
help: consider annotating `Value` with `#[derive(Eq, Hash, PartialEq)]`
1720
|
@@ -22,15 +25,20 @@ error[E0599]: the method `use_eq` exists for struct `Object<NoDerives>`, but its
2225
--> $DIR/issue-91550.rs:26:9
2326
|
2427
LL | pub struct NoDerives;
25-
| -------------------- doesn't satisfy `NoDerives: Eq`
28+
| --------------------
29+
| |
30+
| doesn't satisfy `NoDerives: Eq`
31+
| doesn't satisfy `NoDerives: PartialEq`
2632
LL |
2733
LL | struct Object<T>(T);
2834
| ---------------- method `use_eq` not found for this struct
2935
...
3036
LL | foo.use_eq();
3137
| ^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
3238
|
33-
note: trait bound `NoDerives: Eq` was not satisfied
39+
note: the following trait bounds were not satisfied:
40+
`NoDerives: Eq`
41+
`NoDerives: PartialEq`
3442
--> $DIR/issue-91550.rs:15:9
3543
|
3644
LL | impl<T: Eq> Object<T> {
@@ -46,15 +54,24 @@ error[E0599]: the method `use_ord` exists for struct `Object<NoDerives>`, but it
4654
--> $DIR/issue-91550.rs:27:9
4755
|
4856
LL | pub struct NoDerives;
49-
| -------------------- doesn't satisfy `NoDerives: Ord`
57+
| --------------------
58+
| |
59+
| doesn't satisfy `NoDerives: Eq`
60+
| doesn't satisfy `NoDerives: Ord`
61+
| doesn't satisfy `NoDerives: PartialEq`
62+
| doesn't satisfy `NoDerives: PartialOrd`
5063
LL |
5164
LL | struct Object<T>(T);
5265
| ---------------- method `use_ord` not found for this struct
5366
...
5467
LL | foo.use_ord();
5568
| ^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
5669
|
57-
note: trait bound `NoDerives: Ord` was not satisfied
70+
note: the following trait bounds were not satisfied:
71+
`NoDerives: Eq`
72+
`NoDerives: Ord`
73+
`NoDerives: PartialEq`
74+
`NoDerives: PartialOrd`
5875
--> $DIR/issue-91550.rs:18:9
5976
|
6077
LL | impl<T: Ord> Object<T> {
@@ -72,7 +89,9 @@ error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoD
7289
LL | pub struct NoDerives;
7390
| --------------------
7491
| |
92+
| doesn't satisfy `NoDerives: Eq`
7593
| doesn't satisfy `NoDerives: Ord`
94+
| doesn't satisfy `NoDerives: PartialEq`
7695
| doesn't satisfy `NoDerives: PartialOrd`
7796
LL |
7897
LL | struct Object<T>(T);
@@ -82,7 +101,9 @@ LL | foo.use_ord_and_partial_ord();
82101
| ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
83102
|
84103
note: the following trait bounds were not satisfied:
104+
`NoDerives: Eq`
85105
`NoDerives: Ord`
106+
`NoDerives: PartialEq`
86107
`NoDerives: PartialOrd`
87108
--> $DIR/issue-91550.rs:21:9
88109
|

tests/ui/missing-trait-bounds/issue-35677.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::collections::HashSet;
44
use std::hash::Hash;
55

6-
fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash {
6+
fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash, T: PartialEq {
77
this.is_subset(other)
88
//~^ ERROR the method
99
}

tests/ui/missing-trait-bounds/issue-35677.stderr

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ LL | this.is_subset(other)
66
|
77
= note: the following trait bounds were not satisfied:
88
`T: Eq`
9+
`T: PartialEq`
10+
which is required by `T: Eq`
911
`T: Hash`
1012
help: consider restricting the type parameters to satisfy the trait bounds
1113
|
12-
LL | fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash {
13-
| ++++++++++++++++++++
14+
LL | fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash, T: PartialEq {
15+
| ++++++++++++++++++++++++++++++++++
1416

1517
error: aborting due to previous error
1618

0 commit comments

Comments
 (0)