Skip to content

Commit af03a85

Browse files
committed
assert that non-extended temporaries have scopes
1 parent d773bd0 commit af03a85

File tree

3 files changed

+23
-18
lines changed

3 files changed

+23
-18
lines changed

compiler/rustc_hir_analysis/src/check/region.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,9 @@ fn resolve_local<'tcx>(
498498
// Iterate up to the enclosing destruction scope to find the same scope that will also
499499
// be used for the result of the block itself.
500500
if let Some(inner_scope) = visitor.cx.var_parent {
501-
(visitor.cx.var_parent, _) = visitor.scope_tree.default_temporary_scope(inner_scope)
501+
visitor.cx.var_parent = Some(
502+
visitor.scope_tree.default_temporary_scope(&visitor.scope_tree, inner_scope).0,
503+
)
502504
}
503505
// Don't lifetime-extend child `super let`s or block tail expressions' temporaries in
504506
// the initializer when this `super let` is not itself extended by a parent `let`
@@ -752,10 +754,10 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
752754
// The body of the every fn is a root scope.
753755
resolve_expr(this, body.value, true);
754756
} else {
755-
// Only functions have an outer terminating (drop) scope, while
756-
// temporaries in constant initializers may be 'static, but only
757-
// according to rvalue lifetime semantics, using the same
758-
// syntactical rules used for let initializers.
757+
// All bodies have an outer temporary drop scope, but temporaries
758+
// and `super let` bindings in constant initializers may be extended
759+
// to have 'static lifetimes, using the same syntactical rules used
760+
// for `let` initializers.
759761
//
760762
// e.g., in `let x = &f();`, the temporary holding the result from
761763
// the `f()` call lives for the entirety of the surrounding block.

compiler/rustc_middle/src/middle/region.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_macros::{HashStable, TyDecodable, TyEncodable};
1616
use rustc_span::{DUMMY_SP, Span};
1717
use tracing::debug;
1818

19-
use crate::ty::TyCtxt;
19+
use crate::ty::{self, TyCtxt};
2020

2121
/// Represents a statically-describable scope that can be used to
2222
/// bound the lifetime/region for values.
@@ -302,20 +302,24 @@ impl ScopeTree {
302302

303303
/// Returns the scope of non-lifetime-extended temporaries within a given scope, as well as
304304
/// whether we've recorded a potential backwards-incompatible change to lint on.
305-
/// Returns `None` when no enclosing temporary scope is found, such as for static items.
306-
pub fn default_temporary_scope(&self, inner: Scope) -> (Option<Scope>, Option<Scope>) {
305+
/// Panics if no enclosing temporary scope is found.
306+
pub fn default_temporary_scope(
307+
&self,
308+
scope_tree: &ScopeTree,
309+
inner: Scope,
310+
) -> (Scope, Option<Scope>) {
307311
let mut id = inner;
308312
let mut backwards_incompatible = None;
309313

310314
while let Some(&p) = self.parent_map.get(&id) {
311315
match p.data {
312316
ScopeData::Destruction => {
313317
debug!("temporary_scope({inner:?}) = {id:?} [enclosing]");
314-
return (Some(id), backwards_incompatible);
318+
return (id, backwards_incompatible);
315319
}
316320
ScopeData::IfThenRescope | ScopeData::MatchGuard => {
317321
debug!("temporary_scope({inner:?}) = {p:?} [enclosing]");
318-
return (Some(p), backwards_incompatible);
322+
return (p, backwards_incompatible);
319323
}
320324
ScopeData::Node
321325
| ScopeData::CallSite
@@ -335,7 +339,6 @@ impl ScopeTree {
335339
}
336340
}
337341

338-
debug!("temporary_scope({inner:?}) = None");
339-
(None, backwards_incompatible)
342+
span_bug!(ty::tls::with(|tcx| inner.span(tcx, scope_tree)), "no enclosing temporary scope")
340343
}
341344
}

compiler/rustc_middle/src/ty/rvalue_scopes.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ impl RvalueScopes {
3131
return (s, None);
3232
}
3333

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

4242
/// Make an association between a sub-expression and an extended lifetime

0 commit comments

Comments
 (0)