Skip to content

Commit 3ffdd7f

Browse files
uwu
1 parent 9f075f4 commit 3ffdd7f

File tree

7 files changed

+118
-86
lines changed

7 files changed

+118
-86
lines changed

compiler/rustc_hir_typeck/src/method/probe.rs

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_infer::infer::canonical::{Canonical, QueryResponse};
1515
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
1616
use rustc_infer::infer::DefineOpaqueTypes;
1717
use rustc_infer::infer::{self, InferOk, TyCtxtInferExt};
18+
use rustc_infer::traits::EvaluationResult;
1819
use rustc_middle::middle::stability;
1920
use rustc_middle::query::Providers;
2021
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
@@ -1397,8 +1398,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
13971398
let impl_bounds =
13981399
self.tcx.predicates_of(impl_def_id).instantiate(self.tcx, impl_args);
13991400
let impl_bounds = ocx.normalize(cause, self.param_env, impl_bounds);
1400-
// Convert the bounds into obligations.
1401-
let predicates: Vec<_> = traits::predicates_for_generics(
1401+
for obligation in traits::predicates_for_generics(
14021402
|idx, span| {
14031403
let code = if span.is_dummy() {
14041404
traits::ExprItemObligation(impl_def_id, self.scope_expr_id, idx)
@@ -1414,20 +1414,30 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14141414
},
14151415
self.param_env,
14161416
impl_bounds,
1417-
)
1418-
.collect();
1419-
if let Some(obligation) = predicates.iter().find(|obligation| {
1420-
!self.infcx.next_trait_solver()
1421-
&& !self.infcx.predicate_may_hold(&obligation)
1422-
}) {
1423-
result = ProbeResult::NoMatch;
1424-
possibly_unsatisfied_predicates.push((
1425-
self.resolve_vars_if_possible(obligation.predicate),
1426-
None,
1427-
Some(obligation.cause.clone()),
1428-
));
1429-
} else {
1430-
ocx.register_obligations(predicates);
1417+
) {
1418+
if self.infcx.next_trait_solver() {
1419+
ocx.register_obligation(obligation);
1420+
} else {
1421+
match self.infcx.evaluate_obligation_no_overflow(&obligation) {
1422+
EvaluationResult::EvaluatedToOk => {
1423+
// No side-effects, no need to register obligations.
1424+
}
1425+
EvaluationResult::EvaluatedToOkModuloRegions
1426+
| EvaluationResult::EvaluatedToOkModuloOpaqueTypes
1427+
| EvaluationResult::EvaluatedToAmbig
1428+
| EvaluationResult::EvaluatedToAmbigStackDependent => {
1429+
ocx.register_obligation(obligation);
1430+
}
1431+
EvaluationResult::EvaluatedToErr => {
1432+
result = ProbeResult::NoMatch;
1433+
possibly_unsatisfied_predicates.push((
1434+
self.resolve_vars_if_possible(obligation.predicate),
1435+
None,
1436+
Some(obligation.cause.clone()),
1437+
));
1438+
}
1439+
}
1440+
}
14311441
}
14321442
}
14331443
TraitCandidate(poly_trait_ref) => {
@@ -1472,21 +1482,36 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
14721482
ty::Binder::dummy(trait_ref),
14731483
);
14741484

1475-
// FIXME(-Znext-solver): We only need this hack to deal with fatal
1476-
// overflow in the old solver.
1477-
if self.infcx.next_trait_solver() || self.infcx.predicate_may_hold(&obligation)
1478-
{
1485+
if self.infcx.next_trait_solver() {
14791486
ocx.register_obligation(obligation);
14801487
} else {
1481-
result = ProbeResult::NoMatch;
1482-
if let Ok(Some(candidate)) = self.select_trait_candidate(trait_ref) {
1483-
for nested_obligation in candidate.nested_obligations() {
1484-
if !self.infcx.predicate_may_hold(&nested_obligation) {
1485-
possibly_unsatisfied_predicates.push((
1486-
self.resolve_vars_if_possible(nested_obligation.predicate),
1487-
Some(self.resolve_vars_if_possible(obligation.predicate)),
1488-
Some(nested_obligation.cause),
1489-
));
1488+
match self.infcx.evaluate_obligation_no_overflow(&obligation) {
1489+
EvaluationResult::EvaluatedToOk => {
1490+
// No side-effects, no need to register obligations.
1491+
}
1492+
EvaluationResult::EvaluatedToOkModuloRegions
1493+
| EvaluationResult::EvaluatedToOkModuloOpaqueTypes
1494+
| EvaluationResult::EvaluatedToAmbig
1495+
| EvaluationResult::EvaluatedToAmbigStackDependent => {
1496+
ocx.register_obligation(obligation);
1497+
}
1498+
EvaluationResult::EvaluatedToErr => {
1499+
result = ProbeResult::NoMatch;
1500+
if let Ok(Some(candidate)) = self.select_trait_candidate(trait_ref)
1501+
{
1502+
for nested_obligation in candidate.nested_obligations() {
1503+
if !self.infcx.predicate_may_hold(&nested_obligation) {
1504+
possibly_unsatisfied_predicates.push((
1505+
self.resolve_vars_if_possible(
1506+
nested_obligation.predicate,
1507+
),
1508+
Some(self.resolve_vars_if_possible(
1509+
obligation.predicate,
1510+
)),
1511+
Some(nested_obligation.cause),
1512+
));
1513+
}
1514+
}
14901515
}
14911516
}
14921517
}
Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,10 @@
1-
error[E0599]: the function or associated item `new` exists for struct `Inline<dyn Debug>`, but its trait bounds were not satisfied
2-
--> $DIR/issue-80742.rs:36:36
3-
|
4-
LL | struct Inline<T>
5-
| ---------------- function or associated item `new` not found for this struct
6-
...
7-
LL | let dst = Inline::<dyn Debug>::new(0);
8-
| ^^^ function or associated item cannot be called on `Inline<dyn Debug>` due to unsatisfied trait bounds
9-
|
10-
note: if you're trying to build a new `Inline<dyn Debug>`, consider using `Inline::<T>::new` which returns `Inline<_>`
11-
--> $DIR/issue-80742.rs:30:5
12-
|
13-
LL | pub fn new(val: T) -> Inline<T> {
14-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15-
note: trait bound `dyn Debug: Sized` was not satisfied
16-
--> $DIR/issue-80742.rs:26:6
17-
|
18-
LL | impl<T> Inline<T>
19-
| ^ ---------
20-
| |
21-
| unsatisfied trait bound introduced here
22-
help: consider relaxing the type parameter's implicit `Sized` bound
23-
|
24-
LL | impl<T: ?Sized> Inline<T>
25-
| ++++++++
26-
271
error: internal compiler error: compiler/rustc_const_eval/src/interpret/step.rs:LL:CC: SizeOf MIR operator called for unsized type dyn Debug
282
--> $SRC_DIR/core/src/mem/mod.rs:LL:COL
293

304
Box<dyn Any>
315
query stack during panic:
32-
#0 [eval_to_allocation_raw] const-evaluating + checking `Inline::{constant#0}`
6+
#0 [eval_to_allocation_raw] const-evaluating + checking `<impl at $DIR/issue-80742.rs:26:1: 28:32>::{constant#0}`
337
#1 [eval_to_valtree] evaluating type-level constant
348
end of query stack
35-
error: aborting due to 2 previous errors
9+
error: aborting due to 1 previous error
3610

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

tests/ui/derives/issue-91550.stderr

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@ error[E0599]: the method `insert` exists for struct `HashSet<Value>`, but its tr
22
--> $DIR/issue-91550.rs:8:8
33
|
44
LL | struct Value(u32);
5-
| ------------ doesn't satisfy `Value: Eq`
5+
| ------------ doesn't satisfy `Value: Eq` or `Value: Hash`
66
...
77
LL | hs.insert(Value(0));
88
| ^^^^^^
99
|
1010
= note: the following trait bounds were not satisfied:
1111
`Value: Eq`
12-
help: consider annotating `Value` with `#[derive(Eq, PartialEq)]`
12+
`Value: Hash`
13+
help: consider annotating `Value` with `#[derive(Eq, Hash, PartialEq)]`
1314
|
14-
LL + #[derive(Eq, PartialEq)]
15+
LL + #[derive(Eq, Hash, PartialEq)]
1516
LL | struct Value(u32);
1617
|
1718

@@ -69,20 +70,23 @@ error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoD
6970
--> $DIR/issue-91550.rs:28:9
7071
|
7172
LL | pub struct NoDerives;
72-
| -------------------- doesn't satisfy `NoDerives: Ord`
73+
| -------------------- doesn't satisfy `NoDerives: Ord` or `NoDerives: PartialOrd`
7374
LL |
7475
LL | struct Object<T>(T);
7576
| ---------------- method `use_ord_and_partial_ord` not found for this struct
7677
...
7778
LL | foo.use_ord_and_partial_ord();
7879
| ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
7980
|
80-
note: trait bound `NoDerives: Ord` was not satisfied
81+
note: the following trait bounds were not satisfied:
82+
`NoDerives: Ord`
83+
`NoDerives: PartialOrd`
8184
--> $DIR/issue-91550.rs:21:9
8285
|
8386
LL | impl<T: Ord + PartialOrd> Object<T> {
84-
| ^^^ ---------
85-
| |
87+
| ^^^ ^^^^^^^^^^ ---------
88+
| | |
89+
| | unsatisfied trait bound introduced here
8690
| unsatisfied trait bound introduced here
8791
help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
8892
|

tests/ui/impl-trait/issues/issue-84073.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0275]: overflow assigning `_` to `Option<_>`
2-
--> $DIR/issue-84073.rs:32:27
2+
--> $DIR/issue-84073.rs:32:22
33
|
44
LL | Race::new(|race| race.when());
5-
| ^^^^
5+
| ^^^^
66

77
error: aborting due to 1 previous error
88

tests/ui/methods/method-not-found-generic-arg-elision.stderr

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,15 @@ LL | struct Struct<T> {
8888
LL | s.method();
8989
| ^^^^^^ method cannot be called on `Struct<f64>` due to unsatisfied trait bounds
9090
|
91-
note: trait bound `f64: Eq` was not satisfied
91+
note: the following trait bounds were not satisfied:
92+
`f64: Eq`
93+
`f64: Ord`
9294
--> $DIR/method-not-found-generic-arg-elision.rs:74:36
9395
|
9496
LL | impl<T: Clone + Copy + PartialEq + Eq + PartialOrd + Ord> Struct<T> {
95-
| ^^ ---------
96-
| |
97+
| ^^ ^^^ ---------
98+
| | |
99+
| | unsatisfied trait bound introduced here
97100
| unsatisfied trait bound introduced here
98101

99102
error: aborting due to 9 previous errors

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ LL | this.is_subset(other)
66
|
77
= note: the following trait bounds were not satisfied:
88
`T: Eq`
9-
help: consider restricting the type parameter to satisfy the trait bound
9+
`T: Hash`
10+
help: consider restricting the type parameters to satisfy the trait bounds
1011
|
11-
LL | fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq {
12-
| +++++++++++
12+
LL | fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash {
13+
| ++++++++++++++++++++
1314

1415
error: aborting due to 1 previous error
1516

tests/ui/suggestions/derive-trait-for-method-call.stderr

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,31 @@ error[E0599]: the method `test` exists for struct `Foo<Enum, CloneEnum>`, but it
22
--> $DIR/derive-trait-for-method-call.rs:28:15
33
|
44
LL | enum Enum {
5-
| --------- doesn't satisfy `Enum: Clone`
5+
| --------- doesn't satisfy `Enum: Clone` or `Enum: Default`
6+
...
7+
LL | enum CloneEnum {
8+
| -------------- doesn't satisfy `CloneEnum: Default`
69
...
710
LL | struct Foo<X, Y> (X, Y);
811
| ---------------- method `test` not found for this struct
912
...
1013
LL | let y = x.test();
1114
| ^^^^ method cannot be called on `Foo<Enum, CloneEnum>` due to unsatisfied trait bounds
1215
|
13-
note: trait bound `Enum: Clone` was not satisfied
16+
note: the following trait bounds were not satisfied:
17+
`CloneEnum: Default`
18+
`Enum: Clone`
19+
`Enum: Default`
1420
--> $DIR/derive-trait-for-method-call.rs:20:9
1521
|
1622
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
17-
| ^^^^^ ---------
18-
| |
23+
| ^^^^^ ^^^^^^^ ^^^^^^^ ---------
24+
| | | |
25+
| | | unsatisfied trait bound introduced here
26+
| | unsatisfied trait bound introduced here
1927
| unsatisfied trait bound introduced here
28+
note: the trait `Default` must be implemented
29+
--> $SRC_DIR/core/src/default.rs:LL:COL
2030
help: consider annotating `Enum` with `#[derive(Clone)]`
2131
|
2232
LL + #[derive(Clone)]
@@ -27,24 +37,37 @@ error[E0599]: the method `test` exists for struct `Foo<Struct, CloneStruct>`, bu
2737
--> $DIR/derive-trait-for-method-call.rs:34:15
2838
|
2939
LL | struct Struct {
30-
| ------------- doesn't satisfy `Struct: Clone`
40+
| ------------- doesn't satisfy `Struct: Clone` or `Struct: Default`
41+
...
42+
LL | struct CloneStruct {
43+
| ------------------ doesn't satisfy `CloneStruct: Default`
3144
...
3245
LL | struct Foo<X, Y> (X, Y);
3346
| ---------------- method `test` not found for this struct
3447
...
3548
LL | let y = x.test();
3649
| ^^^^ method cannot be called on `Foo<Struct, CloneStruct>` due to unsatisfied trait bounds
3750
|
38-
note: trait bound `Struct: Clone` was not satisfied
51+
note: the following trait bounds were not satisfied:
52+
`CloneStruct: Default`
53+
`Struct: Clone`
54+
`Struct: Default`
3955
--> $DIR/derive-trait-for-method-call.rs:20:9
4056
|
4157
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
42-
| ^^^^^ ---------
43-
| |
58+
| ^^^^^ ^^^^^^^ ^^^^^^^ ---------
59+
| | | |
60+
| | | unsatisfied trait bound introduced here
61+
| | unsatisfied trait bound introduced here
4462
| unsatisfied trait bound introduced here
45-
help: consider annotating `Struct` with `#[derive(Clone)]`
63+
help: consider annotating `CloneStruct` with `#[derive(Default)]`
4664
|
47-
LL + #[derive(Clone)]
65+
LL + #[derive(Default)]
66+
LL | struct CloneStruct {
67+
|
68+
help: consider annotating `Struct` with `#[derive(Clone, Default)]`
69+
|
70+
LL + #[derive(Clone, Default)]
4871
LL | struct Struct {
4972
|
5073

@@ -57,12 +80,15 @@ LL | struct Foo<X, Y> (X, Y);
5780
LL | let y = x.test();
5881
| ^^^^ method cannot be called on `Foo<Vec<Enum>, Instant>` due to unsatisfied trait bounds
5982
|
60-
note: trait bound `Vec<Enum>: Clone` was not satisfied
83+
note: the following trait bounds were not satisfied:
84+
`Instant: Default`
85+
`Vec<Enum>: Clone`
6186
--> $DIR/derive-trait-for-method-call.rs:20:9
6287
|
6388
LL | impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
64-
| ^^^^^ ---------
65-
| |
89+
| ^^^^^ ^^^^^^^ ---------
90+
| | |
91+
| | unsatisfied trait bound introduced here
6692
| unsatisfied trait bound introduced here
6793

6894
error: aborting due to 3 previous errors

0 commit comments

Comments
 (0)