diff options
| author | dianne <diannes.gm@gmail.com> | 2025-07-03 06:10:37 -0700 |
|---|---|---|
| committer | dianne <diannes.gm@gmail.com> | 2025-08-07 16:43:20 -0700 |
| commit | b2241c78c86a15b8e7e842f036135df4478de0fe (patch) | |
| tree | 68f79ca2b81adced88e3498f28433539e612bca5 /compiler/rustc_mir_build/src/builder/scope.rs | |
| parent | 4ec688110f21b04ab243c5a3e56997ea6c33dbcc (diff) | |
| download | rust-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.rs | 23 |
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(); } } |
