Skip to content

Commit 2eb7c81

Browse files
Only register candidate if it is associated w a shallow certainty
1 parent 7cf1c54 commit 2eb7c81

File tree

4 files changed

+32
-42
lines changed

4 files changed

+32
-42
lines changed

compiler/rustc_middle/src/traits/solve/inspect.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,6 @@ pub enum ProbeKind<'tcx> {
150150
/// do a probe to find out what projection type(s) may be used to prove that
151151
/// the source type upholds all of the target type's object bounds.
152152
UpcastProjectionCompatibility,
153-
/// Try to unify an opaque type with an existing
154-
OpaqueTypeStorageLookup,
153+
/// Try to unify an opaque type with an existing key in the storage.
154+
OpaqueTypeStorageLookup { result: QueryResult<'tcx> },
155155
}

compiler/rustc_middle/src/traits/solve/inspect/format.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
112112
ProbeKind::UpcastProjectionCompatibility => {
113113
write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
114114
}
115-
ProbeKind::OpaqueTypeStorageLookup => {
116-
write!(self.f, "PROBING FOR AN EXISTING OPAQUE:")
115+
ProbeKind::OpaqueTypeStorageLookup { result } => {
116+
write!(self.f, "PROBING FOR AN EXISTING OPAQUE: {result:?}")
117117
}
118118
ProbeKind::TraitCandidate { source, result } => {
119119
write!(self.f, "CANDIDATE {source:?}: {result:?}")

compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -998,8 +998,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
998998
if candidate_key.def_id != key.def_id {
999999
continue;
10001000
}
1001-
values.extend(self.probe(|_| inspect::ProbeKind::OpaqueTypeStorageLookup).enter(
1002-
|ecx| {
1001+
values.extend(
1002+
self.probe(|result| inspect::ProbeKind::OpaqueTypeStorageLookup {
1003+
result: *result,
1004+
})
1005+
.enter(|ecx| {
10031006
for (a, b) in std::iter::zip(candidate_key.args, key.args) {
10041007
ecx.eq(param_env, a, b)?;
10051008
}
@@ -1011,8 +1014,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
10111014
candidate_ty,
10121015
);
10131016
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
1014-
},
1015-
));
1017+
}),
1018+
);
10161019
}
10171020
values
10181021
}

compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

+21-34
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub struct InspectCandidate<'a, 'tcx> {
4545
nested_goals: Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
4646
final_state: inspect::CanonicalState<'tcx, ()>,
4747
result: QueryResult<'tcx>,
48-
candidate_certainty: Option<Certainty>,
48+
shallow_certainty: Certainty,
4949
}
5050

5151
impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
@@ -59,15 +59,14 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
5959

6060
/// Certainty passed into `evaluate_added_goals_and_make_canonical_response`.
6161
///
62-
/// If this certainty is `Some(Yes)`, then we must be confident that the candidate
62+
/// If this certainty is `Yes`, then we must be confident that the candidate
6363
/// must hold iff it's nested goals hold. This is not true if the certainty is
64-
/// `Some(Maybe)`, which suggests we forced ambiguity instead, or if it is `None`,
65-
/// which suggests we may have not assembled any candidates at all.
64+
/// `Maybe(..)`, which suggests we forced ambiguity instead.
6665
///
67-
/// This is *not* the certainty of the candidate's nested evaluation, which can be
68-
/// accessed with [`Self::result`] instead.
69-
pub fn candidate_certainty(&self) -> Option<Certainty> {
70-
self.candidate_certainty
66+
/// This is *not* the certainty of the candidate's full nested evaluation, which
67+
/// can be accessed with [`Self::result`] instead.
68+
pub fn shallow_certainty(&self) -> Certainty {
69+
self.shallow_certainty
7170
}
7271

7372
/// Visit all nested goals of this candidate without rolling
@@ -174,9 +173,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
174173
nested_goals: &mut Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
175174
probe: &inspect::Probe<'tcx>,
176175
) {
177-
let mut candidate_certainty = None;
178-
let num_candidates = candidates.len();
179-
176+
let mut shallow_certainty = None;
180177
for step in &probe.steps {
181178
match step {
182179
&inspect::ProbeStep::AddGoal(_source, goal) => nested_goals.push(goal),
@@ -188,8 +185,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
188185
self.candidates_recur(candidates, nested_goals, probe);
189186
nested_goals.truncate(num_goals);
190187
}
191-
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty } => {
192-
assert_eq!(candidate_certainty.replace(*shallow_certainty), None);
188+
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
189+
assert_eq!(shallow_certainty.replace(*c), None);
193190
}
194191
inspect::ProbeStep::EvaluateGoals(_) => (),
195192
}
@@ -198,37 +195,27 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
198195
match probe.kind {
199196
inspect::ProbeKind::NormalizedSelfTyAssembly
200197
| inspect::ProbeKind::UnsizeAssembly
201-
| inspect::ProbeKind::UpcastProjectionCompatibility
202-
| inspect::ProbeKind::OpaqueTypeStorageLookup => (),
203-
// We add a candidate for the root evaluation if there
198+
| inspect::ProbeKind::UpcastProjectionCompatibility => (),
199+
200+
// We add a candidate even for the root evaluation if there
204201
// is only one way to prove a given goal, e.g. for `WellFormed`.
205-
//
206-
// FIXME: This is currently wrong if we don't even try any
207-
// candidates, e.g. for a trait goal, as in this case `candidates` is
208-
// actually supposed to be empty.
209202
inspect::ProbeKind::Root { result }
210-
| inspect::ProbeKind::TryNormalizeNonRigid { result } => {
211-
if candidates.len() == num_candidates {
203+
| inspect::ProbeKind::TryNormalizeNonRigid { result }
204+
| inspect::ProbeKind::TraitCandidate { source: _, result }
205+
| inspect::ProbeKind::OpaqueTypeStorageLookup { result } => {
206+
// We only add a candidate if `shallow_certainty` was set, which means
207+
// that we ended up calling `evaluate_added_goals_and_make_canonical_response`.
208+
if let Some(shallow_certainty) = shallow_certainty {
212209
candidates.push(InspectCandidate {
213210
goal: self,
214211
kind: probe.kind,
215212
nested_goals: nested_goals.clone(),
216213
final_state: probe.final_state,
217214
result,
218-
candidate_certainty,
219-
})
215+
shallow_certainty,
216+
});
220217
}
221218
}
222-
inspect::ProbeKind::TraitCandidate { source: _, result } => {
223-
candidates.push(InspectCandidate {
224-
goal: self,
225-
kind: probe.kind,
226-
nested_goals: nested_goals.clone(),
227-
final_state: probe.final_state,
228-
result,
229-
candidate_certainty,
230-
});
231-
}
232219
}
233220
}
234221

0 commit comments

Comments
 (0)