Only register candidate if it is associated w a shallow certainty
This commit is contained in:
parent
7cf1c547c2
commit
2eb7c8196b
4 changed files with 32 additions and 42 deletions
|
@ -150,6 +150,6 @@ pub enum ProbeKind<'tcx> {
|
||||||
/// do a probe to find out what projection type(s) may be used to prove that
|
/// 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.
|
/// the source type upholds all of the target type's object bounds.
|
||||||
UpcastProjectionCompatibility,
|
UpcastProjectionCompatibility,
|
||||||
/// Try to unify an opaque type with an existing
|
/// Try to unify an opaque type with an existing key in the storage.
|
||||||
OpaqueTypeStorageLookup,
|
OpaqueTypeStorageLookup { result: QueryResult<'tcx> },
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,8 +112,8 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
|
||||||
ProbeKind::UpcastProjectionCompatibility => {
|
ProbeKind::UpcastProjectionCompatibility => {
|
||||||
write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
|
write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
|
||||||
}
|
}
|
||||||
ProbeKind::OpaqueTypeStorageLookup => {
|
ProbeKind::OpaqueTypeStorageLookup { result } => {
|
||||||
write!(self.f, "PROBING FOR AN EXISTING OPAQUE:")
|
write!(self.f, "PROBING FOR AN EXISTING OPAQUE: {result:?}")
|
||||||
}
|
}
|
||||||
ProbeKind::TraitCandidate { source, result } => {
|
ProbeKind::TraitCandidate { source, result } => {
|
||||||
write!(self.f, "CANDIDATE {source:?}: {result:?}")
|
write!(self.f, "CANDIDATE {source:?}: {result:?}")
|
||||||
|
|
|
@ -998,8 +998,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
if candidate_key.def_id != key.def_id {
|
if candidate_key.def_id != key.def_id {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
values.extend(self.probe(|_| inspect::ProbeKind::OpaqueTypeStorageLookup).enter(
|
values.extend(
|
||||||
|ecx| {
|
self.probe(|result| inspect::ProbeKind::OpaqueTypeStorageLookup {
|
||||||
|
result: *result,
|
||||||
|
})
|
||||||
|
.enter(|ecx| {
|
||||||
for (a, b) in std::iter::zip(candidate_key.args, key.args) {
|
for (a, b) in std::iter::zip(candidate_key.args, key.args) {
|
||||||
ecx.eq(param_env, a, b)?;
|
ecx.eq(param_env, a, b)?;
|
||||||
}
|
}
|
||||||
|
@ -1011,8 +1014,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
candidate_ty,
|
candidate_ty,
|
||||||
);
|
);
|
||||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
},
|
}),
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
values
|
values
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ pub struct InspectCandidate<'a, 'tcx> {
|
||||||
nested_goals: Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
|
nested_goals: Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
|
||||||
final_state: inspect::CanonicalState<'tcx, ()>,
|
final_state: inspect::CanonicalState<'tcx, ()>,
|
||||||
result: QueryResult<'tcx>,
|
result: QueryResult<'tcx>,
|
||||||
candidate_certainty: Option<Certainty>,
|
shallow_certainty: Certainty,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
|
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`.
|
/// 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
|
/// 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`,
|
/// `Maybe(..)`, which suggests we forced ambiguity instead.
|
||||||
/// which suggests we may have not assembled any candidates at all.
|
|
||||||
///
|
///
|
||||||
/// This is *not* the certainty of the candidate's nested evaluation, which can be
|
/// This is *not* the certainty of the candidate's full nested evaluation, which
|
||||||
/// accessed with [`Self::result`] instead.
|
/// can be accessed with [`Self::result`] instead.
|
||||||
pub fn candidate_certainty(&self) -> Option<Certainty> {
|
pub fn shallow_certainty(&self) -> Certainty {
|
||||||
self.candidate_certainty
|
self.shallow_certainty
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Visit all nested goals of this candidate without rolling
|
/// 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>>>>,
|
nested_goals: &mut Vec<inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>>,
|
||||||
probe: &inspect::Probe<'tcx>,
|
probe: &inspect::Probe<'tcx>,
|
||||||
) {
|
) {
|
||||||
let mut candidate_certainty = None;
|
let mut shallow_certainty = None;
|
||||||
let num_candidates = candidates.len();
|
|
||||||
|
|
||||||
for step in &probe.steps {
|
for step in &probe.steps {
|
||||||
match step {
|
match step {
|
||||||
&inspect::ProbeStep::AddGoal(_source, goal) => nested_goals.push(goal),
|
&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);
|
self.candidates_recur(candidates, nested_goals, probe);
|
||||||
nested_goals.truncate(num_goals);
|
nested_goals.truncate(num_goals);
|
||||||
}
|
}
|
||||||
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty } => {
|
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
|
||||||
assert_eq!(candidate_certainty.replace(*shallow_certainty), None);
|
assert_eq!(shallow_certainty.replace(*c), None);
|
||||||
}
|
}
|
||||||
inspect::ProbeStep::EvaluateGoals(_) => (),
|
inspect::ProbeStep::EvaluateGoals(_) => (),
|
||||||
}
|
}
|
||||||
|
@ -198,37 +195,27 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
||||||
match probe.kind {
|
match probe.kind {
|
||||||
inspect::ProbeKind::NormalizedSelfTyAssembly
|
inspect::ProbeKind::NormalizedSelfTyAssembly
|
||||||
| inspect::ProbeKind::UnsizeAssembly
|
| inspect::ProbeKind::UnsizeAssembly
|
||||||
| inspect::ProbeKind::UpcastProjectionCompatibility
|
| inspect::ProbeKind::UpcastProjectionCompatibility => (),
|
||||||
| inspect::ProbeKind::OpaqueTypeStorageLookup => (),
|
|
||||||
// We add a candidate for the root evaluation if there
|
// We add a candidate even for the root evaluation if there
|
||||||
// is only one way to prove a given goal, e.g. for `WellFormed`.
|
// 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::Root { result }
|
||||||
| inspect::ProbeKind::TryNormalizeNonRigid { result } => {
|
| inspect::ProbeKind::TryNormalizeNonRigid { result }
|
||||||
if candidates.len() == num_candidates {
|
| 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 {
|
candidates.push(InspectCandidate {
|
||||||
goal: self,
|
goal: self,
|
||||||
kind: probe.kind,
|
kind: probe.kind,
|
||||||
nested_goals: nested_goals.clone(),
|
nested_goals: nested_goals.clone(),
|
||||||
final_state: probe.final_state,
|
final_state: probe.final_state,
|
||||||
result,
|
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…
Add table
Add a link
Reference in a new issue