librustc: De-@mut the method map

This commit is contained in:
Patrick Walton 2013-12-21 17:04:42 -08:00
parent b9568cdf36
commit f7393d8658
21 changed files with 109 additions and 56 deletions

View File

@ -990,7 +990,8 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
}
{
let r = maps.method_map.find(&id);
let method_map = maps.method_map.borrow();
let r = method_map.get().find(&id);
for &mme in r.iter() {
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
ebml_w.id(id);
@ -1274,9 +1275,9 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
ty_param_defs.get().insert(id, bounds);
}
c::tag_table_method_map => {
dcx.maps.method_map.insert(
id,
val_dsr.read_method_map_entry(xcx));
let entry = val_dsr.read_method_map_entry(xcx);
let mut method_map = dcx.maps.method_map.borrow_mut();
method_map.get().insert(id, entry);
}
c::tag_table_vtable_map => {
let vtable_res =

View File

@ -767,6 +767,7 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
this.check_for_conflicting_loans(expr.id);
this.check_move_out_from_expr(expr);
let method_map = this.bccx.method_map.borrow();
match expr.node {
ast::ExprSelf |
ast::ExprPath(..) => {
@ -791,7 +792,7 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
}
ast::ExprIndex(callee_id, _, rval) |
ast::ExprBinary(callee_id, _, _, rval)
if this.bccx.method_map.contains_key(&expr.id) => {
if method_map.get().contains_key(&expr.id) => {
this.check_call(expr,
None,
callee_id,
@ -799,7 +800,7 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
[rval]);
}
ast::ExprUnary(callee_id, _, _) | ast::ExprIndex(callee_id, _, _)
if this.bccx.method_map.contains_key(&expr.id) => {
if method_map.get().contains_key(&expr.id) => {
this.check_call(expr,
None,
callee_id,

View File

@ -223,6 +223,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
}
// Special checks for various kinds of expressions:
let method_map = this.bccx.method_map.borrow();
match ex.node {
ast::ExprAddrOf(mutbl, base) => {
let base_cmt = this.bccx.cat_expr(base);
@ -270,7 +271,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
ast::ExprIndex(_, _, arg) |
ast::ExprBinary(_, _, _, arg)
if this.bccx.method_map.contains_key(&ex.id) => {
if method_map.get().contains_key(&ex.id) => {
// Arguments in method calls are always passed by ref.
//
// Currently these do not use adjustments, so we have to

View File

@ -519,6 +519,7 @@ fn find_scope(&self,
}
fn is_method_call(&self, expr: &ast::Expr) -> bool {
self.method_map.contains_key(&expr.id)
let method_map = self.method_map.borrow();
method_map.get().contains_key(&expr.id)
}
}

View File

@ -122,7 +122,8 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
}
ExprLit(@codemap::Spanned {node: lit_str(..), ..}) => { }
ExprBinary(..) | ExprUnary(..) => {
if method_map.contains_key(&e.id) {
let method_map = method_map.borrow();
if method_map.get().contains_key(&e.id) {
sess.span_err(e.span, "user-defined operators are not \
allowed in constant expressions");
}

View File

@ -121,7 +121,7 @@ fn variant_expr(variants: &[ast::P<ast::variant>], id: ast::NodeId) -> Option<@E
}
let maps = astencode::Maps {
root_map: @RefCell::new(HashMap::new()),
method_map: @mut HashMap::new(),
method_map: @RefCell::new(HashMap::new()),
vtable_map: @RefCell::new(HashMap::new()),
write_guard_map: @RefCell::new(HashSet::new()),
capture_map: @RefCell::new(HashMap::new())
@ -171,7 +171,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt,
}
let maps = astencode::Maps {
root_map: @RefCell::new(HashMap::new()),
method_map: @mut HashMap::new(),
method_map: @RefCell::new(HashMap::new()),
vtable_map: @RefCell::new(HashMap::new()),
write_guard_map: @RefCell::new(HashSet::new()),
capture_map: @RefCell::new(HashMap::new())

View File

@ -899,7 +899,8 @@ fn find_scope<'a>(&self,
}
fn is_method_call(&self, expr: &ast::Expr) -> bool {
self.dfcx.method_map.contains_key(&expr.id)
let method_map = self.dfcx.method_map.borrow();
method_map.get().contains_key(&expr.id)
}
fn reset(&mut self, bits: &mut [uint]) {

View File

@ -134,7 +134,8 @@ impl Visitor<()> for MarkSymbolVisitor {
fn visit_expr(&mut self, expr: @ast::Expr, _: ()) {
match expr.node {
ast::ExprMethodCall(..) => {
match self.method_map.find(&expr.id) {
let method_map = self.method_map.borrow();
match method_map.get().find(&expr.id) {
Some(&typeck::method_map_entry {
origin: typeck::method_static(def_id),
..

View File

@ -1202,7 +1202,8 @@ fn check_stability(cx: &Context, e: &ast::Expr) {
}
}
ast::ExprMethodCall(..) => {
match cx.method_map.find(&e.id) {
let method_map = cx.method_map.borrow();
match method_map.get().find(&e.id) {
Some(&typeck::method_map_entry { origin, .. }) => {
match origin {
typeck::method_static(def_id) => {

View File

@ -390,7 +390,8 @@ pub fn cat_expr_unadjusted(&self, expr: @ast::Expr) -> cmt {
let expr_ty = self.expr_ty(expr);
match expr.node {
ast::ExprUnary(_, ast::UnDeref, e_base) => {
if self.method_map.contains_key(&expr.id) {
let method_map = self.method_map.borrow();
if method_map.get().contains_key(&expr.id) {
return self.cat_rvalue_node(expr, expr_ty);
}
@ -401,14 +402,16 @@ pub fn cat_expr_unadjusted(&self, expr: @ast::Expr) -> cmt {
ast::ExprField(base, f_name, _) => {
// Method calls are now a special syntactic form,
// so `a.b` should always be a field.
assert!(!self.method_map.contains_key(&expr.id));
let method_map = self.method_map.borrow();
assert!(!method_map.get().contains_key(&expr.id));
let base_cmt = self.cat_expr(base);
self.cat_field(expr, base_cmt, f_name, self.expr_ty(expr))
}
ast::ExprIndex(_, base, _) => {
if self.method_map.contains_key(&expr.id) {
let method_map = self.method_map.borrow();
if method_map.get().contains_key(&expr.id) {
return self.cat_rvalue_node(expr, expr_ty);
}

View File

@ -130,7 +130,7 @@ struct Foo { a: int, b: ~int }
use middle::pat_util::{pat_bindings};
use middle::freevars;
use middle::ty;
use middle::typeck::{method_map};
use middle::typeck::method_map;
use util::ppaux;
use util::ppaux::Repr;
use util::common::indenter;
@ -591,7 +591,8 @@ pub fn use_overloaded_operator(&mut self,
receiver_expr: @Expr,
arg_exprs: &[@Expr])
-> bool {
if !self.method_map.contains_key(&expr.id) {
let method_map = self.method_map.borrow();
if !method_map.get().contains_key(&expr.id) {
return false;
}

View File

@ -622,7 +622,8 @@ fn visit_expr(&mut self, expr: @ast::Expr, _: ()) {
ast::ExprField(base, ident, _) => {
// Method calls are now a special syntactic form,
// so `a.b` should always be a field.
assert!(!self.method_map.contains_key(&expr.id));
let method_map = self.method_map.borrow();
assert!(!method_map.get().contains_key(&expr.id));
// With type_autoderef, make sure we don't
// allow pointers to violate privacy
@ -641,7 +642,8 @@ fn visit_expr(&mut self, expr: @ast::Expr, _: ()) {
ty::expr_ty(self.tcx, base));
match ty::get(t).sty {
ty::ty_enum(_, _) | ty::ty_struct(_, _) => {
let entry = match self.method_map.find(&expr.id) {
let method_map = self.method_map.borrow();
let entry = match method_map.get().find(&expr.id) {
None => {
self.tcx.sess.span_bug(expr.span,
"method call not in \

View File

@ -139,7 +139,8 @@ fn visit_expr(&mut self, expr:@ast::Expr, _:()) {
}
}
ast::ExprMethodCall(..) => {
match self.method_map.find(&expr.id) {
let method_map = self.method_map.borrow();
match method_map.get().find(&expr.id) {
Some(&typeck::method_map_entry {
origin: typeck::method_static(def_id),
..

View File

@ -792,7 +792,7 @@ fn Resolver(session: Session,
graph_root: graph_root,
method_map: @mut HashMap::new(),
method_map: @RefCell::new(HashMap::new()),
structs: HashSet::new(),
unresolved_imports: 0,
@ -834,7 +834,7 @@ struct Resolver {
graph_root: @NameBindings,
method_map: @mut HashMap<Name, HashSet<DefId>>,
method_map: @RefCell<HashMap<Name, HashSet<DefId>>>,
structs: HashSet<DefId>,
// The number of imports that are currently unresolved.
@ -1378,10 +1378,11 @@ fn build_reduced_graph_for_item(&mut self,
let def_id = local_def(item.id);
for (name, _) in method_names.iter() {
if !self.method_map.contains_key(name) {
self.method_map.insert(*name, HashSet::new());
let mut method_map = self.method_map.borrow_mut();
if !method_map.get().contains_key(name) {
method_map.get().insert(*name, HashSet::new());
}
match self.method_map.find_mut(name) {
match method_map.get().find_mut(name) {
Some(s) => { s.insert(def_id); },
_ => fail!("Can't happen"),
}
@ -1699,10 +1700,11 @@ trait method '{}'",
}
}
for name in interned_method_names.iter() {
if !self.method_map.contains_key(name) {
self.method_map.insert(*name, HashSet::new());
let mut method_map = self.method_map.borrow_mut();
if !method_map.get().contains_key(name) {
method_map.get().insert(*name, HashSet::new());
}
match self.method_map.find_mut(name) {
match method_map.get().find_mut(name) {
Some(s) => { s.insert(def_id); },
_ => fail!("Can't happen"),
}
@ -4833,7 +4835,8 @@ fn resolve_module_relative_path(&mut self,
};
match containing_module.kind.get() {
TraitModuleKind | ImplModuleKind => {
match self.method_map.find(&ident.name) {
let method_map = self.method_map.borrow();
match method_map.get().find(&ident.name) {
Some(s) => {
match containing_module.def_id.get() {
Some(def_id) if s.contains(&def_id) => {
@ -5322,7 +5325,8 @@ fn search_for_traits_containing_method(&mut self, name: Ident)
let mut found_traits = ~[];
let mut search_module = self.current_module;
match self.method_map.find(&name.name) {
let method_map = self.method_map.borrow();
match method_map.get().find(&name.name) {
Some(candidate_traits) => loop {
// Look for the current trait.
match self.current_trait_refs {

View File

@ -479,7 +479,11 @@ pub fn trans_method_call(in_cx: @Block,
node_id_type(in_cx, callee_id),
expr_ty(in_cx, call_ex),
|cx| {
match cx.ccx().maps.method_map.find_copy(&call_ex.id) {
let origin_opt = {
let mut method_map = cx.ccx().maps.method_map.borrow_mut();
method_map.get().find_copy(&call_ex.id)
};
match origin_opt {
Some(origin) => {
debug!("origin for {}: {}",
call_ex.repr(in_cx.tcx()),

View File

@ -590,7 +590,10 @@ fn trans_rvalue_datum_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock {
}
ast::ExprBinary(_, op, lhs, rhs) => {
// if overloaded, would be RvalueDpsExpr
assert!(!bcx.ccx().maps.method_map.contains_key(&expr.id));
{
let method_map = bcx.ccx().maps.method_map.borrow();
assert!(!method_map.get().contains_key(&expr.id));
}
return trans_binary(bcx, expr, op, lhs, rhs);
}
@ -1346,7 +1349,10 @@ fn trans_unary_datum(bcx: @Block,
assert!(op != ast::UnDeref);
// if overloaded, would be RvalueDpsExpr
assert!(!bcx.ccx().maps.method_map.contains_key(&un_expr.id));
{
let method_map = bcx.ccx().maps.method_map.borrow();
assert!(!method_map.get().contains_key(&un_expr.id));
}
let un_ty = expr_ty(bcx, un_expr);
let sub_ty = expr_ty(bcx, sub_expr);
@ -1618,7 +1624,10 @@ fn trans_overloaded_op(bcx: @Block,
ret_ty: ty::t,
dest: Dest)
-> @Block {
let origin = bcx.ccx().maps.method_map.get_copy(&expr.id);
let origin = {
let method_map = bcx.ccx().maps.method_map.borrow();
method_map.get().get_copy(&expr.id)
};
let fty = node_id_type(bcx, callee_id);
callee::trans_call_inner(bcx,
expr.info(),
@ -1780,7 +1789,11 @@ fn trans_assign_op(bcx: @Block,
let dst_datum = unpack_datum!(bcx, trans_lvalue_unadjusted(bcx, dst));
// A user-defined operator method
if bcx.ccx().maps.method_map.find(&expr.id).is_some() {
let found = {
let method_map = bcx.ccx().maps.method_map.borrow();
method_map.get().find(&expr.id).is_some()
};
if found {
// FIXME(#2528) evaluates the receiver twice!!
let scratch = scratch_datum(bcx, dst_datum.ty, "__assign_op", false);
let bcx = trans_overloaded_op(bcx,

View File

@ -3049,7 +3049,8 @@ pub fn method_call_type_param_defs(tcx: ctxt,
method_map: typeck::method_map,
id: ast::NodeId)
-> Option<@~[TypeParameterDef]> {
method_map.find(&id).map(|method| {
let method_map = method_map.borrow();
method_map.get().find(&id).map(|method| {
match method.origin {
typeck::method_static(did) => {
// n.b.: When we encode impl methods, the bounds
@ -3112,14 +3113,17 @@ pub enum ExprKind {
pub fn expr_kind(tcx: ctxt,
method_map: typeck::method_map,
expr: &ast::Expr) -> ExprKind {
if method_map.contains_key(&expr.id) {
// Overloaded operations are generally calls, and hence they are
// generated via DPS. However, assign_op (e.g., `x += y`) is an
// exception, as its result is always unit.
return match expr.node {
ast::ExprAssignOp(..) => RvalueStmtExpr,
_ => RvalueDpsExpr
};
{
let method_map = method_map.borrow();
if method_map.get().contains_key(&expr.id) {
// Overloaded operations are generally calls, and hence they are
// generated via DPS. However, assign_op (e.g., `x += y`) is an
// exception, as its result is always unit.
return match expr.node {
ast::ExprAssignOp(..) => RvalueStmtExpr,
_ => RvalueDpsExpr
};
}
}
match expr.node {

View File

@ -265,7 +265,7 @@ fn new(tcx: ty::ctxt,
node_types: RefCell::new(HashMap::new()),
node_type_substs: RefCell::new(HashMap::new()),
adjustments: RefCell::new(HashMap::new()),
method_map: @mut HashMap::new(),
method_map: @RefCell::new(HashMap::new()),
vtable_map: @RefCell::new(HashMap::new()),
}
}
@ -1950,7 +1950,8 @@ fn check_method_call(fcx: @FnCtxt,
AutoderefReceiver) {
Some(ref entry) => {
let method_map = fcx.inh.method_map;
method_map.insert(expr.id, (*entry));
let mut method_map = method_map.borrow_mut();
method_map.get().insert(expr.id, (*entry));
}
None => {
debug!("(checking method call) failing expr is {}", expr.id);
@ -2040,7 +2041,10 @@ fn lookup_op_method(fcx: @FnCtxt,
Some(ref origin) => {
let method_ty = fcx.node_ty(callee_id);
let method_map = fcx.inh.method_map;
method_map.insert(op_ex.id, *origin);
{
let mut method_map = method_map.borrow_mut();
method_map.get().insert(op_ex.id, *origin);
}
check_method_argument_types(fcx, op_ex.span,
method_ty, op_ex, args,
ast::NoSugar, deref_args)

View File

@ -249,7 +249,10 @@ fn visit_expr(rcx: &mut Rcx, expr: @ast::Expr) {
debug!("regionck::visit_expr(e={}, repeating_scope={:?})",
expr.repr(rcx.fcx.tcx()), rcx.repeating_scope);
let has_method_map = rcx.fcx.inh.method_map.contains_key(&expr.id);
let has_method_map = {
let method_map = rcx.fcx.inh.method_map;
method_map.get().contains_key(&expr.id)
};
// Record cleanup scopes, which are used by borrowck to decide the
// maximum lifetime of a temporary rvalue. These were derived by
@ -1113,7 +1116,8 @@ fn categorize_unadjusted(rcx: &mut Rcx,
debug!("categorize_unadjusted()");
let guarantor = {
if rcx.fcx.inh.method_map.contains_key(&expr.id) {
let method_map = rcx.fcx.inh.method_map.borrow();
if method_map.get().contains_key(&expr.id) {
None
} else {
guarantor(rcx, expr)

View File

@ -62,18 +62,23 @@ fn resolve_type_vars_in_types(fcx: @FnCtxt, sp: Span, tys: &[ty::t])
fn resolve_method_map_entry(fcx: @FnCtxt, sp: Span, id: ast::NodeId) {
// Resolve any method map entry
match fcx.inh.method_map.find(&id) {
let method_map_entry_opt = {
let method_map = fcx.inh.method_map.borrow();
method_map.get().find_copy(&id)
};
match method_map_entry_opt {
None => {}
Some(mme) => {
{
let r = resolve_type_vars_in_type(fcx, sp, mme.self_ty);
for t in r.iter() {
let method_map = fcx.ccx.method_map;
let new_entry = method_map_entry { self_ty: *t, ..*mme };
let new_entry = method_map_entry { self_ty: *t, ..mme };
debug!("writeback::resolve_method_map_entry(id={:?}, \
new_entry={:?})",
id, new_entry);
method_map.insert(id, new_entry);
let mut method_map = method_map.borrow_mut();
method_map.get().insert(id, new_entry);
}
}
}

View File

@ -160,7 +160,7 @@ pub struct method_map_entry {
// maps from an expression id that corresponds to a method call to the details
// of the method to be invoked
pub type method_map = @mut HashMap<ast::NodeId, method_map_entry>;
pub type method_map = @RefCell<HashMap<ast::NodeId, method_map_entry>>;
pub type vtable_param_res = @~[vtable_origin];
// Resolutions for bounds of all parameters, left to right, for a given path.
@ -458,7 +458,7 @@ pub fn check_crate(tcx: ty::ctxt,
let time_passes = tcx.sess.time_passes();
let ccx = @CrateCtxt {
trait_map: trait_map,
method_map: @mut HashMap::new(),
method_map: @RefCell::new(HashMap::new()),
vtable_map: @RefCell::new(HashMap::new()),
tcx: tcx
};