#![feature(str_match_indices)]
#![feature(vec_push_all)]
#![feature(wrapping)]
+#![feature(cell_extras)]
#![cfg_attr(test, feature(test))]
#![allow(trivial_casts)]
})
}
- 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);
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);
})
}
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,
})
}
- 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)
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 => {
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);
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 => {
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)
};
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)
}
}
fn check_static_type(&self, e: &ast::Expr) {
let ty = self.tcx.node_id_to_type(e.id);
- let infcx = infer::new_infer_ctxt(self.tcx);
+ let infcx = infer::new_infer_ctxt(self.tcx, None);
let mut fulfill_cx = traits::FulfillmentContext::new(false);
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
- let env = self.tcx.empty_parameter_environment();
- match fulfill_cx.select_all_or_error(&infcx, &env) {
+ match fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) {
Ok(()) => { },
Err(ref errors) => {
traits::report_fulfillment_errors(&infcx, errors);
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,
}
}
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
};
}
}
+//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>,
substs: trait_substs });
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
- let infcx = infer::new_infer_ctxt(tcx);
+ let infcx = infer::new_infer_ctxt(tcx, None);
- let param_env = tcx.empty_parameter_environment();
- let mut selcx = traits::SelectionContext::new(&infcx, ¶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) {
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) => {
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) {
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);
// 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
// For region variables.
region_vars: RegionVarBindings<'a, 'tcx>,
+
+ pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>,
+
+ // pub tables: &'a RefCell<ty::Tables<'tcx>>
}
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
}
}
-pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
+pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
+ param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>)
-> InferCtxt<'a, 'tcx> {
InferCtxt {
tcx: tcx,
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())
}
}
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 {
use syntax::ast;
use syntax::codemap::Span;
-use std::cell::RefCell;
+use std::cell::Ref;
use std::fmt;
use std::rc::Rc;
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>>;
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>;
- fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>;
+ fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>>;
fn is_method_call(&self, id: ast::NodeId) -> bool;
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture>;
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)))
}
}
pub fn cat_expr(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
- match self.typer.adjustments().borrow().get(&expr.id) {
+ match self.typer.adjustments().get(&expr.id) {
None => {
// No adjustments.
self.cat_expr_unadjusted(expr)
}
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) {
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) => {
}
}
+// TODO: this is gonna need to be removed ...
/// Normalizes the parameter environment, reporting errors if they occur.
pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvironment<'a,'tcx>,
cause: ObligationCause<'tcx>)
let elaborated_env = unnormalized_env.with_caller_bounds(predicates);
- let infcx = infer::new_infer_ctxt(tcx);
- let predicates = match fully_normalize(&infcx, &elaborated_env, cause,
- &elaborated_env.caller_bounds) {
+ let infcx = infer::new_infer_ctxt(tcx, Some(elaborated_env));
+ let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause,
+ &infcx.parameter_environment.caller_bounds) {
Ok(predicates) => predicates,
Err(errors) => {
report_fulfillment_errors(&infcx, &errors);
- return unnormalized_env; // an unnormalized env is better than nothing
+ return infcx.parameter_environment; // an unnormalized env is better than nothing
}
};
// 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>,
// maps from an expression id that corresponds to a method call to the details
// of the method to be invoked
-pub type MethodMap<'tcx> = RefCell<FnvHashMap<MethodCall, MethodCallee<'tcx>>>;
+pub type MethodMap<'tcx> = FnvHashMap<MethodCall, MethodCallee<'tcx>>;
// Contains information needed to resolve types and (in the future) look up
// the types of AST nodes.
pub err: Ty<'tcx>,
}
+pub struct Tables<'tcx> {
+ /// Stores the types for various nodes in the AST. Note that this table
+ /// is not guaranteed to be populated until after typeck. See
+ /// typeck::check::fn_ctxt for details.
+ pub node_types: NodeMap<Ty<'tcx>>,
+
+ /// Stores the type parameters which were substituted to obtain the type
+ /// of this node. This only applies to nodes that refer to entities
+ /// parameterized by type parameters, such as generic fns, types, or
+ /// other items.
+ pub item_substs: NodeMap<ItemSubsts<'tcx>>,
+
+ pub adjustments: NodeMap<ty::AutoAdjustment<'tcx>>,
+
+ pub method_map: MethodMap<'tcx>,
+
+ /// Borrows
+ pub upvar_capture_map: UpvarCaptureMap,
+
+ /// Records the type of each closure. The def ID is the ID of the
+ /// expression defining the closure.
+ pub closure_tys: DefIdMap<ClosureTy<'tcx>>,
+
+ /// Records the type of each closure. The def ID is the ID of the
+ /// expression defining the closure.
+ pub closure_kinds: DefIdMap<ClosureKind>,
+}
+
+impl<'tcx> Tables<'tcx> {
+ pub fn empty() -> Tables<'tcx> {
+ Tables {
+ node_types: FnvHashMap(),
+ item_substs: NodeMap(),
+ adjustments: NodeMap(),
+ method_map: FnvHashMap(),
+ upvar_capture_map: FnvHashMap(),
+ closure_tys: DefIdMap(),
+ closure_kinds: DefIdMap(),
+ }
+ }
+}
+
/// The data structure to keep track of all the information that typechecker
/// generates so that so that it can be reused and doesn't have to be redone
/// later on.
// borrowck. (They are not used during trans, and hence are not
// serialized or needed for cross-crate fns.)
free_region_maps: RefCell<NodeMap<FreeRegionMap>>,
+ // FIXME: jroesch make this a refcell
- /// Stores the types for various nodes in the AST. Note that this table
- /// is not guaranteed to be populated until after typeck. See
- /// typeck::check::fn_ctxt for details.
- node_types: RefCell<NodeMap<Ty<'tcx>>>,
-
- /// Stores the type parameters which were substituted to obtain the type
- /// of this node. This only applies to nodes that refer to entities
- /// parameterized by type parameters, such as generic fns, types, or
- /// other items.
- pub item_substs: RefCell<NodeMap<ItemSubsts<'tcx>>>,
+ pub tables: RefCell<Tables<'tcx>>,
/// Maps from a trait item to the trait item "descriptor"
pub impl_or_trait_items: RefCell<DefIdMap<ImplOrTraitItem<'tcx>>>,
pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
pub ty_param_defs: RefCell<NodeMap<TypeParameterDef<'tcx>>>,
- pub adjustments: RefCell<NodeMap<AutoAdjustment<'tcx>>>,
pub normalized_cache: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
pub lang_items: middle::lang_items::LanguageItems,
/// A mapping of fake provided method def_ids to the default implementation
/// FIXME(arielb1): why is this separate from populated_external_types?
pub populated_external_primitive_impls: RefCell<DefIdSet>,
- /// Borrows
- pub upvar_capture_map: RefCell<UpvarCaptureMap>,
-
/// These caches are used by const_eval when decoding external constants.
pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
pub extern_const_fns: RefCell<DefIdMap<ast::NodeId>>,
- pub method_map: MethodMap<'tcx>,
-
pub dependency_formats: RefCell<dependency_format::Dependencies>,
- /// Records the type of each closure. The def ID is the ID of the
- /// expression defining the closure.
- pub closure_kinds: RefCell<DefIdMap<ClosureKind>>,
-
- /// Records the type of each closure. The def ID is the ID of the
- /// expression defining the closure.
- pub closure_tys: RefCell<DefIdMap<ClosureTy<'tcx>>>,
-
pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId, lint::LintId),
lint::LevelSource>>,
}
impl<'tcx> ctxt<'tcx> {
- pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> { self.node_types.borrow() }
+ pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> {
+ fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap<Ty<'tcx>> {
+ &tables.node_types
+ }
+
+ Ref::map(self.tables.borrow(), projection)
+ }
+
pub fn node_type_insert(&self, id: NodeId, ty: Ty<'tcx>) {
- self.node_types.borrow_mut().insert(id, ty);
+ self.tables.borrow_mut().node_types.insert(id, ty);
}
pub fn intern_trait_def(&self, def: TraitDef<'tcx>) -> &'tcx TraitDef<'tcx> {
}
}
+/// Create a type context and call the closure with a `&ty::ctxt` reference
+/// to the context. The closure enforces that the type context and any interned
+/// value (types, substs, etc.) can only be used while `ty::tls` has a valid
+/// reference to the context, to allow formatting values that need it.
+pub fn with_ctxt<'tcx, F, R>(s: Session,
+ arenas: &'tcx CtxtArenas<'tcx>,
+ def_map: DefMap,
+ named_region_map: resolve_lifetime::NamedRegionMap,
+ map: ast_map::Map<'tcx>,
+ freevars: RefCell<FreevarMap>,
+ region_maps: RegionMaps,
+ lang_items: middle::lang_items::LanguageItems,
+ stability: stability::Index<'tcx>,
+ f: F) -> (Session, R)
+ where F: FnOnce(&ctxt<'tcx>) -> R
+{
+ let mut interner = FnvHashMap();
+ let common_types = CommonTypes::new(&arenas.type_, &mut interner);
+
+ tls::enter(ctxt {
+ arenas: arenas,
+ interner: RefCell::new(interner),
+ substs_interner: RefCell::new(FnvHashMap()),
+ bare_fn_interner: RefCell::new(FnvHashMap()),
+ region_interner: RefCell::new(FnvHashMap()),
+ stability_interner: RefCell::new(FnvHashMap()),
+ types: common_types,
+ named_region_map: named_region_map,
+ region_maps: region_maps,
+ free_region_maps: RefCell::new(FnvHashMap()),
+ item_variance_map: RefCell::new(DefIdMap()),
+ variance_computed: Cell::new(false),
+ sess: s,
+ def_map: def_map,
+ tables: RefCell::new(Tables::empty()),
+ impl_trait_refs: RefCell::new(DefIdMap()),
+ trait_defs: RefCell::new(DefIdMap()),
+ predicates: RefCell::new(DefIdMap()),
+ super_predicates: RefCell::new(DefIdMap()),
+ fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()),
+ map: map,
+ freevars: freevars,
+ tcache: RefCell::new(DefIdMap()),
+ rcache: RefCell::new(FnvHashMap()),
+ tc_cache: RefCell::new(FnvHashMap()),
+ ast_ty_to_ty_cache: RefCell::new(NodeMap()),
+ enum_var_cache: RefCell::new(DefIdMap()),
+ impl_or_trait_items: RefCell::new(DefIdMap()),
+ trait_item_def_ids: RefCell::new(DefIdMap()),
+ trait_items_cache: RefCell::new(DefIdMap()),
+ ty_param_defs: RefCell::new(NodeMap()),
+ normalized_cache: RefCell::new(FnvHashMap()),
+ lang_items: lang_items,
+ provided_method_sources: RefCell::new(DefIdMap()),
+ struct_fields: RefCell::new(DefIdMap()),
+ destructor_for_type: RefCell::new(DefIdMap()),
+ destructors: RefCell::new(DefIdSet()),
+ inherent_impls: RefCell::new(DefIdMap()),
+ impl_items: RefCell::new(DefIdMap()),
+ used_unsafe: RefCell::new(NodeSet()),
+ used_mut_nodes: RefCell::new(NodeSet()),
+ populated_external_types: RefCell::new(DefIdSet()),
+ populated_external_primitive_impls: RefCell::new(DefIdSet()),
+ extern_const_statics: RefCell::new(DefIdMap()),
+ extern_const_variants: RefCell::new(DefIdMap()),
+ extern_const_fns: RefCell::new(DefIdMap()),
+ dependency_formats: RefCell::new(FnvHashMap()),
+ node_lint_levels: RefCell::new(FnvHashMap()),
+ transmute_restrictions: RefCell::new(Vec::new()),
+ stability: RefCell::new(stability),
+ selection_cache: traits::SelectionCache::new(),
+ repr_hint_cache: RefCell::new(DefIdMap()),
+ const_qualif_map: RefCell::new(NodeMap()),
+ custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
+ cast_kinds: RefCell::new(NodeMap()),
+ }, f)
+}
+
struct FlagComputation {
flags: TypeFlags,
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()),
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()),
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),
}
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,
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,
span: Span)
-> bool
{
- let infcx = infer::new_infer_ctxt(param_env.tcx());
+ let infcx = infer::new_infer_ctxt(param_env.tcx(), Some(param_env.clone()));
let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env,
self, bound, span);
}
pub fn node_id_to_type_opt(&self, id: ast::NodeId) -> Option<Ty<'tcx>> {
- self.node_types.borrow().get(&id).cloned()
+ self.tables.borrow().node_types.get(&id).cloned()
}
pub fn node_id_item_substs(&self, id: ast::NodeId) -> ItemSubsts<'tcx> {
- match self.item_substs.borrow().get(&id) {
+ match self.tables.borrow().item_substs.get(&id) {
None => ItemSubsts::empty(),
Some(ts) => ts.clone(),
}
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)
})
}
}
pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool {
- self.method_map.borrow().contains_key(&MethodCall::expr(expr_id))
+ self.tables.borrow().method_map.contains_key(&MethodCall::expr(expr_id))
}
pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
- Some(self.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
+ Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
}
}
}
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
- self.tcx.method_map.borrow().get(&method_call).map(|method| method.ty)
+ self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
}
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>
{
- self.tcx.method_map.borrow().get(&method_call).map(|method| method.origin.clone())
+ self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.origin.clone())
}
- fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
- &self.tcx.adjustments
+ fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
+ fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
+ &tables.adjustments
+ }
+
+ Ref::map(self.tcx.tables.borrow(), projection)
}
fn is_method_call(&self, id: ast::NodeId) -> bool {
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| {
_ => 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)) => {
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
}
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 \
#![feature(unicode)]
#![feature(unicode)]
#![feature(vec_push_all)]
+#![feature(cell_extras)]
#![allow(trivial_casts)]
fn process_method_call(&mut self,
ex: &ast::Expr,
args: &Vec<P<ast::Expr>>) {
- let method_map = self.tcx.method_map.borrow();
+ let method_map = &self.tcx.tables.borrow().method_map;
let method_callee = method_map.get(&ty::MethodCall::expr(ex.id)).unwrap();
let (def_id, decl_id) = match method_callee.origin {
ty::MethodStatic(def_id) |
}
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,
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,
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) => {
closure_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Datum<'tcx, Rvalue>> {
- if !ccx.tcx().closure_kinds.borrow().contains_key(&closure_id) {
+ if !ccx.tcx().tables.borrow().closure_kinds.contains_key(&closure_id) {
// Not a closure.
return None
}
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;
// 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.
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
self.tcx()
- .method_map
+ .tables
.borrow()
+ .method_map
.get(&method_call)
.map(|method| monomorphize_type(self, method.ty))
}
-> Option<ty::MethodOrigin<'tcx>>
{
self.tcx()
- .method_map
+ .tables
.borrow()
+ .method_map
.get(&method_call)
.map(|method| method.origin.clone())
}
- fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
- &self.tcx().adjustments
+ fn adjustments<'a>(&'a self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
+ fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
+ &tables.adjustments
+ }
+
+ Ref::map(self.tcx().tables.borrow(), project_adjustments)
}
fn is_method_call(&self, id: ast::NodeId) -> bool {
- self.tcx().method_map.borrow().contains_key(&ty::MethodCall::expr(id))
+ self.tcx().tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
}
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
}
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
- Some(self.tcx().upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
+ Some(self.tcx().tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
}
fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
trait_ref, trait_ref.def_id());
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
- let infcx = infer::new_infer_ctxt(tcx);
+ let infcx = infer::new_infer_ctxt(tcx, None);
// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
predicates);
let tcx = ccx.tcx();
- let infcx = infer::new_infer_ctxt(tcx);
+ let infcx = infer::new_infer_ctxt(tcx, None);
let typer = NormalizingClosureTyper::new(tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
let mut fulfill_cx = traits::FulfillmentContext::new(false);
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>
}
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()
}
};
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);
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
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")
};
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));
{
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);
}
// Don't skip a conversion from Box<T> to &T, etc.
ty::TyRef(..) => {
let method_call = MethodCall::autoderef(expr.id, 0);
- if bcx.tcx().method_map.borrow().contains_key(&method_call) {
+ if bcx.tcx().tables.borrow().method_map.contains_key(&method_call) {
// Don't skip an overloaded deref.
0
} else {
// 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 {
// 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);
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 => {
dest: Option<Dest>,
autoref: bool)
-> Result<'blk, 'tcx> {
- let method_ty = bcx.tcx().method_map.borrow().get(&method_call).unwrap().ty;
+ let method_ty = bcx.tcx()
+ .tables
+ .borrow()
+ .method_map
+ .get(&method_call).unwrap().ty;
+
callee::trans_call_inner(bcx,
expr.debug_loc(),
monomorphize_type(bcx, method_ty),
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;
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"));
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);
}
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 {
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) |
}
// FIXME(#20304) -- cache
-
- let infcx = infer::new_infer_ctxt(tcx);
+ // NOTE: @jroesch
+ // Here is of an example where we do not use a param_env but use a typer instead.
+ let infcx = infer::new_infer_ctxt(tcx, None);
let typer = NormalizingClosureTyper::new(tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
let cause = traits::ObligationCause::dummy();
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)]
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);
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 => { }
}
}
debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}",
impl_trait_ref);
- let infcx = infer::new_infer_ctxt(tcx);
+ let mut infcx = infer::new_infer_ctxt(tcx, None);
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
let trait_to_impl_substs = &impl_trait_ref.substs;
let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.into_vec());
let trait_param_env = traits::normalize_param_env_or_error(trait_param_env,
normalize_cause.clone());
+ // TODO (@jroesch) this seems ugly, but is a temporary change
+ infcx.parameter_environment = trait_param_env;
debug!("compare_impl_method: trait_bounds={:?}",
- trait_param_env.caller_bounds);
+ infcx.parameter_environment.caller_bounds);
- let mut selcx = traits::SelectionContext::new(&infcx, &trait_param_env);
+ let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment);
for predicate in impl_pred.fns {
let traits::Normalized { value: predicate, .. } =
// 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(_) => {}
}
// 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);
debug!("compare_const_impl(impl_trait_ref={:?})",
impl_trait_ref);
- let infcx = infer::new_infer_ctxt(tcx);
+ let infcx = infer::new_infer_ctxt(tcx, None);
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
// The below is for the most part highly similar to the procedure
ty: named_type } =
tcx.lookup_item_type(self_type_did);
- let infcx = infer::new_infer_ctxt(tcx);
+ let infcx = infer::new_infer_ctxt(tcx, None);
+
infcx.commit_if_ok(|snapshot| {
let (named_type_to_skolem, skol_map) =
infcx.construct_skolemized_subst(named_type_generics, snapshot);
// 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,
// 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 => {
// 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,
// 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 {
_ => 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 => {
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)
use middle::ty::{FnSig, GenericPredicates, TypeScheme};
use middle::ty::{Disr, ParamTy, ParameterEnvironment};
use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
-use middle::ty::{MethodCall, MethodCallee, MethodMap};
+use middle::ty::{MethodCall, MethodCallee};
use middle::ty_fold::{TypeFolder, TypeFoldable};
use rscope::RegionScope;
use session::Session;
pub struct Inherited<'a, 'tcx: 'a> {
infcx: infer::InferCtxt<'a, 'tcx>,
locals: RefCell<NodeMap<Ty<'tcx>>>,
- param_env: ty::ParameterEnvironment<'a, 'tcx>,
- // Temporary tables:
- node_types: RefCell<NodeMap<Ty<'tcx>>>,
- item_substs: RefCell<NodeMap<ty::ItemSubsts<'tcx>>>,
- adjustments: RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>,
- method_map: MethodMap<'tcx>,
- upvar_capture_map: RefCell<ty::UpvarCaptureMap>,
- closure_tys: RefCell<DefIdMap<ty::ClosureTy<'tcx>>>,
- closure_kinds: RefCell<DefIdMap<ty::ClosureKind>>,
+ tables: &'a RefCell<ty::Tables<'tcx>>,
// A mapping from each fn's id to its signature, with all bound
// regions replaced with free ones. Unlike the other tables, this
let ty = self.node_ty(id);
self.resolve_type_vars_or_error(&ty)
}
+
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
- let ty = self.adjust_expr_ty(expr, self.inh.adjustments.borrow().get(&expr.id));
+ let ty = self.adjust_expr_ty(expr, self.inh.tables.borrow().adjustments.get(&expr.id));
self.resolve_type_vars_or_error(&ty)
}
+
fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
let ty = self.infcx().resolve_type_vars_if_possible(&ty);
!traits::type_known_to_meet_builtin_bound(self.infcx(), self, ty, ty::BoundCopy, span)
}
+
fn node_method_ty(&self, method_call: ty::MethodCall)
-> Option<Ty<'tcx>> {
- self.inh.method_map.borrow()
- .get(&method_call)
- .map(|method| method.ty)
- .map(|ty| self.infcx().resolve_type_vars_if_possible(&ty))
+ self.inh.tables
+ .borrow()
+ .method_map
+ .get(&method_call)
+ .map(|method| method.ty)
+ .map(|ty| self.infcx().resolve_type_vars_if_possible(&ty))
}
+
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>
{
- self.inh.method_map.borrow()
- .get(&method_call)
- .map(|method| method.origin.clone())
+ self.inh.tables
+ .borrow()
+ .method_map
+ .get(&method_call)
+ .map(|method| method.origin.clone())
}
- fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
- &self.inh.adjustments
+
+ fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
+ fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
+ &tables.adjustments
+ }
+
+ Ref::map(self.inh.tables.borrow(), project_adjustments)
}
+
fn is_method_call(&self, id: ast::NodeId) -> bool {
- self.inh.method_map.borrow().contains_key(&ty::MethodCall::expr(id))
+ self.inh.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
}
+
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
self.param_env().temporary_scope(rvalue_id)
}
+
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
- self.inh.upvar_capture_map.borrow().get(&upvar_id).cloned()
+ self.inh.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
}
}
impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
- &self.inh.param_env
+ &self.inh.infcx.parameter_environment
}
fn closure_kind(&self,
def_id: ast::DefId)
-> Option<ty::ClosureKind>
{
- self.inh.closure_kinds.borrow().get(&def_id).cloned()
+ self.inh.tables.borrow().closure_kinds.get(&def_id).cloned()
}
fn closure_type(&self,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>
{
- self.inh.closure_tys.borrow().get(&def_id).unwrap().subst(self.tcx(), substs)
+ self.inh.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self.tcx(), substs)
}
fn closure_upvars(&self,
impl<'a, 'tcx> Inherited<'a, 'tcx> {
fn new(tcx: &'a ty::ctxt<'tcx>,
+ tables: &'a RefCell<ty::Tables<'tcx>>,
param_env: ty::ParameterEnvironment<'a, 'tcx>)
-> Inherited<'a, 'tcx> {
+
Inherited {
- infcx: infer::new_infer_ctxt(tcx),
+ infcx: infer::new_infer_ctxt(tcx, Some(param_env)),
locals: RefCell::new(NodeMap()),
- param_env: param_env,
- node_types: RefCell::new(NodeMap()),
- item_substs: RefCell::new(NodeMap()),
- adjustments: RefCell::new(NodeMap()),
- method_map: RefCell::new(FnvHashMap()),
- upvar_capture_map: RefCell::new(FnvHashMap()),
- closure_tys: RefCell::new(DefIdMap()),
- closure_kinds: RefCell::new(DefIdMap()),
+ tables: tables,
fn_sig_map: RefCell::new(NodeMap()),
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(true)),
deferred_call_resolutions: RefCell::new(DefIdMap()),
}
}
-fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>)
+fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, tables: &'a RefCell<ty::Tables<'tcx>>)
-> Inherited<'a, 'tcx> {
// It's kind of a kludge to manufacture a fake function context
// and statement context, but we might as well do write the code only once
let param_env = ccx.tcx.empty_parameter_environment();
- Inherited::new(ccx.tcx, param_env)
+ Inherited::new(ccx.tcx, &tables, param_env)
}
struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
{
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);
}
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,
-> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
{
let def = self.tcx().type_parameter_def(node_id);
- let r = self.inh.param_env.caller_bounds
+ let r = self.inh.infcx.parameter_environment
+ .caller_bounds
.iter()
.filter_map(|predicate| {
match *predicate {
}
pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
- &self.inh.param_env
+ &self.inh.infcx.parameter_environment
}
pub fn sess(&self) -> &Session {
/// ! 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());
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>) {
substs,
self.tag());
- self.inh.item_substs.borrow_mut().insert(node_id, substs);
+ self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
}
}
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
}
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 {}",
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 => {
}
pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'tcx>>> {
- self.inh.item_substs.borrow()
+ // NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if it changes
+ // when we upgrade the snapshot compiler
+ fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap<ty::ItemSubsts<'tcx>> {
+ &tables.item_substs
+ }
+
+ Ref::map(self.inh.tables.borrow(), project_item_susbts)
}
pub fn opt_node_ty_substs<F>(&self,
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 => { }
}
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
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) => {
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);
}
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;
let rty = ccx.tcx.node_id_to_type(id);
let mut disr_vals: Vec<ty::Disr> = Vec::new();
- let inh = static_inherited_fields(ccx);
+ let tables = RefCell::new(ty::Tables::empty());
+ let inh = static_inherited_fields(ccx, &tables);
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
// 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
}
}
}
-
pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) {
let mut rcx = Rcx::new(fcx, RepeatingScope(item.id), item.id, Subject(item.id));
let tcx = fcx.tcx();
- rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds);
+ rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.infcx.parameter_environment.caller_bounds);
rcx.visit_region_obligations(item.id);
rcx.resolve_regions_and_report_errors();
}
}
let tcx = fcx.tcx();
- rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds);
+ rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.infcx.parameter_environment.caller_bounds);
rcx.resolve_regions_and_report_errors();
}
fn resolve_method_type(&self, method_call: MethodCall) -> Option<Ty<'tcx>> {
- let method_ty = self.fcx.inh.method_map.borrow()
+ let method_ty = self.fcx.inh.tables.borrow().method_map
.get(&method_call).map(|method| method.ty);
method_ty.map(|method_ty| self.resolve_type(method_ty))
}
} 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))
}
}
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);
ast::ExprUnary(ast::UnDeref, ref base) => {
// For *a, the lifetime of a must enclose the deref
let method_call = MethodCall::expr(expr.id);
- let base_ty = match rcx.fcx.inh.method_map.borrow().get(&method_call) {
+ let base_ty = match rcx.fcx.inh.tables.borrow().method_map.get(&method_call) {
Some(method) => {
constrain_call(rcx, expr, Some(&**base),
None::<ast::Expr>.iter(), true);
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);
// 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={:?})",
// 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
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,
_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);
}
}
};
- 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);
}
});
}
// 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) => {
// 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);
}
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={:?}",
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;
&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();
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);
// 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);
};
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
.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 }
})
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,
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);
}
}
}
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) => {
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);
}
}
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);
}
}
}
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);
}
}
};
debug!("Adjustments for node {}: {:?}", id, resolved_adjustment);
- self.tcx().adjustments.borrow_mut().insert(
+ self.tcx().tables.borrow_mut().adjustments.insert(
id, resolved_adjustment);
}
}
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,
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 => {}
}
debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (free)",
source, target);
- let infcx = new_infer_ctxt(tcx);
+ let infcx = new_infer_ctxt(tcx, Some(param_env));
let check_mutbl = |mt_a: ty::mt<'tcx>, mt_b: ty::mt<'tcx>,
mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| {
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 {
pub fn check_coherence(crate_context: &CrateCtxt) {
CoherenceChecker {
crate_context: crate_context,
- inference_context: new_infer_ctxt(crate_context.tcx),
+ inference_context: new_infer_ctxt(crate_context.tcx, None),
inherent_impls: RefCell::new(FnvHashMap()),
}.check(crate_context.tcx.map.krate());
unsafety::check(crate_context.tcx);
impl1_def_id,
impl2_def_id);
- let infcx = infer::new_infer_ctxt(self.tcx);
+ let infcx = infer::new_infer_ctxt(self.tcx, None);
if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) {
self.report_overlap_error(trait_def_id, impl1_def_id, impl2_def_id);
}
base_type,
base_type_free);
- let infcx = infer::new_infer_ctxt(tcx);
+ let infcx = infer::new_infer_ctxt(tcx, None);
drop(::require_same_types(tcx,
Some(&infcx),
false,
#![feature(slice_extras)]
#![feature(staged_api)]
#![feature(vec_push_all)]
+#![feature(cell_extras)]
#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
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);
}
}
{
let result = match maybe_infcx {
None => {
- let infcx = infer::new_infer_ctxt(tcx);
+ let infcx = infer::new_infer_ctxt(tcx, None);
infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2)
}
Some(infcx) => {