summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/solve
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2023-06-16 14:46:15 +0530
committerGitHub <noreply@github.com>2023-06-16 14:46:15 +0530
commit64f6c00772321324d77dfd8a0ee708fbb0d9a277 (patch)
treebf5761fe7042f156c7b39836c99faeee00c64907 /compiler/rustc_trait_selection/src/solve
parentb41db841e8fe01af6b1f2d17a25a2704950b937f (diff)
parent01377e8064a5b3d987b177c16e18da4bffec03a4 (diff)
downloadrust-64f6c00772321324d77dfd8a0ee708fbb0d9a277.tar.gz
rust-64f6c00772321324d77dfd8a0ee708fbb0d9a277.zip
Rollup merge of #112443 - compiler-errors:next-solver-opportunistically-resolve-regions, r=lcnr
Opportunistically resolve regions in new solver

Use `opportunistic_resolve_var` during canonicalization to collapse some regions.

We have to start using `CanonicalVarValues::is_identity_modulo_regions`. We also have to modify that function to consider responses like `['static, ^0, '^1, ^2]` to be an "identity" response, since because we opportunistically resolve regions, there's no longer a 1:1 mapping between canonical var values and bound var indices in the response...

There's one nasty side-effect -- one test (`tests/ui/dyn-star/param-env-infer.rs`) starts to ICE because the certainty goes from `Yes` to `Maybe(Overflow)`... Not exactly sure why, though? Putting this up for discussion/investigation.

r? ```@lcnr```
Diffstat (limited to 'compiler/rustc_trait_selection/src/solve')
-rw-r--r--compiler/rustc_trait_selection/src/solve/canonicalize.rs21
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs5
2 files changed, 23 insertions, 3 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
index 29bdb5ff67d..05248cb9d17 100644
--- a/compiler/rustc_trait_selection/src/solve/canonicalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
@@ -208,8 +208,25 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
         t
     }
 
-    fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        let r = self.infcx.shallow_resolve(r);
+    fn fold_region(&mut self, mut r: ty::Region<'tcx>) -> ty::Region<'tcx> {
+        match self.canonicalize_mode {
+            CanonicalizeMode::Input => {
+                // Don't resolve infer vars in input, since it affects
+                // caching and may cause trait selection bugs which rely
+                // on regions to be equal.
+            }
+            CanonicalizeMode::Response { .. } => {
+                if let ty::ReVar(vid) = *r {
+                    r = self
+                        .infcx
+                        .inner
+                        .borrow_mut()
+                        .unwrap_region_constraints()
+                        .opportunistic_resolve_var(self.infcx.tcx, vid);
+                }
+            }
+        }
+
         let kind = match *r {
             ty::ReLateBound(..) => return r,
 
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index a8a0e1ebfb4..8592fc164d0 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -263,7 +263,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             let (_orig_values, canonical_goal) = self.canonicalize_goal(goal);
             let new_canonical_response =
                 EvalCtxt::evaluate_canonical_goal(self.tcx(), self.search_graph, canonical_goal)?;
-            if !new_canonical_response.value.var_values.is_identity() {
+            // 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() {
                 bug!(
                     "unstable result: re-canonicalized goal={canonical_goal:#?} \
                     first_response={canonical_response:#?} \