about summary refs log tree commit diff
path: root/compiler/rustc_mir_build/src/builder/scope.rs
diff options
context:
space:
mode:
authordianne <diannes.gm@gmail.com>2025-07-03 06:10:37 -0700
committerdianne <diannes.gm@gmail.com>2025-08-07 16:43:20 -0700
commitb2241c78c86a15b8e7e842f036135df4478de0fe (patch)
tree68f79ca2b81adced88e3498f28433539e612bca5 /compiler/rustc_mir_build/src/builder/scope.rs
parent4ec688110f21b04ab243c5a3e56997ea6c33dbcc (diff)
downloadrust-b2241c78c86a15b8e7e842f036135df4478de0fe.tar.gz
rust-b2241c78c86a15b8e7e842f036135df4478de0fe.zip
add a scope for `if let` guard temporaries and bindings
This ensures `if let` guard temporaries and bindings are dropped before
the match arm's pattern's bindings.
Diffstat (limited to 'compiler/rustc_mir_build/src/builder/scope.rs')
-rw-r--r--compiler/rustc_mir_build/src/builder/scope.rs23
1 files changed, 15 insertions, 8 deletions
diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs
index 1240b34cf9d..403e7167a69 100644
--- a/compiler/rustc_mir_build/src/builder/scope.rs
+++ b/compiler/rustc_mir_build/src/builder/scope.rs
@@ -1750,17 +1750,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         success_block
     }
 
-    /// Unschedules any drops in the top scope.
+    /// Unschedules any drops in the top two scopes.
     ///
-    /// This is only needed for `match` arm scopes, because they have one
-    /// entrance per pattern, but only one exit.
-    pub(crate) fn clear_top_scope(&mut self, region_scope: region::Scope) {
-        let top_scope = self.scopes.scopes.last_mut().unwrap();
+    /// This is only needed for pattern-matches combining guards and or-patterns: or-patterns lead
+    /// to guards being lowered multiple times before lowering the arm body, so we unschedle drops
+    /// for guards' temporaries and bindings between lowering each instance of an match arm's guard.
+    pub(crate) fn clear_match_arm_and_guard_scopes(&mut self, region_scope: region::Scope) {
+        let [.., arm_scope, guard_scope] = &mut *self.scopes.scopes else {
+            bug!("matches with guards should introduce separate scopes for the pattern and guard");
+        };
 
-        assert_eq!(top_scope.region_scope, region_scope);
+        assert_eq!(arm_scope.region_scope, region_scope);
+        assert_eq!(guard_scope.region_scope.data, region::ScopeData::MatchGuard);
+        assert_eq!(guard_scope.region_scope.local_id, region_scope.local_id);
 
-        top_scope.drops.clear();
-        top_scope.invalidate_cache();
+        arm_scope.drops.clear();
+        arm_scope.invalidate_cache();
+        guard_scope.drops.clear();
+        guard_scope.invalidate_cache();
     }
 }