Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions compiler/rustc_hir_analysis/src/check/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,8 @@ fn resolve_local<'tcx>(
// Iterate up to the enclosing destruction scope to find the same scope that will also
// be used for the result of the block itself.
if let Some(inner_scope) = visitor.cx.var_parent {
(visitor.cx.var_parent, _) = visitor.scope_tree.default_temporary_scope(inner_scope)
visitor.cx.var_parent =
Some(visitor.scope_tree.default_temporary_scope(inner_scope).0)
}
// Don't lifetime-extend child `super let`s or block tail expressions' temporaries in
// the initializer when this `super let` is not itself extended by a parent `let`
Expand Down Expand Up @@ -752,10 +753,10 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
// The body of the every fn is a root scope.
resolve_expr(this, body.value, true);
} else {
// Only functions have an outer terminating (drop) scope, while
// temporaries in constant initializers may be 'static, but only
// according to rvalue lifetime semantics, using the same
// syntactical rules used for let initializers.
// All bodies have an outer temporary drop scope, but temporaries
// and `super let` bindings in constant initializers may be extended
// to have 'static lifetimes, using the same syntactical rules used
// for `let` initializers.
//
// e.g., in `let x = &f();`, the temporary holding the result from
// the `f()` call lives for the entirety of the surrounding block.
Expand Down
13 changes: 6 additions & 7 deletions compiler/rustc_middle/src/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable};
use rustc_span::{DUMMY_SP, Span};
use tracing::debug;

use crate::ty::TyCtxt;
use crate::ty::{self, TyCtxt};

/// Represents a statically-describable scope that can be used to
/// bound the lifetime/region for values.
Expand Down Expand Up @@ -302,20 +302,20 @@ impl ScopeTree {

/// 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>) {
/// Panics if no enclosing temporary scope is found.
pub fn default_temporary_scope(&self, inner: Scope) -> (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);
return (id, backwards_incompatible);
}
ScopeData::IfThenRescope | ScopeData::MatchGuard => {
debug!("temporary_scope({inner:?}) = {p:?} [enclosing]");
return (Some(p), backwards_incompatible);
return (p, backwards_incompatible);
}
ScopeData::Node
| ScopeData::CallSite
Expand All @@ -335,7 +335,6 @@ impl ScopeTree {
}
}

debug!("temporary_scope({inner:?}) = None");
(None, backwards_incompatible)
span_bug!(ty::tls::with(|tcx| inner.span(tcx, self)), "no enclosing temporary scope")
}
}
10 changes: 4 additions & 6 deletions compiler/rustc_middle/src/ty/rvalue_scopes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,10 @@ impl RvalueScopes {
return (s, None);
}

// Otherwise, locate the innermost terminating scope
// if there's one. Static items, for instance, won't
// have an enclosing scope, hence no scope will be
// returned.
region_scope_tree
.default_temporary_scope(Scope { local_id: expr_id, data: ScopeData::Node })
// Otherwise, locate the innermost terminating scope.
let (scope, backward_incompatible) = region_scope_tree
.default_temporary_scope(Scope { local_id: expr_id, data: ScopeData::Node });
(Some(scope), backward_incompatible)
}

/// Make an association between a sub-expression and an extended lifetime
Expand Down
Loading