use util::nodemap::{FxHashMap, NodeMap, NodeSet};
use ty;
-use std::cell::RefCell;
use std::collections::hash_map::Entry;
use std::fmt;
use std::mem;
let region_maps = tcx.region_maps();
{
let code_extents = ®ion_maps.code_extents;
- if let Some(data) = code_extents.borrow().get(self.0 as usize) {
+ if let Some(data) = code_extents.get(self.0 as usize) {
write!(f, "/{:?}", data)?;
}
mem::drop(code_extents); // FIXME why is this necessary?
/// The region maps encode information about region relationships.
pub struct RegionMaps {
- code_extents: RefCell<Vec<CodeExtentData>>,
- code_extent_interner: RefCell<FxHashMap<CodeExtentData, CodeExtent>>,
+ code_extents: Vec<CodeExtentData>,
+ code_extent_interner: FxHashMap<CodeExtentData, CodeExtent>,
/// `scope_map` maps from a scope id to the enclosing scope id;
/// this is usually corresponding to the lexical nesting, though
/// in the case of closures the parent scope is the innermost
/// conditional expression or repeating block. (Note that the
/// enclosing scope id for the block associated with a closure is
/// the closure itself.)
- scope_map: RefCell<Vec<CodeExtent>>,
+ scope_map: Vec<CodeExtent>,
/// `var_map` maps from a variable or binding id to the block in
/// which that variable is declared.
- var_map: RefCell<NodeMap<CodeExtent>>,
+ var_map: NodeMap<CodeExtent>,
/// `rvalue_scopes` includes entries for those expressions whose cleanup scope is
/// larger than the default. The map goes from the expression id
/// table, the appropriate cleanup scope is the innermost
/// enclosing statement, conditional expression, or repeating
/// block (see `terminating_scopes`).
- rvalue_scopes: RefCell<NodeMap<CodeExtent>>,
+ rvalue_scopes: NodeMap<CodeExtent>,
/// Records the value of rvalue scopes before they were shrunk by
/// #36082, for error reporting.
///
/// FIXME: this should be temporary. Remove this by 1.18.0 or
/// so.
- shrunk_rvalue_scopes: RefCell<NodeMap<CodeExtent>>,
+ shrunk_rvalue_scopes: NodeMap<CodeExtent>,
/// Encodes the hierarchy of fn bodies. Every fn body (including
/// closures) forms its own distinct region hierarchy, rooted in
/// closure defined by that fn. See the "Modeling closures"
/// section of the README in infer::region_inference for
/// more details.
- fn_tree: RefCell<NodeMap<ast::NodeId>>,
+ fn_tree: NodeMap<ast::NodeId>,
}
#[derive(Debug, Copy, Clone)]
sess: &'a Session,
// Generated maps:
- region_maps: &'a RegionMaps,
+ region_maps: &'a mut RegionMaps,
cx: Context,
impl RegionMaps {
/// create a bogus code extent for the regions in astencode types. Nobody
/// really cares about the contents of these.
- pub fn bogus_code_extent(&self, e: CodeExtentData) -> CodeExtent {
+ pub fn bogus_code_extent(&mut self, e: CodeExtentData) -> CodeExtent {
self.intern_code_extent(e, DUMMY_CODE_EXTENT)
}
pub fn lookup_code_extent(&self, e: CodeExtentData) -> CodeExtent {
- match self.code_extent_interner.borrow().get(&e) {
+ match self.code_extent_interner.get(&e) {
Some(&d) => d,
None => bug!("unknown code extent {:?}", e)
}
self.lookup_code_extent(CodeExtentData::CallSiteScope { fn_id: fn_id, body_id: body_id })
}
pub fn opt_destruction_extent(&self, n: ast::NodeId) -> Option<CodeExtent> {
- self.code_extent_interner.borrow().get(&CodeExtentData::DestructionScope(n)).cloned()
+ self.code_extent_interner.get(&CodeExtentData::DestructionScope(n)).cloned()
}
- pub fn intern_code_extent(&self,
+ pub fn intern_code_extent(&mut self,
e: CodeExtentData,
parent: CodeExtent) -> CodeExtent {
- match self.code_extent_interner.borrow_mut().entry(e) {
+ match self.code_extent_interner.entry(e) {
Entry::Occupied(o) => {
// this can happen when the bogus code extents from tydecode
// have (bogus) NodeId-s that overlap items created during
info!("CodeExtent({}) = {:?} [parent={}] BOGUS!",
idx.0, e, parent.0);
} else {
- assert_eq!(self.scope_map.borrow()[idx.0 as usize],
+ assert_eq!(self.scope_map[idx.0 as usize],
DUMMY_CODE_EXTENT);
info!("CodeExtent({}) = {:?} [parent={}] RECLAIMED!",
idx.0, e, parent.0);
- self.scope_map.borrow_mut()[idx.0 as usize] = parent;
+ self.scope_map[idx.0 as usize] = parent;
}
idx
}
Entry::Vacant(v) => {
- if self.code_extents.borrow().len() > 0xffffffffusize {
+ if self.code_extents.len() > 0xffffffffusize {
bug!() // should pass a sess,
// but this isn't the only place
}
- let idx = CodeExtent(self.code_extents.borrow().len() as u32);
+ let idx = CodeExtent(self.code_extents.len() as u32);
debug!("CodeExtent({}) = {:?} [parent={}]", idx.0, e, parent.0);
- self.code_extents.borrow_mut().push(e);
- self.scope_map.borrow_mut().push(parent);
+ self.code_extents.push(e);
+ self.scope_map.push(parent);
*v.insert(idx)
}
}
}
- pub fn intern_node(&self,
+ pub fn intern_node(&mut self,
n: ast::NodeId,
parent: CodeExtent) -> CodeExtent {
self.intern_code_extent(CodeExtentData::Misc(n), parent)
}
pub fn code_extent_data(&self, e: CodeExtent) -> CodeExtentData {
- self.code_extents.borrow()[e.0 as usize]
+ self.code_extents[e.0 as usize]
}
pub fn each_encl_scope<E>(&self, mut e:E) where E: FnMut(&CodeExtent, &CodeExtent) {
- for child_id in 1..self.code_extents.borrow().len() {
+ for child_id in 1..self.code_extents.len() {
let child = CodeExtent(child_id as u32);
if let Some(parent) = self.opt_encl_scope(child) {
e(&child, &parent)
}
}
pub fn each_var_scope<E>(&self, mut e:E) where E: FnMut(&ast::NodeId, &CodeExtent) {
- for (child, parent) in self.var_map.borrow().iter() {
+ for (child, parent) in self.var_map.iter() {
e(child, parent)
}
}
/// Records that `sub_fn` is defined within `sup_fn`. These ids
/// should be the id of the block that is the fn body, which is
/// also the root of the region hierarchy for that fn.
- fn record_fn_parent(&self, sub_fn: ast::NodeId, sup_fn: ast::NodeId) {
+ fn record_fn_parent(&mut self, sub_fn: ast::NodeId, sup_fn: ast::NodeId) {
debug!("record_fn_parent(sub_fn={:?}, sup_fn={:?})", sub_fn, sup_fn);
assert!(sub_fn != sup_fn);
- let previous = self.fn_tree.borrow_mut().insert(sub_fn, sup_fn);
+ let previous = self.fn_tree.insert(sub_fn, sup_fn);
assert!(previous.is_none());
}
fn fn_is_enclosed_by(&self, mut sub_fn: ast::NodeId, sup_fn: ast::NodeId) -> bool {
- let fn_tree = self.fn_tree.borrow();
loop {
if sub_fn == sup_fn { return true; }
- match fn_tree.get(&sub_fn) {
+ match self.fn_tree.get(&sub_fn) {
Some(&s) => { sub_fn = s; }
None => { return false; }
}
}
}
- fn record_var_scope(&self, var: ast::NodeId, lifetime: CodeExtent) {
+ fn record_var_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent) {
debug!("record_var_scope(sub={:?}, sup={:?})", var, lifetime);
assert!(var != lifetime.node_id(self));
- self.var_map.borrow_mut().insert(var, lifetime);
+ self.var_map.insert(var, lifetime);
}
- fn record_rvalue_scope(&self, var: ast::NodeId, lifetime: CodeExtent) {
+ fn record_rvalue_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent) {
debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
assert!(var != lifetime.node_id(self));
- self.rvalue_scopes.borrow_mut().insert(var, lifetime);
+ self.rvalue_scopes.insert(var, lifetime);
}
- fn record_shrunk_rvalue_scope(&self, var: ast::NodeId, lifetime: CodeExtent) {
+ fn record_shrunk_rvalue_scope(&mut self, var: ast::NodeId, lifetime: CodeExtent) {
debug!("record_rvalue_scope(sub={:?}, sup={:?})", var, lifetime);
assert!(var != lifetime.node_id(self));
- self.shrunk_rvalue_scopes.borrow_mut().insert(var, lifetime);
+ self.shrunk_rvalue_scopes.insert(var, lifetime);
}
pub fn opt_encl_scope(&self, id: CodeExtent) -> Option<CodeExtent> {
//! Returns the narrowest scope that encloses `id`, if any.
- self.scope_map.borrow()[id.0 as usize].into_option()
+ self.scope_map[id.0 as usize].into_option()
}
#[allow(dead_code)] // used in cfg
/// Returns the lifetime of the local variable `var_id`
pub fn var_scope(&self, var_id: ast::NodeId) -> CodeExtent {
- match self.var_map.borrow().get(&var_id) {
+ match self.var_map.get(&var_id) {
Some(&r) => r,
None => { bug!("no enclosing scope for id {:?}", var_id); }
}
pub fn temporary_scope2(&self, expr_id: ast::NodeId) -> (Option<CodeExtent>, bool) {
let temporary_scope = self.temporary_scope(expr_id);
- let was_shrunk = match self.shrunk_rvalue_scopes.borrow().get(&expr_id) {
+ let was_shrunk = match self.shrunk_rvalue_scopes.get(&expr_id) {
Some(&s) => {
info!("temporary_scope2({:?}, scope={:?}, shrunk={:?})",
expr_id, temporary_scope, s);
let temporary_scope = self.temporary_scope(expr_id);
(temporary_scope,
self.shrunk_rvalue_scopes
- .borrow().get(&expr_id).cloned()
+ .get(&expr_id).cloned()
.or(temporary_scope))
}
//! Returns the scope when temp created by expr_id will be cleaned up
// check for a designated rvalue scope
- if let Some(&s) = self.rvalue_scopes.borrow().get(&expr_id) {
+ if let Some(&s) = self.rvalue_scopes.get(&expr_id) {
debug!("temporary_scope({:?}) = {:?} [custom]", expr_id, s);
return Some(s);
}
- let scope_map : &[CodeExtent] = &self.scope_map.borrow();
- let code_extents: &[CodeExtentData] = &self.code_extents.borrow();
+ let scope_map : &[CodeExtent] = &self.scope_map;
+ let code_extents: &[CodeExtentData] = &self.code_extents;
// else, locate the innermost terminating scope
// if there's one. Static items, for instance, won't
let mut a_vec: Vec<CodeExtent> = vec![];
let mut b_buf: [CodeExtent; 32] = [ROOT_CODE_EXTENT; 32];
let mut b_vec: Vec<CodeExtent> = vec![];
- let scope_map : &[CodeExtent] = &self.scope_map.borrow();
+ let scope_map : &[CodeExtent] = &self.scope_map;
let a_ancestors = ancestors_of(scope_map,
scope_a, &mut a_buf, &mut a_vec);
let b_ancestors = ancestors_of(scope_map,
// functions put their destruction scopes *inside* their parameter
// scopes.
let scope = CodeExtentData::DestructionScope(id);
- if !self.region_maps.code_extent_interner.borrow().contains_key(&scope) {
+ if !self.region_maps.code_extent_interner.contains_key(&scope) {
self.region_maps.intern_code_extent(scope, ROOT_CODE_EXTENT);
}
}
let krate = hir_map.krate();
- let maps = RegionMaps {
- code_extents: RefCell::new(vec![]),
- code_extent_interner: RefCell::new(FxHashMap()),
- scope_map: RefCell::new(vec![]),
- var_map: RefCell::new(NodeMap()),
- rvalue_scopes: RefCell::new(NodeMap()),
- shrunk_rvalue_scopes: RefCell::new(NodeMap()),
- fn_tree: RefCell::new(NodeMap()),
+ let mut maps = RegionMaps {
+ code_extents: vec![],
+ code_extent_interner: FxHashMap(),
+ scope_map: vec![],
+ var_map: NodeMap(),
+ rvalue_scopes: NodeMap(),
+ shrunk_rvalue_scopes: NodeMap(),
+ fn_tree: NodeMap(),
};
let root_extent = maps.bogus_code_extent(
CodeExtentData::DestructionScope(ast::DUMMY_NODE_ID));
{
let mut visitor = RegionResolutionVisitor {
sess: sess,
- region_maps: &maps,
+ region_maps: &mut maps,
map: hir_map,
cx: Context {
root_id: None,