about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-04-28 15:35:35 -0400
committerMichael Goulet <michael@errs.io>2024-04-29 10:25:51 -0400
commit2eb7c8196bbbd0b990f053365f7c934f10963af0 (patch)
treebadb208dd914b7d58acb3c920ffd798fdc0254cf /compiler/rustc_trait_selection/src
parent7cf1c547c2ea1eb2ceae943b505faee6aca1e4d4 (diff)
downloadrust-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.rs11
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs55
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,
-                });
-            }
         }
     }