Only register candidate if it is associated w a shallow certainty
This commit is contained in:
parent
7cf1c547c2
commit
2eb7c8196b
@ -150,6 +150,6 @@ pub enum ProbeKind<'tcx> {
|
||||
/// do a probe to find out what projection type(s) may be used to prove that
|
||||
/// the source type upholds all of the target type's object bounds.
|
||||
UpcastProjectionCompatibility,
|
||||
/// Try to unify an opaque type with an existing
|
||||
OpaqueTypeStorageLookup,
|
||||
/// Try to unify an opaque type with an existing key in the storage.
|
||||
OpaqueTypeStorageLookup { result: QueryResult<'tcx> },
|
||||
}
|
||||
|
@ -112,8 +112,8 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
|
||||
ProbeKind::UpcastProjectionCompatibility => {
|
||||
write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
|
||||
}
|
||||
ProbeKind::OpaqueTypeStorageLookup => {
|
||||
write!(self.f, "PROBING FOR AN EXISTING OPAQUE:")
|
||||
ProbeKind::OpaqueTypeStorageLookup { result } => {
|
||||
write!(self.f, "PROBING FOR AN EXISTING OPAQUE: {result:?}")
|
||||
}
|
||||
ProbeKind::TraitCandidate { source, result } => {
|
||||
write!(self.f, "CANDIDATE {source:?}: {result:?}")
|
||||
|
@ -998,8 +998,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
if candidate_key.def_id != key.def_id {
|
||||
continue;
|
||||
}
|
||||
values.extend(self.probe(|_| inspect::ProbeKind::OpaqueTypeStorageLookup).enter(
|
||||
|ecx| {
|
||||
values.extend(
|
||||
self.probe(|result| inspect::ProbeKind::OpaqueTypeStorageLookup {
|
||||
result: *result,
|
||||
})
|
||||
.enter(|ecx| {
|
||||
for (a, b) in std::iter::zip(candidate_key.args, key.args) {
|
||||
ecx.eq(param_env, a, b)?;
|
||||
}
|
||||
@ -1011,8 +1014,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
candidate_ty,
|
||||
);
|
||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
},
|
||||
));
|
||||
}),
|
||||
);
|
||||
}
|
||||
values
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ pub struct InspectCandidate<'a, 'tcx> {
|
||||
nested_goals: Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
|
||||
final_state: inspect::CanonicalState<'tcx, ()>,
|
||||
result: QueryResult<'tcx>,
|
||||
candidate_certainty: Option<Certainty>,
|
||||
shallow_certainty: Certainty,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
|
||||
@ -59,15 +59,14 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
|
||||
|
||||
/// Certainty passed into `evaluate_added_goals_and_make_canonical_response`.
|
||||
///
|
||||
/// If this certainty is `Some(Yes)`, then we must be confident that the candidate
|
||||
/// If this certainty is `Yes`, then we must be confident that the candidate
|
||||
/// must hold iff it's nested goals hold. This is not true if the certainty is
|
||||
/// `Some(Maybe)`, which suggests we forced ambiguity instead, or if it is `None`,
|
||||
/// which suggests we may have not assembled any candidates at all.
|
||||
/// `Maybe(..)`, which suggests we forced ambiguity instead.
|
||||
///
|
||||
/// This is *not* the certainty of the candidate's nested evaluation, which can be
|
||||
/// accessed with [`Self::result`] instead.
|
||||
pub fn candidate_certainty(&self) -> Option<Certainty> {
|
||||
self.candidate_certainty
|
||||
/// This is *not* the certainty of the candidate's full nested evaluation, which
|
||||
/// can be accessed with [`Self::result`] instead.
|
||||
pub fn shallow_certainty(&self) -> Certainty {
|
||||
self.shallow_certainty
|
||||
}
|
||||
|
||||
/// Visit all nested goals of this candidate without rolling
|
||||
@ -174,9 +173,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
||||
nested_goals: &mut Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
|
||||
probe: &inspect::Probe<'tcx>,
|
||||
) {
|
||||
let mut candidate_certainty = None;
|
||||
let num_candidates = candidates.len();
|
||||
|
||||
let mut shallow_certainty = None;
|
||||
for step in &probe.steps {
|
||||
match step {
|
||||
&inspect::ProbeStep::AddGoal(_source, goal) => nested_goals.push(goal),
|
||||
@ -188,8 +185,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
||||
self.candidates_recur(candidates, nested_goals, probe);
|
||||
nested_goals.truncate(num_goals);
|
||||
}
|
||||
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty } => {
|
||||
assert_eq!(candidate_certainty.replace(*shallow_certainty), None);
|
||||
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
|
||||
assert_eq!(shallow_certainty.replace(*c), None);
|
||||
}
|
||||
inspect::ProbeStep::EvaluateGoals(_) => (),
|
||||
}
|
||||
@ -198,37 +195,27 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
||||
match probe.kind {
|
||||
inspect::ProbeKind::NormalizedSelfTyAssembly
|
||||
| inspect::ProbeKind::UnsizeAssembly
|
||||
| inspect::ProbeKind::UpcastProjectionCompatibility
|
||||
| inspect::ProbeKind::OpaqueTypeStorageLookup => (),
|
||||
// We add a candidate for the root evaluation if there
|
||||
| inspect::ProbeKind::UpcastProjectionCompatibility => (),
|
||||
|
||||
// We add a candidate even for the root evaluation if there
|
||||
// is only one way to prove a given goal, e.g. for `WellFormed`.
|
||||
//
|
||||
// FIXME: This is currently wrong if we don't even try any
|
||||
// candidates, e.g. for a trait goal, as in this case `candidates` is
|
||||
// actually supposed to be empty.
|
||||
inspect::ProbeKind::Root { result }
|
||||
| inspect::ProbeKind::TryNormalizeNonRigid { result } => {
|
||||
if candidates.len() == num_candidates {
|
||||
| inspect::ProbeKind::TryNormalizeNonRigid { result }
|
||||
| inspect::ProbeKind::TraitCandidate { source: _, result }
|
||||
| inspect::ProbeKind::OpaqueTypeStorageLookup { result } => {
|
||||
// We only add a candidate if `shallow_certainty` was set, which means
|
||||
// that we ended up calling `evaluate_added_goals_and_make_canonical_response`.
|
||||
if let Some(shallow_certainty) = shallow_certainty {
|
||||
candidates.push(InspectCandidate {
|
||||
goal: self,
|
||||
kind: probe.kind,
|
||||
nested_goals: nested_goals.clone(),
|
||||
final_state: probe.final_state,
|
||||
result,
|
||||
candidate_certainty,
|
||||
})
|
||||
shallow_certainty,
|
||||
});
|
||||
}
|
||||
}
|
||||
inspect::ProbeKind::TraitCandidate { source: _, result } => {
|
||||
candidates.push(InspectCandidate {
|
||||
goal: self,
|
||||
kind: probe.kind,
|
||||
nested_goals: nested_goals.clone(),
|
||||
final_state: probe.final_state,
|
||||
result,
|
||||
candidate_certainty,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user