about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2023-11-09 11:00:26 +0100
committerlcnr <rust@lcnr.de>2023-11-09 11:32:51 +0100
commitfce71adf31cde954f16795269c00a82b24df9238 (patch)
tree551c4380d07185529ddc672ac688b3c7b1d21120
parent442e112d173b155e53dd0403b8202bbac05c4227 (diff)
downloadrust-fce71adf31cde954f16795269c00a82b24df9238.tar.gz
rust-fce71adf31cde954f16795269c00a82b24df9238.zip
remove stability assert in `evaluate_goal`
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs73
-rw-r--r--compiler/rustc_trait_selection/src/solve/search_graph.rs33
2 files changed, 8 insertions, 98 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 a14b54ed357..c448b57158b 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -333,7 +333,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         let (orig_values, canonical_goal) = self.canonicalize_goal(goal);
         let mut goal_evaluation =
             self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind);
-        let encountered_overflow = self.search_graph.encountered_overflow();
         let canonical_response = EvalCtxt::evaluate_canonical_goal(
             self.tcx(),
             self.search_graph,
@@ -368,75 +367,19 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             bug!("an unchanged goal shouldn't have any side-effects on instantiation");
         }
 
-        // Check that rerunning this query with its inference constraints applied
-        // doesn't result in new inference constraints and has the same result.
+        // FIXME: We previously had an assert here that checked that recomputing
+        // a goal after applying its constraints did not change its response.
         //
-        // If we have projection goals like `<T as Trait>::Assoc == u32` we recursively
-        // call `exists<U> <T as Trait>::Assoc == U` to enable better caching. This goal
-        // could constrain `U` to `u32` which would cause this check to result in a
-        // solver cycle.
-        if cfg!(debug_assertions)
-            && has_changed
-            && !matches!(
-                goal_evaluation_kind,
-                GoalEvaluationKind::Nested { is_normalizes_to_hack: IsNormalizesToHack::Yes }
-            )
-            && !self.search_graph.in_cycle()
-        {
-            // The nested evaluation has to happen with the original state
-            // of `encountered_overflow`.
-            let from_original_evaluation =
-                self.search_graph.reset_encountered_overflow(encountered_overflow);
-            self.check_evaluate_goal_stable_result(goal, canonical_goal, canonical_response);
-            // In case the evaluation was unstable, we manually make sure that this
-            // debug check does not influence the result of the parent goal.
-            self.search_graph.reset_encountered_overflow(from_original_evaluation);
-        }
+        // This assert was removed as it did not hold for goals constraining
+        // an inference variable to a recursive alias, e.g. in
+        // tests/ui/traits/new-solver/overflow/recursive-self-normalization.rs.
+        //
+        // Once we have decided on how to handle trait-system-refactor-initiative#75,
+        // we should re-add an assert here.
 
         Ok((has_changed, certainty, nested_goals))
     }
 
-    fn check_evaluate_goal_stable_result(
-        &mut self,
-        goal: Goal<'tcx, ty::Predicate<'tcx>>,
-        original_input: CanonicalInput<'tcx>,
-        original_result: CanonicalResponse<'tcx>,
-    ) {
-        let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
-        let result = EvalCtxt::evaluate_canonical_goal(
-            self.tcx(),
-            self.search_graph,
-            canonical_goal,
-            // FIXME(-Ztrait-solver=next): we do not track what happens in `evaluate_canonical_goal`
-            &mut ProofTreeBuilder::new_noop(),
-        );
-
-        macro_rules! fail {
-            ($msg:expr) => {{
-                let msg = $msg;
-                warn!(
-                    "unstable result: {msg}\n\
-                    original goal: {original_input:?},\n\
-                    original result: {original_result:?}\n\
-                    re-canonicalized goal: {canonical_goal:?}\n\
-                    second response: {result:?}"
-                );
-                return;
-            }};
-        }
-
-        let Ok(new_canonical_response) = result else { fail!("second response was error") };
-        // We only check for modulo regions as we convert all regions in
-        // the input to new existentials, even if they're expected to be
-        // `'static` or a placeholder region.
-        if !new_canonical_response.value.var_values.is_identity_modulo_regions() {
-            fail!("additional constraints from second response")
-        }
-        if original_result.value.certainty != new_canonical_response.value.certainty {
-            fail!("unstable certainty")
-        }
-    }
-
     fn compute_goal(&mut self, goal: Goal<'tcx, ty::Predicate<'tcx>>) -> QueryResult<'tcx> {
         let Goal { param_env, predicate } = goal;
         let kind = predicate.kind();
diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs
index 7ffa1d7d319..68f81a05536 100644
--- a/compiler/rustc_trait_selection/src/solve/search_graph.rs
+++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs
@@ -110,39 +110,6 @@ impl<'tcx> SearchGraph<'tcx> {
         self.stack.is_empty()
     }
 
-    /// Whether we're currently in a cycle. This should only be used
-    /// for debug assertions.
-    pub(super) fn in_cycle(&self) -> bool {
-        if let Some(stack_depth) = self.stack.last_index() {
-            // Either the current goal on the stack is the root of a cycle
-            // or it depends on a goal with a lower depth.
-            self.stack[stack_depth].has_been_used
-                || self.stack[stack_depth].cycle_root_depth != stack_depth
-        } else {
-            false
-        }
-    }
-
-    /// Fetches whether the current goal encountered overflow.
-    ///
-    /// This should only be used for the check in `evaluate_goal`.
-    pub(super) fn encountered_overflow(&self) -> bool {
-        if let Some(last) = self.stack.raw.last() { last.encountered_overflow } else { false }
-    }
-
-    /// Resets `encountered_overflow` of the current goal.
-    ///
-    /// This should only be used for the check in `evaluate_goal`.
-    pub(super) fn reset_encountered_overflow(&mut self, encountered_overflow: bool) -> bool {
-        if let Some(last) = self.stack.raw.last_mut() {
-            let prev = last.encountered_overflow;
-            last.encountered_overflow = encountered_overflow;
-            prev
-        } else {
-            false
-        }
-    }
-
     /// Returns the remaining depth allowed for nested goals.
     ///
     /// This is generally simply one less than the current depth.