Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
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.
  • Loading branch information
jroesch committed Jun 27, 2015
commit 79d02895fffa865c6a4ccfaad1fa35d8f732d497
1 change: 1 addition & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#![feature(str_match_indices)]
#![feature(vec_push_all)]
#![feature(wrapping)]
#![feature(cell_extras)]
#![cfg_attr(test, feature(test))]

#![allow(trivial_casts)]
Expand Down
26 changes: 13 additions & 13 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
})
}

if let Some(item_substs) = tcx.item_substs.borrow().get(&id) {
if let Some(item_substs) = tcx.tables.borrow().item_substs.get(&id) {
rbml_w.tag(c::tag_table_item_subst, |rbml_w| {
rbml_w.id(id);
rbml_w.emit_substs(ecx, &item_substs.substs);
Expand All @@ -1051,7 +1051,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
var_id: var_id,
closure_expr_id: id
};
let upvar_capture = tcx.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone();
let upvar_capture = tcx.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone();
var_id.encode(rbml_w);
upvar_capture.encode(rbml_w);
})
Expand All @@ -1074,19 +1074,19 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
}

let method_call = MethodCall::expr(id);
if let Some(method) = tcx.method_map.borrow().get(&method_call) {
if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) {
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
rbml_w.id(id);
encode_method_callee(ecx, rbml_w, method_call.autoderef, method)
})
}

if let Some(adjustment) = tcx.adjustments.borrow().get(&id) {
if let Some(adjustment) = tcx.tables.borrow().adjustments.get(&id) {
match *adjustment {
ty::AdjustDerefRef(ref adj) => {
for autoderef in 0..adj.autoderefs {
let method_call = MethodCall::autoderef(id, autoderef as u32);
if let Some(method) = tcx.method_map.borrow().get(&method_call) {
if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) {
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
rbml_w.id(id);
encode_method_callee(ecx, rbml_w,
Expand All @@ -1104,14 +1104,14 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
})
}

if let Some(closure_type) = tcx.closure_tys.borrow().get(&ast_util::local_def(id)) {
if let Some(closure_type) = tcx.tables.borrow().closure_tys.get(&ast_util::local_def(id)) {
rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
rbml_w.id(id);
rbml_w.emit_closure_type(ecx, closure_type);
})
}

if let Some(closure_kind) = tcx.closure_kinds.borrow().get(&ast_util::local_def(id)) {
if let Some(closure_kind) = tcx.tables.borrow().closure_kinds.get(&ast_util::local_def(id)) {
rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
rbml_w.id(id);
encode_closure_kind(rbml_w, *closure_kind)
Expand Down Expand Up @@ -1630,7 +1630,7 @@ fn decode_side_tables(dcx: &DecodeContext,
let item_substs = ty::ItemSubsts {
substs: val_dsr.read_substs(dcx)
};
dcx.tcx.item_substs.borrow_mut().insert(
dcx.tcx.tables.borrow_mut().item_substs.insert(
id, item_substs);
}
c::tag_table_freevars => {
Expand All @@ -1646,7 +1646,7 @@ fn decode_side_tables(dcx: &DecodeContext,
closure_expr_id: id
};
let ub: ty::UpvarCapture = Decodable::decode(val_dsr).unwrap();
dcx.tcx.upvar_capture_map.borrow_mut().insert(upvar_id, ub.tr(dcx));
dcx.tcx.tables.borrow_mut().upvar_capture_map.insert(upvar_id, ub.tr(dcx));
}
c::tag_table_tcache => {
let type_scheme = val_dsr.read_type_scheme(dcx);
Expand All @@ -1663,22 +1663,22 @@ fn decode_side_tables(dcx: &DecodeContext,
expr_id: id,
autoderef: autoderef
};
dcx.tcx.method_map.borrow_mut().insert(method_call, method);
dcx.tcx.tables.borrow_mut().method_map.insert(method_call, method);
}
c::tag_table_adjustments => {
let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(dcx);
dcx.tcx.adjustments.borrow_mut().insert(id, adj);
dcx.tcx.tables.borrow_mut().adjustments.insert(id, adj);
}
c::tag_table_closure_tys => {
let closure_ty =
val_dsr.read_closure_ty(dcx);
dcx.tcx.closure_tys.borrow_mut().insert(ast_util::local_def(id),
dcx.tcx.tables.borrow_mut().closure_tys.insert(ast_util::local_def(id),
closure_ty);
}
c::tag_table_closure_kinds => {
let closure_kind =
val_dsr.read_closure_kind(dcx);
dcx.tcx.closure_kinds.borrow_mut().insert(ast_util::local_def(id),
dcx.tcx.tables.borrow_mut().closure_kinds.insert(ast_util::local_def(id),
closure_kind);
}
c::tag_table_cast_kinds => {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/cfg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
func_or_rcvr: &ast::Expr,
args: I) -> CFGIndex {
let method_call = ty::MethodCall::expr(call_expr.id);
let fn_ty = match self.tcx.method_map.borrow().get(&method_call) {
let fn_ty = match self.tcx.tables.borrow().method_map.get(&method_call) {
Some(method) => method.ty,
None => self.tcx.expr_ty_adjusted(func_or_rcvr)
};
Expand Down Expand Up @@ -634,6 +634,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {

fn is_method_call(&self, expr: &ast::Expr) -> bool {
let method_call = ty::MethodCall::expr(expr.id);
self.tcx.method_map.borrow().contains_key(&method_call)
self.tcx.tables.borrow().method_map.contains_key(&method_call)
}
}
9 changes: 4 additions & 5 deletions src/librustc/middle/check_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,11 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {

fn check_static_type(&self, e: &ast::Expr) {
let ty = self.tcx.node_id_to_type(e.id);
let infcx = infer::new_infer_ctxt(self.tcx);
let infcx = infer::new_infer_ctxt(self.tcx, None);
let mut fulfill_cx = traits::FulfillmentContext::new(false);
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
let env = self.tcx.empty_parameter_environment();
match fulfill_cx.select_all_or_error(&infcx, &env) {
match fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) {
Ok(()) => { },
Err(ref errors) => {
traits::report_fulfillment_errors(&infcx, errors);
Expand Down Expand Up @@ -544,7 +543,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
match e.node {
ast::ExprUnary(..) |
ast::ExprBinary(..) |
ast::ExprIndex(..) if v.tcx.method_map.borrow().contains_key(&method_call) => {
ast::ExprIndex(..) if v.tcx.tables.borrow().method_map.contains_key(&method_call) => {
v.add_qualif(ConstQualif::NOT_CONST);
if v.mode != Mode::Var {
span_err!(v.tcx.sess, e.span, E0011,
Expand Down Expand Up @@ -695,7 +694,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
}
}
ast::ExprMethodCall(..) => {
let method_did = match v.tcx.method_map.borrow()[&method_call].origin {
let method_did = match v.tcx.tables.borrow().method_map[&method_call].origin {
ty::MethodStatic(did) => Some(did),
_ => None
};
Expand Down
1 change: 1 addition & 0 deletions src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ impl<'a> FromIterator<Vec<&'a Pat>> for Matrix<'a> {
}
}

//NOTE: appears to be the only place other then InferCtxt to contain a ParamEnv
pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
pub tcx: &'a ty::ctxt<'tcx>,
pub param_env: ParameterEnvironment<'a, 'tcx>,
Expand Down
5 changes: 2 additions & 3 deletions src/librustc/middle/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1031,10 +1031,9 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
substs: trait_substs });

tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
let infcx = infer::new_infer_ctxt(tcx);
let infcx = infer::new_infer_ctxt(tcx, None);

let param_env = tcx.empty_parameter_environment();
let mut selcx = traits::SelectionContext::new(&infcx, &param_env);
let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment);
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
trait_ref.to_poly_trait_predicate());
let selection = match selcx.select(&obligation) {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
fn lookup_and_handle_method(&mut self, id: ast::NodeId,
span: codemap::Span) {
let method_call = ty::MethodCall::expr(id);
match self.tcx.method_map.borrow().get(&method_call) {
match self.tcx.tables.borrow().method_map.get(&method_call) {
Some(method) => {
match method.origin {
ty::MethodStatic(def_id) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/effect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
match expr.node {
ast::ExprMethodCall(_, _, _) => {
let method_call = MethodCall::expr(expr.id);
let base_type = self.tcx.method_map.borrow().get(&method_call).unwrap().ty;
let base_type = self.tcx.tables.borrow().method_map.get(&method_call).unwrap().ty;
debug!("effect: method call case, base type is {:?}",
base_type);
if type_is_unsafe_function(base_type) {
Expand Down
9 changes: 6 additions & 3 deletions src/librustc/middle/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,9 @@ impl OverloadedCallType {
fn from_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
-> OverloadedCallType {
let trait_did =
tcx.closure_kinds
tcx.tables
.borrow()
.closure_kinds
.get(&closure_did)
.expect("OverloadedCallType::from_closure: didn't find closure id")
.trait_did(tcx);
Expand Down Expand Up @@ -787,8 +788,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
// process.
fn walk_adjustment(&mut self, expr: &ast::Expr) {
let typer = self.typer;
if let Some(adjustment) = typer.adjustments().borrow().get(&expr.id) {
match *adjustment {
//NOTE(@jroesch): mixed RefCell borrow causes crash
let adj = typer.adjustments().get(&expr.id).map(|x| x.clone());
if let Some(adjustment) = adj {
match adjustment {
ty::AdjustReifyFnPointer |
ty::AdjustUnsafeFnPointer => {
// Creating a closure/fn-pointer or unsizing consumes
Expand Down
8 changes: 7 additions & 1 deletion src/librustc/middle/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ pub struct InferCtxt<'a, 'tcx: 'a> {

// For region variables.
region_vars: RegionVarBindings<'a, 'tcx>,

pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>,

// pub tables: &'a RefCell<ty::Tables<'tcx>>
}

/// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
Expand Down Expand Up @@ -309,14 +313,16 @@ pub fn fixup_err_to_string(f: fixup_err) -> String {
}
}

pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>)
-> InferCtxt<'a, 'tcx> {
InferCtxt {
tcx: tcx,
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
int_unification_table: RefCell::new(UnificationTable::new()),
float_unification_table: RefCell::new(UnificationTable::new()),
region_vars: RegionVarBindings::new(tcx),
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment())
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {

ast::ExprMethodCall(_, _, ref args) => {
let method_call = ty::MethodCall::expr(expr.id);
let method_ty = self.ir.tcx.method_map.borrow().get(&method_call).unwrap().ty;
let method_ty = self.ir.tcx.tables.borrow().method_map.get(&method_call).unwrap().ty;
let succ = if method_ty.fn_ret().diverges() {
self.s.exit_ln
} else {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ use syntax::ast::{MutImmutable, MutMutable};
use syntax::ast;
use syntax::codemap::Span;

use std::cell::RefCell;
use std::cell::Ref;
use std::fmt;
use std::rc::Rc;

Expand Down Expand Up @@ -289,7 +289,7 @@ pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> {
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>>;
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>;
fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>;
fn adjustments(&self) -> Ref<NodeMap<ty::AutoAdjustment<'tcx>>>;
fn is_method_call(&self, id: ast::NodeId) -> bool;
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
fn upvar_capture(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarCapture>;
Expand Down Expand Up @@ -408,7 +408,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
let unadjusted_ty = try!(self.expr_ty(expr));
Ok(unadjusted_ty.adjust(
self.tcx(), expr.span, expr.id,
self.typer.adjustments().borrow().get(&expr.id),
self.typer.adjustments().get(&expr.id),
|method_call| self.typer.node_method_ty(method_call)))
}

Expand Down Expand Up @@ -440,7 +440,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
}

pub fn cat_expr(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
match self.typer.adjustments().borrow().get(&expr.id) {
match self.typer.adjustments().get(&expr.id) {
None => {
// No adjustments.
self.cat_expr_unadjusted(expr)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
}
ast::ExprMethodCall(..) => {
let method_call = ty::MethodCall::expr(expr.id);
match (*self.tcx.method_map.borrow()).get(&method_call).unwrap().origin {
match self.tcx.tables.borrow().method_map.get(&method_call).unwrap().origin {
ty::MethodStatic(def_id) => {
if is_local(def_id) {
if self.def_id_represents_local_inlined_item(def_id) {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
ast::ExprMethodCall(i, _, _) => {
span = i.span;
let method_call = ty::MethodCall::expr(e.id);
match tcx.method_map.borrow().get(&method_call) {
match tcx.tables.borrow().method_map.get(&method_call) {
Some(method) => {
match method.origin {
ty::MethodStatic(def_id) => {
Expand Down
13 changes: 7 additions & 6 deletions src/librustc/middle/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
}
}

// TODO: this is gonna need to be removed ...
/// Normalizes the parameter environment, reporting errors if they occur.
pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvironment<'a,'tcx>,
cause: ObligationCause<'tcx>)
Expand Down Expand Up @@ -396,13 +397,13 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi

let elaborated_env = unnormalized_env.with_caller_bounds(predicates);

let infcx = infer::new_infer_ctxt(tcx);
let predicates = match fully_normalize(&infcx, &elaborated_env, cause,
&elaborated_env.caller_bounds) {
let infcx = infer::new_infer_ctxt(tcx, Some(elaborated_env));
let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause,
&infcx.parameter_environment.caller_bounds) {
Ok(predicates) => predicates,
Err(errors) => {
report_fulfillment_errors(&infcx, &errors);
return unnormalized_env; // an unnormalized env is better than nothing
return infcx.parameter_environment; // an unnormalized env is better than nothing
}
};

Expand All @@ -420,11 +421,11 @@ pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvi
// all things considered.
let err_msg = fixup_err_to_string(fixup_err);
tcx.sess.span_err(span, &err_msg);
return elaborated_env; // an unnormalized env is better than nothing
return infcx.parameter_environment; // an unnormalized env is better than nothing
}
};

elaborated_env.with_caller_bounds(predicates)
infcx.parameter_environment.with_caller_bounds(predicates)
}

pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
Expand Down
Loading