1 use crate::middle::region::{Scope, ScopeData, ScopeTree};
2 use rustc_data_structures::fx::FxHashMap;
5 /// `RvalueScopes` is a mapping from sub-expressions to _extended_ lifetime as determined by
6 /// rules laid out in `rustc_hir_analysis::check::rvalue_scopes`.
7 #[derive(TyEncodable, TyDecodable, Clone, Debug, Default, Eq, PartialEq, HashStable)]
8 pub struct RvalueScopes {
9 map: FxHashMap<hir::ItemLocalId, Option<Scope>>,
13 pub fn new() -> Self {
14 Self { map: <_>::default() }
17 /// Returns the scope when the temp created by `expr_id` will be cleaned up.
18 pub fn temporary_scope(
20 region_scope_tree: &ScopeTree,
21 expr_id: hir::ItemLocalId,
23 // Check for a designated rvalue scope.
24 if let Some(&s) = self.map.get(&expr_id) {
25 debug!("temporary_scope({expr_id:?}) = {s:?} [custom]");
29 // Otherwise, locate the innermost terminating scope
30 // if there's one. Static items, for instance, won't
31 // have an enclosing scope, hence no scope will be
33 let mut id = Scope { id: expr_id, data: ScopeData::Node };
35 while let Some(&(p, _)) = region_scope_tree.parent_map.get(&id) {
37 ScopeData::Destruction => {
38 debug!("temporary_scope({expr_id:?}) = {id:?} [enclosing]");
45 debug!("temporary_scope({expr_id:?}) = None");
49 /// Make an association between a sub-expression and an extended lifetime
50 pub fn record_rvalue_scope(&mut self, var: hir::ItemLocalId, lifetime: Option<Scope>) {
51 debug!("record_rvalue_scope(var={var:?}, lifetime={lifetime:?})");
52 if let Some(lifetime) = lifetime {
53 assert!(var != lifetime.item_local_id());
55 self.map.insert(var, lifetime);