about summary refs log tree commit diff
path: root/compiler/rustc_middle/src/middle
diff options
context:
space:
mode:
authordianne <diannes.gm@gmail.com>2025-08-13 01:02:13 -0700
committerdianne <diannes.gm@gmail.com>2025-08-13 01:38:22 -0700
commit8fc3938d9961568dfec38b10506f33fd9bc7c147 (patch)
treea6e4f51b31faad2c7ce7b0aef74e524b685c33fa /compiler/rustc_middle/src/middle
parentbbf08d87eb92f618120b6517651588950780b3e4 (diff)
downloadrust-8fc3938d9961568dfec38b10506f33fd9bc7c147.tar.gz
rust-8fc3938d9961568dfec38b10506f33fd9bc7c147.zip
fix scope of `super let` bindings within `if let`
They now use the enclosing temporary scope as their scope, regardless of
which `ScopeData` was used to mark it.
Diffstat (limited to 'compiler/rustc_middle/src/middle')
-rw-r--r--compiler/rustc_middle/src/middle/region.rs39
1 files changed, 39 insertions, 0 deletions
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 857d041224f..5367e5edd49 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -299,4 +299,43 @@ impl ScopeTree {
 
         true
     }
+
+    /// Returns the scope of non-lifetime-extended temporaries within a given scope, as well as
+    /// whether we've recorded a potential backwards-incompatible change to lint on.
+    /// Returns `None` when no enclosing temporary scope is found, such as for static items.
+    pub fn default_temporary_scope(&self, inner: Scope) -> (Option<Scope>, Option<Scope>) {
+        let mut id = inner;
+        let mut backwards_incompatible = None;
+
+        while let Some(&p) = self.parent_map.get(&id) {
+            match p.data {
+                ScopeData::Destruction => {
+                    debug!("temporary_scope({inner:?}) = {id:?} [enclosing]");
+                    return (Some(id), backwards_incompatible);
+                }
+                ScopeData::IfThenRescope | ScopeData::MatchGuard => {
+                    debug!("temporary_scope({inner:?}) = {p:?} [enclosing]");
+                    return (Some(p), backwards_incompatible);
+                }
+                ScopeData::Node
+                | ScopeData::CallSite
+                | ScopeData::Arguments
+                | ScopeData::IfThen
+                | ScopeData::Remainder(_) => {
+                    // If we haven't already passed through a backwards-incompatible node,
+                    // then check if we are passing through one now and record it if so.
+                    // This is for now only working for cases where a temporary lifetime is
+                    // *shortened*.
+                    if backwards_incompatible.is_none() {
+                        backwards_incompatible =
+                            self.backwards_incompatible_scope.get(&p.local_id).copied();
+                    }
+                    id = p
+                }
+            }
+        }
+
+        debug!("temporary_scope({inner:?}) = None");
+        (None, backwards_incompatible)
+    }
 }