]> git.lizzy.rs Git - rust.git/commitdiff
Begin refactor type checking state
authorJared Roesch <roeschinc@gmail.com>
Wed, 24 Jun 2015 20:40:54 +0000 (13:40 -0700)
committerJared Roesch <roeschinc@gmail.com>
Sat, 27 Jun 2015 20:43:20 +0000 (13:43 -0700)
This first patch starts by moving around pieces of state related to
type checking. The goal is to slowly unify the type checking state
into a single typing context. This initial patch moves the
ParameterEnvironment into the InferCtxt and moves shared tables
from Inherited and ty::ctxt into their own struct Tables. This
is the foundational work to refactoring the type checker to
enable future evolution of the language and tooling.

45 files changed:
src/librustc/lib.rs
src/librustc/middle/astencode.rs
src/librustc/middle/cfg/construct.rs
src/librustc/middle/check_const.rs
src/librustc/middle/check_match.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/dead.rs
src/librustc/middle/effect.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/infer/mod.rs
src/librustc/middle/liveness.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/reachable.rs
src/librustc/middle/stability.rs
src/librustc/middle/traits/mod.rs
src/librustc/middle/ty.rs
src/librustc/util/ppaux.rs
src/librustc_lint/builtin.rs
src/librustc_privacy/lib.rs
src/librustc_trans/lib.rs
src/librustc_trans/save/dump_csv.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/closure.rs
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/meth.rs
src/librustc_trans/trans/monomorphize.rs
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/method/confirm.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/op.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/upvar.rs
src/librustc_typeck/check/wf.rs
src/librustc_typeck/check/writeback.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/overlap.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/lib.rs

index c19ba19f5b76bed5d8a48e471ae95c488303eadf..2cec42b76bce3359e8f772ea1bda80a492cbabd3 100644 (file)
@@ -61,6 +61,7 @@
 #![feature(str_match_indices)]
 #![feature(vec_push_all)]
 #![feature(wrapping)]
+#![feature(cell_extras)]
 #![cfg_attr(test, feature(test))]
 
 #![allow(trivial_casts)]
index 21e2ad198810efc4a62bfc0f76b538a52ec2a78b..f2ae396173bc0c7e2b9ecb62a80f59f75e139be4 100644 (file)
@@ -1027,7 +1027,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
         })
     }
 
-    if let Some(item_substs) = tcx.item_substs.borrow().get(&id) {
+    if let Some(item_substs) = tcx.tables.borrow().item_substs.get(&id) {
         rbml_w.tag(c::tag_table_item_subst, |rbml_w| {
             rbml_w.id(id);
             rbml_w.emit_substs(ecx, &item_substs.substs);
@@ -1051,7 +1051,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
                     var_id: var_id,
                     closure_expr_id: id
                 };
-                let upvar_capture = tcx.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone();
+                let upvar_capture = tcx.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone();
                 var_id.encode(rbml_w);
                 upvar_capture.encode(rbml_w);
             })
@@ -1074,19 +1074,19 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
     }
 
     let method_call = MethodCall::expr(id);
-    if let Some(method) = tcx.method_map.borrow().get(&method_call) {
+    if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) {
         rbml_w.tag(c::tag_table_method_map, |rbml_w| {
             rbml_w.id(id);
             encode_method_callee(ecx, rbml_w, method_call.autoderef, method)
         })
     }
 
-    if let Some(adjustment) = tcx.adjustments.borrow().get(&id) {
+    if let Some(adjustment) = tcx.tables.borrow().adjustments.get(&id) {
         match *adjustment {
             ty::AdjustDerefRef(ref adj) => {
                 for autoderef in 0..adj.autoderefs {
                     let method_call = MethodCall::autoderef(id, autoderef as u32);
-                    if let Some(method) = tcx.method_map.borrow().get(&method_call) {
+                    if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) {
                         rbml_w.tag(c::tag_table_method_map, |rbml_w| {
                             rbml_w.id(id);
                             encode_method_callee(ecx, rbml_w,
@@ -1104,14 +1104,14 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
         })
     }
 
-    if let Some(closure_type) = tcx.closure_tys.borrow().get(&ast_util::local_def(id)) {
+    if let Some(closure_type) = tcx.tables.borrow().closure_tys.get(&ast_util::local_def(id)) {
         rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
             rbml_w.id(id);
             rbml_w.emit_closure_type(ecx, closure_type);
         })
     }
 
-    if let Some(closure_kind) = tcx.closure_kinds.borrow().get(&ast_util::local_def(id)) {
+    if let Some(closure_kind) = tcx.tables.borrow().closure_kinds.get(&ast_util::local_def(id)) {
         rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
             rbml_w.id(id);
             encode_closure_kind(rbml_w, *closure_kind)
@@ -1630,7 +1630,7 @@ fn decode_side_tables(dcx: &DecodeContext,
                         let item_substs = ty::ItemSubsts {
                             substs: val_dsr.read_substs(dcx)
                         };
-                        dcx.tcx.item_substs.borrow_mut().insert(
+                        dcx.tcx.tables.borrow_mut().item_substs.insert(
                             id, item_substs);
                     }
                     c::tag_table_freevars => {
@@ -1646,7 +1646,7 @@ fn decode_side_tables(dcx: &DecodeContext,
                             closure_expr_id: id
                         };
                         let ub: ty::UpvarCapture = Decodable::decode(val_dsr).unwrap();
-                        dcx.tcx.upvar_capture_map.borrow_mut().insert(upvar_id, ub.tr(dcx));
+                        dcx.tcx.tables.borrow_mut().upvar_capture_map.insert(upvar_id, ub.tr(dcx));
                     }
                     c::tag_table_tcache => {
                         let type_scheme = val_dsr.read_type_scheme(dcx);
@@ -1663,22 +1663,22 @@ fn decode_side_tables(dcx: &DecodeContext,
                             expr_id: id,
                             autoderef: autoderef
                         };
-                        dcx.tcx.method_map.borrow_mut().insert(method_call, method);
+                        dcx.tcx.tables.borrow_mut().method_map.insert(method_call, method);
                     }
                     c::tag_table_adjustments => {
                         let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(dcx);
-                        dcx.tcx.adjustments.borrow_mut().insert(id, adj);
+                        dcx.tcx.tables.borrow_mut().adjustments.insert(id, adj);
                     }
                     c::tag_table_closure_tys => {
                         let closure_ty =
                             val_dsr.read_closure_ty(dcx);
-                        dcx.tcx.closure_tys.borrow_mut().insert(ast_util::local_def(id),
+                        dcx.tcx.tables.borrow_mut().closure_tys.insert(ast_util::local_def(id),
                                                                 closure_ty);
                     }
                     c::tag_table_closure_kinds => {
                         let closure_kind =
                             val_dsr.read_closure_kind(dcx);
-                        dcx.tcx.closure_kinds.borrow_mut().insert(ast_util::local_def(id),
+                        dcx.tcx.tables.borrow_mut().closure_kinds.insert(ast_util::local_def(id),
                                                                   closure_kind);
                     }
                     c::tag_table_cast_kinds => {
index 801b3a721e40d614daa4eb5f5856aca01bcb2e89..7d62b6ff900408e62de48bd258153df79f68736e 100644 (file)
@@ -411,7 +411,7 @@ fn call<'b, I: Iterator<Item=&'b ast::Expr>>(&mut self,
             func_or_rcvr: &ast::Expr,
             args: I) -> CFGIndex {
         let method_call = ty::MethodCall::expr(call_expr.id);
-        let fn_ty = match self.tcx.method_map.borrow().get(&method_call) {
+        let fn_ty = match self.tcx.tables.borrow().method_map.get(&method_call) {
             Some(method) => method.ty,
             None => self.tcx.expr_ty_adjusted(func_or_rcvr)
         };
@@ -634,6 +634,6 @@ fn find_scope(&self,
 
     fn is_method_call(&self, expr: &ast::Expr) -> bool {
         let method_call = ty::MethodCall::expr(expr.id);
-        self.tcx.method_map.borrow().contains_key(&method_call)
+        self.tcx.tables.borrow().method_map.contains_key(&method_call)
     }
 }
index 62bf1648725cd4c122e523ef8a619a0f6d7b2081..b156a2c087b021b5e5a5eabe3c079d210f989df8 100644 (file)
@@ -283,12 +283,11 @@ fn check_static_mut_type(&self, e: &ast::Expr) {
 
     fn check_static_type(&self, e: &ast::Expr) {
         let ty = self.tcx.node_id_to_type(e.id);
-        let infcx = infer::new_infer_ctxt(self.tcx);
+        let infcx = infer::new_infer_ctxt(self.tcx, None);
         let mut fulfill_cx = traits::FulfillmentContext::new(false);
         let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
         fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
-        let env = self.tcx.empty_parameter_environment();
-        match fulfill_cx.select_all_or_error(&infcx, &env) {
+        match fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) {
             Ok(()) => { },
             Err(ref errors) => {
                 traits::report_fulfillment_errors(&infcx, errors);
@@ -544,7 +543,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
     match e.node {
         ast::ExprUnary(..) |
         ast::ExprBinary(..) |
-        ast::ExprIndex(..) if v.tcx.method_map.borrow().contains_key(&method_call) => {
+        ast::ExprIndex(..) if v.tcx.tables.borrow().method_map.contains_key(&method_call) => {
             v.add_qualif(ConstQualif::NOT_CONST);
             if v.mode != Mode::Var {
                 span_err!(v.tcx.sess, e.span, E0011,
@@ -695,7 +694,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
             }
         }
         ast::ExprMethodCall(..) => {
-            let method_did = match v.tcx.method_map.borrow()[&method_call].origin {
+            let method_did = match v.tcx.tables.borrow().method_map[&method_call].origin {
                 ty::MethodStatic(did) => Some(did),
                 _ => None
             };
index d2b3b83e4f42f95bcd343ce00ce4e77b384213ad..f61884e213666046ba54f91ec1897c1543a22c49 100644 (file)
@@ -98,6 +98,7 @@ fn from_iter<T: IntoIterator<Item=Vec<&'a Pat>>>(iter: T) -> Matrix<'a> {
     }
 }
 
+//NOTE: appears to be the only place other then InferCtxt to contain a ParamEnv
 pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
     pub tcx: &'a ty::ctxt<'tcx>,
     pub param_env: ParameterEnvironment<'a, 'tcx>,
index 1b1725dd15c851fea0cfddf49c22061177089fd2..8f19a6e9e152b47bfb486fc9485f30deff449596 100644 (file)
@@ -1031,10 +1031,9 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
                                               substs: trait_substs });
 
     tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
-    let infcx = infer::new_infer_ctxt(tcx);
+    let infcx = infer::new_infer_ctxt(tcx, None);
 
-    let param_env = tcx.empty_parameter_environment();
-    let mut selcx = traits::SelectionContext::new(&infcx, &param_env);
+    let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment);
     let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
                                              trait_ref.to_poly_trait_predicate());
     let selection = match selcx.select(&obligation) {
index bd8b8afbdfe88de30b24c88deb6f623dc4c77b3e..d8ee38b847830f941f2eaeceef92f8d0b70f8a87 100644 (file)
@@ -96,7 +96,7 @@ fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
     fn lookup_and_handle_method(&mut self, id: ast::NodeId,
                                 span: codemap::Span) {
         let method_call = ty::MethodCall::expr(id);
-        match self.tcx.method_map.borrow().get(&method_call) {
+        match self.tcx.tables.borrow().method_map.get(&method_call) {
             Some(method) => {
                 match method.origin {
                     ty::MethodStatic(def_id) => {
index c48d5d5da40200bcc8d7b51b200722d00e9c1206..8084c2b0c39b884a677ee86da98c5889bd282530 100644 (file)
@@ -140,7 +140,7 @@ fn visit_expr(&mut self, expr: &ast::Expr) {
         match expr.node {
             ast::ExprMethodCall(_, _, _) => {
                 let method_call = MethodCall::expr(expr.id);
-                let base_type = self.tcx.method_map.borrow().get(&method_call).unwrap().ty;
+                let base_type = self.tcx.tables.borrow().method_map.get(&method_call).unwrap().ty;
                 debug!("effect: method call case, base type is {:?}",
                         base_type);
                 if type_is_unsafe_function(base_type) {
index a15d02ea29605903a4f9d083dcb0ef41b2a67658..25728c50c61f4a6784ae7fccd8d52aa3c7634970 100644 (file)
@@ -257,8 +257,9 @@ fn from_method_id(tcx: &ty::ctxt, method_id: ast::DefId)
     fn from_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
                     -> OverloadedCallType {
         let trait_did =
-            tcx.closure_kinds
+            tcx.tables
                .borrow()
+               .closure_kinds
                .get(&closure_did)
                .expect("OverloadedCallType::from_closure: didn't find closure id")
                .trait_did(tcx);
@@ -787,8 +788,10 @@ fn contains_field_named(field: &ty::field,
     // process.
     fn walk_adjustment(&mut self, expr: &ast::Expr) {
         let typer = self.typer;
-        if let Some(adjustment) = typer.adjustments().borrow().get(&expr.id) {
-            match *adjustment {
+        //NOTE(@jroesch): mixed RefCell borrow causes crash
+        let adj = typer.adjustments().get(&expr.id).map(|x| x.clone());
+        if let Some(adjustment) = adj {
+            match adjustment {
                 ty::AdjustReifyFnPointer |
                 ty::AdjustUnsafeFnPointer => {
                     // Creating a closure/fn-pointer or unsizing consumes
index f1af2705d4ed891d9f619eb2709886f909c80889..8e53747e89973c339adb74c2adb1cdc052c742ba 100644 (file)
@@ -77,6 +77,10 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
 
     // For region variables.
     region_vars: RegionVarBindings<'a, 'tcx>,
+
+    pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>,
+
+    // pub tables: &'a RefCell<ty::Tables<'tcx>>
 }
 
 /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
@@ -309,7 +313,8 @@ pub fn fixup_err_to_string(f: fixup_err) -> String {
     }
 }
 
-pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
+pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
+                                param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>)
                                 -> InferCtxt<'a, 'tcx> {
     InferCtxt {
         tcx: tcx,
@@ -317,6 +322,7 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
         int_unification_table: RefCell::new(UnificationTable::new()),
         float_unification_table: RefCell::new(UnificationTable::new()),
         region_vars: RegionVarBindings::new(tcx),
+        parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment())
     }
 }
 
index d354c1667da38b7b03dcfcfaffaf5aab0c9a0c02..7d237a511c4a173240da94101c01a582c85f6dae 100644 (file)
@@ -1150,7 +1150,7 @@ fn propagate_through_expr(&mut self, expr: &Expr, succ: LiveNode)
 
           ast::ExprMethodCall(_, _, ref args) => {
             let method_call = ty::MethodCall::expr(expr.id);
-            let method_ty = self.ir.tcx.method_map.borrow().get(&method_call).unwrap().ty;
+            let method_ty = self.ir.tcx.tables.borrow().method_map.get(&method_call).unwrap().ty;
             let succ = if method_ty.fn_ret().diverges() {
                 self.s.exit_ln
             } else {
index 969ffaf88a719cee613a7df622075f404d974cfa..13e127e9126139caed875c100b53c51d17c7b09c 100644 (file)
@@ -83,7 +83,7 @@
 use syntax::ast;
 use syntax::codemap::Span;
 
-use std::cell::RefCell;
+use std::cell::Ref;
 use std::fmt;
 use std::rc::Rc;
 
@@ -289,7 +289,7 @@ pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> {
     fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>>;
     fn node_method_origin(&self, method_call: ty::MethodCall)
                           -> Option<ty::MethodOrigin<'tcx>>;
-    fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>;
+    fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>>;
     fn is_method_call(&self, id: ast::NodeId) -> bool;
     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
     fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture>;
@@ -408,7 +408,7 @@ fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
         let unadjusted_ty = try!(self.expr_ty(expr));
         Ok(unadjusted_ty.adjust(
             self.tcx(), expr.span, expr.id,
-            self.typer.adjustments().borrow().get(&expr.id),
+            self.typer.adjustments().get(&expr.id),
             |method_call| self.typer.node_method_ty(method_call)))
     }
 
@@ -440,7 +440,7 @@ fn pat_ty(&self, pat: &ast::Pat) -> McResult<Ty<'tcx>> {
     }
 
     pub fn cat_expr(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
-        match self.typer.adjustments().borrow().get(&expr.id) {
+        match self.typer.adjustments().get(&expr.id) {
             None => {
                 // No adjustments.
                 self.cat_expr_unadjusted(expr)
index 0bbcfa700388c847eb94716a9b0a828bf354ee56..6ea726062cad6eab58668bc5dbb82a590f18bf68 100644 (file)
@@ -128,7 +128,7 @@ fn visit_expr(&mut self, expr: &ast::Expr) {
             }
             ast::ExprMethodCall(..) => {
                 let method_call = ty::MethodCall::expr(expr.id);
-                match (*self.tcx.method_map.borrow()).get(&method_call).unwrap().origin {
+                match self.tcx.tables.borrow().method_map.get(&method_call).unwrap().origin {
                     ty::MethodStatic(def_id) => {
                         if is_local(def_id) {
                             if self.def_id_represents_local_inlined_item(def_id) {
index 4766ae8933d0b535564e6e0769e3d21a16df50cb..e6bbae6405bf4f8c4f02ef04a8151a30490e4e72 100644 (file)
@@ -406,7 +406,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
         ast::ExprMethodCall(i, _, _) => {
             span = i.span;
             let method_call = ty::MethodCall::expr(e.id);
-            match tcx.method_map.borrow().get(&method_call) {
+            match tcx.tables.borrow().method_map.get(&method_call) {
                 Some(method) => {
                     match method.origin {
                         ty::MethodStatic(def_id) => {
index 845ba62307fa57340b9ed4c995f085ced55306f1..eb839eade143f7a516c41fcf22f1932701149c80 100644 (file)
@@ -351,6 +351,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
     }
 }
 
+// TODO: this is gonna need to be removed ...
 /// Normalizes the parameter environment, reporting errors if they occur.
 pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvironment<'a,'tcx>,
                                              cause: ObligationCause<'tcx>)
@@ -396,13 +397,13 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
 
     let elaborated_env = unnormalized_env.with_caller_bounds(predicates);
 
-    let infcx = infer::new_infer_ctxt(tcx);
-    let predicates = match fully_normalize(&infcx, &elaborated_env, cause,
-                                           &elaborated_env.caller_bounds) {
+    let infcx = infer::new_infer_ctxt(tcx, Some(elaborated_env));
+    let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause,
+                                           &infcx.parameter_environment.caller_bounds) {
         Ok(predicates) => predicates,
         Err(errors) => {
             report_fulfillment_errors(&infcx, &errors);
-            return unnormalized_env; // an unnormalized env is better than nothing
+            return infcx.parameter_environment; // an unnormalized env is better than nothing
         }
     };
 
@@ -420,11 +421,11 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
             // all things considered.
             let err_msg = fixup_err_to_string(fixup_err);
             tcx.sess.span_err(span, &err_msg);
-            return elaborated_env; // an unnormalized env is better than nothing
+            return infcx.parameter_environment; // an unnormalized env is better than nothing
         }
     };
 
-    elaborated_env.with_caller_bounds(predicates)
+    infcx.parameter_environment.with_caller_bounds(predicates)
 }
 
 pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
index 302ec08db6f26751918c3bd0b7fa36712e850dcc..cdf7f6ef9b6b68e9445f70b24dd2f502042b4fd2 100644 (file)
@@ -728,7 +728,7 @@ pub fn autoderef(expr_id: ast::NodeId, autoderef: u32) -> MethodCall {
 
 // maps from an expression id that corresponds to a method call to the details
 // of the method to be invoked
-pub type MethodMap<'tcx> = RefCell<FnvHashMap<MethodCall, MethodCallee<'tcx>>>;
+pub type MethodMap<'tcx> = FnvHashMap<MethodCall, MethodCallee<'tcx>>;
 
 // Contains information needed to resolve types and (in the future) look up
 // the types of AST nodes.
@@ -815,6 +815,48 @@ pub struct CommonTypes<'tcx> {
     pub err: Ty<'tcx>,
 }
 
+pub struct Tables<'tcx> {
+    /// Stores the types for various nodes in the AST.  Note that this table
+    /// is not guaranteed to be populated until after typeck.  See
+    /// typeck::check::fn_ctxt for details.
+    pub node_types: NodeMap<Ty<'tcx>>,
+
+    /// Stores the type parameters which were substituted to obtain the type
+    /// of this node.  This only applies to nodes that refer to entities
+    /// parameterized by type parameters, such as generic fns, types, or
+    /// other items.
+    pub item_substs: NodeMap<ItemSubsts<'tcx>>,
+
+    pub adjustments: NodeMap<ty::AutoAdjustment<'tcx>>,
+
+    pub method_map: MethodMap<'tcx>,
+
+    /// Borrows
+    pub upvar_capture_map: UpvarCaptureMap,
+
+    /// Records the type of each closure. The def ID is the ID of the
+    /// expression defining the closure.
+    pub closure_tys: DefIdMap<ClosureTy<'tcx>>,
+
+    /// Records the type of each closure. The def ID is the ID of the
+    /// expression defining the closure.
+    pub closure_kinds: DefIdMap<ClosureKind>,
+}
+
+impl<'tcx> Tables<'tcx> {
+    pub fn empty() -> Tables<'tcx> {
+        Tables {
+            node_types: FnvHashMap(),
+            item_substs: NodeMap(),
+            adjustments: NodeMap(),
+            method_map: FnvHashMap(),
+            upvar_capture_map: FnvHashMap(),
+            closure_tys: DefIdMap(),
+            closure_kinds: DefIdMap(),
+        }
+    }
+}
+
 /// The data structure to keep track of all the information that typechecker
 /// generates so that so that it can be reused and doesn't have to be redone
 /// later on.
@@ -850,17 +892,9 @@ pub struct ctxt<'tcx> {
     // borrowck. (They are not used during trans, and hence are not
     // serialized or needed for cross-crate fns.)
     free_region_maps: RefCell<NodeMap<FreeRegionMap>>,
+    // FIXME: jroesch make this a refcell
 
-    /// Stores the types for various nodes in the AST.  Note that this table
-    /// is not guaranteed to be populated until after typeck.  See
-    /// typeck::check::fn_ctxt for details.
-    node_types: RefCell<NodeMap<Ty<'tcx>>>,
-
-    /// Stores the type parameters which were substituted to obtain the type
-    /// of this node.  This only applies to nodes that refer to entities
-    /// parameterized by type parameters, such as generic fns, types, or
-    /// other items.
-    pub item_substs: RefCell<NodeMap<ItemSubsts<'tcx>>>,
+    pub tables: RefCell<Tables<'tcx>>,
 
     /// Maps from a trait item to the trait item "descriptor"
     pub impl_or_trait_items: RefCell<DefIdMap<ImplOrTraitItem<'tcx>>>,
@@ -894,7 +928,6 @@ pub struct ctxt<'tcx> {
     pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
     pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
     pub ty_param_defs: RefCell<NodeMap<TypeParameterDef<'tcx>>>,
-    pub adjustments: RefCell<NodeMap<AutoAdjustment<'tcx>>>,
     pub normalized_cache: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
     pub lang_items: middle::lang_items::LanguageItems,
     /// A mapping of fake provided method def_ids to the default implementation
@@ -944,26 +977,13 @@ pub struct ctxt<'tcx> {
     /// FIXME(arielb1): why is this separate from populated_external_types?
     pub populated_external_primitive_impls: RefCell<DefIdSet>,
 
-    /// Borrows
-    pub upvar_capture_map: RefCell<UpvarCaptureMap>,
-
     /// These caches are used by const_eval when decoding external constants.
     pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
     pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
     pub extern_const_fns: RefCell<DefIdMap<ast::NodeId>>,
 
-    pub method_map: MethodMap<'tcx>,
-
     pub dependency_formats: RefCell<dependency_format::Dependencies>,
 
-    /// Records the type of each closure. The def ID is the ID of the
-    /// expression defining the closure.
-    pub closure_kinds: RefCell<DefIdMap<ClosureKind>>,
-
-    /// Records the type of each closure. The def ID is the ID of the
-    /// expression defining the closure.
-    pub closure_tys: RefCell<DefIdMap<ClosureTy<'tcx>>>,
-
     pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId, lint::LintId),
                                               lint::LevelSource>>,
 
@@ -1000,9 +1020,16 @@ pub struct ctxt<'tcx> {
 }
 
 impl<'tcx> ctxt<'tcx> {
-    pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> { self.node_types.borrow() }
+    pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> {
+        fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) ->  &'a NodeMap<Ty<'tcx>> {
+            &tables.node_types
+        }
+
+        Ref::map(self.tables.borrow(), projection)
+    }
+
     pub fn node_type_insert(&self, id: NodeId, ty: Ty<'tcx>) {
-        self.node_types.borrow_mut().insert(id, ty);
+        self.tables.borrow_mut().node_types.insert(id, ty);
     }
 
     pub fn intern_trait_def(&self, def: TraitDef<'tcx>) -> &'tcx TraitDef<'tcx> {
@@ -3195,6 +3222,84 @@ fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
     }
 }
 
+/// Create a type context and call the closure with a `&ty::ctxt` reference
+/// to the context. The closure enforces that the type context and any interned
+/// value (types, substs, etc.) can only be used while `ty::tls` has a valid
+/// reference to the context, to allow formatting values that need it.
+pub fn with_ctxt<'tcx, F, R>(s: Session,
+                             arenas: &'tcx CtxtArenas<'tcx>,
+                             def_map: DefMap,
+                             named_region_map: resolve_lifetime::NamedRegionMap,
+                             map: ast_map::Map<'tcx>,
+                             freevars: RefCell<FreevarMap>,
+                             region_maps: RegionMaps,
+                             lang_items: middle::lang_items::LanguageItems,
+                             stability: stability::Index<'tcx>,
+                             f: F) -> (Session, R)
+                             where F: FnOnce(&ctxt<'tcx>) -> R
+{
+    let mut interner = FnvHashMap();
+    let common_types = CommonTypes::new(&arenas.type_, &mut interner);
+
+    tls::enter(ctxt {
+        arenas: arenas,
+        interner: RefCell::new(interner),
+        substs_interner: RefCell::new(FnvHashMap()),
+        bare_fn_interner: RefCell::new(FnvHashMap()),
+        region_interner: RefCell::new(FnvHashMap()),
+        stability_interner: RefCell::new(FnvHashMap()),
+        types: common_types,
+        named_region_map: named_region_map,
+        region_maps: region_maps,
+        free_region_maps: RefCell::new(FnvHashMap()),
+        item_variance_map: RefCell::new(DefIdMap()),
+        variance_computed: Cell::new(false),
+        sess: s,
+        def_map: def_map,
+        tables: RefCell::new(Tables::empty()),
+        impl_trait_refs: RefCell::new(DefIdMap()),
+        trait_defs: RefCell::new(DefIdMap()),
+        predicates: RefCell::new(DefIdMap()),
+        super_predicates: RefCell::new(DefIdMap()),
+        fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()),
+        map: map,
+        freevars: freevars,
+        tcache: RefCell::new(DefIdMap()),
+        rcache: RefCell::new(FnvHashMap()),
+        tc_cache: RefCell::new(FnvHashMap()),
+        ast_ty_to_ty_cache: RefCell::new(NodeMap()),
+        enum_var_cache: RefCell::new(DefIdMap()),
+        impl_or_trait_items: RefCell::new(DefIdMap()),
+        trait_item_def_ids: RefCell::new(DefIdMap()),
+        trait_items_cache: RefCell::new(DefIdMap()),
+        ty_param_defs: RefCell::new(NodeMap()),
+        normalized_cache: RefCell::new(FnvHashMap()),
+        lang_items: lang_items,
+        provided_method_sources: RefCell::new(DefIdMap()),
+        struct_fields: RefCell::new(DefIdMap()),
+        destructor_for_type: RefCell::new(DefIdMap()),
+        destructors: RefCell::new(DefIdSet()),
+        inherent_impls: RefCell::new(DefIdMap()),
+        impl_items: RefCell::new(DefIdMap()),
+        used_unsafe: RefCell::new(NodeSet()),
+        used_mut_nodes: RefCell::new(NodeSet()),
+        populated_external_types: RefCell::new(DefIdSet()),
+        populated_external_primitive_impls: RefCell::new(DefIdSet()),
+        extern_const_statics: RefCell::new(DefIdMap()),
+        extern_const_variants: RefCell::new(DefIdMap()),
+        extern_const_fns: RefCell::new(DefIdMap()),
+        dependency_formats: RefCell::new(FnvHashMap()),
+        node_lint_levels: RefCell::new(FnvHashMap()),
+        transmute_restrictions: RefCell::new(Vec::new()),
+        stability: RefCell::new(stability),
+        selection_cache: traits::SelectionCache::new(),
+        repr_hint_cache: RefCell::new(DefIdMap()),
+        const_qualif_map: RefCell::new(NodeMap()),
+        custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
+        cast_kinds: RefCell::new(NodeMap()),
+   }, f)
+}
+
 struct FlagComputation {
     flags: TypeFlags,
 
@@ -3421,8 +3526,7 @@ pub fn create_and_enter<F, R>(s: Session,
             variance_computed: Cell::new(false),
             sess: s,
             def_map: def_map,
-            node_types: RefCell::new(FnvHashMap()),
-            item_substs: RefCell::new(NodeMap()),
+            tables: RefCell::new(Tables::empty()),
             impl_trait_refs: RefCell::new(DefIdMap()),
             trait_defs: RefCell::new(DefIdMap()),
             predicates: RefCell::new(DefIdMap()),
@@ -3439,7 +3543,6 @@ pub fn create_and_enter<F, R>(s: Session,
             trait_item_def_ids: RefCell::new(DefIdMap()),
             trait_items_cache: RefCell::new(DefIdMap()),
             ty_param_defs: RefCell::new(NodeMap()),
-            adjustments: RefCell::new(NodeMap()),
             normalized_cache: RefCell::new(FnvHashMap()),
             lang_items: lang_items,
             provided_method_sources: RefCell::new(DefIdMap()),
@@ -3452,14 +3555,10 @@ pub fn create_and_enter<F, R>(s: Session,
             used_mut_nodes: RefCell::new(NodeSet()),
             populated_external_types: RefCell::new(DefIdSet()),
             populated_external_primitive_impls: RefCell::new(DefIdSet()),
-            upvar_capture_map: RefCell::new(FnvHashMap()),
             extern_const_statics: RefCell::new(DefIdMap()),
             extern_const_variants: RefCell::new(DefIdMap()),
             extern_const_fns: RefCell::new(DefIdMap()),
-            method_map: RefCell::new(FnvHashMap()),
             dependency_formats: RefCell::new(FnvHashMap()),
-            closure_kinds: RefCell::new(DefIdMap()),
-            closure_tys: RefCell::new(DefIdMap()),
             node_lint_levels: RefCell::new(FnvHashMap()),
             transmute_restrictions: RefCell::new(Vec::new()),
             stability: RefCell::new(stability),
@@ -3515,7 +3614,7 @@ pub fn mk_region(&self, region: Region) -> &'tcx Region {
     }
 
     pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
-        *self.closure_kinds.borrow().get(&def_id).unwrap()
+        *self.tables.borrow().closure_kinds.get(&def_id).unwrap()
     }
 
     pub fn closure_type(&self,
@@ -3523,7 +3622,7 @@ pub fn closure_type(&self,
                         substs: &subst::Substs<'tcx>)
                         -> ty::ClosureTy<'tcx>
     {
-        self.closure_tys.borrow().get(&def_id).unwrap().subst(self, substs)
+        self.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self, substs)
     }
 
     pub fn type_parameter_def(&self,
@@ -4369,7 +4468,7 @@ fn impls_bound<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
                        span: Span)
                        -> bool
     {
-        let infcx = infer::new_infer_ctxt(param_env.tcx());
+        let infcx = infer::new_infer_ctxt(param_env.tcx(), Some(param_env.clone()));
 
         let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env,
                                                                 self, bound, span);
@@ -5276,11 +5375,11 @@ pub fn node_id_to_type(&self, id: ast::NodeId) -> Ty<'tcx> {
     }
 
     pub fn node_id_to_type_opt(&self, id: ast::NodeId) -> Option<Ty<'tcx>> {
-        self.node_types.borrow().get(&id).cloned()
+        self.tables.borrow().node_types.get(&id).cloned()
     }
 
     pub fn node_id_item_substs(&self, id: ast::NodeId) -> ItemSubsts<'tcx> {
-        match self.item_substs.borrow().get(&id) {
+        match self.tables.borrow().item_substs.get(&id) {
             None => ItemSubsts::empty(),
             Some(ts) => ts.clone(),
         }
@@ -5325,9 +5424,9 @@ pub fn expr_ty_opt(&self, expr: &ast::Expr) -> Option<Ty<'tcx>> {
     pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
         self.expr_ty(expr)
             .adjust(self, expr.span, expr.id,
-                    self.adjustments.borrow().get(&expr.id),
+                    self.tables.borrow().adjustments.get(&expr.id),
                     |method_call| {
-            self.method_map.borrow().get(&method_call).map(|method| method.ty)
+            self.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
         })
     }
 
@@ -6671,11 +6770,11 @@ pub fn construct_parameter_environment<'a>(&'a self,
     }
 
     pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool {
-        self.method_map.borrow().contains_key(&MethodCall::expr(expr_id))
+        self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id))
     }
 
     pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
-        Some(self.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
+        Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
     }
 }
 
@@ -6689,17 +6788,21 @@ fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
     }
 
     fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
-        self.tcx.method_map.borrow().get(&method_call).map(|method| method.ty)
+        self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
     }
 
     fn node_method_origin(&self, method_call: ty::MethodCall)
                           -> Option<ty::MethodOrigin<'tcx>>
     {
-        self.tcx.method_map.borrow().get(&method_call).map(|method| method.origin.clone())
+        self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.origin.clone())
     }
 
-    fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
-        &self.tcx.adjustments
+    fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
+        fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
+            &tables.adjustments
+        }
+
+        Ref::map(self.tcx.tables.borrow(), projection)
     }
 
     fn is_method_call(&self, id: ast::NodeId) -> bool {
index dcdf457965efa054a9ca5df60cdd02ee3301f81f..de2f33e8a4ac9dd3233639804f2428759eec7e17 100644 (file)
@@ -688,7 +688,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             TyStr => write!(f, "str"),
             TyClosure(ref did, substs) => ty::tls::with(|tcx| {
                 try!(write!(f, "[closure"));
-                let closure_tys = tcx.closure_tys.borrow();
+                let closure_tys = &tcx.tables.borrow().closure_tys;
                 try!(closure_tys.get(did).map(|cty| &cty.sig).and_then(|sig| {
                     tcx.lift(&substs).map(|substs| sig.subst(tcx, substs))
                 }).map(|sig| {
index 8fe07da157970dd04a9d2000e8e04ea6e6825b8d..db48608823d216e1f8278a79b08e4cab0d2cd447 100644 (file)
@@ -1446,7 +1446,7 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
             _ => return
         }
 
-        if let Some(adjustment) = cx.tcx.adjustments.borrow().get(&e.id) {
+        if let Some(adjustment) = cx.tcx.tables.borrow().adjustments.get(&e.id) {
             if let ty::AdjustDerefRef(ty::AutoDerefRef { ref autoref, .. }) = *adjustment {
                 match autoref {
                     &Some(ty::AutoPtr(_, ast::MutImmutable)) => {
@@ -1984,7 +1984,7 @@ fn id_refers_to_this_method<'tcx>(tcx: &ty::ctxt<'tcx>,
                                           method_id: ast::NodeId,
                                           method_name: ast::Ident,
                                           id: ast::NodeId) -> bool {
-            let did = match tcx.method_map.borrow().get(&ty::MethodCall::expr(id)) {
+            let did = match tcx.tables.borrow().method_map.get(&ty::MethodCall::expr(id)) {
                 None => return false,
                 Some(m) => match m.origin {
                     // There's no way to know if a method call via a
index 24803562fa3734fffef5be24fa77caf5d2b4ad42..239141df9e8c7be7274d0fd8742aab53daa83a05 100644 (file)
@@ -904,7 +904,7 @@ fn visit_expr(&mut self, expr: &ast::Expr) {
             }
             ast::ExprMethodCall(ident, _, _) => {
                 let method_call = MethodCall::expr(expr.id);
-                match self.tcx.method_map.borrow().get(&method_call) {
+                match self.tcx.tables.borrow().method_map.get(&method_call) {
                     None => {
                         self.tcx.sess.span_bug(expr.span,
                                                 "method call not in \
index bb7e95cd4ae44d7eb4db5f05c0c62d4953a35286..dc692b0e765dd5e9949a920067bdf687ebc99bc4 100644 (file)
@@ -43,6 +43,7 @@
 #![feature(unicode)]
 #![feature(unicode)]
 #![feature(vec_push_all)]
+#![feature(cell_extras)]
 
 #![allow(trivial_casts)]
 
index 5ddad0e1947e83eda92f508ace6a8398ebdd6424..d86242f39cea7763e94e9d3ebff435a0402059f4 100644 (file)
@@ -886,7 +886,7 @@ fn process_struct_lit(&mut self,
     fn process_method_call(&mut self,
                            ex: &ast::Expr,
                            args: &Vec<P<ast::Expr>>) {
-        let method_map = self.tcx.method_map.borrow();
+        let method_map = &self.tcx.tables.borrow().method_map;
         let method_callee = method_map.get(&ty::MethodCall::expr(ex.id)).unwrap();
         let (def_id, decl_id) = match method_callee.origin {
             ty::MethodStatic(def_id) |
index f035b32e3596df0c30544ccffd4d12d3b2856c71..0cd6bbad03aa9206dfbc3789c62f0f15277e89ac 100644 (file)
@@ -212,7 +212,7 @@ pub fn self_type_for_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 }
 
 pub fn kind_for_closure(ccx: &CrateContext, closure_id: ast::DefId) -> ty::ClosureKind {
-    *ccx.tcx().closure_kinds.borrow().get(&closure_id).unwrap()
+    *ccx.tcx().tables.borrow().closure_kinds.get(&closure_id).unwrap()
 }
 
 pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId,
index 24abe0ed3fdd2f7c36867bd704e2a12987ff0b3a..dfe807d6c9152012511317d7a797587c6269f2cd 100644 (file)
@@ -518,7 +518,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
             let ref_ty = match node {
                 ExprId(id) => tcx.node_id_to_type(id),
                 MethodCallKey(method_call) => {
-                    tcx.method_map.borrow().get(&method_call).unwrap().ty
+                    tcx.tables.borrow().method_map.get(&method_call).unwrap().ty
                 }
             };
             let ref_ty = monomorphize::apply_param_substs(tcx,
@@ -610,7 +610,7 @@ pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("trans_method_call");
     debug!("trans_method_call(call_expr={:?})", call_expr);
     let method_call = MethodCall::expr(call_expr.id);
-    let method_ty = match bcx.tcx().method_map.borrow().get(&method_call) {
+    let method_ty = match bcx.tcx().tables.borrow().method_map.get(&method_call) {
         Some(method) => match method.origin {
             ty::MethodTraitObject(_) => match method.ty.sty {
                 ty::TyBareFn(_, ref fty) => {
index cb30bcdbf53996ed0dd26f587d1cfe7d16f9f436..b6378062855400c5b885961feede03c4ca34f11a 100644 (file)
@@ -130,7 +130,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
                                                       closure_id: ast::DefId,
                                                       substs: &Substs<'tcx>)
                                                       -> Option<Datum<'tcx, Rvalue>> {
-    if !ccx.tcx().closure_kinds.borrow().contains_key(&closure_id) {
+    if !ccx.tcx().tables.borrow().closure_kinds.contains_key(&closure_id) {
         // Not a closure.
         return None
     }
index 777b61f25f0ef1f0536c49ee5b11f9b5b4aa3684..dc8c92429615d189f7c7c206dd713592bff277c5 100644 (file)
@@ -47,7 +47,7 @@
 use arena::TypedArena;
 use libc::{c_uint, c_char};
 use std::ffi::CString;
-use std::cell::{Cell, RefCell};
+use std::cell::{Cell, RefCell, Ref};
 use std::result::Result as StdResult;
 use std::vec::Vec;
 use syntax::ast;
@@ -353,7 +353,7 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
     // section of the executable we're generating.
     pub llfn: ValueRef,
 
-    // always an empty parameter-environment
+    // always an empty parameter-environment NOTE: @jroesch another use of ParamEnv
     pub param_env: ty::ParameterEnvironment<'a, 'tcx>,
 
     // The environment argument in a closure.
@@ -630,8 +630,9 @@ fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
 
     fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
         self.tcx()
-            .method_map
+            .tables
             .borrow()
+            .method_map
             .get(&method_call)
             .map(|method| monomorphize_type(self, method.ty))
     }
@@ -640,18 +641,23 @@ fn node_method_origin(&self, method_call: ty::MethodCall)
                           -> Option<ty::MethodOrigin<'tcx>>
     {
         self.tcx()
-            .method_map
+            .tables
             .borrow()
+            .method_map
             .get(&method_call)
             .map(|method| method.origin.clone())
     }
 
-    fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
-        &self.tcx().adjustments
+    fn adjustments<'a>(&'a self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
+        fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
+            &tables.adjustments
+        }
+
+        Ref::map(self.tcx().tables.borrow(), project_adjustments)
     }
 
     fn is_method_call(&self, id: ast::NodeId) -> bool {
-        self.tcx().method_map.borrow().contains_key(&ty::MethodCall::expr(id))
+        self.tcx().tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
     }
 
     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
@@ -659,7 +665,7 @@ fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>
     }
 
     fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
-        Some(self.tcx().upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
+        Some(self.tcx().tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
     }
 
     fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
@@ -991,7 +997,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
            trait_ref, trait_ref.def_id());
 
     tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
-    let infcx = infer::new_infer_ctxt(tcx);
+    let infcx = infer::new_infer_ctxt(tcx, None);
 
     // Do the initial selection for the obligation. This yields the
     // shallow result we are looking for -- that is, what specific impl.
@@ -1053,7 +1059,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
            predicates);
 
     let tcx = ccx.tcx();
-    let infcx = infer::new_infer_ctxt(tcx);
+    let infcx = infer::new_infer_ctxt(tcx, None);
     let typer = NormalizingClosureTyper::new(tcx);
     let mut selcx = traits::SelectionContext::new(&infcx, &typer);
     let mut fulfill_cx = traits::FulfillmentContext::new(false);
@@ -1070,6 +1076,10 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok()
 }
 
+// NOTE: here is another use of parameter environment without an InferCtxt,
+// this is obviously related to the typer interface requiring a parameter env.
+// We should pay attention to this when refactoring
+// - @jroesch
 pub struct NormalizingClosureTyper<'a,'tcx:'a> {
     param_env: ty::ParameterEnvironment<'a, 'tcx>
 }
@@ -1191,7 +1201,7 @@ pub fn node_id_substs<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             tcx.node_id_item_substs(id).substs
         }
         MethodCallKey(method_call) => {
-            tcx.method_map.borrow().get(&method_call).unwrap().substs.clone()
+            tcx.tables.borrow().method_map.get(&method_call).unwrap().substs.clone()
         }
     };
 
index 8ec60000ee8425014f7385d3f2e0e410a68ca087..57af688ef60d7bea7af9e1a5d9f098fc2f64081a 100644 (file)
@@ -228,7 +228,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
             match def {
                 def::DefConst(def_id) | def::DefAssociatedConst(def_id, _) => {
-                    if !ccx.tcx().adjustments.borrow().contains_key(&expr.id) {
+                    if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
                         debug!("get_const_expr_as_global ({:?}): found const {:?}",
                                expr.id, def_id);
                         return get_const_val(ccx, def_id, expr);
@@ -281,7 +281,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let mut llconst = llconst;
     let mut ety_adjusted = monomorphize::apply_param_substs(cx.tcx(), param_substs,
                                                             &cx.tcx().expr_ty_adjusted(e));
-    let opt_adj = cx.tcx().adjustments.borrow().get(&e.id).cloned();
+    let opt_adj = cx.tcx().tables.borrow().adjustments.get(&e.id).cloned();
     match opt_adj {
         Some(ty::AdjustReifyFnPointer) => {
             // FIXME(#19925) once fn item types are
@@ -894,7 +894,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
           ast::ExprMethodCall(_, _, ref args) => {
               let arg_vals = map_list(args);
               let method_call = ty::MethodCall::expr(e.id);
-              let method_did = match cx.tcx().method_map.borrow()[&method_call].origin {
+              let method_did = match cx.tcx().tables.borrow().method_map[&method_call].origin {
                   ty::MethodStatic(did) => did,
                   _ => cx.sess().span_bug(e.span, "expected a const method def")
               };
index 8fd88055b8e45a58417999ed8567778b34680f66..045cc69bf954b26c357015ed0e80c5edce398d88 100644 (file)
@@ -117,7 +117,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
 
-    if bcx.tcx().adjustments.borrow().contains_key(&expr.id) {
+    if bcx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
         // use trans, which may be less efficient but
         // which will perform the adjustments:
         let datum = unpack_datum!(bcx, trans(bcx, expr));
@@ -345,7 +345,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 {
     let mut bcx = bcx;
     let mut datum = datum;
-    let adjustment = match bcx.tcx().adjustments.borrow().get(&expr.id).cloned() {
+    let adjustment = match bcx.tcx().tables.borrow().adjustments.get(&expr.id).cloned() {
         None => {
             return DatumBlock::new(bcx, datum);
         }
@@ -372,7 +372,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                     // Don't skip a conversion from Box<T> to &T, etc.
                     ty::TyRef(..) => {
                         let method_call = MethodCall::autoderef(expr.id, 0);
-                        if bcx.tcx().method_map.borrow().contains_key(&method_call) {
+                        if bcx.tcx().tables.borrow().method_map.contains_key(&method_call) {
                             // Don't skip an overloaded deref.
                             0
                         } else {
@@ -774,8 +774,9 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
     // Check for overloaded index.
     let method_ty = ccx.tcx()
-                       .method_map
+                       .tables
                        .borrow()
+                       .method_map
                        .get(&method_call)
                        .map(|method| method.ty);
     let elt_datum = match method_ty {
@@ -1617,7 +1618,7 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     // Otherwise, we should be in the RvalueDpsExpr path.
     assert!(
         op == ast::UnDeref ||
-        !ccx.tcx().method_map.borrow().contains_key(&method_call));
+        !ccx.tcx().tables.borrow().method_map.contains_key(&method_call));
 
     let un_ty = expr_ty(bcx, expr);
 
@@ -1910,7 +1911,7 @@ fn trans_binary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let ccx = bcx.ccx();
 
     // if overloaded, would be RvalueDpsExpr
-    assert!(!ccx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id)));
+    assert!(!ccx.tcx().tables.borrow().method_map.contains_key(&MethodCall::expr(expr.id)));
 
     match op.node {
         ast::BiAnd => {
@@ -1950,7 +1951,12 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                    dest: Option<Dest>,
                                    autoref: bool)
                                    -> Result<'blk, 'tcx> {
-    let method_ty = bcx.tcx().method_map.borrow().get(&method_call).unwrap().ty;
+    let method_ty = bcx.tcx()
+                       .tables
+                       .borrow()
+                       .method_map
+                       .get(&method_call).unwrap().ty;
+
     callee::trans_call_inner(bcx,
                              expr.debug_loc(),
                              monomorphize_type(bcx, method_ty),
@@ -1973,8 +1979,9 @@ fn trans_overloaded_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     debug!("trans_overloaded_call {}", expr.id);
     let method_call = MethodCall::expr(expr.id);
     let method_type = bcx.tcx()
-                         .method_map
+                         .tables
                          .borrow()
+                         .method_map
                          .get(&method_call)
                          .unwrap()
                          .ty;
@@ -2154,7 +2161,7 @@ fn trans_assign_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     debug!("trans_assign_op(expr={:?})", expr);
 
     // User-defined operator methods cannot be used with `+=` etc right now
-    assert!(!bcx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id)));
+    assert!(!bcx.tcx().tables.borrow().method_map.contains_key(&MethodCall::expr(expr.id)));
 
     // Evaluate LHS (destination), which should be an lvalue
     let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op"));
@@ -2229,8 +2236,12 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let mut bcx = bcx;
 
     // Check for overloaded deref.
-    let method_ty = ccx.tcx().method_map.borrow()
+    let method_ty = ccx.tcx()
+                       .tables
+                       .borrow()
+                       .method_map
                        .get(&method_call).map(|method| method.ty);
+
     let datum = match method_ty {
         Some(method_ty) => {
             let method_ty = monomorphize_type(bcx, method_ty);
@@ -2615,7 +2626,7 @@ enum ExprKind {
 }
 
 fn expr_kind(tcx: &ty::ctxt, expr: &ast::Expr) -> ExprKind {
-    if tcx.method_map.borrow().contains_key(&MethodCall::expr(expr.id)) {
+    if tcx.tables.borrow().method_map.contains_key(&MethodCall::expr(expr.id)) {
         // Overloaded operations are generally calls, and hence they are
         // generated via DPS, but there are a few exceptions:
         return match expr.node {
index a3e5b640fd0f1f5d022161f6dd5808e754f641a4..e46c3b5fab1f784e7a34ebbc55f5a3e4c44ca580 100644 (file)
@@ -109,11 +109,13 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("meth::trans_method_callee");
 
     let (origin, method_ty) =
-        bcx.tcx().method_map
-                 .borrow()
-                 .get(&method_call)
-                 .map(|method| (method.origin.clone(), method.ty))
-                 .unwrap();
+        bcx.tcx()
+           .tables
+           .borrow()
+           .method_map
+           .get(&method_call)
+           .map(|method| (method.origin.clone(), method.ty))
+           .unwrap();
 
     match origin {
         ty::MethodStatic(did) |
index cae810c9082e5f94a899cdd1881fa3040fa8764f..fa992511cc19beda817401ff739e752512f45fbc 100644 (file)
@@ -322,8 +322,9 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
     }
 
     // FIXME(#20304) -- cache
-
-    let infcx = infer::new_infer_ctxt(tcx);
+    // NOTE: @jroesch
+    // Here is of an example where we do not use a param_env but use a typer instead.
+    let infcx = infer::new_infer_ctxt(tcx, None);
     let typer = NormalizingClosureTyper::new(tcx);
     let mut selcx = traits::SelectionContext::new(&infcx, &typer);
     let cause = traits::ObligationCause::dummy();
index 7109e45b55279533f04b9d258ea690160f779e12..c2170686faccb1bedba4849b868e71d615a9239e 100644 (file)
@@ -324,7 +324,7 @@ fn write_overloaded_call_method_map<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                              call_expr: &ast::Expr,
                                              method_callee: ty::MethodCallee<'tcx>) {
     let method_call = ty::MethodCall::expr(call_expr.id);
-    fcx.inh.method_map.borrow_mut().insert(method_call, method_callee);
+    fcx.inh.tables.borrow_mut().method_map.insert(method_call, method_callee);
 }
 
 #[derive(Debug)]
index d431c0fda986580839723df4af652c241888c877..b5ee46ece94be16d505654aaa7dc5f7d68b6bf8b 100644 (file)
@@ -61,7 +61,7 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
         expected_sig);
 
     let closure_type = fcx.ccx.tcx.mk_closure(expr_def_id,
-        fcx.ccx.tcx.mk_substs(fcx.inh.param_env.free_substs.clone()));
+        fcx.ccx.tcx.mk_substs(fcx.inh.infcx.parameter_environment.free_substs.clone()));
 
     fcx.write_ty(expr.id, closure_type);
 
@@ -86,9 +86,9 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
            fn_ty.sig,
            opt_kind);
 
-    fcx.inh.closure_tys.borrow_mut().insert(expr_def_id, fn_ty);
+    fcx.inh.tables.borrow_mut().closure_tys.insert(expr_def_id, fn_ty);
     match opt_kind {
-        Some(kind) => { fcx.inh.closure_kinds.borrow_mut().insert(expr_def_id, kind); }
+        Some(kind) => { fcx.inh.tables.borrow_mut().closure_kinds.insert(expr_def_id, kind); }
         None => { }
     }
 }
index 349d1a8bb65a8e1a0feb9000c3330876bd78a474..dc8ef46a7ba6456aff6c13cf91d72b02f1427ee0 100644 (file)
@@ -43,7 +43,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
     debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}",
            impl_trait_ref);
 
-    let infcx = infer::new_infer_ctxt(tcx);
+    let mut infcx = infer::new_infer_ctxt(tcx, None);
     let mut fulfillment_cx = traits::FulfillmentContext::new(true);
 
     let trait_to_impl_substs = &impl_trait_ref.substs;
@@ -240,11 +240,13 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
     let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.into_vec());
     let trait_param_env = traits::normalize_param_env_or_error(trait_param_env,
                                                                normalize_cause.clone());
+    // TODO (@jroesch) this seems ugly, but is a temporary change
+    infcx.parameter_environment = trait_param_env;
 
     debug!("compare_impl_method: trait_bounds={:?}",
-        trait_param_env.caller_bounds);
+        infcx.parameter_environment.caller_bounds);
 
-    let mut selcx = traits::SelectionContext::new(&infcx, &trait_param_env);
+    let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment);
 
     for predicate in impl_pred.fns {
         let traits::Normalized { value: predicate, .. } =
@@ -345,7 +347,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
 
     // Check that all obligations are satisfied by the implementation's
     // version.
-    match fulfillment_cx.select_all_or_error(&infcx, &trait_param_env) {
+    match fulfillment_cx.select_all_or_error(&infcx, &infcx.parameter_environment) {
         Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors) }
         Ok(_) => {}
     }
@@ -360,7 +362,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
     // anyway, so it shouldn't be needed there either. Anyway, we can
     // always add more relations later (it's backwards compat).
     let mut free_regions = FreeRegionMap::new();
-    free_regions.relate_free_regions_from_predicates(tcx, &trait_param_env.caller_bounds);
+    free_regions.relate_free_regions_from_predicates(tcx, &infcx.parameter_environment.caller_bounds);
 
     infcx.resolve_regions_and_report_errors(&free_regions, impl_m_body_id);
 
@@ -416,7 +418,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>,
     debug!("compare_const_impl(impl_trait_ref={:?})",
            impl_trait_ref);
 
-    let infcx = infer::new_infer_ctxt(tcx);
+    let infcx = infer::new_infer_ctxt(tcx, None);
     let mut fulfillment_cx = traits::FulfillmentContext::new(true);
 
     // The below is for the most part highly similar to the procedure
index a48cffb4472f44d9d1664a18a3ade43d384b3d4d..4abfd84d8ef3c3d6c73549c2b719660c564ddb2a 100644 (file)
@@ -93,7 +93,8 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
                          ty: named_type } =
         tcx.lookup_item_type(self_type_did);
 
-    let infcx = infer::new_infer_ctxt(tcx);
+    let infcx = infer::new_infer_ctxt(tcx, None);
+    
     infcx.commit_if_ok(|snapshot| {
         let (named_type_to_skolem, skol_map) =
             infcx.construct_skolemized_subst(named_type_generics, snapshot);
index 5f7a78ec611a29e477b63679f49df5eb490cb1dd..5601888a1f0734265da956a8eaf4c3b36481a4b9 100644 (file)
@@ -488,8 +488,9 @@ fn fixup_derefs_on_method_receiver_if_necessary(&self,
             // Count autoderefs.
             let autoderef_count = match self.fcx
                                             .inh
-                                            .adjustments
+                                            .tables
                                             .borrow()
+                                            .adjustments
                                             .get(&expr.id) {
                 Some(&ty::AdjustDerefRef(ref adj)) => adj.autoderefs,
                 Some(_) | None => 0,
@@ -527,7 +528,7 @@ fn fixup_derefs_on_method_receiver_if_necessary(&self,
                         // expects. This is annoying and horrible. We
                         // ought to recode this routine so it doesn't
                         // (ab)use the normal type checking paths.
-                        let adj = self.fcx.inh.adjustments.borrow().get(&base_expr.id).cloned();
+                        let adj = self.fcx.inh.tables.borrow().adjustments.get(&base_expr.id).cloned();
                         let (autoderefs, unsize) = match adj {
                             Some(ty::AdjustDerefRef(adr)) => match adr.autoref {
                                 None => {
@@ -589,7 +590,7 @@ fn fixup_derefs_on_method_receiver_if_necessary(&self,
                         // if this is an overloaded deref, then re-evaluate with
                         // a preference for mut
                         let method_call = MethodCall::expr(expr.id);
-                        if self.fcx.inh.method_map.borrow().contains_key(&method_call) {
+                        if self.fcx.inh.tables.borrow().method_map.contains_key(&method_call) {
                             check::try_overloaded_deref(
                                 self.fcx,
                                 expr.span,
index 8026fce69ecca5a418d6e46b446fd300eb02b217..2cf041919147c67246ecd3555049139e161aca3f 100644 (file)
@@ -477,7 +477,7 @@ fn assemble_inherent_candidates_from_param(&mut self,
         // FIXME -- Do we want to commit to this behavior for param bounds?
 
         let bounds: Vec<_> =
-            self.fcx.inh.param_env.caller_bounds
+            self.fcx.inh.infcx.parameter_environment.caller_bounds
             .iter()
             .filter_map(|predicate| {
                 match *predicate {
@@ -742,7 +742,7 @@ fn assemble_closure_candidates(&mut self,
                 _ => continue,
             };
 
-            let closure_kinds = self.fcx.inh.closure_kinds.borrow();
+            let closure_kinds = &self.fcx.inh.tables.borrow().closure_kinds;
             let closure_kind = match closure_kinds.get(&closure_def_id) {
                 Some(&k) => k,
                 None => {
@@ -845,7 +845,7 @@ fn assemble_where_clause_candidates(&mut self,
         debug!("assemble_where_clause_candidates(trait_def_id={:?})",
                trait_def_id);
 
-        let caller_predicates = self.fcx.inh.param_env.caller_bounds.clone();
+        let caller_predicates = self.fcx.inh.infcx.parameter_environment.caller_bounds.clone();
         for poly_bound in traits::elaborate_predicates(self.tcx(), caller_predicates)
                           .filter_map(|p| p.to_opt_poly_trait_ref())
                           .filter(|b| b.def_id() == trait_def_id)
index 299ccd579ccb77130cd113dbf6e1864ab5aa7c46..058cbe020b7d6b5c79ae2f99954fdd8757687bf0 100644 (file)
@@ -97,7 +97,7 @@
 use middle::ty::{FnSig, GenericPredicates, TypeScheme};
 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
 use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
-use middle::ty::{MethodCall, MethodCallee, MethodMap};
+use middle::ty::{MethodCall, MethodCallee};
 use middle::ty_fold::{TypeFolder, TypeFoldable};
 use rscope::RegionScope;
 use session::Session;
 pub struct Inherited<'a, 'tcx: 'a> {
     infcx: infer::InferCtxt<'a, 'tcx>,
     locals: RefCell<NodeMap<Ty<'tcx>>>,
-    param_env: ty::ParameterEnvironment<'a, 'tcx>,
 
-    // Temporary tables:
-    node_types: RefCell<NodeMap<Ty<'tcx>>>,
-    item_substs: RefCell<NodeMap<ty::ItemSubsts<'tcx>>>,
-    adjustments: RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>,
-    method_map: MethodMap<'tcx>,
-    upvar_capture_map: RefCell<ty::UpvarCaptureMap>,
-    closure_tys: RefCell<DefIdMap<ty::ClosureTy<'tcx>>>,
-    closure_kinds: RefCell<DefIdMap<ty::ClosureKind>>,
+    tables: &'a RefCell<ty::Tables<'tcx>>,
 
     // A mapping from each fn's id to its signature, with all bound
     // regions replaced with free ones. Unlike the other tables, this
@@ -303,52 +295,68 @@ fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
         let ty = self.node_ty(id);
         self.resolve_type_vars_or_error(&ty)
     }
+
     fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
-        let ty = self.adjust_expr_ty(expr, self.inh.adjustments.borrow().get(&expr.id));
+        let ty = self.adjust_expr_ty(expr, self.inh.tables.borrow().adjustments.get(&expr.id));
         self.resolve_type_vars_or_error(&ty)
     }
+
     fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
         let ty = self.infcx().resolve_type_vars_if_possible(&ty);
         !traits::type_known_to_meet_builtin_bound(self.infcx(), self, ty, ty::BoundCopy, span)
     }
+
     fn node_method_ty(&self, method_call: ty::MethodCall)
                       -> Option<Ty<'tcx>> {
-        self.inh.method_map.borrow()
-                           .get(&method_call)
-                           .map(|method| method.ty)
-                           .map(|ty| self.infcx().resolve_type_vars_if_possible(&ty))
+        self.inh.tables
+                .borrow()
+                .method_map
+                .get(&method_call)
+                .map(|method| method.ty)
+                .map(|ty| self.infcx().resolve_type_vars_if_possible(&ty))
     }
+
     fn node_method_origin(&self, method_call: ty::MethodCall)
                           -> Option<ty::MethodOrigin<'tcx>>
     {
-        self.inh.method_map.borrow()
-                           .get(&method_call)
-                           .map(|method| method.origin.clone())
+        self.inh.tables
+                .borrow()
+                .method_map
+                .get(&method_call)
+                .map(|method| method.origin.clone())
     }
-    fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
-        &self.inh.adjustments
+
+    fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
+        fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
+            &tables.adjustments
+        }
+
+        Ref::map(self.inh.tables.borrow(), project_adjustments)
     }
+
     fn is_method_call(&self, id: ast::NodeId) -> bool {
-        self.inh.method_map.borrow().contains_key(&ty::MethodCall::expr(id))
+        self.inh.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
     }
+
     fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
         self.param_env().temporary_scope(rvalue_id)
     }
+
     fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
-        self.inh.upvar_capture_map.borrow().get(&upvar_id).cloned()
+        self.inh.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
     }
 }
 
 impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
     fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
-        &self.inh.param_env
+        &self.inh.infcx.parameter_environment
     }
 
     fn closure_kind(&self,
                     def_id: ast::DefId)
                     -> Option<ty::ClosureKind>
     {
-        self.inh.closure_kinds.borrow().get(&def_id).cloned()
+        self.inh.tables.borrow().closure_kinds.get(&def_id).cloned()
     }
 
     fn closure_type(&self,
@@ -356,7 +364,7 @@ fn closure_type(&self,
                     substs: &subst::Substs<'tcx>)
                     -> ty::ClosureTy<'tcx>
     {
-        self.inh.closure_tys.borrow().get(&def_id).unwrap().subst(self.tcx(), substs)
+        self.inh.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self.tcx(), substs)
     }
 
     fn closure_upvars(&self,
@@ -369,19 +377,14 @@ fn closure_upvars(&self,
 
 impl<'a, 'tcx> Inherited<'a, 'tcx> {
     fn new(tcx: &'a ty::ctxt<'tcx>,
+           tables: &'a RefCell<ty::Tables<'tcx>>,
            param_env: ty::ParameterEnvironment<'a, 'tcx>)
            -> Inherited<'a, 'tcx> {
+
         Inherited {
-            infcx: infer::new_infer_ctxt(tcx),
+            infcx: infer::new_infer_ctxt(tcx, Some(param_env)),
             locals: RefCell::new(NodeMap()),
-            param_env: param_env,
-            node_types: RefCell::new(NodeMap()),
-            item_substs: RefCell::new(NodeMap()),
-            adjustments: RefCell::new(NodeMap()),
-            method_map: RefCell::new(FnvHashMap()),
-            upvar_capture_map: RefCell::new(FnvHashMap()),
-            closure_tys: RefCell::new(DefIdMap()),
-            closure_kinds: RefCell::new(DefIdMap()),
+            tables: tables,
             fn_sig_map: RefCell::new(NodeMap()),
             fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(true)),
             deferred_call_resolutions: RefCell::new(DefIdMap()),
@@ -424,12 +427,12 @@ pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
     }
 }
 
-fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>)
+fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, tables: &'a RefCell<ty::Tables<'tcx>>)
                                     -> Inherited<'a, 'tcx> {
     // It's kind of a kludge to manufacture a fake function context
     // and statement context, but we might as well do write the code only once
     let param_env = ccx.tcx.empty_parameter_environment();
-    Inherited::new(ccx.tcx, param_env)
+    Inherited::new(ccx.tcx, &tables, param_env)
 }
 
 struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
@@ -504,16 +507,20 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 {
     match raw_fty.sty {
         ty::TyBareFn(_, ref fn_ty) => {
-            let inh = Inherited::new(ccx.tcx, param_env);
+            let tables = RefCell::new(ty::Tables::empty());
+            let inh = Inherited::new(ccx.tcx, &tables, param_env);
 
             // Compute the fty from point of view of inside fn.
             let fn_sig =
-                fn_ty.sig.subst(ccx.tcx, &inh.param_env.free_substs);
+                fn_ty.sig.subst(ccx.tcx, &inh.infcx.parameter_environment.free_substs);
             let fn_sig =
                 ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id),
                                                     &fn_sig);
             let fn_sig =
-                inh.normalize_associated_types_in(&inh.param_env, body.span, body.id, &fn_sig);
+                inh.normalize_associated_types_in(&inh.infcx.parameter_environment,
+                                                  body.span,
+                                                  body.id,
+                                                  &fn_sig);
 
             let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
                                decl, fn_id, body, &inh);
@@ -1198,7 +1205,7 @@ fn ensure_super_predicates(&self, _: Span, _: ast::DefId) -> Result<(), ErrorRep
     }
 
     fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
-        Some(&self.inh.param_env.free_substs)
+        Some(&self.inh.infcx.parameter_environment.free_substs)
     }
 
     fn get_type_parameter_bounds(&self,
@@ -1207,7 +1214,8 @@ fn get_type_parameter_bounds(&self,
                                  -> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
     {
         let def = self.tcx().type_parameter_def(node_id);
-        let r = self.inh.param_env.caller_bounds
+        let r = self.inh.infcx.parameter_environment
+                                  .caller_bounds
                                   .iter()
                                   .filter_map(|predicate| {
                                       match *predicate {
@@ -1273,7 +1281,7 @@ pub fn infcx(&self) -> &infer::InferCtxt<'a,'tcx> {
     }
 
     pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
-        &self.inh.param_env
+        &self.inh.infcx.parameter_environment
     }
 
     pub fn sess(&self) -> &Session {
@@ -1368,7 +1376,7 @@ pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> {
     /// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
     pub fn default_type_parameters(&self) {
         use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
-        for (_, &mut ref ty) in &mut *self.inh.node_types.borrow_mut() {
+        for (_, &mut ref ty) in &mut self.inh.tables.borrow_mut().node_types {
             let resolved = self.infcx().resolve_type_vars_if_possible(ty);
             if self.infcx().type_var_diverges(resolved) {
                 demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
@@ -1390,7 +1398,7 @@ pub fn default_type_parameters(&self) {
     pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
         debug!("write_ty({}, {:?}) in fcx {}",
                node_id, ty, self.tag());
-        self.inh.node_types.borrow_mut().insert(node_id, ty);
+        self.inh.tables.borrow_mut().node_types.insert(node_id, ty);
     }
 
     pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
@@ -1400,7 +1408,7 @@ pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
                    substs,
                    self.tag());
 
-            self.inh.item_substs.borrow_mut().insert(node_id, substs);
+            self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
         }
     }
 
@@ -1426,7 +1434,7 @@ pub fn write_adjustment(&self,
             return;
         }
 
-        self.inh.adjustments.borrow_mut().insert(node_id, adj);
+        self.inh.tables.borrow_mut().adjustments.insert(node_id, adj);
     }
 
     /// Basically whenever we are converting from a type scheme into
@@ -1627,7 +1635,7 @@ pub fn to_ty(&self, ast_t: &ast::Ty) -> Ty<'tcx> {
     }
 
     pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> {
-        match self.inh.node_types.borrow().get(&ex.id) {
+        match self.inh.tables.borrow().node_types.get(&ex.id) {
             Some(&t) => t,
             None => {
                 self.tcx().sess.bug(&format!("no type for expr in fcx {}",
@@ -1646,13 +1654,13 @@ pub fn adjust_expr_ty(&self,
         let raw_ty = self.infcx().shallow_resolve(raw_ty);
         let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
         raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
-            self.inh.method_map.borrow().get(&method_call)
+            self.inh.tables.borrow().method_map.get(&method_call)
                                         .map(|method| resolve_ty(method.ty))
         })
     }
 
     pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
-        match self.inh.node_types.borrow().get(&id) {
+        match self.inh.tables.borrow().node_types.get(&id) {
             Some(&t) => t,
             None if self.err_count_since_creation() != 0 => self.tcx().types.err,
             None => {
@@ -1665,7 +1673,13 @@ pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
     }
 
     pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
-        self.inh.item_substs.borrow()
+        // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if it changes
+        // when we upgrade the snapshot compiler
+        fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
+            &tables.item_substs
+        }
+
+        Ref::map(self.inh.tables.borrow(), project_item_susbts)
     }
 
     pub fn opt_node_ty_substs<F>(&self,
@@ -1673,7 +1687,7 @@ pub fn opt_node_ty_substs<F>(&self,
                                  f: F) where
         F: FnOnce(&ty::ItemSubsts<'tcx>),
     {
-        match self.inh.item_substs.borrow().get(&id) {
+        match self.inh.tables.borrow().item_substs.get(&id) {
             Some(s) => { f(s) }
             None => { }
         }
@@ -2039,7 +2053,7 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
 
             if let Some(method_call) = method_call {
-                fcx.inh.method_map.borrow_mut().insert(method_call, method);
+                fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
             }
 
             // method returns &T, but the type as visible to user is T, so deref
@@ -2640,7 +2654,7 @@ fn check_method_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
             Ok(method) => {
                 let method_ty = method.ty;
                 let method_call = MethodCall::expr(expr.id);
-                fcx.inh.method_map.borrow_mut().insert(method_call, method);
+                fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
                 method_ty
             }
             Err(error) => {
@@ -4074,7 +4088,8 @@ fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
                                 expr: &'tcx ast::Expr,
                                 expected_type: Ty<'tcx>) {
-    let inh = static_inherited_fields(ccx);
+    let tables = RefCell::new(ty::Tables::empty());
+    let inh = static_inherited_fields(ccx, &tables);
     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
     check_const_with_ty(&fcx, expr.span, expr, expected_type);
 }
@@ -4083,7 +4098,8 @@ fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                         sp: Span,
                         e: &'tcx ast::Expr,
                         id: ast::NodeId) {
-    let inh = static_inherited_fields(ccx);
+    let tables = RefCell::new(ty::Tables::empty());
+    let inh = static_inherited_fields(ccx, &tables);
     let rty = ccx.tcx.node_id_to_type(id);
     let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
     let declty = fcx.ccx.tcx.tcache.borrow().get(&local_def(id)).unwrap().ty;
@@ -4235,7 +4251,8 @@ fn do_check<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         let rty = ccx.tcx.node_id_to_type(id);
         let mut disr_vals: Vec<ty::Disr> = Vec::new();
 
-        let inh = static_inherited_fields(ccx);
+        let tables = RefCell::new(ty::Tables::empty());
+        let inh = static_inherited_fields(ccx, &tables);
         let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
 
         let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
index 5a114c811191cdfa4659424f6d1dcdd2ac6d4579..c419a986f95b189491811fe1a1476af6a0386798 100644 (file)
@@ -330,7 +330,7 @@ fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
 
             // HACK(eddyb) Fully qualified path to work around a resolve bug.
             let method_call = ::middle::ty::MethodCall::expr(expr.id);
-            fcx.inh.method_map.borrow_mut().insert(method_call, method);
+            fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
 
             // extract return type for method; all late bound regions
             // should have been instantiated by now
@@ -454,4 +454,3 @@ fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>,
         }
     }
 }
-
index 13961834aebdde4a63f6f0ef025d38169da199a2..8f8ec0f7264aa2f8dc965733b1212d35e80b60ec 100644 (file)
@@ -124,7 +124,7 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) {
 pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) {
     let mut rcx = Rcx::new(fcx, RepeatingScope(item.id), item.id, Subject(item.id));
     let tcx = fcx.tcx();
-    rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds);
+    rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.infcx.parameter_environment.caller_bounds);
     rcx.visit_region_obligations(item.id);
     rcx.resolve_regions_and_report_errors();
 }
@@ -143,7 +143,7 @@ pub fn regionck_fn(fcx: &FnCtxt,
     }
 
     let tcx = fcx.tcx();
-    rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds);
+    rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.infcx.parameter_environment.caller_bounds);
 
     rcx.resolve_regions_and_report_errors();
 
@@ -254,7 +254,7 @@ fn resolve_node_type(&self, id: ast::NodeId) -> Ty<'tcx> {
     }
 
     fn resolve_method_type(&self, method_call: MethodCall) -> Option<Ty<'tcx>> {
-        let method_ty = self.fcx.inh.method_map.borrow()
+        let method_ty = self.fcx.inh.tables.borrow().method_map
                             .get(&method_call).map(|method| method.ty);
         method_ty.map(|method_ty| self.resolve_type(method_ty))
     }
@@ -267,7 +267,7 @@ pub fn resolve_expr_type_adjusted(&mut self, expr: &ast::Expr) -> Ty<'tcx> {
         } else {
             ty_unadjusted.adjust(
                 self.fcx.tcx(), expr.span, expr.id,
-                self.fcx.inh.adjustments.borrow().get(&expr.id),
+                self.fcx.inh.tables.borrow().adjustments.get(&expr.id),
                 |method_call| self.resolve_method_type(method_call))
         }
     }
@@ -511,12 +511,13 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
                       expr_ty, ty::ReScope(CodeExtent::from_node_id(expr.id)));
 
     let method_call = MethodCall::expr(expr.id);
-    let has_method_map = rcx.fcx.inh.method_map.borrow().contains_key(&method_call);
+    let has_method_map = rcx.fcx.inh.tables.borrow().method_map.contains_key(&method_call);
 
     // Check any autoderefs or autorefs that appear.
-    if let Some(adjustment) = rcx.fcx.inh.adjustments.borrow().get(&expr.id) {
+    let adjustment = rcx.fcx.inh.tables.borrow().adjustments.get(&expr.id).map(|a| a.clone());
+    if let Some(adjustment) = adjustment {
         debug!("adjustment={:?}", adjustment);
-        match *adjustment {
+        match adjustment {
             ty::AdjustDerefRef(ty::AutoDerefRef {autoderefs, ref autoref, ..}) => {
                 let expr_ty = rcx.resolve_node_type(expr.id);
                 constrain_autoderefs(rcx, expr, autoderefs, expr_ty);
@@ -657,7 +658,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
         ast::ExprUnary(ast::UnDeref, ref base) => {
             // For *a, the lifetime of a must enclose the deref
             let method_call = MethodCall::expr(expr.id);
-            let base_ty = match rcx.fcx.inh.method_map.borrow().get(&method_call) {
+            let base_ty = match rcx.fcx.inh.tables.borrow().method_map.get(&method_call) {
                 Some(method) => {
                     constrain_call(rcx, expr, Some(&**base),
                                    None::<ast::Expr>.iter(), true);
@@ -884,7 +885,9 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
         let method_call = MethodCall::autoderef(deref_expr.id, i as u32);
         debug!("constrain_autoderefs: method_call={:?} (of {:?} total)", method_call, derefs);
 
-        derefd_ty = match rcx.fcx.inh.method_map.borrow().get(&method_call) {
+        let method = rcx.fcx.inh.tables.borrow().method_map.get(&method_call).map(|m| m.clone());
+
+        derefd_ty = match method {
             Some(method) => {
                 debug!("constrain_autoderefs: #{} is overloaded, method={:?}",
                        i, method);
@@ -1018,7 +1021,7 @@ fn type_of_node_must_outlive<'a, 'tcx>(
     // report errors later on in the writeback phase.
     let ty0 = rcx.resolve_node_type(id);
     let ty = ty0.adjust(tcx, origin.span(), id,
-                        rcx.fcx.inh.adjustments.borrow().get(&id),
+                        rcx.fcx.inh.tables.borrow().adjustments.get(&id),
                         |method_call| rcx.resolve_method_type(method_call));
     debug!("constrain_regions_in_type_of_node(\
             ty={}, ty0={}, id={}, minimum_lifetime={:?})",
@@ -1292,7 +1295,7 @@ fn link_reborrowed_region<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
     // Detect by-ref upvar `x`:
     let cause = match note {
         mc::NoteUpvarRef(ref upvar_id) => {
-            let upvar_capture_map = rcx.fcx.inh.upvar_capture_map.borrow_mut();
+            let upvar_capture_map = &rcx.fcx.inh.tables.borrow_mut().upvar_capture_map;
             match upvar_capture_map.get(upvar_id) {
                 Some(&ty::UpvarCapture::ByRef(ref upvar_borrow)) => {
                     // The mutability of the upvar may have been modified
@@ -1453,7 +1456,7 @@ fn generic_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
                                   origin: infer::SubregionOrigin<'tcx>,
                                   region: ty::Region,
                                   generic: &GenericKind<'tcx>) {
-    let param_env = &rcx.fcx.inh.param_env;
+    let param_env = &rcx.fcx.inh.infcx.parameter_environment;
 
     debug!("param_must_outlive(region={:?}, generic={:?})",
            region,
index 1345f322476b9789a73488a25d9b6baf5a47932f..db32b29ebab81aca0ae8ba325b7d36998877c91c 100644 (file)
@@ -129,9 +129,9 @@ fn check_closure(&mut self,
                      _body: &ast::Block)
     {
         let closure_def_id = ast_util::local_def(expr.id);
-        if !self.fcx.inh.closure_kinds.borrow().contains_key(&closure_def_id) {
+        if !self.fcx.inh.tables.borrow().closure_kinds.contains_key(&closure_def_id) {
             self.closures_with_inferred_kinds.insert(expr.id);
-            self.fcx.inh.closure_kinds.borrow_mut().insert(closure_def_id, ty::FnClosureKind);
+            self.fcx.inh.tables.borrow_mut().closure_kinds.insert(closure_def_id, ty::FnClosureKind);
             debug!("check_closure: adding closure_id={:?} to closures_with_inferred_kinds",
                    closure_def_id);
         }
@@ -156,7 +156,7 @@ fn check_closure(&mut self,
                     }
                 };
 
-                self.fcx.inh.upvar_capture_map.borrow_mut().insert(upvar_id, capture_kind);
+                self.fcx.inh.tables.borrow_mut().upvar_capture_map.insert(upvar_id, capture_kind);
             }
         });
     }
@@ -267,7 +267,7 @@ fn adjust_upvar_borrow_kind_for_consume(&self,
                         // to move out of an upvar, this must be a FnOnce closure
                         self.adjust_closure_kind(upvar_id.closure_expr_id, ty::FnOnceClosureKind);
 
-                        let mut upvar_capture_map = self.fcx.inh.upvar_capture_map.borrow_mut();
+                        let upvar_capture_map = &mut self.fcx.inh.tables.borrow_mut().upvar_capture_map;
                         upvar_capture_map.insert(upvar_id, ty::UpvarCapture::ByValue);
                     }
                     mc::NoteClosureEnv(upvar_id) => {
@@ -374,9 +374,11 @@ fn try_adjust_upvar_deref(&self,
                 // upvar, then we need to modify the
                 // borrow_kind of the upvar to make sure it
                 // is inferred to mutable if necessary
-                let mut upvar_capture_map = self.fcx.inh.upvar_capture_map.borrow_mut();
-                let ub = upvar_capture_map.get_mut(&upvar_id).unwrap();
-                self.adjust_upvar_borrow_kind(upvar_id, ub, borrow_kind);
+                {
+                    let upvar_capture_map = &mut self.fcx.inh.tables.borrow_mut().upvar_capture_map;
+                    let ub = upvar_capture_map.get_mut(&upvar_id).unwrap();
+                    self.adjust_upvar_borrow_kind(upvar_id, ub, borrow_kind);
+                }
 
                 // also need to be in an FnMut closure since this is not an ImmBorrow
                 self.adjust_closure_kind(upvar_id.closure_expr_id, ty::FnMutClosureKind);
@@ -442,7 +444,7 @@ fn adjust_closure_kind(&self,
         }
 
         let closure_def_id = ast_util::local_def(closure_id);
-        let mut closure_kinds = self.fcx.inh.closure_kinds.borrow_mut();
+        let closure_kinds = &mut self.fcx.inh.tables.borrow_mut().closure_kinds;
         let existing_kind = *closure_kinds.get(&closure_def_id).unwrap();
 
         debug!("adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}",
index 00bbbafd5cd32922dd60593ae1ee5404d3cb7304..c2852e425b6f9cd0ab291e14e8f77594d21f558e 100644 (file)
@@ -18,6 +18,7 @@
 use middle::ty::{self, Ty};
 use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty};
 
+use std::cell::RefCell;
 use std::collections::HashSet;
 use syntax::ast;
 use syntax::ast_util::local_def;
@@ -143,7 +144,8 @@ fn with_fcx<F>(&mut self, item: &ast::Item, mut f: F) where
                                                                 &type_scheme.generics,
                                                                 &type_predicates,
                                                                 item.id);
-        let inh = Inherited::new(ccx.tcx, param_env);
+        let tables = RefCell::new(ty::Tables::empty());
+        let inh = Inherited::new(ccx.tcx, &tables, param_env);
         let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id);
         f(self, &fcx);
         fcx.select_all_obligations_or_error();
@@ -199,7 +201,7 @@ fn check_item_type(&mut self,
 
             let type_scheme = fcx.tcx().lookup_item_type(local_def(item.id));
             let item_ty = fcx.instantiate_type_scheme(item.span,
-                                                      &fcx.inh.param_env.free_substs,
+                                                      &fcx.inh.infcx.parameter_environment.free_substs,
                                                       &type_scheme.ty);
 
             bounds_checker.check_traits_in_ty(item_ty, item.span);
@@ -220,7 +222,7 @@ fn check_impl(&mut self,
             // to free.
             let self_ty = fcx.tcx().node_id_to_type(item.id);
             let self_ty = fcx.instantiate_type_scheme(item.span,
-                                                      &fcx.inh.param_env.free_substs,
+                                                      &fcx.inh.infcx.parameter_environment.free_substs,
                                                       &self_ty);
 
             bounds_checker.check_traits_in_ty(self_ty, item.span);
@@ -233,7 +235,7 @@ fn check_impl(&mut self,
             };
 
             let trait_ref = fcx.instantiate_type_scheme(item.span,
-                                                        &fcx.inh.param_env.free_substs,
+                                                        &fcx.inh.infcx.parameter_environment.free_substs,
                                                         &trait_ref);
 
             // We are stricter on the trait-ref in an impl than the
@@ -635,7 +637,7 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         .map(|field| {
             let field_ty = fcx.tcx().node_id_to_type(field.node.id);
             let field_ty = fcx.instantiate_type_scheme(field.span,
-                                                       &fcx.inh.param_env.free_substs,
+                                                       &fcx.inh.infcx.parameter_environment.free_substs,
                                                        &field_ty);
             AdtField { ty: field_ty, span: field.span }
         })
@@ -660,7 +662,7 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                             let arg_ty = arg_tys[index];
                             let arg_ty =
                                 fcx.instantiate_type_scheme(variant.span,
-                                                            &fcx.inh.param_env.free_substs,
+                                                            &fcx.inh.infcx.parameter_environment.free_substs,
                                                             &arg_ty);
                             AdtField {
                                 ty: arg_ty,
index 29119f3b5946dcc8de5a0a3fb4ae1a94abf73187..d990697949659f4887ed9fbe07d8f2505c392395 100644 (file)
@@ -96,14 +96,14 @@ fn fix_scalar_binary_expr(&mut self, e: &ast::Expr) {
             let rhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&rhs_ty);
 
             if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
-                self.fcx.inh.method_map.borrow_mut().remove(&MethodCall::expr(e.id));
+                self.fcx.inh.tables.borrow_mut().method_map.remove(&MethodCall::expr(e.id));
 
                 // weird but true: the by-ref binops put an
                 // adjustment on the lhs but not the rhs; the
                 // adjustment for rhs is kind of baked into the
                 // system.
                 if !ast_util::is_by_value_binop(op.node) {
-                    self.fcx.inh.adjustments.borrow_mut().remove(&lhs.id);
+                    self.fcx.inh.tables.borrow_mut().adjustments.remove(&lhs.id);
                 }
             }
         }
@@ -204,7 +204,7 @@ fn visit_upvar_borrow_map(&self) {
             return;
         }
 
-        for (upvar_id, upvar_capture) in self.fcx.inh.upvar_capture_map.borrow().iter() {
+        for (upvar_id, upvar_capture) in self.fcx.inh.tables.borrow().upvar_capture_map.iter() {
             let new_upvar_capture = match *upvar_capture {
                 ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
                 ty::UpvarCapture::ByRef(ref upvar_borrow) => {
@@ -217,7 +217,7 @@ fn visit_upvar_borrow_map(&self) {
             debug!("Upvar capture for {:?} resolved to {:?}",
                    upvar_id,
                    new_upvar_capture);
-            self.fcx.tcx().upvar_capture_map.borrow_mut().insert(*upvar_id, new_upvar_capture);
+            self.fcx.tcx().tables.borrow_mut().upvar_capture_map.insert(*upvar_id, new_upvar_capture);
         }
     }
 
@@ -226,13 +226,13 @@ fn visit_closures(&self) {
             return
         }
 
-        for (def_id, closure_ty) in self.fcx.inh.closure_tys.borrow().iter() {
+        for (def_id, closure_ty) in self.fcx.inh.tables.borrow().closure_tys.iter() {
             let closure_ty = self.resolve(closure_ty, ResolvingClosure(*def_id));
-            self.fcx.tcx().closure_tys.borrow_mut().insert(*def_id, closure_ty);
+            self.fcx.tcx().tables.borrow_mut().closure_tys.insert(*def_id, closure_ty);
         }
 
-        for (def_id, &closure_kind) in self.fcx.inh.closure_kinds.borrow().iter() {
-            self.fcx.tcx().closure_kinds.borrow_mut().insert(*def_id, closure_kind);
+        for (def_id, &closure_kind) in self.fcx.inh.tables.borrow().closure_kinds.iter() {
+            self.fcx.tcx().tables.borrow_mut().closure_kinds.insert(*def_id, closure_kind);
         }
     }
 
@@ -254,7 +254,8 @@ fn visit_node_id(&self, reason: ResolveReason, id: ast::NodeId) {
     }
 
     fn visit_adjustments(&self, reason: ResolveReason, id: ast::NodeId) {
-        match self.fcx.inh.adjustments.borrow_mut().remove(&id) {
+        let adjustments = self.fcx.inh.tables.borrow_mut().adjustments.remove(&id);
+        match adjustments {
             None => {
                 debug!("No adjustments for node {}", id);
             }
@@ -281,7 +282,7 @@ fn visit_adjustments(&self, reason: ResolveReason, id: ast::NodeId) {
                     }
                 };
                 debug!("Adjustments for node {}: {:?}", id, resolved_adjustment);
-                self.tcx().adjustments.borrow_mut().insert(
+                self.tcx().tables.borrow_mut().adjustments.insert(
                     id, resolved_adjustment);
             }
         }
@@ -291,7 +292,7 @@ fn visit_method_map_entry(&self,
                               reason: ResolveReason,
                               method_call: MethodCall) {
         // Resolve any method map entry
-        match self.fcx.inh.method_map.borrow_mut().remove(&method_call) {
+        let new_method = match self.fcx.inh.tables.borrow_mut().method_map.remove(&method_call) {
             Some(method) => {
                 debug!("writeback::resolve_method_map_entry(call={:?}, entry={:?})",
                        method_call,
@@ -302,9 +303,17 @@ fn visit_method_map_entry(&self,
                     substs: self.resolve(&method.substs, reason),
                 };
 
-                self.tcx().method_map.borrow_mut().insert(
+                Some(new_method)
+            }
+            None => None
+        };
+
+        //NB(jroesch): We need to match twice to avoid a double borrow which would cause an ICE
+        match new_method {
+            Some(method) => {
+                self.tcx().tables.borrow_mut().method_map.insert(
                     method_call,
-                    new_method);
+                    method);
             }
             None => {}
         }
index 06bd572ac12f3729388a2906add266dcc0d83d53..5441f0b6772000c8b4b69b80bb1788fa426845bf 100644 (file)
@@ -448,7 +448,7 @@ fn check_implementations_of_coerce_unsized(&self) {
             debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (free)",
                    source, target);
 
-            let infcx = new_infer_ctxt(tcx);
+            let infcx = new_infer_ctxt(tcx, Some(param_env));
 
             let check_mutbl = |mt_a: ty::mt<'tcx>, mt_b: ty::mt<'tcx>,
                                mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| {
@@ -540,13 +540,13 @@ fn check_implementations_of_coerce_unsized(&self) {
             fulfill_cx.register_predicate_obligation(&infcx, predicate);
 
             // Check that all transitive obligations are satisfied.
-            if let Err(errors) = fulfill_cx.select_all_or_error(&infcx, &param_env) {
+            if let Err(errors) = fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) {
                 traits::report_fulfillment_errors(&infcx, &errors);
             }
 
             // Finally, resolve all regions.
             let mut free_regions = FreeRegionMap::new();
-            free_regions.relate_free_regions_from_predicates(tcx, &param_env.caller_bounds);
+            free_regions.relate_free_regions_from_predicates(tcx, &infcx.parameter_environment.caller_bounds);
             infcx.resolve_regions_and_report_errors(&free_regions, impl_did.node);
 
             if let Some(kind) = kind {
@@ -630,7 +630,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
 pub fn check_coherence(crate_context: &CrateCtxt) {
     CoherenceChecker {
         crate_context: crate_context,
-        inference_context: new_infer_ctxt(crate_context.tcx),
+        inference_context: new_infer_ctxt(crate_context.tcx, None),
         inherent_impls: RefCell::new(FnvHashMap()),
     }.check(crate_context.tcx.map.krate());
     unsafety::check(crate_context.tcx);
index b4ad55ef2e46b8a7ae3c24d64a24d75fd293cae6..a851bb93e3fc75b560d0bd65422501554b034d9e 100644 (file)
@@ -133,7 +133,7 @@ fn check_if_impls_overlap(&self,
                    impl1_def_id,
                    impl2_def_id);
 
-            let infcx = infer::new_infer_ctxt(self.tcx);
+            let infcx = infer::new_infer_ctxt(self.tcx, None);
             if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) {
                 self.report_overlap_error(trait_def_id, impl1_def_id, impl2_def_id);
             }
index e43a3542b6e338181397124ad8264abeccbdf885..3e2a88e1f79c10002d2b5172c9d3a2aced04ea4f 100644 (file)
@@ -2204,7 +2204,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
                base_type,
                base_type_free);
 
-        let infcx = infer::new_infer_ctxt(tcx);
+        let infcx = infer::new_infer_ctxt(tcx, None);
         drop(::require_same_types(tcx,
                                   Some(&infcx),
                                   false,
index fc825c198e7513980376b8171a4a8ee67af9b2fe..5d589d2ec78c978dbf65144ae03aa0f26044ce3c 100644 (file)
@@ -88,6 +88,7 @@
 #![feature(slice_extras)]
 #![feature(staged_api)]
 #![feature(vec_push_all)]
+#![feature(cell_extras)]
 
 #[macro_use] extern crate log;
 #[macro_use] extern crate syntax;
@@ -162,7 +163,7 @@ fn write_substs_to_tcx<'tcx>(tcx: &ty::ctxt<'tcx>,
 
         assert!(!item_substs.substs.types.needs_infer());
 
-        tcx.item_substs.borrow_mut().insert(node_id, item_substs);
+        tcx.tables.borrow_mut().item_substs.insert(node_id, item_substs);
     }
 }
 
@@ -187,7 +188,7 @@ fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>,
 {
     let result = match maybe_infcx {
         None => {
-            let infcx = infer::new_infer_ctxt(tcx);
+            let infcx = infer::new_infer_ctxt(tcx, None);
             infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2)
         }
         Some(infcx) => {