about summary refs log tree commit diff
path: root/compiler/rustc_next_trait_solver/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-10-10 11:00:28 +0000
committerbors <bors@rust-lang.org>2024-10-10 11:00:28 +0000
commit4cc494bbfe9911d24f3ee521f98d5c6bb7e3ffe8 (patch)
treee19d6f2a7cab3a46426146fa6e8edf8c43730f9b /compiler/rustc_next_trait_solver/src
parentde19f2b73d4fd456be06f299a5d9d8fd622ca298 (diff)
parent1c62cff89775b6ab0feb0ed6c888114a64a1798f (diff)
downloadrust-4cc494bbfe9911d24f3ee521f98d5c6bb7e3ffe8.tar.gz
rust-4cc494bbfe9911d24f3ee521f98d5c6bb7e3ffe8.zip
Auto merge of #131495 - matthiaskrgr:rollup-lwf2u4i, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #130625 (Fix a few relative paths in rustc doc)
 - #131397 (fix/update teach_note from 'escaping mutable ref/ptr' const-check)
 - #131479 (Apple: Avoid redundant `-Wl,-dylib` flag when linking)
 - #131480 (Fix hardcoded strip path when cross-compiling from Linux to Darwin)
 - #131482 (structurally resolve adts and tuples expectations too)
 - #131484 (Add myself back to review rotation)
 - #131491 (impossible obligations fast path)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_next_trait_solver/src')
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs72
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs8
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/search_graph.rs3
3 files changed, 62 insertions, 21 deletions
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index ffa800348f2..bc324dcbf51 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -18,8 +18,8 @@ use crate::solve::inspect::{self, ProofTreeBuilder};
 use crate::solve::search_graph::SearchGraph;
 use crate::solve::{
     CanonicalInput, CanonicalResponse, Certainty, FIXPOINT_STEP_LIMIT, Goal, GoalEvaluationKind,
-    GoalSource, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData, QueryResult,
-    SolverMode,
+    GoalSource, HasChanged, NestedNormalizationGoals, NoSolution, PredefinedOpaquesData,
+    QueryResult, SolverMode,
 };
 
 pub(super) mod canonical;
@@ -126,11 +126,31 @@ pub enum GenerateProofTree {
 }
 
 pub trait SolverDelegateEvalExt: SolverDelegate {
+    /// Evaluates a goal from **outside** of the trait solver.
+    ///
+    /// Using this while inside of the solver is wrong as it uses a new
+    /// search graph which would break cycle detection.
     fn evaluate_root_goal(
         &self,
         goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
         generate_proof_tree: GenerateProofTree,
-    ) -> (Result<(bool, Certainty), NoSolution>, Option<inspect::GoalEvaluation<Self::Interner>>);
+    ) -> (
+        Result<(HasChanged, Certainty), NoSolution>,
+        Option<inspect::GoalEvaluation<Self::Interner>>,
+    );
+
+    /// Check whether evaluating `goal` with a depth of `root_depth` may
+    /// succeed. This only returns `false` if the goal is guaranteed to
+    /// not hold. In case evaluation overflows and fails with ambiguity this
+    /// returns `true`.
+    ///
+    /// This is only intended to be used as a performance optimization
+    /// in coherence checking.
+    fn root_goal_may_hold_with_depth(
+        &self,
+        root_depth: usize,
+        goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
+    ) -> bool;
 
     // FIXME: This is only exposed because we need to use it in `analyse.rs`
     // which is not yet uplifted. Once that's done, we should remove this.
@@ -139,7 +159,7 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
         goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
         generate_proof_tree: GenerateProofTree,
     ) -> (
-        Result<(NestedNormalizationGoals<Self::Interner>, bool, Certainty), NoSolution>,
+        Result<(NestedNormalizationGoals<Self::Interner>, HasChanged, Certainty), NoSolution>,
         Option<inspect::GoalEvaluation<Self::Interner>>,
     );
 }
@@ -149,31 +169,41 @@ where
     D: SolverDelegate<Interner = I>,
     I: Interner,
 {
-    /// Evaluates a goal from **outside** of the trait solver.
-    ///
-    /// Using this while inside of the solver is wrong as it uses a new
-    /// search graph which would break cycle detection.
     #[instrument(level = "debug", skip(self))]
     fn evaluate_root_goal(
         &self,
         goal: Goal<I, I::Predicate>,
         generate_proof_tree: GenerateProofTree,
-    ) -> (Result<(bool, Certainty), NoSolution>, Option<inspect::GoalEvaluation<I>>) {
-        EvalCtxt::enter_root(self, generate_proof_tree, |ecx| {
+    ) -> (Result<(HasChanged, Certainty), NoSolution>, Option<inspect::GoalEvaluation<I>>) {
+        EvalCtxt::enter_root(self, self.cx().recursion_limit(), generate_proof_tree, |ecx| {
             ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal)
         })
     }
 
+    fn root_goal_may_hold_with_depth(
+        &self,
+        root_depth: usize,
+        goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
+    ) -> bool {
+        self.probe(|| {
+            EvalCtxt::enter_root(self, root_depth, GenerateProofTree::No, |ecx| {
+                ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal)
+            })
+            .0
+        })
+        .is_ok()
+    }
+
     #[instrument(level = "debug", skip(self))]
     fn evaluate_root_goal_raw(
         &self,
         goal: Goal<I, I::Predicate>,
         generate_proof_tree: GenerateProofTree,
     ) -> (
-        Result<(NestedNormalizationGoals<I>, bool, Certainty), NoSolution>,
+        Result<(NestedNormalizationGoals<I>, HasChanged, Certainty), NoSolution>,
         Option<inspect::GoalEvaluation<I>>,
     ) {
-        EvalCtxt::enter_root(self, generate_proof_tree, |ecx| {
+        EvalCtxt::enter_root(self, self.cx().recursion_limit(), generate_proof_tree, |ecx| {
             ecx.evaluate_goal_raw(GoalEvaluationKind::Root, GoalSource::Misc, goal)
         })
     }
@@ -197,10 +227,11 @@ where
     /// over using this manually (such as [`SolverDelegateEvalExt::evaluate_root_goal`]).
     pub(super) fn enter_root<R>(
         delegate: &D,
+        root_depth: usize,
         generate_proof_tree: GenerateProofTree,
         f: impl FnOnce(&mut EvalCtxt<'_, D>) -> R,
     ) -> (R, Option<inspect::GoalEvaluation<I>>) {
-        let mut search_graph = SearchGraph::new(delegate.solver_mode());
+        let mut search_graph = SearchGraph::new(delegate.solver_mode(), root_depth);
 
         let mut ecx = EvalCtxt {
             delegate,
@@ -339,7 +370,7 @@ where
         goal_evaluation_kind: GoalEvaluationKind,
         source: GoalSource,
         goal: Goal<I, I::Predicate>,
-    ) -> Result<(bool, Certainty), NoSolution> {
+    ) -> Result<(HasChanged, Certainty), NoSolution> {
         let (normalization_nested_goals, has_changed, certainty) =
             self.evaluate_goal_raw(goal_evaluation_kind, source, goal)?;
         assert!(normalization_nested_goals.is_empty());
@@ -360,7 +391,7 @@ where
         goal_evaluation_kind: GoalEvaluationKind,
         _source: GoalSource,
         goal: Goal<I, I::Predicate>,
-    ) -> Result<(NestedNormalizationGoals<I>, bool, Certainty), NoSolution> {
+    ) -> Result<(NestedNormalizationGoals<I>, HasChanged, Certainty), NoSolution> {
         let (orig_values, canonical_goal) = self.canonicalize_goal(goal);
         let mut goal_evaluation =
             self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind);
@@ -378,8 +409,13 @@ where
             Ok(response) => response,
         };
 
-        let has_changed = !response.value.var_values.is_identity_modulo_regions()
-            || !response.value.external_constraints.opaque_types.is_empty();
+        let has_changed = if !response.value.var_values.is_identity_modulo_regions()
+            || !response.value.external_constraints.opaque_types.is_empty()
+        {
+            HasChanged::Yes
+        } else {
+            HasChanged::No
+        };
 
         let (normalization_nested_goals, certainty) =
             self.instantiate_and_apply_query_response(goal.param_env, orig_values, response);
@@ -552,7 +588,7 @@ where
         for (source, goal) in goals.goals {
             let (has_changed, certainty) =
                 self.evaluate_goal(GoalEvaluationKind::Nested, source, goal)?;
-            if has_changed {
+            if has_changed == HasChanged::Yes {
                 unchanged_certainty = None;
             }
 
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index 309ab7f28d1..97f7c71f3fc 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -48,6 +48,14 @@ enum GoalEvaluationKind {
     Nested,
 }
 
+/// Whether evaluating this goal ended up changing the
+/// inference state.
+#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)]
+pub enum HasChanged {
+    Yes,
+    No,
+}
+
 // FIXME(trait-system-refactor-initiative#117): we don't detect whether a response
 // ended up pulling down any universes.
 fn has_no_inference_or_external_constraints<I: Interner>(
diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs
index e47cc03f5ad..0e3f179b0c8 100644
--- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs
@@ -40,9 +40,6 @@ where
     }
 
     const DIVIDE_AVAILABLE_DEPTH_ON_OVERFLOW: usize = 4;
-    fn recursion_limit(cx: I) -> usize {
-        cx.recursion_limit()
-    }
 
     fn initial_provisional_result(
         cx: I,