From e7b02046a0b34ec6d114a7ba5549db8457684ec4 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 10 May 2020 21:09:56 +0100 Subject: [PATCH] Fix hang in lexical_region_resolve --- .../infer/lexical_region_resolve/mod.rs | 20 +++++++++++++++---- .../regions/issue-72051-member-region-hang.rs | 7 +++++++ 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/regions/issue-72051-member-region-hang.rs diff --git a/src/librustc_infer/infer/lexical_region_resolve/mod.rs b/src/librustc_infer/infer/lexical_region_resolve/mod.rs index 3ff0e26a4dc38..33a80fb747101 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 0000000000000..b7340b79d682a --- /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() {}