about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-05-14 18:21:48 +0200
committerGitHub <noreply@github.com>2020-05-14 18:21:48 +0200
commit2e65f7bc1f9e0cfab801672874655224ead8deed (patch)
tree4990c5e8c97c65feb77b77d29514b23e347b4bfc
parentb20b200d2edc22a97d8bf6a1621f37eacd9bc008 (diff)
parente7b02046a0b34ec6d114a7ba5549db8457684ec4 (diff)
downloadrust-2e65f7bc1f9e0cfab801672874655224ead8deed.tar.gz
rust-2e65f7bc1f9e0cfab801672874655224ead8deed.zip
Rollup merge of #72087 - matthewjasper:regionck-hang, r=nikomatsakis
Fix hang in lexical_region_resolve

Regionck was stuck in a loop where a region value was changing between two equal regions.

Closes #72051
-rw-r--r--src/librustc_infer/infer/lexical_region_resolve/mod.rs20
-rw-r--r--src/test/ui/regions/issue-72051-member-region-hang.rs7
2 files changed, 23 insertions, 4 deletions
diff --git a/src/librustc_infer/infer/lexical_region_resolve/mod.rs b/src/librustc_infer/infer/lexical_region_resolve/mod.rs
index 3ff0e26a4dc..33a80fb7471 100644
--- a/src/librustc_infer/infer/lexical_region_resolve/mod.rs
+++ b/src/librustc_infer/infer/lexical_region_resolve/mod.rs
@@ -325,8 +325,21 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
             }
         }
 
-        debug!("enforce_member_constraint: final least choice = {:?}", least_choice);
-        if least_choice != member_lower_bound {
+        // (#72087) Different `ty::Regions` can be known to be equal, for
+        // example, we know that `'a` and `'static` are equal in a function
+        // with a parameter of type `&'static &'a ()`.
+        //
+        // When we have two equal regions like this `expansion` will use
+        // `lub_concrete_regions` to pick a canonical representative. The same
+        // choice is needed here so that we don't end up in a cycle of
+        // `expansion` changing the region one way and the code here changing
+        // it back.
+        let lub = self.lub_concrete_regions(least_choice, member_lower_bound);
+        debug!(
+            "enforce_member_constraint: final least choice = {:?}\nlub = {:?}",
+            least_choice, lub
+        );
+        if lub != member_lower_bound {
             *var_values.value_mut(member_vid) = VarValue::Value(least_choice);
             true
         } else {
@@ -578,8 +591,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
                 self.tcx().mk_region(ReScope(lub))
             }
 
-            (&ReEarlyBound(_), &ReEarlyBound(_) | &ReFree(_))
-            | (&ReFree(_), &ReEarlyBound(_) | &ReFree(_)) => {
+            (&ReEarlyBound(_) | &ReFree(_), &ReEarlyBound(_) | &ReFree(_)) => {
                 self.region_rels.lub_free_regions(a, b)
             }
 
diff --git a/src/test/ui/regions/issue-72051-member-region-hang.rs b/src/test/ui/regions/issue-72051-member-region-hang.rs
new file mode 100644
index 00000000000..b7340b79d68
--- /dev/null
+++ b/src/test/ui/regions/issue-72051-member-region-hang.rs
@@ -0,0 +1,7 @@
+// Regression test for #72051, hang when resolving regions.
+
+// check-pass
+// edition:2018
+
+pub async fn query<'a>(_: &(), _: &(), _: (&(dyn std::any::Any + 'a),) ) {}
+fn main() {}