about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2022-11-23 14:34:11 +0800
committeryukang <moorekang@gmail.com>2022-11-23 15:17:00 +0800
commitb0d39c6ed039afde82abc40cd830d546a3434d37 (patch)
tree14f018f70f0a7dc618a2bfaa4156c4402955406c
parent11432fe952cdc531785bd1bf7dc4e8a15da6daab (diff)
downloadrust-b0d39c6ed039afde82abc40cd830d546a3434d37.tar.gz
rust-b0d39c6ed039afde82abc40cd830d546a3434d37.zip
Fix #104639, find the right lower bound region in the scenario of partial order relations
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs27
-rw-r--r--src/test/ui/borrowck/issue-104639-lifetime-order.rs10
2 files changed, 17 insertions, 20 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 8b63294fbab..dde8efc9edb 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -758,27 +758,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // Otherwise, we need to find the minimum remaining choice, if
         // any, and take that.
         debug!("choice_regions remaining are {:#?}", choice_regions);
-        let min = |r1: ty::RegionVid, r2: ty::RegionVid| -> Option<ty::RegionVid> {
-            let r1_outlives_r2 = self.universal_region_relations.outlives(r1, r2);
-            let r2_outlives_r1 = self.universal_region_relations.outlives(r2, r1);
-            match (r1_outlives_r2, r2_outlives_r1) {
-                (true, true) => Some(r1.min(r2)),
-                (true, false) => Some(r2),
-                (false, true) => Some(r1),
-                (false, false) => None,
-            }
+        let Some(&min_choice) = choice_regions.iter().find(|&r1| {
+            choice_regions.iter().all(|&r2| {
+                self.universal_region_relations.outlives(r2, *r1)
+            })
+        }) else {
+            debug!("no choice region outlived by all others");
+            return false;
         };
-        let mut min_choice = choice_regions[0];
-        for &other_option in &choice_regions[1..] {
-            debug!(?min_choice, ?other_option,);
-            match min(min_choice, other_option) {
-                Some(m) => min_choice = m,
-                None => {
-                    debug!(?min_choice, ?other_option, "incomparable; no min choice",);
-                    return false;
-                }
-            }
-        }
 
         let min_choice_scc = self.constraint_sccs.scc(min_choice);
         debug!(?min_choice, ?min_choice_scc);
diff --git a/src/test/ui/borrowck/issue-104639-lifetime-order.rs b/src/test/ui/borrowck/issue-104639-lifetime-order.rs
new file mode 100644
index 00000000000..db1f8f8d588
--- /dev/null
+++ b/src/test/ui/borrowck/issue-104639-lifetime-order.rs
@@ -0,0 +1,10 @@
+// edition:2018
+// check-pass
+
+#![allow(dead_code)]
+async fn fail<'a, 'b, 'c>(_: &'static str) where 'a: 'c, 'b: 'c, {}
+async fn pass<'a, 'c, 'b>(_: &'static str) where 'a: 'c, 'b: 'c, {}
+async fn pass2<'a, 'b, 'c>(_: &'static str) where 'a: 'c, 'b: 'c, 'c: 'a, {}
+async fn pass3<'a, 'b, 'c>(_: &'static str) where 'a: 'b, 'b: 'c, 'c: 'a, {}
+
+fn main() { }