Auto merge of #26582 - jroesch:infer-ctxt-refactor, r=nikomatsakis

This branch begins the work of unifying our type checking contexts into a single piece of state. The goal is to eventually have a single context that we can pass around instead of the fractured situation we currently have. There are still several things that must be done before beginning to make tables item local:

- [ ] move FulfillmentContext into InferCtxt
- [ ] modify SelectionContext to only take a single context argument
- [ ] remove remaining typer impls 
- [ ] remove the ClosureTyper + Typer trait
- [ ] do some renaming to make these things more applicable to their new roles

r? @nikomatsakis 

As a side note there are a couple oddities that are temporary refactors that will be quickly cleaned up in a follow-up PR.

cc @eddyb @Aatch @arielb1 @nrc
This commit is contained in:
bors 2015-06-29 00:03:37 +00:00
commit a973e4cda5
51 changed files with 586 additions and 351 deletions

View file

@ -61,6 +61,7 @@
#![feature(str_match_indices)]
#![feature(vec_push_all)]
#![feature(wrapping)]
#![feature(cell_extras)]
#![cfg_attr(test, feature(test))]
#![allow(trivial_casts)]

View file

@ -1027,7 +1027,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
})
}
if let Some(item_substs) = tcx.item_substs.borrow().get(&id) {
if let Some(item_substs) = tcx.tables.borrow().item_substs.get(&id) {
rbml_w.tag(c::tag_table_item_subst, |rbml_w| {
rbml_w.id(id);
rbml_w.emit_substs(ecx, &item_substs.substs);
@ -1051,7 +1051,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 => {

View file

@ -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)
}
}

View file

@ -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
};

View file

@ -98,6 +98,7 @@ impl<'a> FromIterator<Vec<&'a Pat>> 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>,

View file

@ -1031,10 +1031,9 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
substs: trait_substs });
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
let infcx = infer::new_infer_ctxt(tcx);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let param_env = tcx.empty_parameter_environment();
let mut selcx = traits::SelectionContext::new(&infcx, &param_env);
let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment);
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
trait_ref.to_poly_trait_predicate());
let selection = match selcx.select(&obligation) {

View file

@ -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) => {

View file

@ -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) {

View file

@ -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

View file

@ -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<T> = Result<T, fixup_err>; // "fixup result"
pub struct InferCtxt<'a, 'tcx: 'a> {
pub tcx: &'a ty::ctxt<'tcx>,
pub tables: &'a RefCell<ty::Tables<'tcx>>,
// We instantiate UnificationTable with bounds<Ty> 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<ty::Tables<'tcx>>,
param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>)
-> 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<Ty<'tcx>> {
let ty = self.node_ty(id);
self.resolve_type_vars_or_error(&ty)
}
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
let ty = self.adjust_expr_ty(expr, self.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<Ty<'tcx>> {
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<ty::MethodOrigin<'tcx>>
{
self.tables
.borrow()
.method_map
.get(&method_call)
.map(|method| method.origin.clone())
}
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.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<CodeExtent> {
self.parameter_environment.temporary_scope(rvalue_id)
}
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
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<ty::ClosureKind>
{
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<Vec<ty::ClosureUpvar<'tcx>>>
{
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<T:TypeFoldable<'tcx>>(&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<Ty<'tcx>> {
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<T:TypeFoldable<'tcx>>(&self, value: &T) -> fres<T> {
/*!
* Attempts to resolve all type/region variables in

View file

@ -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 {

View file

@ -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<Ty<'tcx>>;
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>;
fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>;
fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>>;
fn is_method_call(&self, id: ast::NodeId) -> bool;
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture>;
@ -408,7 +408,7 @@ 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<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)

View file

@ -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) {

View file

@ -406,7 +406,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
ast::ExprMethodCall(i, _, _) => {
span = i.span;
let method_call = ty::MethodCall::expr(e.id);
match tcx.method_map.borrow().get(&method_call) {
match tcx.tables.borrow().method_map.get(&method_call) {
Some(method) => {
match method.origin {
ty::MethodStatic(def_id) => {

View file

@ -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>,

View file

@ -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,
}

View file

@ -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<FnvHashMap<MethodCall, MethodCallee<'tcx>>>;
pub type MethodMap<'tcx> = FnvHashMap<MethodCall, MethodCallee<'tcx>>;
// Contains information needed to resolve types and (in the future) look up
// the types of AST nodes.
@ -815,6 +815,48 @@ pub struct CommonTypes<'tcx> {
pub err: Ty<'tcx>,
}
pub struct Tables<'tcx> {
/// Stores the types for various nodes in the AST. Note that this table
/// is not guaranteed to be populated until after typeck. See
/// typeck::check::fn_ctxt for details.
pub node_types: NodeMap<Ty<'tcx>>,
/// Stores the type parameters which were substituted to obtain the type
/// of this node. This only applies to nodes that refer to entities
/// parameterized by type parameters, such as generic fns, types, or
/// other items.
pub item_substs: NodeMap<ItemSubsts<'tcx>>,
pub adjustments: NodeMap<ty::AutoAdjustment<'tcx>>,
pub method_map: MethodMap<'tcx>,
/// Borrows
pub upvar_capture_map: UpvarCaptureMap,
/// Records the type of each closure. The def ID is the ID of the
/// expression defining the closure.
pub closure_tys: DefIdMap<ClosureTy<'tcx>>,
/// Records the type of each closure. The def ID is the ID of the
/// expression defining the closure.
pub closure_kinds: DefIdMap<ClosureKind>,
}
impl<'tcx> Tables<'tcx> {
pub fn empty() -> Tables<'tcx> {
Tables {
node_types: FnvHashMap(),
item_substs: NodeMap(),
adjustments: NodeMap(),
method_map: FnvHashMap(),
upvar_capture_map: FnvHashMap(),
closure_tys: DefIdMap(),
closure_kinds: DefIdMap(),
}
}
}
/// The data structure to keep track of all the information that typechecker
/// generates so that so that it can be reused and doesn't have to be redone
/// later on.
@ -850,17 +892,9 @@ pub struct ctxt<'tcx> {
// borrowck. (They are not used during trans, and hence are not
// serialized or needed for cross-crate fns.)
free_region_maps: RefCell<NodeMap<FreeRegionMap>>,
// FIXME: jroesch make this a refcell
/// Stores the types for various nodes in the AST. Note that this table
/// is not guaranteed to be populated until after typeck. See
/// typeck::check::fn_ctxt for details.
node_types: RefCell<NodeMap<Ty<'tcx>>>,
/// Stores the type parameters which were substituted to obtain the type
/// of this node. This only applies to nodes that refer to entities
/// parameterized by type parameters, such as generic fns, types, or
/// other items.
pub item_substs: RefCell<NodeMap<ItemSubsts<'tcx>>>,
pub tables: RefCell<Tables<'tcx>>,
/// Maps from a trait item to the trait item "descriptor"
pub impl_or_trait_items: RefCell<DefIdMap<ImplOrTraitItem<'tcx>>>,
@ -894,7 +928,6 @@ pub struct ctxt<'tcx> {
pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
pub ty_param_defs: RefCell<NodeMap<TypeParameterDef<'tcx>>>,
pub adjustments: RefCell<NodeMap<AutoAdjustment<'tcx>>>,
pub normalized_cache: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
pub lang_items: middle::lang_items::LanguageItems,
/// A mapping of fake provided method def_ids to the default implementation
@ -944,26 +977,13 @@ pub struct ctxt<'tcx> {
/// FIXME(arielb1): why is this separate from populated_external_types?
pub populated_external_primitive_impls: RefCell<DefIdSet>,
/// Borrows
pub upvar_capture_map: RefCell<UpvarCaptureMap>,
/// These caches are used by const_eval when decoding external constants.
pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
pub extern_const_fns: RefCell<DefIdMap<ast::NodeId>>,
pub method_map: MethodMap<'tcx>,
pub dependency_formats: RefCell<dependency_format::Dependencies>,
/// Records the type of each closure. The def ID is the ID of the
/// expression defining the closure.
pub closure_kinds: RefCell<DefIdMap<ClosureKind>>,
/// Records the type of each closure. The def ID is the ID of the
/// expression defining the closure.
pub closure_tys: RefCell<DefIdMap<ClosureTy<'tcx>>>,
pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId, lint::LintId),
lint::LevelSource>>,
@ -1000,9 +1020,16 @@ pub struct ctxt<'tcx> {
}
impl<'tcx> ctxt<'tcx> {
pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> { self.node_types.borrow() }
pub fn node_types(&self) -> Ref<NodeMap<Ty<'tcx>>> {
fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap<Ty<'tcx>> {
&tables.node_types
}
Ref::map(self.tables.borrow(), projection)
}
pub fn node_type_insert(&self, id: NodeId, ty: Ty<'tcx>) {
self.node_types.borrow_mut().insert(id, ty);
self.tables.borrow_mut().node_types.insert(id, ty);
}
pub fn intern_trait_def(&self, def: TraitDef<'tcx>) -> &'tcx TraitDef<'tcx> {
@ -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<Ty<'tcx>> {
self.node_types.borrow().get(&id).cloned()
self.tables.borrow().node_types.get(&id).cloned()
}
pub fn node_id_item_substs(&self, id: ast::NodeId) -> ItemSubsts<'tcx> {
match self.item_substs.borrow().get(&id) {
match self.tables.borrow().item_substs.get(&id) {
None => ItemSubsts::empty(),
Some(ts) => ts.clone(),
}
@ -5325,9 +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<ty::UpvarCapture> {
Some(self.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
}
}
@ -6689,17 +6711,21 @@ impl<'a,'tcx> Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
}
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
self.tcx.method_map.borrow().get(&method_call).map(|method| method.ty)
self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
}
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>
{
self.tcx.method_map.borrow().get(&method_call).map(|method| method.origin.clone())
self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.origin.clone())
}
fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
&self.tcx.adjustments
fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
fn projection<'a, 'tcx>(tables: &'a Tables<'tcx>) -> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
&tables.adjustments
}
Ref::map(self.tcx.tables.borrow(), projection)
}
fn is_method_call(&self, id: ast::NodeId) -> bool {

View file

@ -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| {

View file

@ -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();

View file

@ -140,7 +140,7 @@ fn test_env<F>(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);

View file

@ -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

View file

@ -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 \

View file

@ -43,6 +43,7 @@
#![feature(unicode)]
#![feature(unicode)]
#![feature(vec_push_all)]
#![feature(cell_extras)]
#![allow(trivial_casts)]

View file

@ -886,7 +886,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
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) |

View file

@ -212,7 +212,7 @@ pub fn self_type_for_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
}
pub fn kind_for_closure(ccx: &CrateContext, closure_id: ast::DefId) -> ty::ClosureKind {
*ccx.tcx().closure_kinds.borrow().get(&closure_id).unwrap()
*ccx.tcx().tables.borrow().closure_kinds.get(&closure_id).unwrap()
}
pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId,

View file

@ -518,7 +518,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
let ref_ty = match node {
ExprId(id) => tcx.node_id_to_type(id),
MethodCallKey(method_call) => {
tcx.method_map.borrow().get(&method_call).unwrap().ty
tcx.tables.borrow().method_map.get(&method_call).unwrap().ty
}
};
let ref_ty = monomorphize::apply_param_substs(tcx,
@ -610,7 +610,7 @@ pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let _icx = push_ctxt("trans_method_call");
debug!("trans_method_call(call_expr={:?})", call_expr);
let method_call = MethodCall::expr(call_expr.id);
let method_ty = match bcx.tcx().method_map.borrow().get(&method_call) {
let method_ty = match bcx.tcx().tables.borrow().method_map.get(&method_call) {
Some(method) => match method.origin {
ty::MethodTraitObject(_) => match method.ty.sty {
ty::TyBareFn(_, ref fty) => {

View file

@ -130,7 +130,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
closure_id: ast::DefId,
substs: &Substs<'tcx>)
-> Option<Datum<'tcx, Rvalue>> {
if !ccx.tcx().closure_kinds.borrow().contains_key(&closure_id) {
if !ccx.tcx().tables.borrow().closure_kinds.contains_key(&closure_id) {
// Not a closure.
return None
}

View file

@ -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<Ty<'tcx>> {
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<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>>> {
// 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<ty::AutoAdjustment<'tcx>> {
&tables.adjustments
}
Ref::map(self.tcx().tables.borrow(), project_adjustments)
}
fn is_method_call(&self, id: ast::NodeId) -> bool {
self.tcx().method_map.borrow().contains_key(&ty::MethodCall::expr(id))
self.tcx().tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
}
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
@ -659,7 +668,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
}
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
Some(self.tcx().upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
Some(self.tcx().tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
}
fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
@ -991,7 +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()
}
};

View file

@ -228,7 +228,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
match def {
def::DefConst(def_id) | def::DefAssociatedConst(def_id, _) => {
if !ccx.tcx().adjustments.borrow().contains_key(&expr.id) {
if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
debug!("get_const_expr_as_global ({:?}): found const {:?}",
expr.id, def_id);
return get_const_val(ccx, def_id, expr);
@ -281,7 +281,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let mut llconst = llconst;
let mut ety_adjusted = monomorphize::apply_param_substs(cx.tcx(), param_substs,
&cx.tcx().expr_ty_adjusted(e));
let opt_adj = cx.tcx().adjustments.borrow().get(&e.id).cloned();
let opt_adj = cx.tcx().tables.borrow().adjustments.get(&e.id).cloned();
match opt_adj {
Some(ty::AdjustReifyFnPointer) => {
// FIXME(#19925) once fn item types are
@ -894,7 +894,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
ast::ExprMethodCall(_, _, ref args) => {
let arg_vals = map_list(args);
let method_call = ty::MethodCall::expr(e.id);
let method_did = match cx.tcx().method_map.borrow()[&method_call].origin {
let method_did = match cx.tcx().tables.borrow().method_map[&method_call].origin {
ty::MethodStatic(did) => did,
_ => cx.sess().span_bug(e.span, "expected a const method def")
};

View file

@ -117,7 +117,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
if bcx.tcx().adjustments.borrow().contains_key(&expr.id) {
if bcx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
// use trans, which may be less efficient but
// which will perform the adjustments:
let datum = unpack_datum!(bcx, trans(bcx, expr));
@ -345,7 +345,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
{
let mut bcx = bcx;
let mut datum = datum;
let adjustment = match bcx.tcx().adjustments.borrow().get(&expr.id).cloned() {
let adjustment = match bcx.tcx().tables.borrow().adjustments.get(&expr.id).cloned() {
None => {
return DatumBlock::new(bcx, datum);
}
@ -372,7 +372,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Don't skip a conversion from Box<T> to &T, etc.
ty::TyRef(..) => {
let method_call = MethodCall::autoderef(expr.id, 0);
if bcx.tcx().method_map.borrow().contains_key(&method_call) {
if bcx.tcx().tables.borrow().method_map.contains_key(&method_call) {
// Don't skip an overloaded deref.
0
} else {
@ -774,8 +774,9 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Check for overloaded index.
let method_ty = ccx.tcx()
.method_map
.tables
.borrow()
.method_map
.get(&method_call)
.map(|method| method.ty);
let elt_datum = match method_ty {
@ -1617,7 +1618,7 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Otherwise, we should be in the RvalueDpsExpr path.
assert!(
op == ast::UnDeref ||
!ccx.tcx().method_map.borrow().contains_key(&method_call));
!ccx.tcx().tables.borrow().method_map.contains_key(&method_call));
let un_ty = expr_ty(bcx, expr);
@ -1910,7 +1911,7 @@ fn trans_binary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let ccx = bcx.ccx();
// if overloaded, would be RvalueDpsExpr
assert!(!ccx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id)));
assert!(!ccx.tcx().tables.borrow().method_map.contains_key(&MethodCall::expr(expr.id)));
match op.node {
ast::BiAnd => {
@ -1950,7 +1951,12 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
dest: Option<Dest>,
autoref: bool)
-> Result<'blk, 'tcx> {
let method_ty = bcx.tcx().method_map.borrow().get(&method_call).unwrap().ty;
let method_ty = bcx.tcx()
.tables
.borrow()
.method_map
.get(&method_call).unwrap().ty;
callee::trans_call_inner(bcx,
expr.debug_loc(),
monomorphize_type(bcx, method_ty),
@ -1973,8 +1979,9 @@ fn trans_overloaded_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
debug!("trans_overloaded_call {}", expr.id);
let method_call = MethodCall::expr(expr.id);
let method_type = bcx.tcx()
.method_map
.tables
.borrow()
.method_map
.get(&method_call)
.unwrap()
.ty;
@ -2154,7 +2161,7 @@ fn trans_assign_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
debug!("trans_assign_op(expr={:?})", expr);
// User-defined operator methods cannot be used with `+=` etc right now
assert!(!bcx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id)));
assert!(!bcx.tcx().tables.borrow().method_map.contains_key(&MethodCall::expr(expr.id)));
// Evaluate LHS (destination), which should be an lvalue
let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op"));
@ -2229,8 +2236,12 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let mut bcx = bcx;
// Check for overloaded deref.
let method_ty = ccx.tcx().method_map.borrow()
let method_ty = ccx.tcx()
.tables
.borrow()
.method_map
.get(&method_call).map(|method| method.ty);
let datum = match method_ty {
Some(method_ty) => {
let method_ty = monomorphize_type(bcx, method_ty);
@ -2615,7 +2626,7 @@ enum ExprKind {
}
fn expr_kind(tcx: &ty::ctxt, expr: &ast::Expr) -> ExprKind {
if tcx.method_map.borrow().contains_key(&MethodCall::expr(expr.id)) {
if tcx.tables.borrow().method_map.contains_key(&MethodCall::expr(expr.id)) {
// Overloaded operations are generally calls, and hence they are
// generated via DPS, but there are a few exceptions:
return match expr.node {

View file

@ -109,11 +109,13 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let _icx = push_ctxt("meth::trans_method_callee");
let (origin, method_ty) =
bcx.tcx().method_map
.borrow()
.get(&method_call)
.map(|method| (method.origin.clone(), method.ty))
.unwrap();
bcx.tcx()
.tables
.borrow()
.method_map
.get(&method_call)
.map(|method| (method.origin.clone(), method.ty))
.unwrap();
match origin {
ty::MethodStatic(did) |

View file

@ -322,8 +322,9 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
}
// FIXME(#20304) -- cache
let infcx = infer::new_infer_ctxt(tcx);
// NOTE: @jroesch
// Here is of an example where we do not use a param_env but use a typer instead.
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
let typer = NormalizingClosureTyper::new(tcx);
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
let cause = traits::ObligationCause::dummy();

View file

@ -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,

View file

@ -61,7 +61,7 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
expected_sig);
let closure_type = fcx.ccx.tcx.mk_closure(expr_def_id,
fcx.ccx.tcx.mk_substs(fcx.inh.param_env.free_substs.clone()));
fcx.ccx.tcx.mk_substs(fcx.inh.infcx.parameter_environment.free_substs.clone()));
fcx.write_ty(expr.id, closure_type);
@ -86,9 +86,9 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
fn_ty.sig,
opt_kind);
fcx.inh.closure_tys.borrow_mut().insert(expr_def_id, fn_ty);
fcx.inh.tables.borrow_mut().closure_tys.insert(expr_def_id, fn_ty);
match opt_kind {
Some(kind) => { fcx.inh.closure_kinds.borrow_mut().insert(expr_def_id, kind); }
Some(kind) => { fcx.inh.tables.borrow_mut().closure_kinds.insert(expr_def_id, kind); }
None => { }
}
}

View file

@ -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();

View file

@ -43,7 +43,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}",
impl_trait_ref);
let infcx = infer::new_infer_ctxt(tcx);
let mut infcx = infer::new_infer_ctxt(tcx, &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

View file

@ -93,7 +93,8 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
ty: named_type } =
tcx.lookup_item_type(self_type_did);
let infcx = infer::new_infer_ctxt(tcx);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
infcx.commit_if_ok(|snapshot| {
let (named_type_to_skolem, skol_map) =
infcx.construct_skolemized_subst(named_type_generics, snapshot);

View file

@ -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,

View file

@ -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.

View file

@ -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.

View file

@ -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();

View file

@ -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<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
@ -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<Ty<'tcx>> {
let ty = self.node_ty(id);
self.resolve_type_vars_or_error(&ty)
}
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
let ty = self.adjust_expr_ty(expr, self.inh.adjustments.borrow().get(&expr.id));
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))
}
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())
}
fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
&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<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()
}
}
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<ty::ClosureKind>
{
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<Vec<ty::ClosureUpvar<'tcx>>> {
ty::ctxt::closure_upvars(self, def_id, substs)
}
}
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, 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<ty::Tables<'tcx>>)
-> Inherited<'a, 'tcx> {
// It's kind of a kludge to manufacture a fake function context
// and statement context, but we might as well do write the code only once
let param_env = ccx.tcx.empty_parameter_environment();
Inherited::new(ccx.tcx, param_env)
Inherited::new(ccx.tcx, &tables, param_env)
}
struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
@ -504,16 +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<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
{
let def = self.tcx().type_parameter_def(node_id);
let r = self.inh.param_env.caller_bounds
let r = self.inh.infcx.parameter_environment
.caller_bounds
.iter()
.filter_map(|predicate| {
match *predicate {
@ -1273,7 +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<Ty<'tcx>> {
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<T>(&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<NodeMap<ty::ItemSubsts<'tcx>>> {
self.inh.item_substs.borrow()
// NOTE: @jroesch this is hack that appears to be fixed on nightly, will monitor if
// it changes when we upgrade the snapshot compiler
fn project_item_susbts<'a, 'tcx>(tables: &'a ty::Tables<'tcx>)
-> &'a NodeMap<ty::ItemSubsts<'tcx>> {
&tables.item_substs
}
Ref::map(self.inh.tables.borrow(), project_item_susbts)
}
pub fn opt_node_ty_substs<F>(&self,
@ -1673,7 +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<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));

View file

@ -330,7 +330,7 @@ fn lookup_op_method<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
// HACK(eddyb) Fully qualified path to work around a resolve bug.
let method_call = ::middle::ty::MethodCall::expr(expr.id);
fcx.inh.method_map.borrow_mut().insert(method_call, method);
fcx.inh.tables.borrow_mut().method_map.insert(method_call, method);
// extract return type for method; all late bound regions
// should have been instantiated by now
@ -454,4 +454,3 @@ fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>,
}
}
}

View file

@ -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<Ty<'tcx>> {
let method_ty = self.fcx.inh.method_map.borrow()
let method_ty = self.fcx.inh.tables.borrow().method_map
.get(&method_call).map(|method| method.ty);
method_ty.map(|method_ty| self.resolve_type(method_ty))
}
@ -267,7 +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::<ast::Expr>.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<FnCtxt<'a, 'tcx>>,
mc: mc::MemCategorizationContext<InferCtxt<'a, 'tcx>>,
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,

View file

@ -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={:?}",

View file

@ -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,

View file

@ -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 => {}
}

View file

@ -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, &param_env) {
if let Err(errors) = fulfill_cx.select_all_or_error(&infcx,
&infcx.parameter_environment) {
traits::report_fulfillment_errors(&infcx, &errors);
}
// Finally, resolve all regions.
let mut free_regions = FreeRegionMap::new();
free_regions.relate_free_regions_from_predicates(tcx, &param_env.caller_bounds);
free_regions.relate_free_regions_from_predicates(tcx, &infcx.parameter_environment
.caller_bounds);
infcx.resolve_regions_and_report_errors(&free_regions, impl_did.node);
if let Some(kind) = kind {
@ -630,7 +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);

View file

@ -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);
}

View file

@ -2204,7 +2204,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
base_type,
base_type_free);
let infcx = infer::new_infer_ctxt(tcx);
let infcx = infer::new_infer_ctxt(tcx, &tcx.tables, None);
drop(::require_same_types(tcx,
Some(&infcx),
false,

View file

@ -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) => {