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

+1
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

+13-13
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

+2-2
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

+4-5
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

+1
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

+2-3
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

+1-1
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

+1-1
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

+6-3
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

+7-1
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

src/librustc/middle/liveness.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
11501150

11511151
ast::ExprMethodCall(_, _, ref args) => {
11521152
let method_call = ty::MethodCall::expr(expr.id);
1153-
let method_ty = self.ir.tcx.method_map.borrow().get(&method_call).unwrap().ty;
1153+
let method_ty = self.ir.tcx.tables.borrow().method_map.get(&method_call).unwrap().ty;
11541154
let succ = if method_ty.fn_ret().diverges() {
11551155
self.s.exit_ln
11561156
} else {

src/librustc/middle/mem_categorization.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ use syntax::ast::{MutImmutable, MutMutable};
8383
use syntax::ast;
8484
use syntax::codemap::Span;
8585

86-
use std::cell::RefCell;
86+
use std::cell::Ref;
8787
use std::fmt;
8888
use std::rc::Rc;
8989

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

@@ -440,7 +440,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
440440
}
441441

442442
pub fn cat_expr(&self, expr: &ast::Expr) -> McResult<cmt<'tcx>> {
443-
match self.typer.adjustments().borrow().get(&expr.id) {
443+
match self.typer.adjustments().get(&expr.id) {
444444
None => {
445445
// No adjustments.
446446
self.cat_expr_unadjusted(expr)

src/librustc/middle/reachable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
128128
}
129129
ast::ExprMethodCall(..) => {
130130
let method_call = ty::MethodCall::expr(expr.id);
131-
match (*self.tcx.method_map.borrow()).get(&method_call).unwrap().origin {
131+
match self.tcx.tables.borrow().method_map.get(&method_call).unwrap().origin {
132132
ty::MethodStatic(def_id) => {
133133
if is_local(def_id) {
134134
if self.def_id_represents_local_inlined_item(def_id) {

src/librustc/middle/stability.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
406406
ast::ExprMethodCall(i, _, _) => {
407407
span = i.span;
408408
let method_call = ty::MethodCall::expr(e.id);
409-
match tcx.method_map.borrow().get(&method_call) {
409+
match tcx.tables.borrow().method_map.get(&method_call) {
410410
Some(method) => {
411411
match method.origin {
412412
ty::MethodStatic(def_id) => {

src/librustc/middle/traits/mod.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
351351
}
352352
}
353353

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

397398
let elaborated_env = unnormalized_env.with_caller_bounds(predicates);
398399

399-
let infcx = infer::new_infer_ctxt(tcx);
400-
let predicates = match fully_normalize(&infcx, &elaborated_env, cause,
401-
&elaborated_env.caller_bounds) {
400+
let infcx = infer::new_infer_ctxt(tcx, Some(elaborated_env));
401+
let predicates = match fully_normalize(&infcx, &infcx.parameter_environment, cause,
402+
&infcx.parameter_environment.caller_bounds) {
402403
Ok(predicates) => predicates,
403404
Err(errors) => {
404405
report_fulfillment_errors(&infcx, &errors);
405-
return unnormalized_env; // an unnormalized env is better than nothing
406+
return infcx.parameter_environment; // an unnormalized env is better than nothing
406407
}
407408
};
408409

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

427-
elaborated_env.with_caller_bounds(predicates)
428+
infcx.parameter_environment.with_caller_bounds(predicates)
428429
}
429430

430431
pub fn fully_normalize<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,

0 commit comments

Comments
 (0)