Begin refactor type checking state
This first patch starts by moving around pieces of state related to type checking. The goal is to slowly unify the type checking state into a single typing context. This initial patch moves the ParameterEnvironment into the InferCtxt and moves shared tables from Inherited and ty::ctxt into their own struct Tables. This is the foundational work to refactoring the type checker to enable future evolution of the language and tooling.
This commit is contained in:
parent
2ba46f8bbc
commit
79d02895ff
45 changed files with 427 additions and 252 deletions
|
@ -61,6 +61,7 @@
|
||||||
#![feature(str_match_indices)]
|
#![feature(str_match_indices)]
|
||||||
#![feature(vec_push_all)]
|
#![feature(vec_push_all)]
|
||||||
#![feature(wrapping)]
|
#![feature(wrapping)]
|
||||||
|
#![feature(cell_extras)]
|
||||||
#![cfg_attr(test, feature(test))]
|
#![cfg_attr(test, feature(test))]
|
||||||
|
|
||||||
#![allow(trivial_casts)]
|
#![allow(trivial_casts)]
|
||||||
|
|
|
@ -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.tag(c::tag_table_item_subst, |rbml_w| {
|
||||||
rbml_w.id(id);
|
rbml_w.id(id);
|
||||||
rbml_w.emit_substs(ecx, &item_substs.substs);
|
rbml_w.emit_substs(ecx, &item_substs.substs);
|
||||||
|
@ -1051,7 +1051,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||||
var_id: var_id,
|
var_id: var_id,
|
||||||
closure_expr_id: 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);
|
var_id.encode(rbml_w);
|
||||||
upvar_capture.encode(rbml_w);
|
upvar_capture.encode(rbml_w);
|
||||||
})
|
})
|
||||||
|
@ -1074,19 +1074,19 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
let method_call = MethodCall::expr(id);
|
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.tag(c::tag_table_method_map, |rbml_w| {
|
||||||
rbml_w.id(id);
|
rbml_w.id(id);
|
||||||
encode_method_callee(ecx, rbml_w, method_call.autoderef, method)
|
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 {
|
match *adjustment {
|
||||||
ty::AdjustDerefRef(ref adj) => {
|
ty::AdjustDerefRef(ref adj) => {
|
||||||
for autoderef in 0..adj.autoderefs {
|
for autoderef in 0..adj.autoderefs {
|
||||||
let method_call = MethodCall::autoderef(id, autoderef as u32);
|
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.tag(c::tag_table_method_map, |rbml_w| {
|
||||||
rbml_w.id(id);
|
rbml_w.id(id);
|
||||||
encode_method_callee(ecx, rbml_w,
|
encode_method_callee(ecx, rbml_w,
|
||||||
|
@ -1104,14 +1104,14 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(closure_type) = tcx.closure_tys.borrow().get(&ast_util::local_def(id)) {
|
if let Some(closure_type) = tcx.tables.borrow().closure_tys.get(&ast_util::local_def(id)) {
|
||||||
rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
|
rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
|
||||||
rbml_w.id(id);
|
rbml_w.id(id);
|
||||||
rbml_w.emit_closure_type(ecx, closure_type);
|
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.tag(c::tag_table_closure_kinds, |rbml_w| {
|
||||||
rbml_w.id(id);
|
rbml_w.id(id);
|
||||||
encode_closure_kind(rbml_w, *closure_kind)
|
encode_closure_kind(rbml_w, *closure_kind)
|
||||||
|
@ -1630,7 +1630,7 @@ fn decode_side_tables(dcx: &DecodeContext,
|
||||||
let item_substs = ty::ItemSubsts {
|
let item_substs = ty::ItemSubsts {
|
||||||
substs: val_dsr.read_substs(dcx)
|
substs: val_dsr.read_substs(dcx)
|
||||||
};
|
};
|
||||||
dcx.tcx.item_substs.borrow_mut().insert(
|
dcx.tcx.tables.borrow_mut().item_substs.insert(
|
||||||
id, item_substs);
|
id, item_substs);
|
||||||
}
|
}
|
||||||
c::tag_table_freevars => {
|
c::tag_table_freevars => {
|
||||||
|
@ -1646,7 +1646,7 @@ fn decode_side_tables(dcx: &DecodeContext,
|
||||||
closure_expr_id: id
|
closure_expr_id: id
|
||||||
};
|
};
|
||||||
let ub: ty::UpvarCapture = Decodable::decode(val_dsr).unwrap();
|
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 => {
|
c::tag_table_tcache => {
|
||||||
let type_scheme = val_dsr.read_type_scheme(dcx);
|
let type_scheme = val_dsr.read_type_scheme(dcx);
|
||||||
|
@ -1663,22 +1663,22 @@ fn decode_side_tables(dcx: &DecodeContext,
|
||||||
expr_id: id,
|
expr_id: id,
|
||||||
autoderef: autoderef
|
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 => {
|
c::tag_table_adjustments => {
|
||||||
let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(dcx);
|
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 => {
|
c::tag_table_closure_tys => {
|
||||||
let closure_ty =
|
let closure_ty =
|
||||||
val_dsr.read_closure_ty(dcx);
|
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);
|
closure_ty);
|
||||||
}
|
}
|
||||||
c::tag_table_closure_kinds => {
|
c::tag_table_closure_kinds => {
|
||||||
let closure_kind =
|
let closure_kind =
|
||||||
val_dsr.read_closure_kind(dcx);
|
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);
|
closure_kind);
|
||||||
}
|
}
|
||||||
c::tag_table_cast_kinds => {
|
c::tag_table_cast_kinds => {
|
||||||
|
|
|
@ -411,7 +411,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||||
func_or_rcvr: &ast::Expr,
|
func_or_rcvr: &ast::Expr,
|
||||||
args: I) -> CFGIndex {
|
args: I) -> CFGIndex {
|
||||||
let method_call = ty::MethodCall::expr(call_expr.id);
|
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,
|
Some(method) => method.ty,
|
||||||
None => self.tcx.expr_ty_adjusted(func_or_rcvr)
|
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 {
|
fn is_method_call(&self, expr: &ast::Expr) -> bool {
|
||||||
let method_call = ty::MethodCall::expr(expr.id);
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,12 +283,11 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
fn check_static_type(&self, e: &ast::Expr) {
|
fn check_static_type(&self, e: &ast::Expr) {
|
||||||
let ty = self.tcx.node_id_to_type(e.id);
|
let ty = self.tcx.node_id_to_type(e.id);
|
||||||
let infcx = infer::new_infer_ctxt(self.tcx);
|
let infcx = infer::new_infer_ctxt(self.tcx, None);
|
||||||
let mut fulfill_cx = traits::FulfillmentContext::new(false);
|
let mut fulfill_cx = traits::FulfillmentContext::new(false);
|
||||||
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
|
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
|
||||||
fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
|
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, &infcx.parameter_environment) {
|
||||||
match fulfill_cx.select_all_or_error(&infcx, &env) {
|
|
||||||
Ok(()) => { },
|
Ok(()) => { },
|
||||||
Err(ref errors) => {
|
Err(ref errors) => {
|
||||||
traits::report_fulfillment_errors(&infcx, errors);
|
traits::report_fulfillment_errors(&infcx, errors);
|
||||||
|
@ -544,7 +543,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
||||||
match e.node {
|
match e.node {
|
||||||
ast::ExprUnary(..) |
|
ast::ExprUnary(..) |
|
||||||
ast::ExprBinary(..) |
|
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);
|
v.add_qualif(ConstQualif::NOT_CONST);
|
||||||
if v.mode != Mode::Var {
|
if v.mode != Mode::Var {
|
||||||
span_err!(v.tcx.sess, e.span, E0011,
|
span_err!(v.tcx.sess, e.span, E0011,
|
||||||
|
@ -695,7 +694,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ExprMethodCall(..) => {
|
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),
|
ty::MethodStatic(did) => Some(did),
|
||||||
_ => None
|
_ => None
|
||||||
};
|
};
|
||||||
|
|
|
@ -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 struct MatchCheckCtxt<'a, 'tcx: 'a> {
|
||||||
pub tcx: &'a ty::ctxt<'tcx>,
|
pub tcx: &'a ty::ctxt<'tcx>,
|
||||||
pub param_env: ParameterEnvironment<'a, 'tcx>,
|
pub param_env: ParameterEnvironment<'a, 'tcx>,
|
||||||
|
|
|
@ -1031,10 +1031,9 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
|
||||||
substs: trait_substs });
|
substs: trait_substs });
|
||||||
|
|
||||||
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
|
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
|
||||||
let infcx = infer::new_infer_ctxt(tcx);
|
let infcx = infer::new_infer_ctxt(tcx, None);
|
||||||
|
|
||||||
let param_env = tcx.empty_parameter_environment();
|
let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment);
|
||||||
let mut selcx = traits::SelectionContext::new(&infcx, ¶m_env);
|
|
||||||
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
|
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
|
||||||
trait_ref.to_poly_trait_predicate());
|
trait_ref.to_poly_trait_predicate());
|
||||||
let selection = match selcx.select(&obligation) {
|
let selection = match selcx.select(&obligation) {
|
||||||
|
|
|
@ -96,7 +96,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||||
fn lookup_and_handle_method(&mut self, id: ast::NodeId,
|
fn lookup_and_handle_method(&mut self, id: ast::NodeId,
|
||||||
span: codemap::Span) {
|
span: codemap::Span) {
|
||||||
let method_call = ty::MethodCall::expr(id);
|
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) => {
|
Some(method) => {
|
||||||
match method.origin {
|
match method.origin {
|
||||||
ty::MethodStatic(def_id) => {
|
ty::MethodStatic(def_id) => {
|
||||||
|
|
|
@ -140,7 +140,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ast::ExprMethodCall(_, _, _) => {
|
ast::ExprMethodCall(_, _, _) => {
|
||||||
let method_call = MethodCall::expr(expr.id);
|
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 {:?}",
|
debug!("effect: method call case, base type is {:?}",
|
||||||
base_type);
|
base_type);
|
||||||
if type_is_unsafe_function(base_type) {
|
if type_is_unsafe_function(base_type) {
|
||||||
|
|
|
@ -257,8 +257,9 @@ impl OverloadedCallType {
|
||||||
fn from_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
|
fn from_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
|
||||||
-> OverloadedCallType {
|
-> OverloadedCallType {
|
||||||
let trait_did =
|
let trait_did =
|
||||||
tcx.closure_kinds
|
tcx.tables
|
||||||
.borrow()
|
.borrow()
|
||||||
|
.closure_kinds
|
||||||
.get(&closure_did)
|
.get(&closure_did)
|
||||||
.expect("OverloadedCallType::from_closure: didn't find closure id")
|
.expect("OverloadedCallType::from_closure: didn't find closure id")
|
||||||
.trait_did(tcx);
|
.trait_did(tcx);
|
||||||
|
@ -787,8 +788,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
|
||||||
// process.
|
// process.
|
||||||
fn walk_adjustment(&mut self, expr: &ast::Expr) {
|
fn walk_adjustment(&mut self, expr: &ast::Expr) {
|
||||||
let typer = self.typer;
|
let typer = self.typer;
|
||||||
if let Some(adjustment) = typer.adjustments().borrow().get(&expr.id) {
|
//NOTE(@jroesch): mixed RefCell borrow causes crash
|
||||||
match *adjustment {
|
let adj = typer.adjustments().get(&expr.id).map(|x| x.clone());
|
||||||
|
if let Some(adjustment) = adj {
|
||||||
|
match adjustment {
|
||||||
ty::AdjustReifyFnPointer |
|
ty::AdjustReifyFnPointer |
|
||||||
ty::AdjustUnsafeFnPointer => {
|
ty::AdjustUnsafeFnPointer => {
|
||||||
// Creating a closure/fn-pointer or unsizing consumes
|
// Creating a closure/fn-pointer or unsizing consumes
|
||||||
|
|
|
@ -77,6 +77,10 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
|
||||||
|
|
||||||
// For region variables.
|
// For region variables.
|
||||||
region_vars: RegionVarBindings<'a, 'tcx>,
|
region_vars: RegionVarBindings<'a, 'tcx>,
|
||||||
|
|
||||||
|
pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>,
|
||||||
|
|
||||||
|
// pub tables: &'a RefCell<ty::Tables<'tcx>>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
|
/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
|
||||||
|
@ -309,7 +313,8 @@ pub fn fixup_err_to_string(f: fixup_err) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
|
pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
|
||||||
|
param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>)
|
||||||
-> InferCtxt<'a, 'tcx> {
|
-> InferCtxt<'a, 'tcx> {
|
||||||
InferCtxt {
|
InferCtxt {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
|
@ -317,6 +322,7 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
|
||||||
int_unification_table: RefCell::new(UnificationTable::new()),
|
int_unification_table: RefCell::new(UnificationTable::new()),
|
||||||
float_unification_table: RefCell::new(UnificationTable::new()),
|
float_unification_table: RefCell::new(UnificationTable::new()),
|
||||||
region_vars: RegionVarBindings::new(tcx),
|
region_vars: RegionVarBindings::new(tcx),
|
||||||
|
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1150,7 +1150,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
|
|
||||||
ast::ExprMethodCall(_, _, ref args) => {
|
ast::ExprMethodCall(_, _, ref args) => {
|
||||||
let method_call = ty::MethodCall::expr(expr.id);
|
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() {
|
let succ = if method_ty.fn_ret().diverges() {
|
||||||
self.s.exit_ln
|
self.s.exit_ln
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -83,7 +83,7 @@ use syntax::ast::{MutImmutable, MutMutable};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::Ref;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
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_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>>;
|
||||||
fn node_method_origin(&self, method_call: ty::MethodCall)
|
fn node_method_origin(&self, method_call: ty::MethodCall)
|
||||||
-> Option<ty::MethodOrigin<'tcx>>;
|
-> 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 is_method_call(&self, id: ast::NodeId) -> bool;
|
||||||
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
|
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
|
||||||
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture>;
|
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));
|
let unadjusted_ty = try!(self.expr_ty(expr));
|
||||||
Ok(unadjusted_ty.adjust(
|
Ok(unadjusted_ty.adjust(
|
||||||
self.tcx(), expr.span, expr.id,
|
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)))
|
|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>> {
|
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 => {
|
None => {
|
||||||
// No adjustments.
|
// No adjustments.
|
||||||
self.cat_expr_unadjusted(expr)
|
self.cat_expr_unadjusted(expr)
|
||||||
|
|
|
@ -128,7 +128,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
ast::ExprMethodCall(..) => {
|
ast::ExprMethodCall(..) => {
|
||||||
let method_call = ty::MethodCall::expr(expr.id);
|
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) => {
|
ty::MethodStatic(def_id) => {
|
||||||
if is_local(def_id) {
|
if is_local(def_id) {
|
||||||
if self.def_id_represents_local_inlined_item(def_id) {
|
if self.def_id_represents_local_inlined_item(def_id) {
|
||||||
|
|
|
@ -406,7 +406,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
|
||||||
ast::ExprMethodCall(i, _, _) => {
|
ast::ExprMethodCall(i, _, _) => {
|
||||||
span = i.span;
|
span = i.span;
|
||||||
let method_call = ty::MethodCall::expr(e.id);
|
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) => {
|
Some(method) => {
|
||||||
match method.origin {
|
match method.origin {
|
||||||
ty::MethodStatic(def_id) => {
|
ty::MethodStatic(def_id) => {
|
||||||
|
|
|
@ -351,6 +351,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this is gonna need to be removed ...
|
||||||
/// Normalizes the parameter environment, reporting errors if they occur.
|
/// Normalizes the parameter environment, reporting errors if they occur.
|
||||||
pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvironment<'a,'tcx>,
|
pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvironment<'a,'tcx>,
|
||||||
cause: ObligationCause<'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 elaborated_env = unnormalized_env.with_caller_bounds(predicates);
|
||||||
|
|
||||||
let infcx = infer::new_infer_ctxt(tcx);
|
let infcx = infer::new_infer_ctxt(tcx, Some(elaborated_env));
|
||||||
let predicates = match fully_normalize(&infcx, &elaborated_env, cause,
|
let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause,
|
||||||
&elaborated_env.caller_bounds) {
|
&infcx.parameter_environment.caller_bounds) {
|
||||||
Ok(predicates) => predicates,
|
Ok(predicates) => predicates,
|
||||||
Err(errors) => {
|
Err(errors) => {
|
||||||
report_fulfillment_errors(&infcx, &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.
|
// all things considered.
|
||||||
let err_msg = fixup_err_to_string(fixup_err);
|
let err_msg = fixup_err_to_string(fixup_err);
|
||||||
tcx.sess.span_err(span, &err_msg);
|
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>,
|
pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||||
|
|
|
@ -728,7 +728,7 @@ impl MethodCall {
|
||||||
|
|
||||||
// maps from an expression id that corresponds to a method call to the details
|
// maps from an expression id that corresponds to a method call to the details
|
||||||
// of the method to be invoked
|
// 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
|
// Contains information needed to resolve types and (in the future) look up
|
||||||
// the types of AST nodes.
|
// the types of AST nodes.
|
||||||
|
@ -815,6 +815,48 @@ pub struct CommonTypes<'tcx> {
|
||||||
pub err: Ty<'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
|
/// 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
|
/// generates so that so that it can be reused and doesn't have to be redone
|
||||||
/// later on.
|
/// later on.
|
||||||
|
@ -850,17 +892,9 @@ pub struct ctxt<'tcx> {
|
||||||
// borrowck. (They are not used during trans, and hence are not
|
// borrowck. (They are not used during trans, and hence are not
|
||||||
// serialized or needed for cross-crate fns.)
|
// serialized or needed for cross-crate fns.)
|
||||||
free_region_maps: RefCell<NodeMap<FreeRegionMap>>,
|
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
|
pub tables: RefCell<Tables<'tcx>>,
|
||||||
/// 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>>>,
|
|
||||||
|
|
||||||
/// Maps from a trait item to the trait item "descriptor"
|
/// Maps from a trait item to the trait item "descriptor"
|
||||||
pub impl_or_trait_items: RefCell<DefIdMap<ImplOrTraitItem<'tcx>>>,
|
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 ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
|
||||||
pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
|
pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
|
||||||
pub ty_param_defs: RefCell<NodeMap<TypeParameterDef<'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 normalized_cache: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
|
||||||
pub lang_items: middle::lang_items::LanguageItems,
|
pub lang_items: middle::lang_items::LanguageItems,
|
||||||
/// A mapping of fake provided method def_ids to the default implementation
|
/// 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?
|
/// FIXME(arielb1): why is this separate from populated_external_types?
|
||||||
pub populated_external_primitive_impls: RefCell<DefIdSet>,
|
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.
|
/// These caches are used by const_eval when decoding external constants.
|
||||||
pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
|
pub extern_const_statics: RefCell<DefIdMap<ast::NodeId>>,
|
||||||
pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
|
pub extern_const_variants: RefCell<DefIdMap<ast::NodeId>>,
|
||||||
pub extern_const_fns: RefCell<DefIdMap<ast::NodeId>>,
|
pub extern_const_fns: RefCell<DefIdMap<ast::NodeId>>,
|
||||||
|
|
||||||
pub method_map: MethodMap<'tcx>,
|
|
||||||
|
|
||||||
pub dependency_formats: RefCell<dependency_format::Dependencies>,
|
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),
|
pub node_lint_levels: RefCell<FnvHashMap<(ast::NodeId, lint::LintId),
|
||||||
lint::LevelSource>>,
|
lint::LevelSource>>,
|
||||||
|
|
||||||
|
@ -1000,9 +1020,16 @@ pub struct ctxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> 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>) {
|
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> {
|
pub fn intern_trait_def(&self, def: TraitDef<'tcx>) -> &'tcx TraitDef<'tcx> {
|
||||||
|
@ -3195,6 +3222,84 @@ impl<'tcx> CommonTypes<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a type context and call the closure with a `&ty::ctxt` reference
|
||||||
|
/// to the context. The closure enforces that the type context and any interned
|
||||||
|
/// value (types, substs, etc.) can only be used while `ty::tls` has a valid
|
||||||
|
/// reference to the context, to allow formatting values that need it.
|
||||||
|
pub fn with_ctxt<'tcx, F, R>(s: Session,
|
||||||
|
arenas: &'tcx CtxtArenas<'tcx>,
|
||||||
|
def_map: DefMap,
|
||||||
|
named_region_map: resolve_lifetime::NamedRegionMap,
|
||||||
|
map: ast_map::Map<'tcx>,
|
||||||
|
freevars: RefCell<FreevarMap>,
|
||||||
|
region_maps: RegionMaps,
|
||||||
|
lang_items: middle::lang_items::LanguageItems,
|
||||||
|
stability: stability::Index<'tcx>,
|
||||||
|
f: F) -> (Session, R)
|
||||||
|
where F: FnOnce(&ctxt<'tcx>) -> R
|
||||||
|
{
|
||||||
|
let mut interner = FnvHashMap();
|
||||||
|
let common_types = CommonTypes::new(&arenas.type_, &mut interner);
|
||||||
|
|
||||||
|
tls::enter(ctxt {
|
||||||
|
arenas: arenas,
|
||||||
|
interner: RefCell::new(interner),
|
||||||
|
substs_interner: RefCell::new(FnvHashMap()),
|
||||||
|
bare_fn_interner: RefCell::new(FnvHashMap()),
|
||||||
|
region_interner: RefCell::new(FnvHashMap()),
|
||||||
|
stability_interner: RefCell::new(FnvHashMap()),
|
||||||
|
types: common_types,
|
||||||
|
named_region_map: named_region_map,
|
||||||
|
region_maps: region_maps,
|
||||||
|
free_region_maps: RefCell::new(FnvHashMap()),
|
||||||
|
item_variance_map: RefCell::new(DefIdMap()),
|
||||||
|
variance_computed: Cell::new(false),
|
||||||
|
sess: s,
|
||||||
|
def_map: def_map,
|
||||||
|
tables: RefCell::new(Tables::empty()),
|
||||||
|
impl_trait_refs: RefCell::new(DefIdMap()),
|
||||||
|
trait_defs: RefCell::new(DefIdMap()),
|
||||||
|
predicates: RefCell::new(DefIdMap()),
|
||||||
|
super_predicates: RefCell::new(DefIdMap()),
|
||||||
|
fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()),
|
||||||
|
map: map,
|
||||||
|
freevars: freevars,
|
||||||
|
tcache: RefCell::new(DefIdMap()),
|
||||||
|
rcache: RefCell::new(FnvHashMap()),
|
||||||
|
tc_cache: RefCell::new(FnvHashMap()),
|
||||||
|
ast_ty_to_ty_cache: RefCell::new(NodeMap()),
|
||||||
|
enum_var_cache: RefCell::new(DefIdMap()),
|
||||||
|
impl_or_trait_items: RefCell::new(DefIdMap()),
|
||||||
|
trait_item_def_ids: RefCell::new(DefIdMap()),
|
||||||
|
trait_items_cache: RefCell::new(DefIdMap()),
|
||||||
|
ty_param_defs: RefCell::new(NodeMap()),
|
||||||
|
normalized_cache: RefCell::new(FnvHashMap()),
|
||||||
|
lang_items: lang_items,
|
||||||
|
provided_method_sources: RefCell::new(DefIdMap()),
|
||||||
|
struct_fields: RefCell::new(DefIdMap()),
|
||||||
|
destructor_for_type: RefCell::new(DefIdMap()),
|
||||||
|
destructors: RefCell::new(DefIdSet()),
|
||||||
|
inherent_impls: RefCell::new(DefIdMap()),
|
||||||
|
impl_items: RefCell::new(DefIdMap()),
|
||||||
|
used_unsafe: RefCell::new(NodeSet()),
|
||||||
|
used_mut_nodes: RefCell::new(NodeSet()),
|
||||||
|
populated_external_types: RefCell::new(DefIdSet()),
|
||||||
|
populated_external_primitive_impls: RefCell::new(DefIdSet()),
|
||||||
|
extern_const_statics: RefCell::new(DefIdMap()),
|
||||||
|
extern_const_variants: RefCell::new(DefIdMap()),
|
||||||
|
extern_const_fns: RefCell::new(DefIdMap()),
|
||||||
|
dependency_formats: RefCell::new(FnvHashMap()),
|
||||||
|
node_lint_levels: RefCell::new(FnvHashMap()),
|
||||||
|
transmute_restrictions: RefCell::new(Vec::new()),
|
||||||
|
stability: RefCell::new(stability),
|
||||||
|
selection_cache: traits::SelectionCache::new(),
|
||||||
|
repr_hint_cache: RefCell::new(DefIdMap()),
|
||||||
|
const_qualif_map: RefCell::new(NodeMap()),
|
||||||
|
custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
|
||||||
|
cast_kinds: RefCell::new(NodeMap()),
|
||||||
|
}, f)
|
||||||
|
}
|
||||||
|
|
||||||
struct FlagComputation {
|
struct FlagComputation {
|
||||||
flags: TypeFlags,
|
flags: TypeFlags,
|
||||||
|
|
||||||
|
@ -3421,8 +3526,7 @@ impl<'tcx> ctxt<'tcx> {
|
||||||
variance_computed: Cell::new(false),
|
variance_computed: Cell::new(false),
|
||||||
sess: s,
|
sess: s,
|
||||||
def_map: def_map,
|
def_map: def_map,
|
||||||
node_types: RefCell::new(FnvHashMap()),
|
tables: RefCell::new(Tables::empty()),
|
||||||
item_substs: RefCell::new(NodeMap()),
|
|
||||||
impl_trait_refs: RefCell::new(DefIdMap()),
|
impl_trait_refs: RefCell::new(DefIdMap()),
|
||||||
trait_defs: RefCell::new(DefIdMap()),
|
trait_defs: RefCell::new(DefIdMap()),
|
||||||
predicates: RefCell::new(DefIdMap()),
|
predicates: RefCell::new(DefIdMap()),
|
||||||
|
@ -3439,7 +3543,6 @@ impl<'tcx> ctxt<'tcx> {
|
||||||
trait_item_def_ids: RefCell::new(DefIdMap()),
|
trait_item_def_ids: RefCell::new(DefIdMap()),
|
||||||
trait_items_cache: RefCell::new(DefIdMap()),
|
trait_items_cache: RefCell::new(DefIdMap()),
|
||||||
ty_param_defs: RefCell::new(NodeMap()),
|
ty_param_defs: RefCell::new(NodeMap()),
|
||||||
adjustments: RefCell::new(NodeMap()),
|
|
||||||
normalized_cache: RefCell::new(FnvHashMap()),
|
normalized_cache: RefCell::new(FnvHashMap()),
|
||||||
lang_items: lang_items,
|
lang_items: lang_items,
|
||||||
provided_method_sources: RefCell::new(DefIdMap()),
|
provided_method_sources: RefCell::new(DefIdMap()),
|
||||||
|
@ -3452,14 +3555,10 @@ impl<'tcx> ctxt<'tcx> {
|
||||||
used_mut_nodes: RefCell::new(NodeSet()),
|
used_mut_nodes: RefCell::new(NodeSet()),
|
||||||
populated_external_types: RefCell::new(DefIdSet()),
|
populated_external_types: RefCell::new(DefIdSet()),
|
||||||
populated_external_primitive_impls: RefCell::new(DefIdSet()),
|
populated_external_primitive_impls: RefCell::new(DefIdSet()),
|
||||||
upvar_capture_map: RefCell::new(FnvHashMap()),
|
|
||||||
extern_const_statics: RefCell::new(DefIdMap()),
|
extern_const_statics: RefCell::new(DefIdMap()),
|
||||||
extern_const_variants: RefCell::new(DefIdMap()),
|
extern_const_variants: RefCell::new(DefIdMap()),
|
||||||
extern_const_fns: RefCell::new(DefIdMap()),
|
extern_const_fns: RefCell::new(DefIdMap()),
|
||||||
method_map: RefCell::new(FnvHashMap()),
|
|
||||||
dependency_formats: RefCell::new(FnvHashMap()),
|
dependency_formats: RefCell::new(FnvHashMap()),
|
||||||
closure_kinds: RefCell::new(DefIdMap()),
|
|
||||||
closure_tys: RefCell::new(DefIdMap()),
|
|
||||||
node_lint_levels: RefCell::new(FnvHashMap()),
|
node_lint_levels: RefCell::new(FnvHashMap()),
|
||||||
transmute_restrictions: RefCell::new(Vec::new()),
|
transmute_restrictions: RefCell::new(Vec::new()),
|
||||||
stability: RefCell::new(stability),
|
stability: RefCell::new(stability),
|
||||||
|
@ -3515,7 +3614,7 @@ impl<'tcx> ctxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
|
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,
|
pub fn closure_type(&self,
|
||||||
|
@ -3523,7 +3622,7 @@ impl<'tcx> ctxt<'tcx> {
|
||||||
substs: &subst::Substs<'tcx>)
|
substs: &subst::Substs<'tcx>)
|
||||||
-> ty::ClosureTy<'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,
|
pub fn type_parameter_def(&self,
|
||||||
|
@ -4369,7 +4468,7 @@ impl<'tcx> TyS<'tcx> {
|
||||||
span: Span)
|
span: Span)
|
||||||
-> bool
|
-> bool
|
||||||
{
|
{
|
||||||
let infcx = infer::new_infer_ctxt(param_env.tcx());
|
let infcx = infer::new_infer_ctxt(param_env.tcx(), Some(param_env.clone()));
|
||||||
|
|
||||||
let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env,
|
let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env,
|
||||||
self, bound, span);
|
self, bound, span);
|
||||||
|
@ -5276,11 +5375,11 @@ impl<'tcx> ctxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_id_to_type_opt(&self, id: ast::NodeId) -> Option<Ty<'tcx>> {
|
pub fn node_id_to_type_opt(&self, id: ast::NodeId) -> Option<Ty<'tcx>> {
|
||||||
self.node_types.borrow().get(&id).cloned()
|
self.tables.borrow().node_types.get(&id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_id_item_substs(&self, id: ast::NodeId) -> ItemSubsts<'tcx> {
|
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(),
|
None => ItemSubsts::empty(),
|
||||||
Some(ts) => ts.clone(),
|
Some(ts) => ts.clone(),
|
||||||
}
|
}
|
||||||
|
@ -5325,9 +5424,9 @@ impl<'tcx> ctxt<'tcx> {
|
||||||
pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
|
pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
|
||||||
self.expr_ty(expr)
|
self.expr_ty(expr)
|
||||||
.adjust(self, expr.span, expr.id,
|
.adjust(self, expr.span, expr.id,
|
||||||
self.adjustments.borrow().get(&expr.id),
|
self.tables.borrow().adjustments.get(&expr.id),
|
||||||
|method_call| {
|
|method_call| {
|
||||||
self.method_map.borrow().get(&method_call).map(|method| method.ty)
|
self.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6671,11 +6770,11 @@ impl<'tcx> ctxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool {
|
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> {
|
pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
|
||||||
Some(self.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
|
Some(self.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6689,17 +6788,21 @@ impl<'a,'tcx> Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
|
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
|
||||||
self.tcx.method_map.borrow().get(&method_call).map(|method| method.ty)
|
self.tcx.tables.borrow().method_map.get(&method_call).map(|method| method.ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_method_origin(&self, method_call: ty::MethodCall)
|
fn node_method_origin(&self, method_call: ty::MethodCall)
|
||||||
-> Option<ty::MethodOrigin<'tcx>>
|
-> 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>>> {
|
fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
|
||||||
&self.tcx.adjustments
|
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 {
|
fn is_method_call(&self, id: ast::NodeId) -> bool {
|
||||||
|
|
|
@ -688,7 +688,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
|
||||||
TyStr => write!(f, "str"),
|
TyStr => write!(f, "str"),
|
||||||
TyClosure(ref did, substs) => ty::tls::with(|tcx| {
|
TyClosure(ref did, substs) => ty::tls::with(|tcx| {
|
||||||
try!(write!(f, "[closure"));
|
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| {
|
try!(closure_tys.get(did).map(|cty| &cty.sig).and_then(|sig| {
|
||||||
tcx.lift(&substs).map(|substs| sig.subst(tcx, substs))
|
tcx.lift(&substs).map(|substs| sig.subst(tcx, substs))
|
||||||
}).map(|sig| {
|
}).map(|sig| {
|
||||||
|
|
|
@ -1446,7 +1446,7 @@ impl LintPass for UnusedAllocation {
|
||||||
_ => return
|
_ => 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 {
|
if let ty::AdjustDerefRef(ty::AutoDerefRef { ref autoref, .. }) = *adjustment {
|
||||||
match autoref {
|
match autoref {
|
||||||
&Some(ty::AutoPtr(_, ast::MutImmutable)) => {
|
&Some(ty::AutoPtr(_, ast::MutImmutable)) => {
|
||||||
|
@ -1984,7 +1984,7 @@ impl LintPass for UnconditionalRecursion {
|
||||||
method_id: ast::NodeId,
|
method_id: ast::NodeId,
|
||||||
method_name: ast::Ident,
|
method_name: ast::Ident,
|
||||||
id: ast::NodeId) -> bool {
|
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,
|
None => return false,
|
||||||
Some(m) => match m.origin {
|
Some(m) => match m.origin {
|
||||||
// There's no way to know if a method call via a
|
// There's no way to know if a method call via a
|
||||||
|
|
|
@ -904,7 +904,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
ast::ExprMethodCall(ident, _, _) => {
|
ast::ExprMethodCall(ident, _, _) => {
|
||||||
let method_call = MethodCall::expr(expr.id);
|
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 => {
|
None => {
|
||||||
self.tcx.sess.span_bug(expr.span,
|
self.tcx.sess.span_bug(expr.span,
|
||||||
"method call not in \
|
"method call not in \
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#![feature(unicode)]
|
#![feature(unicode)]
|
||||||
#![feature(unicode)]
|
#![feature(unicode)]
|
||||||
#![feature(vec_push_all)]
|
#![feature(vec_push_all)]
|
||||||
|
#![feature(cell_extras)]
|
||||||
|
|
||||||
#![allow(trivial_casts)]
|
#![allow(trivial_casts)]
|
||||||
|
|
||||||
|
|
|
@ -886,7 +886,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
||||||
fn process_method_call(&mut self,
|
fn process_method_call(&mut self,
|
||||||
ex: &ast::Expr,
|
ex: &ast::Expr,
|
||||||
args: &Vec<P<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 method_callee = method_map.get(&ty::MethodCall::expr(ex.id)).unwrap();
|
||||||
let (def_id, decl_id) = match method_callee.origin {
|
let (def_id, decl_id) = match method_callee.origin {
|
||||||
ty::MethodStatic(def_id) |
|
ty::MethodStatic(def_id) |
|
||||||
|
|
|
@ -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 {
|
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,
|
pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId,
|
||||||
|
|
|
@ -518,7 +518,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
|
||||||
let ref_ty = match node {
|
let ref_ty = match node {
|
||||||
ExprId(id) => tcx.node_id_to_type(id),
|
ExprId(id) => tcx.node_id_to_type(id),
|
||||||
MethodCallKey(method_call) => {
|
MethodCallKey(method_call) => {
|
||||||
tcx.method_map.borrow().get(&method_call).unwrap().ty
|
tcx.tables.borrow().method_map.get(&method_call).unwrap().ty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let ref_ty = monomorphize::apply_param_substs(tcx,
|
let 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");
|
let _icx = push_ctxt("trans_method_call");
|
||||||
debug!("trans_method_call(call_expr={:?})", call_expr);
|
debug!("trans_method_call(call_expr={:?})", call_expr);
|
||||||
let method_call = MethodCall::expr(call_expr.id);
|
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 {
|
Some(method) => match method.origin {
|
||||||
ty::MethodTraitObject(_) => match method.ty.sty {
|
ty::MethodTraitObject(_) => match method.ty.sty {
|
||||||
ty::TyBareFn(_, ref fty) => {
|
ty::TyBareFn(_, ref fty) => {
|
||||||
|
|
|
@ -130,7 +130,7 @@ pub fn get_or_create_declaration_if_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tc
|
||||||
closure_id: ast::DefId,
|
closure_id: ast::DefId,
|
||||||
substs: &Substs<'tcx>)
|
substs: &Substs<'tcx>)
|
||||||
-> Option<Datum<'tcx, Rvalue>> {
|
-> 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.
|
// Not a closure.
|
||||||
return None
|
return None
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ use util::nodemap::{FnvHashMap, NodeMap};
|
||||||
use arena::TypedArena;
|
use arena::TypedArena;
|
||||||
use libc::{c_uint, c_char};
|
use libc::{c_uint, c_char};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell, Ref};
|
||||||
use std::result::Result as StdResult;
|
use std::result::Result as StdResult;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
@ -353,7 +353,7 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
|
||||||
// section of the executable we're generating.
|
// section of the executable we're generating.
|
||||||
pub llfn: ValueRef,
|
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>,
|
pub param_env: ty::ParameterEnvironment<'a, 'tcx>,
|
||||||
|
|
||||||
// The environment argument in a closure.
|
// 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>> {
|
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
|
||||||
self.tcx()
|
self.tcx()
|
||||||
.method_map
|
.tables
|
||||||
.borrow()
|
.borrow()
|
||||||
|
.method_map
|
||||||
.get(&method_call)
|
.get(&method_call)
|
||||||
.map(|method| monomorphize_type(self, method.ty))
|
.map(|method| monomorphize_type(self, method.ty))
|
||||||
}
|
}
|
||||||
|
@ -640,18 +641,23 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
|
||||||
-> Option<ty::MethodOrigin<'tcx>>
|
-> Option<ty::MethodOrigin<'tcx>>
|
||||||
{
|
{
|
||||||
self.tcx()
|
self.tcx()
|
||||||
.method_map
|
.tables
|
||||||
.borrow()
|
.borrow()
|
||||||
|
.method_map
|
||||||
.get(&method_call)
|
.get(&method_call)
|
||||||
.map(|method| method.origin.clone())
|
.map(|method| method.origin.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
|
fn adjustments<'a>(&'a self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
|
||||||
&self.tcx().adjustments
|
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 {
|
fn is_method_call(&self, id: ast::NodeId) -> bool {
|
||||||
self.tcx().method_map.borrow().contains_key(&ty::MethodCall::expr(id))
|
self.tcx().tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
|
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent> {
|
||||||
|
@ -659,7 +665,7 @@ impl<'blk, 'tcx> mc::Typer<'tcx> for BlockS<'blk, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
|
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 {
|
fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
|
||||||
|
@ -991,7 +997,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
trait_ref, trait_ref.def_id());
|
trait_ref, trait_ref.def_id());
|
||||||
|
|
||||||
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
|
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
|
||||||
let infcx = infer::new_infer_ctxt(tcx);
|
let infcx = infer::new_infer_ctxt(tcx, None);
|
||||||
|
|
||||||
// Do the initial selection for the obligation. This yields the
|
// Do the initial selection for the obligation. This yields the
|
||||||
// shallow result we are looking for -- that is, what specific impl.
|
// shallow result we are looking for -- that is, what specific impl.
|
||||||
|
@ -1053,7 +1059,7 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
predicates);
|
predicates);
|
||||||
|
|
||||||
let tcx = ccx.tcx();
|
let tcx = ccx.tcx();
|
||||||
let infcx = infer::new_infer_ctxt(tcx);
|
let infcx = infer::new_infer_ctxt(tcx, None);
|
||||||
let typer = NormalizingClosureTyper::new(tcx);
|
let typer = NormalizingClosureTyper::new(tcx);
|
||||||
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
|
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
|
||||||
let mut fulfill_cx = traits::FulfillmentContext::new(false);
|
let mut fulfill_cx = traits::FulfillmentContext::new(false);
|
||||||
|
@ -1070,6 +1076,10 @@ pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok()
|
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> {
|
pub struct NormalizingClosureTyper<'a,'tcx:'a> {
|
||||||
param_env: ty::ParameterEnvironment<'a, 'tcx>
|
param_env: ty::ParameterEnvironment<'a, 'tcx>
|
||||||
}
|
}
|
||||||
|
@ -1191,7 +1201,7 @@ pub fn node_id_substs<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
tcx.node_id_item_substs(id).substs
|
tcx.node_id_item_substs(id).substs
|
||||||
}
|
}
|
||||||
MethodCallKey(method_call) => {
|
MethodCallKey(method_call) => {
|
||||||
tcx.method_map.borrow().get(&method_call).unwrap().substs.clone()
|
tcx.tables.borrow().method_map.get(&method_call).unwrap().substs.clone()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
|
||||||
match def {
|
match def {
|
||||||
def::DefConst(def_id) | def::DefAssociatedConst(def_id, _) => {
|
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 {:?}",
|
debug!("get_const_expr_as_global ({:?}): found const {:?}",
|
||||||
expr.id, def_id);
|
expr.id, def_id);
|
||||||
return get_const_val(ccx, def_id, expr);
|
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 llconst = llconst;
|
||||||
let mut ety_adjusted = monomorphize::apply_param_substs(cx.tcx(), param_substs,
|
let mut ety_adjusted = monomorphize::apply_param_substs(cx.tcx(), param_substs,
|
||||||
&cx.tcx().expr_ty_adjusted(e));
|
&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 {
|
match opt_adj {
|
||||||
Some(ty::AdjustReifyFnPointer) => {
|
Some(ty::AdjustReifyFnPointer) => {
|
||||||
// FIXME(#19925) once fn item types are
|
// 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) => {
|
ast::ExprMethodCall(_, _, ref args) => {
|
||||||
let arg_vals = map_list(args);
|
let arg_vals = map_list(args);
|
||||||
let method_call = ty::MethodCall::expr(e.id);
|
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,
|
ty::MethodStatic(did) => did,
|
||||||
_ => cx.sess().span_bug(e.span, "expected a const method def")
|
_ => cx.sess().span_bug(e.span, "expected a const method def")
|
||||||
};
|
};
|
||||||
|
|
|
@ -117,7 +117,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
|
|
||||||
debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
|
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
|
// use trans, which may be less efficient but
|
||||||
// which will perform the adjustments:
|
// which will perform the adjustments:
|
||||||
let datum = unpack_datum!(bcx, trans(bcx, expr));
|
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 bcx = bcx;
|
||||||
let mut datum = datum;
|
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 => {
|
None => {
|
||||||
return DatumBlock::new(bcx, datum);
|
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.
|
// Don't skip a conversion from Box<T> to &T, etc.
|
||||||
ty::TyRef(..) => {
|
ty::TyRef(..) => {
|
||||||
let method_call = MethodCall::autoderef(expr.id, 0);
|
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.
|
// Don't skip an overloaded deref.
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
|
@ -774,8 +774,9 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
|
|
||||||
// Check for overloaded index.
|
// Check for overloaded index.
|
||||||
let method_ty = ccx.tcx()
|
let method_ty = ccx.tcx()
|
||||||
.method_map
|
.tables
|
||||||
.borrow()
|
.borrow()
|
||||||
|
.method_map
|
||||||
.get(&method_call)
|
.get(&method_call)
|
||||||
.map(|method| method.ty);
|
.map(|method| method.ty);
|
||||||
let elt_datum = match 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.
|
// Otherwise, we should be in the RvalueDpsExpr path.
|
||||||
assert!(
|
assert!(
|
||||||
op == ast::UnDeref ||
|
op == ast::UnDeref ||
|
||||||
!ccx.tcx().method_map.borrow().contains_key(&method_call));
|
!ccx.tcx().tables.borrow().method_map.contains_key(&method_call));
|
||||||
|
|
||||||
let un_ty = expr_ty(bcx, expr);
|
let un_ty = expr_ty(bcx, expr);
|
||||||
|
|
||||||
|
@ -1910,7 +1911,7 @@ fn trans_binary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
let ccx = bcx.ccx();
|
let ccx = bcx.ccx();
|
||||||
|
|
||||||
// if overloaded, would be RvalueDpsExpr
|
// 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 {
|
match op.node {
|
||||||
ast::BiAnd => {
|
ast::BiAnd => {
|
||||||
|
@ -1950,7 +1951,12 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
dest: Option<Dest>,
|
dest: Option<Dest>,
|
||||||
autoref: bool)
|
autoref: bool)
|
||||||
-> Result<'blk, 'tcx> {
|
-> 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,
|
callee::trans_call_inner(bcx,
|
||||||
expr.debug_loc(),
|
expr.debug_loc(),
|
||||||
monomorphize_type(bcx, method_ty),
|
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);
|
debug!("trans_overloaded_call {}", expr.id);
|
||||||
let method_call = MethodCall::expr(expr.id);
|
let method_call = MethodCall::expr(expr.id);
|
||||||
let method_type = bcx.tcx()
|
let method_type = bcx.tcx()
|
||||||
.method_map
|
.tables
|
||||||
.borrow()
|
.borrow()
|
||||||
|
.method_map
|
||||||
.get(&method_call)
|
.get(&method_call)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.ty;
|
.ty;
|
||||||
|
@ -2154,7 +2161,7 @@ fn trans_assign_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
debug!("trans_assign_op(expr={:?})", expr);
|
debug!("trans_assign_op(expr={:?})", expr);
|
||||||
|
|
||||||
// User-defined operator methods cannot be used with `+=` etc right now
|
// 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
|
// Evaluate LHS (destination), which should be an lvalue
|
||||||
let dst_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, dst, "assign_op"));
|
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;
|
let mut bcx = bcx;
|
||||||
|
|
||||||
// Check for overloaded deref.
|
// 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);
|
.get(&method_call).map(|method| method.ty);
|
||||||
|
|
||||||
let datum = match method_ty {
|
let datum = match method_ty {
|
||||||
Some(method_ty) => {
|
Some(method_ty) => {
|
||||||
let method_ty = monomorphize_type(bcx, 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 {
|
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
|
// Overloaded operations are generally calls, and hence they are
|
||||||
// generated via DPS, but there are a few exceptions:
|
// generated via DPS, but there are a few exceptions:
|
||||||
return match expr.node {
|
return match expr.node {
|
||||||
|
|
|
@ -109,8 +109,10 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
let _icx = push_ctxt("meth::trans_method_callee");
|
let _icx = push_ctxt("meth::trans_method_callee");
|
||||||
|
|
||||||
let (origin, method_ty) =
|
let (origin, method_ty) =
|
||||||
bcx.tcx().method_map
|
bcx.tcx()
|
||||||
|
.tables
|
||||||
.borrow()
|
.borrow()
|
||||||
|
.method_map
|
||||||
.get(&method_call)
|
.get(&method_call)
|
||||||
.map(|method| (method.origin.clone(), method.ty))
|
.map(|method| (method.origin.clone(), method.ty))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -322,8 +322,9 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(#20304) -- cache
|
// FIXME(#20304) -- cache
|
||||||
|
// NOTE: @jroesch
|
||||||
let infcx = infer::new_infer_ctxt(tcx);
|
// Here is of an example where we do not use a param_env but use a typer instead.
|
||||||
|
let infcx = infer::new_infer_ctxt(tcx, None);
|
||||||
let typer = NormalizingClosureTyper::new(tcx);
|
let typer = NormalizingClosureTyper::new(tcx);
|
||||||
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
|
let mut selcx = traits::SelectionContext::new(&infcx, &typer);
|
||||||
let cause = traits::ObligationCause::dummy();
|
let cause = traits::ObligationCause::dummy();
|
||||||
|
|
|
@ -324,7 +324,7 @@ fn write_overloaded_call_method_map<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
call_expr: &ast::Expr,
|
call_expr: &ast::Expr,
|
||||||
method_callee: ty::MethodCallee<'tcx>) {
|
method_callee: ty::MethodCallee<'tcx>) {
|
||||||
let method_call = ty::MethodCall::expr(call_expr.id);
|
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)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -61,7 +61,7 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||||
expected_sig);
|
expected_sig);
|
||||||
|
|
||||||
let closure_type = fcx.ccx.tcx.mk_closure(expr_def_id,
|
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);
|
fcx.write_ty(expr.id, closure_type);
|
||||||
|
|
||||||
|
@ -86,9 +86,9 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
|
||||||
fn_ty.sig,
|
fn_ty.sig,
|
||||||
opt_kind);
|
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 {
|
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 => { }
|
None => { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||||
debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}",
|
debug!("compare_impl_method: impl_trait_ref (liberated) = {:?}",
|
||||||
impl_trait_ref);
|
impl_trait_ref);
|
||||||
|
|
||||||
let infcx = infer::new_infer_ctxt(tcx);
|
let mut infcx = infer::new_infer_ctxt(tcx, None);
|
||||||
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
|
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
|
||||||
|
|
||||||
let trait_to_impl_substs = &impl_trait_ref.substs;
|
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 = impl_param_env.with_caller_bounds(hybrid_preds.into_vec());
|
||||||
let trait_param_env = traits::normalize_param_env_or_error(trait_param_env,
|
let trait_param_env = traits::normalize_param_env_or_error(trait_param_env,
|
||||||
normalize_cause.clone());
|
normalize_cause.clone());
|
||||||
|
// TODO (@jroesch) this seems ugly, but is a temporary change
|
||||||
|
infcx.parameter_environment = trait_param_env;
|
||||||
|
|
||||||
debug!("compare_impl_method: trait_bounds={:?}",
|
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 {
|
for predicate in impl_pred.fns {
|
||||||
let traits::Normalized { value: predicate, .. } =
|
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
|
// Check that all obligations are satisfied by the implementation's
|
||||||
// version.
|
// 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) }
|
Err(ref errors) => { traits::report_fulfillment_errors(&infcx, errors) }
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
}
|
}
|
||||||
|
@ -360,7 +362,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||||
// anyway, so it shouldn't be needed there either. Anyway, we can
|
// anyway, so it shouldn't be needed there either. Anyway, we can
|
||||||
// always add more relations later (it's backwards compat).
|
// always add more relations later (it's backwards compat).
|
||||||
let mut free_regions = FreeRegionMap::new();
|
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);
|
infcx.resolve_regions_and_report_errors(&free_regions, impl_m_body_id);
|
||||||
|
|
||||||
|
@ -416,7 +418,7 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||||
debug!("compare_const_impl(impl_trait_ref={:?})",
|
debug!("compare_const_impl(impl_trait_ref={:?})",
|
||||||
impl_trait_ref);
|
impl_trait_ref);
|
||||||
|
|
||||||
let infcx = infer::new_infer_ctxt(tcx);
|
let infcx = infer::new_infer_ctxt(tcx, None);
|
||||||
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
|
let mut fulfillment_cx = traits::FulfillmentContext::new(true);
|
||||||
|
|
||||||
// The below is for the most part highly similar to the procedure
|
// The below is for the most part highly similar to the procedure
|
||||||
|
|
|
@ -93,7 +93,8 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
|
||||||
ty: named_type } =
|
ty: named_type } =
|
||||||
tcx.lookup_item_type(self_type_did);
|
tcx.lookup_item_type(self_type_did);
|
||||||
|
|
||||||
let infcx = infer::new_infer_ctxt(tcx);
|
let infcx = infer::new_infer_ctxt(tcx, None);
|
||||||
|
|
||||||
infcx.commit_if_ok(|snapshot| {
|
infcx.commit_if_ok(|snapshot| {
|
||||||
let (named_type_to_skolem, skol_map) =
|
let (named_type_to_skolem, skol_map) =
|
||||||
infcx.construct_skolemized_subst(named_type_generics, snapshot);
|
infcx.construct_skolemized_subst(named_type_generics, snapshot);
|
||||||
|
|
|
@ -488,8 +488,9 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||||
// Count autoderefs.
|
// Count autoderefs.
|
||||||
let autoderef_count = match self.fcx
|
let autoderef_count = match self.fcx
|
||||||
.inh
|
.inh
|
||||||
.adjustments
|
.tables
|
||||||
.borrow()
|
.borrow()
|
||||||
|
.adjustments
|
||||||
.get(&expr.id) {
|
.get(&expr.id) {
|
||||||
Some(&ty::AdjustDerefRef(ref adj)) => adj.autoderefs,
|
Some(&ty::AdjustDerefRef(ref adj)) => adj.autoderefs,
|
||||||
Some(_) | None => 0,
|
Some(_) | None => 0,
|
||||||
|
@ -527,7 +528,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||||
// expects. This is annoying and horrible. We
|
// expects. This is annoying and horrible. We
|
||||||
// ought to recode this routine so it doesn't
|
// ought to recode this routine so it doesn't
|
||||||
// (ab)use the normal type checking paths.
|
// (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 {
|
let (autoderefs, unsize) = match adj {
|
||||||
Some(ty::AdjustDerefRef(adr)) => match adr.autoref {
|
Some(ty::AdjustDerefRef(adr)) => match adr.autoref {
|
||||||
None => {
|
None => {
|
||||||
|
@ -589,7 +590,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||||
// if this is an overloaded deref, then re-evaluate with
|
// if this is an overloaded deref, then re-evaluate with
|
||||||
// a preference for mut
|
// a preference for mut
|
||||||
let method_call = MethodCall::expr(expr.id);
|
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(
|
check::try_overloaded_deref(
|
||||||
self.fcx,
|
self.fcx,
|
||||||
expr.span,
|
expr.span,
|
||||||
|
|
|
@ -477,7 +477,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||||
// FIXME -- Do we want to commit to this behavior for param bounds?
|
// FIXME -- Do we want to commit to this behavior for param bounds?
|
||||||
|
|
||||||
let bounds: Vec<_> =
|
let bounds: Vec<_> =
|
||||||
self.fcx.inh.param_env.caller_bounds
|
self.fcx.inh.infcx.parameter_environment.caller_bounds
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|predicate| {
|
.filter_map(|predicate| {
|
||||||
match *predicate {
|
match *predicate {
|
||||||
|
@ -742,7 +742,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||||
_ => continue,
|
_ => 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) {
|
let closure_kind = match closure_kinds.get(&closure_def_id) {
|
||||||
Some(&k) => k,
|
Some(&k) => k,
|
||||||
None => {
|
None => {
|
||||||
|
@ -845,7 +845,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||||
debug!("assemble_where_clause_candidates(trait_def_id={:?})",
|
debug!("assemble_where_clause_candidates(trait_def_id={:?})",
|
||||||
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)
|
for poly_bound in traits::elaborate_predicates(self.tcx(), caller_predicates)
|
||||||
.filter_map(|p| p.to_opt_poly_trait_ref())
|
.filter_map(|p| p.to_opt_poly_trait_ref())
|
||||||
.filter(|b| b.def_id() == trait_def_id)
|
.filter(|b| b.def_id() == trait_def_id)
|
||||||
|
|
|
@ -97,7 +97,7 @@ use middle::traits::{self, report_fulfillment_errors};
|
||||||
use middle::ty::{FnSig, GenericPredicates, TypeScheme};
|
use middle::ty::{FnSig, GenericPredicates, TypeScheme};
|
||||||
use middle::ty::{Disr, ParamTy, ParameterEnvironment};
|
use middle::ty::{Disr, ParamTy, ParameterEnvironment};
|
||||||
use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
|
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 middle::ty_fold::{TypeFolder, TypeFoldable};
|
||||||
use rscope::RegionScope;
|
use rscope::RegionScope;
|
||||||
use session::Session;
|
use session::Session;
|
||||||
|
@ -152,16 +152,8 @@ mod op;
|
||||||
pub struct Inherited<'a, 'tcx: 'a> {
|
pub struct Inherited<'a, 'tcx: 'a> {
|
||||||
infcx: infer::InferCtxt<'a, 'tcx>,
|
infcx: infer::InferCtxt<'a, 'tcx>,
|
||||||
locals: RefCell<NodeMap<Ty<'tcx>>>,
|
locals: RefCell<NodeMap<Ty<'tcx>>>,
|
||||||
param_env: ty::ParameterEnvironment<'a, 'tcx>,
|
|
||||||
|
|
||||||
// Temporary tables:
|
tables: &'a RefCell<ty::Tables<'tcx>>,
|
||||||
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>>,
|
|
||||||
|
|
||||||
// A mapping from each fn's id to its signature, with all bound
|
// A mapping from each fn's id to its signature, with all bound
|
||||||
// regions replaced with free ones. Unlike the other tables, this
|
// regions replaced with free ones. Unlike the other tables, this
|
||||||
|
@ -303,52 +295,68 @@ impl<'a, 'tcx> mc::Typer<'tcx> for FnCtxt<'a, 'tcx> {
|
||||||
let ty = self.node_ty(id);
|
let ty = self.node_ty(id);
|
||||||
self.resolve_type_vars_or_error(&ty)
|
self.resolve_type_vars_or_error(&ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
|
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
|
||||||
let ty = self.adjust_expr_ty(expr, self.inh.adjustments.borrow().get(&expr.id));
|
let ty = self.adjust_expr_ty(expr, self.inh.tables.borrow().adjustments.get(&expr.id));
|
||||||
self.resolve_type_vars_or_error(&ty)
|
self.resolve_type_vars_or_error(&ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
|
fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
|
||||||
let ty = self.infcx().resolve_type_vars_if_possible(&ty);
|
let ty = self.infcx().resolve_type_vars_if_possible(&ty);
|
||||||
!traits::type_known_to_meet_builtin_bound(self.infcx(), self, ty, ty::BoundCopy, span)
|
!traits::type_known_to_meet_builtin_bound(self.infcx(), self, ty, ty::BoundCopy, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_method_ty(&self, method_call: ty::MethodCall)
|
fn node_method_ty(&self, method_call: ty::MethodCall)
|
||||||
-> Option<Ty<'tcx>> {
|
-> Option<Ty<'tcx>> {
|
||||||
self.inh.method_map.borrow()
|
self.inh.tables
|
||||||
|
.borrow()
|
||||||
|
.method_map
|
||||||
.get(&method_call)
|
.get(&method_call)
|
||||||
.map(|method| method.ty)
|
.map(|method| method.ty)
|
||||||
.map(|ty| self.infcx().resolve_type_vars_if_possible(&ty))
|
.map(|ty| self.infcx().resolve_type_vars_if_possible(&ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_method_origin(&self, method_call: ty::MethodCall)
|
fn node_method_origin(&self, method_call: ty::MethodCall)
|
||||||
-> Option<ty::MethodOrigin<'tcx>>
|
-> Option<ty::MethodOrigin<'tcx>>
|
||||||
{
|
{
|
||||||
self.inh.method_map.borrow()
|
self.inh.tables
|
||||||
|
.borrow()
|
||||||
|
.method_map
|
||||||
.get(&method_call)
|
.get(&method_call)
|
||||||
.map(|method| method.origin.clone())
|
.map(|method| method.origin.clone())
|
||||||
}
|
}
|
||||||
fn adjustments(&self) -> &RefCell<NodeMap<ty::AutoAdjustment<'tcx>>> {
|
|
||||||
&self.inh.adjustments
|
fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>> {
|
||||||
|
fn project_adjustments<'a, 'tcx>(tables: &'a ty::Tables<'tcx>) -> &'a NodeMap<ty::AutoAdjustment<'tcx>> {
|
||||||
|
&tables.adjustments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ref::map(self.inh.tables.borrow(), project_adjustments)
|
||||||
|
}
|
||||||
|
|
||||||
fn is_method_call(&self, id: ast::NodeId) -> bool {
|
fn is_method_call(&self, id: ast::NodeId) -> bool {
|
||||||
self.inh.method_map.borrow().contains_key(&ty::MethodCall::expr(id))
|
self.inh.tables.borrow().method_map.contains_key(&ty::MethodCall::expr(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
|
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
|
||||||
self.param_env().temporary_scope(rvalue_id)
|
self.param_env().temporary_scope(rvalue_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
|
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture> {
|
||||||
self.inh.upvar_capture_map.borrow().get(&upvar_id).cloned()
|
self.inh.tables.borrow().upvar_capture_map.get(&upvar_id).cloned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
|
||||||
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
|
fn param_env<'b>(&'b self) -> &'b ty::ParameterEnvironment<'b,'tcx> {
|
||||||
&self.inh.param_env
|
&self.inh.infcx.parameter_environment
|
||||||
}
|
}
|
||||||
|
|
||||||
fn closure_kind(&self,
|
fn closure_kind(&self,
|
||||||
def_id: ast::DefId)
|
def_id: ast::DefId)
|
||||||
-> Option<ty::ClosureKind>
|
-> Option<ty::ClosureKind>
|
||||||
{
|
{
|
||||||
self.inh.closure_kinds.borrow().get(&def_id).cloned()
|
self.inh.tables.borrow().closure_kinds.get(&def_id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn closure_type(&self,
|
fn closure_type(&self,
|
||||||
|
@ -356,7 +364,7 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
|
||||||
substs: &subst::Substs<'tcx>)
|
substs: &subst::Substs<'tcx>)
|
||||||
-> ty::ClosureTy<'tcx>
|
-> ty::ClosureTy<'tcx>
|
||||||
{
|
{
|
||||||
self.inh.closure_tys.borrow().get(&def_id).unwrap().subst(self.tcx(), substs)
|
self.inh.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self.tcx(), substs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn closure_upvars(&self,
|
fn closure_upvars(&self,
|
||||||
|
@ -369,19 +377,14 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
impl<'a, 'tcx> Inherited<'a, 'tcx> {
|
impl<'a, 'tcx> Inherited<'a, 'tcx> {
|
||||||
fn new(tcx: &'a ty::ctxt<'tcx>,
|
fn new(tcx: &'a ty::ctxt<'tcx>,
|
||||||
|
tables: &'a RefCell<ty::Tables<'tcx>>,
|
||||||
param_env: ty::ParameterEnvironment<'a, 'tcx>)
|
param_env: ty::ParameterEnvironment<'a, 'tcx>)
|
||||||
-> Inherited<'a, 'tcx> {
|
-> Inherited<'a, 'tcx> {
|
||||||
|
|
||||||
Inherited {
|
Inherited {
|
||||||
infcx: infer::new_infer_ctxt(tcx),
|
infcx: infer::new_infer_ctxt(tcx, Some(param_env)),
|
||||||
locals: RefCell::new(NodeMap()),
|
locals: RefCell::new(NodeMap()),
|
||||||
param_env: param_env,
|
tables: tables,
|
||||||
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()),
|
|
||||||
fn_sig_map: RefCell::new(NodeMap()),
|
fn_sig_map: RefCell::new(NodeMap()),
|
||||||
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(true)),
|
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(true)),
|
||||||
deferred_call_resolutions: RefCell::new(DefIdMap()),
|
deferred_call_resolutions: RefCell::new(DefIdMap()),
|
||||||
|
@ -424,12 +427,12 @@ pub fn blank_fn_ctxt<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>)
|
fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>, tables: &'a RefCell<ty::Tables<'tcx>>)
|
||||||
-> Inherited<'a, 'tcx> {
|
-> Inherited<'a, 'tcx> {
|
||||||
// It's kind of a kludge to manufacture a fake function context
|
// 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
|
// and statement context, but we might as well do write the code only once
|
||||||
let param_env = ccx.tcx.empty_parameter_environment();
|
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> }
|
struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
|
||||||
|
@ -504,16 +507,20 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||||
{
|
{
|
||||||
match raw_fty.sty {
|
match raw_fty.sty {
|
||||||
ty::TyBareFn(_, ref fn_ty) => {
|
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.
|
// Compute the fty from point of view of inside fn.
|
||||||
let fn_sig =
|
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 =
|
let fn_sig =
|
||||||
ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id),
|
ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id),
|
||||||
&fn_sig);
|
&fn_sig);
|
||||||
let 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,
|
let fcx = check_fn(ccx, fn_ty.unsafety, fn_id, &fn_sig,
|
||||||
decl, fn_id, body, &inh);
|
decl, fn_id, body, &inh);
|
||||||
|
@ -1198,7 +1205,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_free_substs(&self) -> Option<&Substs<'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,
|
fn get_type_parameter_bounds(&self,
|
||||||
|
@ -1207,7 +1214,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
||||||
-> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
|
-> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
|
||||||
{
|
{
|
||||||
let def = self.tcx().type_parameter_def(node_id);
|
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()
|
.iter()
|
||||||
.filter_map(|predicate| {
|
.filter_map(|predicate| {
|
||||||
match *predicate {
|
match *predicate {
|
||||||
|
@ -1273,7 +1281,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn param_env(&self) -> &ty::ParameterEnvironment<'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 {
|
pub fn sess(&self) -> &Session {
|
||||||
|
@ -1368,7 +1376,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
/// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
|
/// ! gets replaced with (), unconstrained ints with i32, and unconstrained floats with f64.
|
||||||
pub fn default_type_parameters(&self) {
|
pub fn default_type_parameters(&self) {
|
||||||
use middle::ty::UnconstrainedNumeric::{UnconstrainedInt, UnconstrainedFloat, Neither};
|
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);
|
let resolved = self.infcx().resolve_type_vars_if_possible(ty);
|
||||||
if self.infcx().type_var_diverges(resolved) {
|
if self.infcx().type_var_diverges(resolved) {
|
||||||
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
|
demand::eqtype(self, codemap::DUMMY_SP, *ty, self.tcx().mk_nil());
|
||||||
|
@ -1390,7 +1398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
|
pub fn write_ty(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
|
||||||
debug!("write_ty({}, {:?}) in fcx {}",
|
debug!("write_ty({}, {:?}) in fcx {}",
|
||||||
node_id, ty, self.tag());
|
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>) {
|
pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) {
|
||||||
|
@ -1400,7 +1408,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
substs,
|
substs,
|
||||||
self.tag());
|
self.tag());
|
||||||
|
|
||||||
self.inh.item_substs.borrow_mut().insert(node_id, substs);
|
self.inh.tables.borrow_mut().item_substs.insert(node_id, substs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1426,7 +1434,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
return;
|
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
|
/// Basically whenever we are converting from a type scheme into
|
||||||
|
@ -1627,7 +1635,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> {
|
pub fn expr_ty(&self, ex: &ast::Expr) -> Ty<'tcx> {
|
||||||
match self.inh.node_types.borrow().get(&ex.id) {
|
match self.inh.tables.borrow().node_types.get(&ex.id) {
|
||||||
Some(&t) => t,
|
Some(&t) => t,
|
||||||
None => {
|
None => {
|
||||||
self.tcx().sess.bug(&format!("no type for expr in fcx {}",
|
self.tcx().sess.bug(&format!("no type for expr in fcx {}",
|
||||||
|
@ -1646,13 +1654,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let raw_ty = self.infcx().shallow_resolve(raw_ty);
|
let raw_ty = self.infcx().shallow_resolve(raw_ty);
|
||||||
let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&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| {
|
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))
|
.map(|method| resolve_ty(method.ty))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
|
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,
|
Some(&t) => t,
|
||||||
None if self.err_count_since_creation() != 0 => self.tcx().types.err,
|
None if self.err_count_since_creation() != 0 => self.tcx().types.err,
|
||||||
None => {
|
None => {
|
||||||
|
@ -1665,7 +1673,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn item_substs(&self) -> Ref<NodeMap<ty::ItemSubsts<'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,
|
pub fn opt_node_ty_substs<F>(&self,
|
||||||
|
@ -1673,7 +1687,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
f: F) where
|
f: F) where
|
||||||
F: FnOnce(&ty::ItemSubsts<'tcx>),
|
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) }
|
Some(s) => { f(s) }
|
||||||
None => { }
|
None => { }
|
||||||
}
|
}
|
||||||
|
@ -2039,7 +2053,7 @@ fn make_overloaded_lvalue_return_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
|
let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
|
||||||
|
|
||||||
if let Some(method_call) = method_call {
|
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
|
// method returns &T, but the type as visible to user is T, so deref
|
||||||
|
@ -2640,7 +2654,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
Ok(method) => {
|
Ok(method) => {
|
||||||
let method_ty = method.ty;
|
let method_ty = method.ty;
|
||||||
let method_call = MethodCall::expr(expr.id);
|
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
|
method_ty
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
|
@ -4074,7 +4088,8 @@ fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
|
fn check_const_in_type<'a,'tcx>(ccx: &'a CrateCtxt<'a,'tcx>,
|
||||||
expr: &'tcx ast::Expr,
|
expr: &'tcx ast::Expr,
|
||||||
expected_type: Ty<'tcx>) {
|
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);
|
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(expected_type), expr.id);
|
||||||
check_const_with_ty(&fcx, expr.span, expr, expected_type);
|
check_const_with_ty(&fcx, expr.span, expr, expected_type);
|
||||||
}
|
}
|
||||||
|
@ -4083,7 +4098,8 @@ fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
e: &'tcx ast::Expr,
|
e: &'tcx ast::Expr,
|
||||||
id: ast::NodeId) {
|
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 rty = ccx.tcx.node_id_to_type(id);
|
||||||
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
|
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
|
||||||
let declty = fcx.ccx.tcx.tcache.borrow().get(&local_def(id)).unwrap().ty;
|
let declty = fcx.ccx.tcx.tcache.borrow().get(&local_def(id)).unwrap().ty;
|
||||||
|
@ -4235,7 +4251,8 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||||
let rty = ccx.tcx.node_id_to_type(id);
|
let rty = ccx.tcx.node_id_to_type(id);
|
||||||
let mut disr_vals: Vec<ty::Disr> = Vec::new();
|
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 fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
|
||||||
|
|
||||||
let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
|
let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
|
||||||
|
|
|
@ -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.
|
// HACK(eddyb) Fully qualified path to work around a resolve bug.
|
||||||
let method_call = ::middle::ty::MethodCall::expr(expr.id);
|
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
|
// extract return type for method; all late bound regions
|
||||||
// should have been instantiated by now
|
// should have been instantiated by now
|
||||||
|
@ -454,4 +454,3 @@ fn is_builtin_binop<'tcx>(cx: &ty::ctxt<'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) {
|
||||||
pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) {
|
pub fn regionck_item(fcx: &FnCtxt, item: &ast::Item) {
|
||||||
let mut rcx = Rcx::new(fcx, RepeatingScope(item.id), item.id, Subject(item.id));
|
let mut rcx = Rcx::new(fcx, RepeatingScope(item.id), item.id, Subject(item.id));
|
||||||
let tcx = fcx.tcx();
|
let tcx = fcx.tcx();
|
||||||
rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds);
|
rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.infcx.parameter_environment.caller_bounds);
|
||||||
rcx.visit_region_obligations(item.id);
|
rcx.visit_region_obligations(item.id);
|
||||||
rcx.resolve_regions_and_report_errors();
|
rcx.resolve_regions_and_report_errors();
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ pub fn regionck_fn(fcx: &FnCtxt,
|
||||||
}
|
}
|
||||||
|
|
||||||
let tcx = fcx.tcx();
|
let tcx = fcx.tcx();
|
||||||
rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.param_env.caller_bounds);
|
rcx.free_region_map.relate_free_regions_from_predicates(tcx, &fcx.inh.infcx.parameter_environment.caller_bounds);
|
||||||
|
|
||||||
rcx.resolve_regions_and_report_errors();
|
rcx.resolve_regions_and_report_errors();
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_method_type(&self, method_call: MethodCall) -> Option<Ty<'tcx>> {
|
fn resolve_method_type(&self, method_call: MethodCall) -> Option<Ty<'tcx>> {
|
||||||
let method_ty = self.fcx.inh.method_map.borrow()
|
let method_ty = self.fcx.inh.tables.borrow().method_map
|
||||||
.get(&method_call).map(|method| method.ty);
|
.get(&method_call).map(|method| method.ty);
|
||||||
method_ty.map(|method_ty| self.resolve_type(method_ty))
|
method_ty.map(|method_ty| self.resolve_type(method_ty))
|
||||||
}
|
}
|
||||||
|
@ -267,7 +267,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
ty_unadjusted.adjust(
|
ty_unadjusted.adjust(
|
||||||
self.fcx.tcx(), expr.span, expr.id,
|
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))
|
|method_call| self.resolve_method_type(method_call))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,12 +511,13 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||||
expr_ty, ty::ReScope(CodeExtent::from_node_id(expr.id)));
|
expr_ty, ty::ReScope(CodeExtent::from_node_id(expr.id)));
|
||||||
|
|
||||||
let method_call = MethodCall::expr(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.
|
// 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);
|
debug!("adjustment={:?}", adjustment);
|
||||||
match *adjustment {
|
match adjustment {
|
||||||
ty::AdjustDerefRef(ty::AutoDerefRef {autoderefs, ref autoref, ..}) => {
|
ty::AdjustDerefRef(ty::AutoDerefRef {autoderefs, ref autoref, ..}) => {
|
||||||
let expr_ty = rcx.resolve_node_type(expr.id);
|
let expr_ty = rcx.resolve_node_type(expr.id);
|
||||||
constrain_autoderefs(rcx, expr, autoderefs, expr_ty);
|
constrain_autoderefs(rcx, expr, autoderefs, expr_ty);
|
||||||
|
@ -657,7 +658,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
|
||||||
ast::ExprUnary(ast::UnDeref, ref base) => {
|
ast::ExprUnary(ast::UnDeref, ref base) => {
|
||||||
// For *a, the lifetime of a must enclose the deref
|
// For *a, the lifetime of a must enclose the deref
|
||||||
let method_call = MethodCall::expr(expr.id);
|
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) => {
|
Some(method) => {
|
||||||
constrain_call(rcx, expr, Some(&**base),
|
constrain_call(rcx, expr, Some(&**base),
|
||||||
None::<ast::Expr>.iter(), true);
|
None::<ast::Expr>.iter(), true);
|
||||||
|
@ -884,7 +885,9 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
|
||||||
let method_call = MethodCall::autoderef(deref_expr.id, i as u32);
|
let method_call = MethodCall::autoderef(deref_expr.id, i as u32);
|
||||||
debug!("constrain_autoderefs: method_call={:?} (of {:?} total)", method_call, derefs);
|
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) => {
|
Some(method) => {
|
||||||
debug!("constrain_autoderefs: #{} is overloaded, method={:?}",
|
debug!("constrain_autoderefs: #{} is overloaded, method={:?}",
|
||||||
i, method);
|
i, method);
|
||||||
|
@ -1018,7 +1021,7 @@ fn type_of_node_must_outlive<'a, 'tcx>(
|
||||||
// report errors later on in the writeback phase.
|
// report errors later on in the writeback phase.
|
||||||
let ty0 = rcx.resolve_node_type(id);
|
let ty0 = rcx.resolve_node_type(id);
|
||||||
let ty = ty0.adjust(tcx, origin.span(), 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));
|
|method_call| rcx.resolve_method_type(method_call));
|
||||||
debug!("constrain_regions_in_type_of_node(\
|
debug!("constrain_regions_in_type_of_node(\
|
||||||
ty={}, ty0={}, id={}, minimum_lifetime={:?})",
|
ty={}, ty0={}, id={}, minimum_lifetime={:?})",
|
||||||
|
@ -1292,7 +1295,7 @@ fn link_reborrowed_region<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
|
||||||
// Detect by-ref upvar `x`:
|
// Detect by-ref upvar `x`:
|
||||||
let cause = match note {
|
let cause = match note {
|
||||||
mc::NoteUpvarRef(ref upvar_id) => {
|
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) {
|
match upvar_capture_map.get(upvar_id) {
|
||||||
Some(&ty::UpvarCapture::ByRef(ref upvar_borrow)) => {
|
Some(&ty::UpvarCapture::ByRef(ref upvar_borrow)) => {
|
||||||
// The mutability of the upvar may have been modified
|
// The mutability of the upvar may have been modified
|
||||||
|
@ -1453,7 +1456,7 @@ fn generic_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
|
||||||
origin: infer::SubregionOrigin<'tcx>,
|
origin: infer::SubregionOrigin<'tcx>,
|
||||||
region: ty::Region,
|
region: ty::Region,
|
||||||
generic: &GenericKind<'tcx>) {
|
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={:?})",
|
debug!("param_must_outlive(region={:?}, generic={:?})",
|
||||||
region,
|
region,
|
||||||
|
|
|
@ -129,9 +129,9 @@ impl<'a,'tcx> SeedBorrowKind<'a,'tcx> {
|
||||||
_body: &ast::Block)
|
_body: &ast::Block)
|
||||||
{
|
{
|
||||||
let closure_def_id = ast_util::local_def(expr.id);
|
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.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",
|
debug!("check_closure: adding closure_id={:?} to closures_with_inferred_kinds",
|
||||||
closure_def_id);
|
closure_def_id);
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -267,7 +267,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
|
||||||
// to move out of an upvar, this must be a FnOnce closure
|
// to move out of an upvar, this must be a FnOnce closure
|
||||||
self.adjust_closure_kind(upvar_id.closure_expr_id, ty::FnOnceClosureKind);
|
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);
|
upvar_capture_map.insert(upvar_id, ty::UpvarCapture::ByValue);
|
||||||
}
|
}
|
||||||
mc::NoteClosureEnv(upvar_id) => {
|
mc::NoteClosureEnv(upvar_id) => {
|
||||||
|
@ -374,9 +374,11 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
|
||||||
// upvar, then we need to modify the
|
// upvar, then we need to modify the
|
||||||
// borrow_kind of the upvar to make sure it
|
// borrow_kind of the upvar to make sure it
|
||||||
// is inferred to mutable if necessary
|
// is inferred to mutable if necessary
|
||||||
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;
|
||||||
let ub = upvar_capture_map.get_mut(&upvar_id).unwrap();
|
let ub = upvar_capture_map.get_mut(&upvar_id).unwrap();
|
||||||
self.adjust_upvar_borrow_kind(upvar_id, ub, borrow_kind);
|
self.adjust_upvar_borrow_kind(upvar_id, ub, borrow_kind);
|
||||||
|
}
|
||||||
|
|
||||||
// also need to be in an FnMut closure since this is not an ImmBorrow
|
// 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);
|
self.adjust_closure_kind(upvar_id.closure_expr_id, ty::FnMutClosureKind);
|
||||||
|
@ -442,7 +444,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let closure_def_id = ast_util::local_def(closure_id);
|
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();
|
let existing_kind = *closure_kinds.get(&closure_def_id).unwrap();
|
||||||
|
|
||||||
debug!("adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}",
|
debug!("adjust_closure_kind: closure_id={}, existing_kind={:?}, new_kind={:?}",
|
||||||
|
|
|
@ -18,6 +18,7 @@ use middle::traits;
|
||||||
use middle::ty::{self, Ty};
|
use middle::ty::{self, Ty};
|
||||||
use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty};
|
use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty};
|
||||||
|
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast_util::local_def;
|
use syntax::ast_util::local_def;
|
||||||
|
@ -143,7 +144,8 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
||||||
&type_scheme.generics,
|
&type_scheme.generics,
|
||||||
&type_predicates,
|
&type_predicates,
|
||||||
item.id);
|
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);
|
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id);
|
||||||
f(self, &fcx);
|
f(self, &fcx);
|
||||||
fcx.select_all_obligations_or_error();
|
fcx.select_all_obligations_or_error();
|
||||||
|
@ -199,7 +201,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
||||||
|
|
||||||
let type_scheme = fcx.tcx().lookup_item_type(local_def(item.id));
|
let type_scheme = fcx.tcx().lookup_item_type(local_def(item.id));
|
||||||
let item_ty = fcx.instantiate_type_scheme(item.span,
|
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);
|
&type_scheme.ty);
|
||||||
|
|
||||||
bounds_checker.check_traits_in_ty(item_ty, item.span);
|
bounds_checker.check_traits_in_ty(item_ty, item.span);
|
||||||
|
@ -220,7 +222,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
||||||
// to free.
|
// to free.
|
||||||
let self_ty = fcx.tcx().node_id_to_type(item.id);
|
let self_ty = fcx.tcx().node_id_to_type(item.id);
|
||||||
let self_ty = fcx.instantiate_type_scheme(item.span,
|
let self_ty = fcx.instantiate_type_scheme(item.span,
|
||||||
&fcx.inh.param_env.free_substs,
|
&fcx.inh.infcx.parameter_environment.free_substs,
|
||||||
&self_ty);
|
&self_ty);
|
||||||
|
|
||||||
bounds_checker.check_traits_in_ty(self_ty, item.span);
|
bounds_checker.check_traits_in_ty(self_ty, item.span);
|
||||||
|
@ -233,7 +235,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let trait_ref = fcx.instantiate_type_scheme(item.span,
|
let trait_ref = fcx.instantiate_type_scheme(item.span,
|
||||||
&fcx.inh.param_env.free_substs,
|
&fcx.inh.infcx.parameter_environment.free_substs,
|
||||||
&trait_ref);
|
&trait_ref);
|
||||||
|
|
||||||
// We are stricter on the trait-ref in an impl than the
|
// We are stricter on the trait-ref in an impl than the
|
||||||
|
@ -635,7 +637,7 @@ fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
.map(|field| {
|
.map(|field| {
|
||||||
let field_ty = fcx.tcx().node_id_to_type(field.node.id);
|
let field_ty = fcx.tcx().node_id_to_type(field.node.id);
|
||||||
let field_ty = fcx.instantiate_type_scheme(field.span,
|
let field_ty = fcx.instantiate_type_scheme(field.span,
|
||||||
&fcx.inh.param_env.free_substs,
|
&fcx.inh.infcx.parameter_environment.free_substs,
|
||||||
&field_ty);
|
&field_ty);
|
||||||
AdtField { ty: field_ty, span: field.span }
|
AdtField { ty: field_ty, span: field.span }
|
||||||
})
|
})
|
||||||
|
@ -660,7 +662,7 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||||
let arg_ty = arg_tys[index];
|
let arg_ty = arg_tys[index];
|
||||||
let arg_ty =
|
let arg_ty =
|
||||||
fcx.instantiate_type_scheme(variant.span,
|
fcx.instantiate_type_scheme(variant.span,
|
||||||
&fcx.inh.param_env.free_substs,
|
&fcx.inh.infcx.parameter_environment.free_substs,
|
||||||
&arg_ty);
|
&arg_ty);
|
||||||
AdtField {
|
AdtField {
|
||||||
ty: arg_ty,
|
ty: arg_ty,
|
||||||
|
|
|
@ -96,14 +96,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
let rhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&rhs_ty);
|
let rhs_ty = self.fcx.infcx().resolve_type_vars_if_possible(&rhs_ty);
|
||||||
|
|
||||||
if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
|
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
|
// weird but true: the by-ref binops put an
|
||||||
// adjustment on the lhs but not the rhs; the
|
// adjustment on the lhs but not the rhs; the
|
||||||
// adjustment for rhs is kind of baked into the
|
// adjustment for rhs is kind of baked into the
|
||||||
// system.
|
// system.
|
||||||
if !ast_util::is_by_value_binop(op.node) {
|
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;
|
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 {
|
let new_upvar_capture = match *upvar_capture {
|
||||||
ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
|
ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
|
||||||
ty::UpvarCapture::ByRef(ref upvar_borrow) => {
|
ty::UpvarCapture::ByRef(ref upvar_borrow) => {
|
||||||
|
@ -217,7 +217,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
debug!("Upvar capture for {:?} resolved to {:?}",
|
debug!("Upvar capture for {:?} resolved to {:?}",
|
||||||
upvar_id,
|
upvar_id,
|
||||||
new_upvar_capture);
|
new_upvar_capture);
|
||||||
self.fcx.tcx().upvar_capture_map.borrow_mut().insert(*upvar_id, new_upvar_capture);
|
self.fcx.tcx().tables.borrow_mut().upvar_capture_map.insert(*upvar_id, new_upvar_capture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,13 +226,13 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
return
|
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));
|
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() {
|
for (def_id, &closure_kind) in self.fcx.inh.tables.borrow().closure_kinds.iter() {
|
||||||
self.fcx.tcx().closure_kinds.borrow_mut().insert(*def_id, closure_kind);
|
self.fcx.tcx().tables.borrow_mut().closure_kinds.insert(*def_id, closure_kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +254,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_adjustments(&self, reason: ResolveReason, id: ast::NodeId) {
|
fn visit_adjustments(&self, reason: ResolveReason, id: ast::NodeId) {
|
||||||
match self.fcx.inh.adjustments.borrow_mut().remove(&id) {
|
let adjustments = self.fcx.inh.tables.borrow_mut().adjustments.remove(&id);
|
||||||
|
match adjustments {
|
||||||
None => {
|
None => {
|
||||||
debug!("No adjustments for node {}", id);
|
debug!("No adjustments for node {}", id);
|
||||||
}
|
}
|
||||||
|
@ -281,7 +282,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
debug!("Adjustments for node {}: {:?}", id, resolved_adjustment);
|
debug!("Adjustments for node {}: {:?}", id, resolved_adjustment);
|
||||||
self.tcx().adjustments.borrow_mut().insert(
|
self.tcx().tables.borrow_mut().adjustments.insert(
|
||||||
id, resolved_adjustment);
|
id, resolved_adjustment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,7 +292,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
reason: ResolveReason,
|
reason: ResolveReason,
|
||||||
method_call: MethodCall) {
|
method_call: MethodCall) {
|
||||||
// Resolve any method map entry
|
// 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) => {
|
Some(method) => {
|
||||||
debug!("writeback::resolve_method_map_entry(call={:?}, entry={:?})",
|
debug!("writeback::resolve_method_map_entry(call={:?}, entry={:?})",
|
||||||
method_call,
|
method_call,
|
||||||
|
@ -302,9 +303,17 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
substs: self.resolve(&method.substs, reason),
|
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,
|
method_call,
|
||||||
new_method);
|
method);
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -448,7 +448,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||||
debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (free)",
|
debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (free)",
|
||||||
source, target);
|
source, target);
|
||||||
|
|
||||||
let infcx = new_infer_ctxt(tcx);
|
let infcx = new_infer_ctxt(tcx, Some(param_env));
|
||||||
|
|
||||||
let check_mutbl = |mt_a: ty::mt<'tcx>, mt_b: ty::mt<'tcx>,
|
let check_mutbl = |mt_a: ty::mt<'tcx>, mt_b: ty::mt<'tcx>,
|
||||||
mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| {
|
mk_ptr: &Fn(Ty<'tcx>) -> Ty<'tcx>| {
|
||||||
|
@ -540,13 +540,13 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
|
||||||
fulfill_cx.register_predicate_obligation(&infcx, predicate);
|
fulfill_cx.register_predicate_obligation(&infcx, predicate);
|
||||||
|
|
||||||
// Check that all transitive obligations are satisfied.
|
// Check that all transitive obligations are satisfied.
|
||||||
if let Err(errors) = fulfill_cx.select_all_or_error(&infcx, ¶m_env) {
|
if let Err(errors) = fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) {
|
||||||
traits::report_fulfillment_errors(&infcx, &errors);
|
traits::report_fulfillment_errors(&infcx, &errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, resolve all regions.
|
// Finally, resolve all regions.
|
||||||
let mut free_regions = FreeRegionMap::new();
|
let mut free_regions = FreeRegionMap::new();
|
||||||
free_regions.relate_free_regions_from_predicates(tcx, ¶m_env.caller_bounds);
|
free_regions.relate_free_regions_from_predicates(tcx, &infcx.parameter_environment.caller_bounds);
|
||||||
infcx.resolve_regions_and_report_errors(&free_regions, impl_did.node);
|
infcx.resolve_regions_and_report_errors(&free_regions, impl_did.node);
|
||||||
|
|
||||||
if let Some(kind) = kind {
|
if let Some(kind) = kind {
|
||||||
|
@ -630,7 +630,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
|
||||||
pub fn check_coherence(crate_context: &CrateCtxt) {
|
pub fn check_coherence(crate_context: &CrateCtxt) {
|
||||||
CoherenceChecker {
|
CoherenceChecker {
|
||||||
crate_context: crate_context,
|
crate_context: crate_context,
|
||||||
inference_context: new_infer_ctxt(crate_context.tcx),
|
inference_context: new_infer_ctxt(crate_context.tcx, None),
|
||||||
inherent_impls: RefCell::new(FnvHashMap()),
|
inherent_impls: RefCell::new(FnvHashMap()),
|
||||||
}.check(crate_context.tcx.map.krate());
|
}.check(crate_context.tcx.map.krate());
|
||||||
unsafety::check(crate_context.tcx);
|
unsafety::check(crate_context.tcx);
|
||||||
|
|
|
@ -133,7 +133,7 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
|
||||||
impl1_def_id,
|
impl1_def_id,
|
||||||
impl2_def_id);
|
impl2_def_id);
|
||||||
|
|
||||||
let infcx = infer::new_infer_ctxt(self.tcx);
|
let infcx = infer::new_infer_ctxt(self.tcx, None);
|
||||||
if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) {
|
if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id) {
|
||||||
self.report_overlap_error(trait_def_id, impl1_def_id, impl2_def_id);
|
self.report_overlap_error(trait_def_id, impl1_def_id, impl2_def_id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2204,7 +2204,7 @@ fn check_method_self_type<'a, 'tcx, RS:RegionScope>(
|
||||||
base_type,
|
base_type,
|
||||||
base_type_free);
|
base_type_free);
|
||||||
|
|
||||||
let infcx = infer::new_infer_ctxt(tcx);
|
let infcx = infer::new_infer_ctxt(tcx, None);
|
||||||
drop(::require_same_types(tcx,
|
drop(::require_same_types(tcx,
|
||||||
Some(&infcx),
|
Some(&infcx),
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -88,6 +88,7 @@ This API is completely unstable and subject to change.
|
||||||
#![feature(slice_extras)]
|
#![feature(slice_extras)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(vec_push_all)]
|
#![feature(vec_push_all)]
|
||||||
|
#![feature(cell_extras)]
|
||||||
|
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
#[macro_use] extern crate syntax;
|
#[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());
|
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 {
|
let result = match maybe_infcx {
|
||||||
None => {
|
None => {
|
||||||
let infcx = infer::new_infer_ctxt(tcx);
|
let infcx = infer::new_infer_ctxt(tcx, None);
|
||||||
infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2)
|
infer::mk_eqty(&infcx, t1_is_expected, infer::Misc(span), t1, t2)
|
||||||
}
|
}
|
||||||
Some(infcx) => {
|
Some(infcx) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue