about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-08-02 00:43:35 +0000
committerMichael Goulet <michael@errs.io>2023-08-03 20:05:40 +0000
commit5bea48ba18b71c0e4a80fd08f6ec33330c770648 (patch)
tree5bc8a64e9e9dc6ea8e754493a1177185e8a7d545 /compiler
parentdefed6257aa93dfbe798900d959f825ac5410de6 (diff)
downloadrust-5bea48ba18b71c0e4a80fd08f6ec33330c770648.tar.gz
rust-5bea48ba18b71c0e4a80fd08f6ec33330c770648.zip
separate calculation and interning of external query constraints
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs55
1 files changed, 28 insertions, 27 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 7323b98b8ce..749568cd80d 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -18,7 +18,7 @@ use rustc_infer::infer::canonical::CanonicalVarValues;
 use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{
-    ExternalConstraints, ExternalConstraintsData, MaybeCause, PredefinedOpaquesData, QueryInput,
+ ExternalConstraintsData, MaybeCause, PredefinedOpaquesData, QueryInput,
 };
 use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable};
 use rustc_span::DUMMY_SP;
@@ -69,35 +69,36 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             previous call to `try_evaluate_added_goals!`"
         );
 
-        let certainty = certainty.unify_with(goals_certainty);
+        if let Certainty::OVERFLOW = certainty {
+            // If we have overflow, it's probable that we're substituting a type
+            // into itself infinitely and any partial substitutions in the query
+            // response are probably not useful anyways, so just return an empty
+            // query response.
+            //
+            // This may prevent us from potentially useful inference, e.g.
+            // 2 candidates, one ambiguous and one overflow, which both
+            // have the same inference constraints.
+            //
+            // Changing this to retain some constraints in the future
+            // won't be a breaking change, so this is good enough for now.
+            return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow));
+        }
 
-        let response = match certainty {
-            Certainty::Yes | Certainty::Maybe(MaybeCause::Ambiguity) => {
-                let external_constraints = self.compute_external_query_constraints()?;
-                Response { var_values: self.var_values, external_constraints, certainty }
-            }
-            Certainty::Maybe(MaybeCause::Overflow) => {
-                // If we have overflow, it's probable that we're substituting a type
-                // into itself infinitely and any partial substitutions in the query
-                // response are probably not useful anyways, so just return an empty
-                // query response.
-                //
-                // This may prevent us from potentially useful inference, e.g.
-                // 2 candidates, one ambiguous and one overflow, which both
-                // have the same inference constraints.
-                //
-                // Changing this to retain some constraints in the future
-                // won't be a breaking change, so this is good enough for now.
-                return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow));
-            }
-        };
+        let certainty = certainty.unify_with(goals_certainty);
+        let var_values = self.var_values;
+        let external_constraints = self.compute_external_query_constraints()?;
 
         let canonical = Canonicalizer::canonicalize(
             self.infcx,
             CanonicalizeMode::Response { max_input_universe: self.max_input_universe },
             &mut Default::default(),
-            response,
+            Response {
+                var_values,
+                certainty,
+                external_constraints: self.tcx().mk_external_constraints(external_constraints),
+            },
         );
+
         Ok(canonical)
     }
 
@@ -143,7 +144,9 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     /// further constrained by inference, that will be passed back in the var
     /// values.
     #[instrument(level = "debug", skip(self), ret)]
-    fn compute_external_query_constraints(&self) -> Result<ExternalConstraints<'tcx>, NoSolution> {
+    fn compute_external_query_constraints(
+        &self,
+    ) -> Result<ExternalConstraintsData<'tcx>, NoSolution> {
         // We only check for leaks from universes which were entered inside
         // of the query.
         self.infcx.leak_check(self.max_input_universe, None).map_err(|e| {
@@ -173,9 +176,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a)
         });
 
-        Ok(self
-            .tcx()
-            .mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types }))
+        Ok(ExternalConstraintsData { region_constraints, opaque_types })
     }
 
     /// After calling a canonical query, we apply the constraints returned