diff options
| author | Michael Goulet <michael@errs.io> | 2024-04-28 15:35:35 -0400 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-04-29 10:25:51 -0400 |
| commit | 2eb7c8196bbbd0b990f053365f7c934f10963af0 (patch) | |
| tree | badb208dd914b7d58acb3c920ffd798fdc0254cf /compiler/rustc_trait_selection/src | |
| parent | 7cf1c547c2ea1eb2ceae943b505faee6aca1e4d4 (diff) | |
| download | rust-2eb7c8196bbbd0b990f053365f7c934f10963af0.tar.gz rust-2eb7c8196bbbd0b990f053365f7c934f10963af0.zip | |
Only register candidate if it is associated w a shallow certainty
Diffstat (limited to 'compiler/rustc_trait_selection/src')
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/inspect/analyse.rs | 55 |
2 files changed, 28 insertions, 38 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 225479fcff3..d8fd5c05911 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -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 } diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs index 7daf99cb7e5..2d58111e803 100644 --- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs +++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs @@ -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, - }); - } } } |
