Skip to content

Commit 79d0289

Browse files
committed
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.
1 parent 2ba46f8 commit 79d0289

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+427
-252
lines changed

src/librustc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#![feature(str_match_indices)]
6262
#![feature(vec_push_all)]
6363
#![feature(wrapping)]
64+
#![feature(cell_extras)]
6465
#![cfg_attr(test, feature(test))]
6566

6667
#![allow(trivial_casts)]

src/librustc/middle/astencode.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10271027
})
10281028
}
10291029

1030-
if let Some(item_substs) = tcx.item_substs.borrow().get(&id) {
1030+
if let Some(item_substs) = tcx.tables.borrow().item_substs.get(&id) {
10311031
rbml_w.tag(c::tag_table_item_subst, |rbml_w| {
10321032
rbml_w.id(id);
10331033
rbml_w.emit_substs(ecx, &item_substs.substs);
@@ -1051,7 +1051,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10511051
var_id: var_id,
10521052
closure_expr_id: id
10531053
};
1054-
let upvar_capture = tcx.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone();
1054+
let upvar_capture = tcx.tables.borrow().upvar_capture_map.get(&upvar_id).unwrap().clone();
10551055
var_id.encode(rbml_w);
10561056
upvar_capture.encode(rbml_w);
10571057
})
@@ -1074,19 +1074,19 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10741074
}
10751075

10761076
let method_call = MethodCall::expr(id);
1077-
if let Some(method) = tcx.method_map.borrow().get(&method_call) {
1077+
if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) {
10781078
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
10791079
rbml_w.id(id);
10801080
encode_method_callee(ecx, rbml_w, method_call.autoderef, method)
10811081
})
10821082
}
10831083

1084-
if let Some(adjustment) = tcx.adjustments.borrow().get(&id) {
1084+
if let Some(adjustment) = tcx.tables.borrow().adjustments.get(&id) {
10851085
match *adjustment {
10861086
ty::AdjustDerefRef(ref adj) => {
10871087
for autoderef in 0..adj.autoderefs {
10881088
let method_call = MethodCall::autoderef(id, autoderef as u32);
1089-
if let Some(method) = tcx.method_map.borrow().get(&method_call) {
1089+
if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) {
10901090
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
10911091
rbml_w.id(id);
10921092
encode_method_callee(ecx, rbml_w,
@@ -1104,14 +1104,14 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
11041104
})
11051105
}
11061106

1107-
if let Some(closure_type) = tcx.closure_tys.borrow().get(&ast_util::local_def(id)) {
1107+
if let Some(closure_type) = tcx.tables.borrow().closure_tys.get(&ast_util::local_def(id)) {
11081108
rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
11091109
rbml_w.id(id);
11101110
rbml_w.emit_closure_type(ecx, closure_type);
11111111
})
11121112
}
11131113

1114-
if let Some(closure_kind) = tcx.closure_kinds.borrow().get(&ast_util::local_def(id)) {
1114+
if let Some(closure_kind) = tcx.tables.borrow().closure_kinds.get(&ast_util::local_def(id)) {
11151115
rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
11161116
rbml_w.id(id);
11171117
encode_closure_kind(rbml_w, *closure_kind)
@@ -1630,7 +1630,7 @@ fn decode_side_tables(dcx: &DecodeContext,
16301630
let item_substs = ty::ItemSubsts {
16311631
substs: val_dsr.read_substs(dcx)
16321632
};
1633-
dcx.tcx.item_substs.borrow_mut().insert(
1633+
dcx.tcx.tables.borrow_mut().item_substs.insert(
16341634
id, item_substs);
16351635
}
16361636
c::tag_table_freevars => {
@@ -1646,7 +1646,7 @@ fn decode_side_tables(dcx: &DecodeContext,
16461646
closure_expr_id: id
16471647
};
16481648
let ub: ty::UpvarCapture = Decodable::decode(val_dsr).unwrap();
1649-
dcx.tcx.upvar_capture_map.borrow_mut().insert(upvar_id, ub.tr(dcx));
1649+
dcx.tcx.tables.borrow_mut().upvar_capture_map.insert(upvar_id, ub.tr(dcx));
16501650
}
16511651
c::tag_table_tcache => {
16521652
let type_scheme = val_dsr.read_type_scheme(dcx);
@@ -1663,22 +1663,22 @@ fn decode_side_tables(dcx: &DecodeContext,
16631663
expr_id: id,
16641664
autoderef: autoderef
16651665
};
1666-
dcx.tcx.method_map.borrow_mut().insert(method_call, method);
1666+
dcx.tcx.tables.borrow_mut().method_map.insert(method_call, method);
16671667
}
16681668
c::tag_table_adjustments => {
16691669
let adj: ty::AutoAdjustment = val_dsr.read_auto_adjustment(dcx);
1670-
dcx.tcx.adjustments.borrow_mut().insert(id, adj);
1670+
dcx.tcx.tables.borrow_mut().adjustments.insert(id, adj);
16711671
}
16721672
c::tag_table_closure_tys => {
16731673
let closure_ty =
16741674
val_dsr.read_closure_ty(dcx);
1675-
dcx.tcx.closure_tys.borrow_mut().insert(ast_util::local_def(id),
1675+
dcx.tcx.tables.borrow_mut().closure_tys.insert(ast_util::local_def(id),
16761676
closure_ty);
16771677
}
16781678
c::tag_table_closure_kinds => {
16791679
let closure_kind =
16801680
val_dsr.read_closure_kind(dcx);
1681-
dcx.tcx.closure_kinds.borrow_mut().insert(ast_util::local_def(id),
1681+
dcx.tcx.tables.borrow_mut().closure_kinds.insert(ast_util::local_def(id),
16821682
closure_kind);
16831683
}
16841684
c::tag_table_cast_kinds => {

src/librustc/middle/cfg/construct.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
411411
func_or_rcvr: &ast::Expr,
412412
args: I) -> CFGIndex {
413413
let method_call = ty::MethodCall::expr(call_expr.id);
414-
let fn_ty = match self.tcx.method_map.borrow().get(&method_call) {
414+
let fn_ty = match self.tcx.tables.borrow().method_map.get(&method_call) {
415415
Some(method) => method.ty,
416416
None => self.tcx.expr_ty_adjusted(func_or_rcvr)
417417
};
@@ -634,6 +634,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
634634

635635
fn is_method_call(&self, expr: &ast::Expr) -> bool {
636636
let method_call = ty::MethodCall::expr(expr.id);
637-
self.tcx.method_map.borrow().contains_key(&method_call)
637+
self.tcx.tables.borrow().method_map.contains_key(&method_call)
638638
}
639639
}

src/librustc/middle/check_const.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -283,12 +283,11 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
283283

284284
fn check_static_type(&self, e: &ast::Expr) {
285285
let ty = self.tcx.node_id_to_type(e.id);
286-
let infcx = infer::new_infer_ctxt(self.tcx);
286+
let infcx = infer::new_infer_ctxt(self.tcx, None);
287287
let mut fulfill_cx = traits::FulfillmentContext::new(false);
288288
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
289289
fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
290-
let env = self.tcx.empty_parameter_environment();
291-
match fulfill_cx.select_all_or_error(&infcx, &env) {
290+
match fulfill_cx.select_all_or_error(&infcx, &infcx.parameter_environment) {
292291
Ok(()) => { },
293292
Err(ref errors) => {
294293
traits::report_fulfillment_errors(&infcx, errors);
@@ -544,7 +543,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
544543
match e.node {
545544
ast::ExprUnary(..) |
546545
ast::ExprBinary(..) |
547-
ast::ExprIndex(..) if v.tcx.method_map.borrow().contains_key(&method_call) => {
546+
ast::ExprIndex(..) if v.tcx.tables.borrow().method_map.contains_key(&method_call) => {
548547
v.add_qualif(ConstQualif::NOT_CONST);
549548
if v.mode != Mode::Var {
550549
span_err!(v.tcx.sess, e.span, E0011,
@@ -695,7 +694,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
695694
}
696695
}
697696
ast::ExprMethodCall(..) => {
698-
let method_did = match v.tcx.method_map.borrow()[&method_call].origin {
697+
let method_did = match v.tcx.tables.borrow().method_map[&method_call].origin {
699698
ty::MethodStatic(did) => Some(did),
700699
_ => None
701700
};

src/librustc/middle/check_match.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ impl<'a> FromIterator<Vec<&'a Pat>> for Matrix<'a> {
9898
}
9999
}
100100

101+
//NOTE: appears to be the only place other then InferCtxt to contain a ParamEnv
101102
pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
102103
pub tcx: &'a ty::ctxt<'tcx>,
103104
pub param_env: ParameterEnvironment<'a, 'tcx>,

src/librustc/middle/const_eval.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,10 +1031,9 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
10311031
substs: trait_substs });
10321032

10331033
tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
1034-
let infcx = infer::new_infer_ctxt(tcx);
1034+
let infcx = infer::new_infer_ctxt(tcx, None);
10351035

1036-
let param_env = tcx.empty_parameter_environment();
1037-
let mut selcx = traits::SelectionContext::new(&infcx, &param_env);
1036+
let mut selcx = traits::SelectionContext::new(&infcx, &infcx.parameter_environment);
10381037
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
10391038
trait_ref.to_poly_trait_predicate());
10401039
let selection = match selcx.select(&obligation) {

src/librustc/middle/dead.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
9696
fn lookup_and_handle_method(&mut self, id: ast::NodeId,
9797
span: codemap::Span) {
9898
let method_call = ty::MethodCall::expr(id);
99-
match self.tcx.method_map.borrow().get(&method_call) {
99+
match self.tcx.tables.borrow().method_map.get(&method_call) {
100100
Some(method) => {
101101
match method.origin {
102102
ty::MethodStatic(def_id) => {

src/librustc/middle/effect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
140140
match expr.node {
141141
ast::ExprMethodCall(_, _, _) => {
142142
let method_call = MethodCall::expr(expr.id);
143-
let base_type = self.tcx.method_map.borrow().get(&method_call).unwrap().ty;
143+
let base_type = self.tcx.tables.borrow().method_map.get(&method_call).unwrap().ty;
144144
debug!("effect: method call case, base type is {:?}",
145145
base_type);
146146
if type_is_unsafe_function(base_type) {

src/librustc/middle/expr_use_visitor.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,9 @@ impl OverloadedCallType {
257257
fn from_closure(tcx: &ty::ctxt, closure_did: ast::DefId)
258258
-> OverloadedCallType {
259259
let trait_did =
260-
tcx.closure_kinds
260+
tcx.tables
261261
.borrow()
262+
.closure_kinds
262263
.get(&closure_did)
263264
.expect("OverloadedCallType::from_closure: didn't find closure id")
264265
.trait_did(tcx);
@@ -787,8 +788,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
787788
// process.
788789
fn walk_adjustment(&mut self, expr: &ast::Expr) {
789790
let typer = self.typer;
790-
if let Some(adjustment) = typer.adjustments().borrow().get(&expr.id) {
791-
match *adjustment {
791+
//NOTE(@jroesch): mixed RefCell borrow causes crash
792+
let adj = typer.adjustments().get(&expr.id).map(|x| x.clone());
793+
if let Some(adjustment) = adj {
794+
match adjustment {
792795
ty::AdjustReifyFnPointer |
793796
ty::AdjustUnsafeFnPointer => {
794797
// Creating a closure/fn-pointer or unsizing consumes

src/librustc/middle/infer/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
7777

7878
// For region variables.
7979
region_vars: RegionVarBindings<'a, 'tcx>,
80+
81+
pub parameter_environment: ty::ParameterEnvironment<'a, 'tcx>,
82+
83+
// pub tables: &'a RefCell<ty::Tables<'tcx>>
8084
}
8185

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

312-
pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>)
316+
pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
317+
param_env: Option<ty::ParameterEnvironment<'a, 'tcx>>)
313318
-> InferCtxt<'a, 'tcx> {
314319
InferCtxt {
315320
tcx: tcx,
316321
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
317322
int_unification_table: RefCell::new(UnificationTable::new()),
318323
float_unification_table: RefCell::new(UnificationTable::new()),
319324
region_vars: RegionVarBindings::new(tcx),
325+
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment())
320326
}
321327
}
322328

0 commit comments

Comments
 (0)