diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index c19ba19f5b76b..2cec42b76bce3 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -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)] diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 21e2ad198810e..d2c79e1d820bf 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -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,12 @@ 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 +1079,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 +1109,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 +1635,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 +1651,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 +1668,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 => { diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 801b3a721e40d..7d62b6ff90040 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -411,7 +411,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { 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 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { 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) } } diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 62bf1648725cd..8bbb6ae757fc1 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -283,12 +283,11 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> { 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, &self.tcx.tables, 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 }; diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index d2b3b83e4f42f..f61884e213666 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -98,6 +98,7 @@ impl<'a> FromIterator> for 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>, diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 1b1725dd15c85..a6b7d7f832a3c 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -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, &tcx.tables, None); - let param_env = tcx.empty_parameter_environment(); - let mut selcx = traits::SelectionContext::new(&infcx, ¶m_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) { diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index bd8b8afbdfe88..d8ee38b847830 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -96,7 +96,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { 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) => { diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index c48d5d5da4020..8084c2b0c39b8 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -140,7 +140,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> { 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) { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index a15d02ea29605..25728c50c61f4 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -257,8 +257,9 @@ impl OverloadedCallType { 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 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> { // 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 diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index f1af2705d4ed8..c355e8b82a6ef 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -23,19 +23,24 @@ pub use self::freshen::TypeFreshener; pub use self::region_inference::GenericKind; use middle::free_region::FreeRegionMap; +use middle::mem_categorization as mc; +use middle::mem_categorization::McResult; +use middle::region::CodeExtent; use middle::subst; use middle::subst::Substs; +use middle::subst::Subst; +use middle::traits; use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric}; use middle::ty::{self, Ty, HasTypeFlags}; use middle::ty_fold::{self, TypeFolder, TypeFoldable}; use middle::ty_relate::{Relate, RelateResult, TypeRelation}; use rustc_data_structures::unify::{self, UnificationTable}; -use std::cell::{RefCell}; +use std::cell::{RefCell, Ref}; use std::fmt; use syntax::ast; use syntax::codemap; use syntax::codemap::Span; -use util::nodemap::FnvHashMap; +use util::nodemap::{FnvHashMap, NodeMap}; use self::combine::CombineFields; use self::region_inference::{RegionVarBindings, RegionSnapshot}; @@ -64,6 +69,8 @@ pub type fres = Result; // "fixup result" pub struct InferCtxt<'a, 'tcx: 'a> { pub tcx: &'a ty::ctxt<'tcx>, + pub tables: &'a RefCell>, + // We instantiate UnificationTable with bounds because the // types that might instantiate a general type variable have an // order, represented by its upper and lower bounds. @@ -77,6 +84,17 @@ pub struct InferCtxt<'a, 'tcx: 'a> { // For region variables. region_vars: RegionVarBindings<'a, 'tcx>, + + pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>, + + // This is a temporary field used for toggling on normalization in the inference context, + // as we move towards the approach described here: + // https://internals.rust-lang.org/t/flattening-the-contexts-for-fun-and-profit/2293 + // At a point sometime in the future normalization will be done by the typing context + // directly. + normalize: bool, + + err_count_on_creation: usize, } /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized @@ -309,14 +327,20 @@ 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>, + tables: &'a RefCell>, + param_env: Option>) -> InferCtxt<'a, 'tcx> { InferCtxt { tcx: tcx, + tables: tables, type_variables: RefCell::new(type_variable::TypeVariableTable::new()), 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()), + normalize: false, + err_count_on_creation: tcx.sess.err_count() } } @@ -431,6 +455,127 @@ pub struct CombinedSnapshot { region_vars_snapshot: RegionSnapshot, } +impl<'a, 'tcx> mc::Typer<'tcx> for InferCtxt<'a, 'tcx> { + fn node_ty(&self, id: ast::NodeId) -> McResult> { + let ty = self.node_ty(id); + self.resolve_type_vars_or_error(&ty) + } + + fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult> { + let ty = self.adjust_expr_ty(expr, self.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.resolve_type_vars_if_possible(&ty); + !traits::type_known_to_meet_builtin_bound(self, self, ty, ty::BoundCopy, span) + } + + fn node_method_ty(&self, method_call: ty::MethodCall) + -> Option> { + self.tables + .borrow() + .method_map + .get(&method_call) + .map(|method| method.ty) + .map(|ty| self.resolve_type_vars_if_possible(&ty)) + } + + fn node_method_origin(&self, method_call: ty::MethodCall) + -> Option> + { + self.tables + .borrow() + .method_map + .get(&method_call) + .map(|method| method.origin.clone()) + } + + fn adjustments(&self) -> Ref>> { + fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) + -> &'a NodeMap> { + &tables.adjustments + } + + Ref::map(self.tables.borrow(), project_adjustments) + } + + fn is_method_call(&self, id: ast::NodeId) -> bool { + self.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id)) + } + + fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { + self.parameter_environment.temporary_scope(rvalue_id) + } + + fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { + self.tables.borrow().upvar_capture_map.get(&upvar_id).cloned() + } +} + +impl<'a, 'tcx> ty::ClosureTyper<'tcx> for InferCtxt<'a, 'tcx> { + fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> { + &self.parameter_environment + } + + fn closure_kind(&self, + def_id: ast::DefId) + -> Option + { + self.tables.borrow().closure_kinds.get(&def_id).cloned() + } + + fn closure_type(&self, + def_id: ast::DefId, + substs: &subst::Substs<'tcx>) + -> ty::ClosureTy<'tcx> + { + + let closure_ty = self.tables + .borrow() + .closure_tys + .get(&def_id) + .unwrap() + .subst(self.tcx, substs); + + if self.normalize { + // NOTE: this flag is currently *always* set to false, we are slowly folding + // normalization into this trait and will come back to remove this in the near + // future. + + // code from NormalizingClosureTyper: + // the substitutions in `substs` are already monomorphized, + // but we still must normalize associated types + // normalize_associated_type(self.param_env.tcx, &closure_ty) + panic!("see issue 26597: fufillment context refactor must occur") + } else { + closure_ty + } + } + + fn closure_upvars(&self, + def_id: ast::DefId, + substs: &Substs<'tcx>) + -> Option>> + { + let result = ty::ctxt::closure_upvars(self, def_id, substs); + + if self.normalize { + // NOTE: this flag is currently *always* set to false, we are slowly folding + // normalization into this trait and will come back to remove this in the near + // future. + + // code from NormalizingClosureTyper: + // the substitutions in `substs` are already monomorphized, + // but we still must normalize associated types + // monomorphize::normalize_associated_type(self.param_env.tcx, &result) + panic!("see issue 26597: fufillment context refactor must occur") + } else { + result + } + } +} + impl<'a, 'tcx> InferCtxt<'a, 'tcx> { pub fn freshen>(&self, t: T) -> T { t.fold_with(&mut self.freshener()) @@ -852,6 +997,49 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.region_vars.new_bound(debruijn) } + /// Apply `adjustment` to the type of `expr` + pub fn adjust_expr_ty(&self, + expr: &ast::Expr, + adjustment: Option<&ty::AutoAdjustment<'tcx>>) + -> Ty<'tcx> + { + let raw_ty = self.expr_ty(expr); + let raw_ty = self.shallow_resolve(raw_ty); + let resolve_ty = |ty: Ty<'tcx>| self.resolve_type_vars_if_possible(&ty); + raw_ty.adjust(self.tcx, + expr.span, + expr.id, + adjustment, + |method_call| self.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.tables.borrow().node_types.get(&id) { + Some(&t) => t, + // FIXME + None if self.tcx.sess.err_count() - self.err_count_on_creation != 0 => + self.tcx.types.err, + None => { + self.tcx.sess.bug( + &format!("no type for node {}: {} in fcx", + id, self.tcx.map.node_to_string(id))); + } + } + } + + pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> { + match self.tables.borrow().node_types.get(&ex.id) { + Some(&t) => t, + None => { + self.tcx.sess.bug(&format!("no type for expr in fcx")); + } + } + } + pub fn resolve_regions_and_report_errors(&self, free_regions: &FreeRegionMap, subject_node_id: ast::NodeId) { @@ -926,6 +1114,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { value.fold_with(&mut r) } + /// Resolves all type variables in `t` and then, if any were left + /// unresolved, substitutes an error type. This is used after the + /// main checking when doing a second pass before writeback. The + /// justification is that writeback will produce an error for + /// these unconstrained type variables. + fn resolve_type_vars_or_error(&self, t: &Ty<'tcx>) -> mc::McResult> { + let ty = self.resolve_type_vars_if_possible(t); + if ty.has_infer_types() || ty.references_error() { Err(()) } else { Ok(ty) } + } + pub fn fully_resolve>(&self, value: &T) -> fres { /*! * Attempts to resolve all type/region variables in diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index d354c1667da38..7d237a511c4a1 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1150,7 +1150,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { 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 { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 969ffaf88a719..13e127e912613 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -83,7 +83,7 @@ use syntax::ast::{MutImmutable, MutMutable}; 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>; fn node_method_origin(&self, method_call: ty::MethodCall) -> Option>; - fn adjustments<'a>(&'a self) -> &'a RefCell>>; + fn adjustments(&self) -> Ref>>; fn is_method_call(&self, id: ast::NodeId) -> bool; fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option; fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option; @@ -408,7 +408,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { 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 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { } pub fn cat_expr(&self, expr: &ast::Expr) -> McResult> { - match self.typer.adjustments().borrow().get(&expr.id) { + match self.typer.adjustments().get(&expr.id) { None => { // No adjustments. self.cat_expr_unadjusted(expr) diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 0bbcfa700388c..6ea726062cad6 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -128,7 +128,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> { } 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) { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 4766ae8933d0b..e6bbae6405bf4 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -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) => { diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 845ba62307fa5..9df6ed5d68126 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -351,6 +351,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, } } +// FIXME: 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, &tcx.tables, 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>, diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 01faa6b7cf7b9..ae15c8aa8e028 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -54,6 +54,7 @@ use util::nodemap::FnvHashMap; pub struct SelectionContext<'cx, 'tcx:'cx> { infcx: &'cx InferCtxt<'cx, 'tcx>, + closure_typer: &'cx (ty::ClosureTyper<'tcx>+'cx), /// Freshener used specifically for skolemizing entries on the @@ -77,6 +78,7 @@ pub struct SelectionContext<'cx, 'tcx:'cx> { /// other words, we consider `$0 : Bar` to be unimplemented if /// there is no type that the user could *actually name* that /// would satisfy it. This avoids crippling inference, basically. + intercrate: bool, } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 302ec08db6f26..489ce7bc4cf78 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -728,7 +728,7 @@ impl 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>>; +pub type MethodMap<'tcx> = FnvHashMap>; // 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>, + + /// 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>, + + pub adjustments: NodeMap>, + + 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>, + + /// Records the type of each closure. The def ID is the ID of the + /// expression defining the closure. + pub closure_kinds: DefIdMap, +} + +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>, + // 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>>, - - /// 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>>, + pub tables: RefCell>, /// Maps from a trait item to the trait item "descriptor" pub impl_or_trait_items: RefCell>>, @@ -894,7 +928,6 @@ pub struct ctxt<'tcx> { pub ast_ty_to_ty_cache: RefCell>>, pub enum_var_cache: RefCell>>>>>, pub ty_param_defs: RefCell>>, - pub adjustments: RefCell>>, pub normalized_cache: RefCell, 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, - /// Borrows - pub upvar_capture_map: RefCell, - /// These caches are used by const_eval when decoding external constants. pub extern_const_statics: RefCell>, pub extern_const_variants: RefCell>, pub extern_const_fns: RefCell>, - pub method_map: MethodMap<'tcx>, - pub dependency_formats: RefCell, - /// Records the type of each closure. The def ID is the ID of the - /// expression defining the closure. - pub closure_kinds: RefCell>, - - /// Records the type of each closure. The def ID is the ID of the - /// expression defining the closure. - pub closure_tys: RefCell>>, - pub node_lint_levels: RefCell>, @@ -1000,9 +1020,16 @@ pub struct ctxt<'tcx> { } impl<'tcx> ctxt<'tcx> { - pub fn node_types(&self) -> Ref>> { self.node_types.borrow() } + pub fn node_types(&self) -> Ref>> { + fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap> { + &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> { @@ -3421,8 +3448,7 @@ impl<'tcx> ctxt<'tcx> { 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 +3465,6 @@ impl<'tcx> ctxt<'tcx> { 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 +3477,10 @@ impl<'tcx> ctxt<'tcx> { 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 +3536,7 @@ impl<'tcx> ctxt<'tcx> { } 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 +3544,7 @@ impl<'tcx> ctxt<'tcx> { 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 +4390,8 @@ impl<'tcx> TyS<'tcx> { span: Span) -> bool { - let infcx = infer::new_infer_ctxt(param_env.tcx()); + let tcx = param_env.tcx(); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, Some(param_env.clone())); let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, self, bound, span); @@ -5276,11 +5298,11 @@ impl<'tcx> ctxt<'tcx> { } pub fn node_id_to_type_opt(&self, id: ast::NodeId) -> Option> { - 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 +5347,9 @@ impl<'tcx> ctxt<'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 +6693,11 @@ impl<'tcx> ctxt<'tcx> { } 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 { - 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 +6711,21 @@ impl<'a,'tcx> Typer<'tcx> for ParameterEnvironment<'a,'tcx> { } fn node_method_ty(&self, method_call: ty::MethodCall) -> Option> { - 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> { - 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>> { - &self.tcx.adjustments + fn adjustments(&self) -> Ref>> { + fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap> { + &tables.adjustments + } + + Ref::map(self.tcx.tables.borrow(), projection) } fn is_method_call(&self, id: ast::NodeId) -> bool { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index dcdf457965efa..de2f33e8a4ac9 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -688,7 +688,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { 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| { diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 1ad3f53c328d9..80c4fc28703ac 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -602,7 +602,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session, make_glob_map: resolve::MakeGlobMap, f: F) -> (Session, R) - where F: FnOnce(&ty::ctxt<'tcx>, + where F: for<'a> FnOnce(&'a ty::ctxt<'tcx>, ty::CrateAnalysis) -> R { let time_passes = sess.time_passes(); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 5ec6e293684cc..fb2f6b2b08db8 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -140,7 +140,7 @@ fn test_env(source_string: &str, lang_items, stability::Index::new(krate), |tcx| { - let infcx = infer::new_infer_ctxt(tcx); + let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None); body(Env { infcx: &infcx }); let free_regions = FreeRegionMap::new(); infcx.resolve_regions_and_report_errors(&free_regions, ast::CRATE_NODE_ID); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 8fe07da157970..db48608823d21 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1446,7 +1446,7 @@ impl LintPass for UnusedAllocation { _ => 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 @@ impl LintPass for UnconditionalRecursion { 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 diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 24803562fa373..239141df9e8c7 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -904,7 +904,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> { } 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 \ diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index bb7e95cd4ae44..dc692b0e765dd 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -43,6 +43,7 @@ #![feature(unicode)] #![feature(unicode)] #![feature(vec_push_all)] +#![feature(cell_extras)] #![allow(trivial_casts)] diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index 5ddad0e1947e8..d86242f39cea7 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -886,7 +886,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { fn process_method_call(&mut self, ex: &ast::Expr, args: &Vec>) { - 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) | diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index f035b32e3596d..0cd6bbad03aa9 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -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, diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 24abe0ed3fdd2..dfe807d6c9152 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -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) => { diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index cb30bcdbf5399..b637806285540 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -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> { - 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 } diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index 777b61f25f0ef..483d82f508f25 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -47,7 +47,7 @@ use util::nodemap::{FnvHashMap, NodeMap}; 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 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { fn node_method_ty(&self, method_call: ty::MethodCall) -> Option> { self.tcx() - .method_map + .tables .borrow() + .method_map .get(&method_call) .map(|method| monomorphize_type(self, method.ty)) } @@ -640,18 +641,26 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { -> Option> { self.tcx() - .method_map + .tables .borrow() + .method_map .get(&method_call) .map(|method| method.origin.clone()) } - fn adjustments<'a>(&'a self) -> &'a RefCell>> { - &self.tcx().adjustments + fn adjustments<'a>(&'a self) -> Ref>> { + // FIXME (@jroesch): this is becuase we currently have a HR inference problem + // in the snapshot that causes this code not to work. + fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> + &'a NodeMap> { + &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 { @@ -659,7 +668,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> { } fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { - 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 +1000,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, &tcx.tables, None); // Do the initial selection for the obligation. This yields the // shallow result we are looking for -- that is, what specific impl. @@ -1053,7 +1062,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, &tcx.tables, None); let typer = NormalizingClosureTyper::new(tcx); let mut selcx = traits::SelectionContext::new(&infcx, &typer); let mut fulfill_cx = traits::FulfillmentContext::new(false); @@ -1070,6 +1079,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 +1204,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() } }; diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 8ec60000ee842..57af688ef60d7 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -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") }; diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 8fd88055b8e45..045cc69bf954b 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -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 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, 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 { diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index a3e5b640fd0f1..e46c3b5fab1f7 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -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) | diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index cae810c9082e5..67ccf64621a85 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -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, &tcx.tables, None); let typer = NormalizingClosureTyper::new(tcx); let mut selcx = traits::SelectionContext::new(&infcx, &typer); let cause = traits::ObligationCause::dummy(); diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 7109e45b55279..d29c0494572cb 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -137,9 +137,9 @@ fn try_overloaded_call_step<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // Check whether this is a call to a closure where we // haven't yet decided on whether the closure is fn vs // fnmut vs fnonce. If so, we have to defer further processing. - if fcx.closure_kind(def_id).is_none() { + if fcx.infcx().closure_kind(def_id).is_none() { let closure_ty = - fcx.closure_type(def_id, substs); + fcx.infcx().closure_type(def_id, substs); let fn_sig = fcx.infcx().replace_late_bound_regions_with_fresh_var(call_expr.span, infer::FnCall, @@ -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)] @@ -344,7 +344,7 @@ impl<'tcx> DeferredCallResolution<'tcx> for CallResolution<'tcx> { // we should not be invoked until the closure kind has been // determined by upvar inference - assert!(fcx.closure_kind(self.closure_def_id).is_some()); + assert!(fcx.infcx().closure_kind(self.closure_def_id).is_some()); // We may now know enough to figure out fn vs fnmut etc. match try_overloaded_call_traits(fcx, self.call_expr, self.callee_expr, diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index d431c0fda9865..b5ee46ece94be 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -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 => { } } } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 73b9a16d1ebea..b38b6884a98ad 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -273,7 +273,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { }; let source = source.adjust_for_autoref(self.tcx(), reborrow); - let mut selcx = traits::SelectionContext::new(self.fcx.infcx(), self.fcx); + let mut selcx = traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx()); // Use a FIFO queue for this custom fulfillment procedure. let mut queue = VecDeque::new(); diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 349d1a8bb65a8..f62411e85828d 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -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, &tcx.tables, 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()); + // FIXME(@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,8 @@ 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 +419,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, &tcx.tables, None); let mut fulfillment_cx = traits::FulfillmentContext::new(true); // The below is for the most part highly similar to the procedure diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index a48cffb4472f4..6f0fbfebf46cc 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -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, &tcx.tables, None); + infcx.commit_if_ok(|snapshot| { let (named_type_to_skolem, skol_map) = infcx.construct_skolemized_subst(named_type_generics, snapshot); diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 5f7a78ec611a2..9c2d1c4a34df1 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -488,8 +488,9 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { // 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,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { // 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 +591,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { // 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, diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 0f8048f27a0e3..f312db9c4dcf2 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -195,7 +195,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, poly_trait_ref.to_predicate()); // Now we want to know if this can be matched - let mut selcx = traits::SelectionContext::new(fcx.infcx(), fcx); + let mut selcx = traits::SelectionContext::new(fcx.infcx(), fcx.infcx()); if !selcx.evaluate_obligation(&obligation) { debug!("--> Cannot match obligation"); return None; // Cannot be matched, no such method resolution is possible. diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 8026fce69ecca..94a2050829dfa 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -421,7 +421,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // We can't use normalize_associated_types_in as it will pollute the // fcx's fulfillment context after this probe is over. let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); - let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx); + let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx()); let traits::Normalized { value: xform_self_ty, obligations } = traits::normalize(selcx, cause, &xform_self_ty); debug!("assemble_inherent_impl_probe: xform_self_ty = {:?}", @@ -477,7 +477,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // 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 { @@ -681,7 +681,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { // as it will pollute the fcx's fulfillment context after this probe // is over. let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); - let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx); + let mut selcx = &mut traits::SelectionContext::new(self.fcx.infcx(), self.fcx.infcx()); let traits::Normalized { value: xform_self_ty, obligations } = traits::normalize(selcx, cause, &xform_self_ty); @@ -742,7 +742,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { _ => 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 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { 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) @@ -1076,7 +1076,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> { match probe.kind { InherentImplCandidate(impl_def_id, ref substs, ref ref_obligations) | ExtensionImplCandidate(impl_def_id, _, ref substs, _, ref ref_obligations) => { - let selcx = &mut traits::SelectionContext::new(self.infcx(), self.fcx); + let selcx = &mut traits::SelectionContext::new(self.infcx(), self.fcx.infcx()); let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id); // Check whether the impl imposes obligations we have to worry about. diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index b193ddcb21349..b81b672e684a5 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -102,7 +102,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let obligation = Obligation::misc(span, fcx.body_id, poly_trait_ref.to_predicate()); - let mut selcx = SelectionContext::new(infcx, fcx); + let mut selcx = SelectionContext::new(infcx, fcx.infcx()); if selcx.evaluate_obligation(&obligation) { span_stored_function(); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 299ccd579ccb7..7e87dc6540ea5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -87,8 +87,6 @@ use fmt_macros::{Parser, Piece, Position}; use middle::astconv_util::{check_path_args, NO_TPS, NO_REGIONS}; use middle::def; use middle::infer; -use middle::mem_categorization as mc; -use middle::mem_categorization::McResult; use middle::pat_util::{self, pat_id_map}; use middle::privacy::{AllPublic, LastMod}; use middle::region::{self, CodeExtent}; @@ -97,7 +95,7 @@ use middle::traits::{self, report_fulfillment_errors}; 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; @@ -152,16 +150,8 @@ mod op; pub struct Inherited<'a, 'tcx: 'a> { infcx: infer::InferCtxt<'a, 'tcx>, locals: RefCell>>, - param_env: ty::ParameterEnvironment<'a, 'tcx>, - // Temporary tables: - node_types: RefCell>>, - item_substs: RefCell>>, - adjustments: RefCell>>, - method_map: MethodMap<'tcx>, - upvar_capture_map: RefCell, - closure_tys: RefCell>>, - closure_kinds: RefCell>, + tables: &'a RefCell>, // A mapping from each fn's id to its signature, with all bound // regions replaced with free ones. Unlike the other tables, this @@ -298,90 +288,16 @@ pub struct FnCtxt<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx>, } -impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> { - fn node_ty(&self, id: ast::NodeId) -> McResult> { - let ty = self.node_ty(id); - self.resolve_type_vars_or_error(&ty) - } - fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult> { - let ty = self.adjust_expr_ty(expr, self.inh.adjustments.borrow().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> { - self.inh.method_map.borrow() - .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> - { - self.inh.method_map.borrow() - .get(&method_call) - .map(|method| method.origin.clone()) - } - fn adjustments(&self) -> &RefCell>> { - &self.inh.adjustments - } - fn is_method_call(&self, id: ast::NodeId) -> bool { - self.inh.method_map.borrow().contains_key(&ty::MethodCall::expr(id)) - } - fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option { - self.param_env().temporary_scope(rvalue_id) - } - fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option { - self.inh.upvar_capture_map.borrow().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 - } - - fn closure_kind(&self, - def_id: ast::DefId) - -> Option - { - self.inh.closure_kinds.borrow().get(&def_id).cloned() - } - - fn closure_type(&self, - def_id: ast::DefId, - substs: &subst::Substs<'tcx>) - -> ty::ClosureTy<'tcx> - { - self.inh.closure_tys.borrow().get(&def_id).unwrap().subst(self.tcx(), substs) - } - - fn closure_upvars(&self, - def_id: ast::DefId, - substs: &Substs<'tcx>) - -> Option>> { - ty::ctxt::closure_upvars(self, def_id, substs) - } -} - impl<'a, 'tcx> Inherited<'a, 'tcx> { fn new(tcx: &'a ty::ctxt<'tcx>, + tables: &'a RefCell>, param_env: ty::ParameterEnvironment<'a, 'tcx>) -> Inherited<'a, 'tcx> { + Inherited { - infcx: infer::new_infer_ctxt(tcx), + infcx: infer::new_infer_ctxt(tcx, tables, 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 +340,13 @@ 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>) -> 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 +421,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 +1119,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { } 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 +1128,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { -> Result>, 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 +1195,7 @@ impl<'a, 'tcx> FnCtxt<'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 { @@ -1322,16 +1244,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty } - /// Resolves all type variables in `t` and then, if any were left - /// unresolved, substitutes an error type. This is used after the - /// main checking when doing a second pass before writeback. The - /// justification is that writeback will produce an error for - /// these unconstrained type variables. - fn resolve_type_vars_or_error(&self, ty: &Ty<'tcx>) -> mc::McResult> { - let ty = self.infcx().resolve_type_vars_if_possible(ty); - if ty.has_infer_types() || ty.references_error() { Err(()) } else { Ok(ty) } - } - fn record_deferred_call_resolution(&self, closure_def_id: ast::DefId, r: DeferredCallResolutionHandler<'tcx>) { @@ -1368,7 +1280,7 @@ impl<'a, 'tcx> FnCtxt<'a, '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 +1302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 +1312,7 @@ impl<'a, 'tcx> FnCtxt<'a, '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 +1338,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 @@ -1465,7 +1377,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn normalize_associated_types_in(&self, span: Span, value: &T) -> T where T : TypeFoldable<'tcx> + HasTypeFlags { - self.inh.normalize_associated_types_in(self, span, self.body_id, value) + self.inh.normalize_associated_types_in(self.infcx(), span, self.body_id, value) } fn normalize_associated_type(&self, @@ -1480,7 +1392,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.inh.fulfillment_cx .borrow_mut() .normalize_projection_type(self.infcx(), - self, + self.infcx(), ty::ProjectionTy { trait_ref: trait_ref, item_name: item_name, @@ -1627,7 +1539,7 @@ impl<'a, 'tcx> FnCtxt<'a, '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 +1558,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 +1577,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn item_substs(&self) -> Ref>> { - 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> { + &tables.item_substs + } + + Ref::map(self.inh.tables.borrow(), project_item_susbts) } pub fn opt_node_ty_substs(&self, @@ -1673,7 +1592,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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 => { } } @@ -1829,7 +1748,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.select_all_obligations_and_apply_defaults(); let mut fulfillment_cx = self.inh.fulfillment_cx.borrow_mut(); - match fulfillment_cx.select_all_or_error(self.infcx(), self) { + match fulfillment_cx.select_all_or_error(self.infcx(), self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } } @@ -1840,7 +1759,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match self.inh.fulfillment_cx .borrow_mut() - .select_where_possible(self.infcx(), self) + .select_where_possible(self.infcx(), self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } @@ -1855,7 +1774,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match self.inh.fulfillment_cx .borrow_mut() - .select_new_obligations(self.infcx(), self) + .select_new_obligations(self.infcx(), self.infcx()) { Ok(()) => { } Err(errors) => { report_fulfillment_errors(self.infcx(), &errors); } @@ -2039,7 +1958,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 +2559,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(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 +3993,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 +4003,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 +4156,8 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, let rty = ccx.tcx.node_id_to_type(id); let mut disr_vals: Vec = 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)); diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 5a114c811191c..c419a986f95b1 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -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>, } } } - diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 13961834aebdd..a86301907385a 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -86,6 +86,7 @@ use astconv::AstConv; use check::dropck; use check::FnCtxt; use middle::free_region::FreeRegionMap; +use middle::infer::InferCtxt; use middle::implicator; use middle::mem_categorization as mc; use middle::region::CodeExtent; @@ -124,7 +125,8 @@ 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.infcx().parameter_environment.caller_bounds); rcx.visit_region_obligations(item.id); rcx.resolve_regions_and_report_errors(); } @@ -143,7 +145,8 @@ 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.infcx().parameter_environment.caller_bounds); rcx.resolve_regions_and_report_errors(); @@ -254,7 +257,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { } fn resolve_method_type(&self, method_call: MethodCall) -> Option> { - 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 +270,7 @@ impl<'a, 'tcx> Rcx<'a, '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)) } } @@ -353,7 +356,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { debug!("relate_free_regions(t={:?})", ty); let body_scope = CodeExtent::from_node_id(body_id); let body_scope = ty::ReScope(body_scope); - let implications = implicator::implications(self.fcx.infcx(), self.fcx, body_id, + let implications = implicator::implications(self.fcx.infcx(), self.fcx.infcx(), body_id, ty, body_scope, span); // Record any relations between free regions that we observe into the free-region-map. @@ -511,12 +514,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); @@ -548,7 +552,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { // If necessary, constrain destructors in the unadjusted form of this // expression. let cmt_result = { - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); mc.cat_expr_unadjusted(expr) }; match cmt_result { @@ -567,7 +571,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) { // If necessary, constrain destructors in this expression. This will be // the adjusted form if there is an adjustment. let cmt_result = { - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); mc.cat_expr(expr) }; match cmt_result { @@ -657,7 +661,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::.iter(), true); @@ -884,7 +888,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); @@ -909,7 +915,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, r, m); { - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); let self_cmt = ignore_err!(mc.cat_expr_autoderefd(deref_expr, i)); debug!("constrain_autoderefs: self_cmt={:?}", self_cmt); @@ -1018,7 +1024,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={:?})", @@ -1034,7 +1040,7 @@ fn link_addr_of(rcx: &mut Rcx, expr: &ast::Expr, debug!("link_addr_of(expr={:?}, base={:?})", expr, base); let cmt = { - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); ignore_err!(mc.cat_expr(base)) }; @@ -1052,7 +1058,7 @@ fn link_local(rcx: &Rcx, local: &ast::Local) { None => { return; } Some(ref expr) => &**expr, }; - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); let discr_cmt = ignore_err!(mc.cat_expr(init_expr)); link_pattern(rcx, mc, discr_cmt, &*local.pat); } @@ -1062,7 +1068,7 @@ fn link_local(rcx: &Rcx, local: &ast::Local) { /// linked to the lifetime of its guarantor (if any). fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) { debug!("regionck::for_match()"); - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); let discr_cmt = ignore_err!(mc.cat_expr(discr)); debug!("discr_cmt={:?}", discr_cmt); for arm in arms { @@ -1077,7 +1083,7 @@ fn link_match(rcx: &Rcx, discr: &ast::Expr, arms: &[ast::Arm]) { /// linked to the lifetime of its guarantor (if any). fn link_fn_args(rcx: &Rcx, body_scope: CodeExtent, args: &[ast::Arg]) { debug!("regionck::link_fn_args(body_scope={:?})", body_scope); - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); for arg in args { let arg_ty = rcx.fcx.node_ty(arg.id); let re_scope = ty::ReScope(body_scope); @@ -1092,7 +1098,7 @@ fn link_fn_args(rcx: &Rcx, body_scope: CodeExtent, args: &[ast::Arg]) { /// Link lifetimes of any ref bindings in `root_pat` to the pointers found in the discriminant, if /// needed. fn link_pattern<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, - mc: mc::MemCategorizationContext>, + mc: mc::MemCategorizationContext>, discr_cmt: mc::cmt<'tcx>, root_pat: &ast::Pat) { debug!("link_pattern(discr_cmt={:?}, root_pat={:?})", @@ -1131,7 +1137,7 @@ fn link_autoref(rcx: &Rcx, autoref: &ty::AutoRef) { debug!("link_autoref(autoref={:?})", autoref); - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); let expr_cmt = ignore_err!(mc.cat_expr_autoderefd(expr, autoderefs)); debug!("expr_cmt={:?}", expr_cmt); @@ -1155,7 +1161,7 @@ fn link_by_ref(rcx: &Rcx, callee_scope: CodeExtent) { debug!("link_by_ref(expr={:?}, callee_scope={:?})", expr, callee_scope); - let mc = mc::MemCategorizationContext::new(rcx.fcx); + let mc = mc::MemCategorizationContext::new(rcx.fcx.infcx()); let expr_cmt = ignore_err!(mc.cat_expr(expr)); let borrow_region = ty::ReScope(callee_scope); link_region(rcx, expr.span, &borrow_region, ty::ImmBorrow, expr_cmt); @@ -1292,7 +1298,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 @@ -1399,7 +1405,7 @@ pub fn type_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, ty, region); - let implications = implicator::implications(rcx.fcx.infcx(), rcx.fcx, rcx.body_id, + let implications = implicator::implications(rcx.fcx.infcx(), rcx.fcx.infcx(), rcx.body_id, ty, region, origin.span()); for implication in implications { debug!("implication: {:?}", implication); @@ -1440,7 +1446,7 @@ fn closure_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, debug!("closure_must_outlive(region={:?}, def_id={:?}, substs={:?})", region, def_id, substs); - let upvars = rcx.fcx.closure_upvars(def_id, substs).unwrap(); + let upvars = rcx.fcx.infcx().closure_upvars(def_id, substs).unwrap(); for upvar in upvars { let var_id = upvar.def.def_id().local_id(); type_must_outlive( @@ -1453,7 +1459,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, diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 1345f322476b9..c7f084e27cda0 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -129,9 +129,10 @@ impl<'a,'tcx> SeedBorrowKind<'a,'tcx> { _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 +157,7 @@ impl<'a,'tcx> SeedBorrowKind<'a,'tcx> { } }; - 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); } }); } @@ -186,7 +187,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> { debug!("analyzing closure `{}` with fn body id `{}`", id, body.id); - let mut euv = euv::ExprUseVisitor::new(self, self.fcx); + let mut euv = euv::ExprUseVisitor::new(self, self.fcx.infcx()); euv.walk_fn(decl, body); // If we had not yet settled on a closure kind for this closure, @@ -267,7 +268,10 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> { // 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 +378,11 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> { // 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 +448,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> { } 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={:?}", diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs index 00bbbafd5cd32..df01b99fd9b80 100644 --- a/src/librustc_typeck/check/wf.rs +++ b/src/librustc_typeck/check/wf.rs @@ -18,6 +18,7 @@ use middle::traits; 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 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { &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,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { 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 +225,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { // 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 +241,10 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { }; 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 @@ -257,7 +268,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { let predicates = fcx.tcx().lookup_super_predicates(poly_trait_ref.def_id()); let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref); let predicates = { - let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx); + let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx.infcx()); traits::normalize(selcx, cause.clone(), &predicates) }; for predicate in predicates.value.predicates { @@ -635,7 +646,10 @@ 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 +674,10 @@ 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, diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 29119f3b5946d..1fc7224737d2d 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -96,14 +96,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { 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,11 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { 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 +230,13 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { 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 +258,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } 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 +286,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } }; 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 +296,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { 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 +307,17 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { 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 => {} } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 06bd572ac12f3..fbabc287342e9 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -448,7 +448,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (free)", source, target); - let infcx = new_infer_ctxt(tcx); + let infcx = new_infer_ctxt(tcx, &tcx.tables, 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,15 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { 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, ¶m_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, ¶m_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 +632,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, &crate_context.tcx.tables, None), inherent_impls: RefCell::new(FnvHashMap()), }.check(crate_context.tcx.map.krate()); unsafety::check(crate_context.tcx); diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index b4ad55ef2e46b..3495714fcc736 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -133,7 +133,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { impl1_def_id, impl2_def_id); - let infcx = infer::new_infer_ctxt(self.tcx); + let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, 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); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index e43a3542b6e33..ef9dcd56a578b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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, &tcx.tables, None); drop(::require_same_types(tcx, Some(&infcx), false, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index fc825c198e751..48a64675c708a 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -88,6 +88,7 @@ This API is completely unstable and subject to change. #![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, &tcx.tables, None); infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2) } Some(infcx) => {