about summary refs log tree commit diff
path: root/compiler/rustc_borrowck/src/dataflow.rs
diff options
context:
space:
mode:
authorRémy Rakic <remy.rakic+github@gmail.com>2023-10-19 21:44:03 +0000
committerRémy Rakic <remy.rakic+github@gmail.com>2023-10-20 20:59:20 +0000
commitfa45efaafbad50454f8de065be8c9fdea7d89094 (patch)
tree667cebcf3918eac9c1f0bada26c73c12890bc426 /compiler/rustc_borrowck/src/dataflow.rs
parentc69bd9480abd4d26d7e2f5c877053878eec334a4 (diff)
downloadrust-fa45efaafbad50454f8de065be8c9fdea7d89094.tar.gz
rust-fa45efaafbad50454f8de065be8c9fdea7d89094.zip
consider a loan escapes the function via applied member constraints
Diffstat (limited to 'compiler/rustc_borrowck/src/dataflow.rs')
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs21
1 files changed, 14 insertions, 7 deletions
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 6ea84620bbe..16814950b0d 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -272,21 +272,28 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
         loan_issued_at: Location,
     ) {
         let sccs = self.regioncx.constraint_sccs();
+        let universal_regions = self.regioncx.universal_regions();
         let issuing_region_scc = sccs.scc(issuing_region);
 
         // We first handle the cases where the loan doesn't go out of scope, depending on the issuing
         // region's successors.
         for scc in sccs.depth_first_search(issuing_region_scc) {
-            // 1. Via member constraints
+            // 1. Via applied member constraints
             //
             // The issuing region can flow into the choice regions, and they are either:
             // - placeholders or free regions themselves,
             // - or also transitively outlive a free region.
             //
-            // That is to say, if there are member constraints here, the loan escapes the function
-            // and cannot go out of scope. We can early return.
-            if self.regioncx.scc_has_member_constraints(scc) {
-                return;
+            // That is to say, if there are applied member constraints here, the loan escapes the
+            // function and cannot go out of scope. We could early return here.
+            //
+            // For additional insurance via fuzzing and crater, we verify that the constraint's min
+            // choice indeed escapes the function. In the future, we could e.g. turn this check into
+            // a debug assert and early return as an optimization.
+            for constraint in self.regioncx.applied_member_constraints(scc) {
+                if universal_regions.is_universal_region(constraint.min_choice) {
+                    return;
+                }
             }
 
             // 2. Via regions that are live at all points: placeholders and free regions.
@@ -413,12 +420,12 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
             let mut polonius_prec = PoloniusOutOfScopePrecomputer::new(body, regioncx);
             for (loan_idx, loan_data) in borrow_set.iter_enumerated() {
                 let issuing_region = loan_data.region;
-                let issued_location = loan_data.reserve_location;
+                let loan_issued_at = loan_data.reserve_location;
 
                 polonius_prec.precompute_loans_out_of_scope(
                     loan_idx,
                     issuing_region,
-                    issued_location,
+                    loan_issued_at,
                 );
             }