Skip to content

Commit c7ab884

Browse files
committed
Auto merge of #33425 - eddyb:rift, r=nikomatsakis
Split the type context into a global and a local (inference-only) one. After this change, each `InferCtxt` creates its own local type interner for types with inference by-products. Most of the code which handles both a global and a local interner uses `'gcx` and `'tcx` for them. A reference to the type context in that situation (e.g. `infcx.tcx`) is `TyCtxt<'a, 'gcx, 'tcx>`. The global type context which used to be `&'a TyCtxt<'tcx>` is now `TyCtxt<'a, 'tcx, 'tcx>`. In order to minimize the number of extra lifetime parameters, many functions became methods. Where possible (some inherent impls), lifetime parameters were added on the impl, not each method. As inference by-products no longer escape their inference contexts, memory usage is lower. Example of `-Z time-passes` excerpt for `librustc`, stage1 (~100MB gains): Before "rustc: Split local type contexts interners from the global one.": ``` time: 0.395; rss: 335MB item-types checking time: 15.392; rss: 472MB item-bodies checking time: 0.000; rss: 472MB drop-impl checking time: 1.140; rss: 478MB const checking time: 0.139; rss: 478MB privacy checking time: 0.024; rss: 478MB stability index time: 0.072; rss: 478MB intrinsic checking time: 0.038; rss: 478MB effect checking time: 0.255; rss: 478MB match checking time: 0.128; rss: 484MB liveness checking time: 1.372; rss: 484MB rvalue checking time: 1.404; rss: 597MB MIR dump time: 0.809; rss: 599MB MIR passes ``` After: ``` time: 0.467; rss: 337MB item-types checking time: 17.443; rss: 395MB item-bodies checking time: 0.000; rss: 395MB drop-impl checking time: 1.423; rss: 401MB const checking time: 0.141; rss: 401MB privacy checking time: 0.024; rss: 401MB stability index time: 0.116; rss: 401MB intrinsic checking time: 0.038; rss: 401MB effect checking time: 0.382; rss: 401MB match checking time: 0.132; rss: 407MB liveness checking time: 1.678; rss: 407MB rvalue checking time: 1.614; rss: 503MB MIR dump time: 0.957; rss: 512MB MIR passes ``` **NOTE**: Functions changed to methods weren't re-indented to keep this PR easier to review. Once approved, the changes will be mechanically performed. However, indentation changes of function arguments are there - and I believe there's a way to hide whitespace-only changes in diffs on GitHub.
2 parents 80ec1b9 + 42eb703 commit c7ab884

File tree

199 files changed

+15089
-14867
lines changed

Some content is hidden

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

199 files changed

+15089
-14867
lines changed

src/librustc/cfg/construct.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use syntax::ptr::P;
1919
use hir::{self, PatKind};
2020

2121
struct CFGBuilder<'a, 'tcx: 'a> {
22-
tcx: &'a TyCtxt<'tcx>,
22+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
2323
graph: CFGGraph,
2424
fn_exit: CFGIndex,
2525
loop_scopes: Vec<LoopScope>,
@@ -32,8 +32,8 @@ struct LoopScope {
3232
break_index: CFGIndex, // where to go on a `break
3333
}
3434

35-
pub fn construct(tcx: &TyCtxt,
36-
blk: &hir::Block) -> CFG {
35+
pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
36+
blk: &hir::Block) -> CFG {
3737
let mut graph = graph::Graph::new();
3838
let entry = graph.add_node(CFGNodeData::Entry);
3939

src/librustc/cfg/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ pub type CFGNode = graph::Node<CFGNodeData>;
5858
pub type CFGEdge = graph::Edge<CFGEdgeData>;
5959

6060
impl CFG {
61-
pub fn new(tcx: &TyCtxt,
62-
blk: &hir::Block) -> CFG {
61+
pub fn new<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
62+
blk: &hir::Block) -> CFG {
6363
construct::construct(tcx, blk)
6464
}
6565

src/librustc/dep_graph/visit.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ use super::dep_node::DepNode;
2222
/// read edge from the corresponding AST node. This is used in
2323
/// compiler passes to automatically record the item that they are
2424
/// working on.
25-
pub fn visit_all_items_in_krate<'tcx,V,F>(tcx: &TyCtxt<'tcx>,
26-
mut dep_node_fn: F,
27-
visitor: &mut V)
25+
pub fn visit_all_items_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
26+
mut dep_node_fn: F,
27+
visitor: &mut V)
2828
where F: FnMut(DefId) -> DepNode<DefId>, V: Visitor<'tcx>
2929
{
3030
struct TrackingVisitor<'visit, 'tcx: 'visit, F: 'visit, V: 'visit> {
31-
tcx: &'visit TyCtxt<'tcx>,
31+
tcx: TyCtxt<'visit, 'tcx, 'tcx>,
3232
dep_node_fn: &'visit mut F,
3333
visitor: &'visit mut V
3434
}

src/librustc/hir/def.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ use hir;
1717
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1818
pub enum Def {
1919
Fn(DefId),
20-
SelfTy(Option<DefId>, // trait id
21-
Option<(ast::NodeId, ast::NodeId)>), // (impl id, self type id)
20+
SelfTy(Option<DefId> /* trait */, Option<ast::NodeId> /* impl */),
2221
Mod(DefId),
2322
ForeignMod(DefId),
2423
Static(DefId, bool /* is_mutbl */),

src/librustc/hir/pat_util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option<ast::Name> {
209209
}
210210
}
211211

212-
pub fn def_to_path(tcx: &TyCtxt, id: DefId) -> hir::Path {
212+
pub fn def_to_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> hir::Path {
213213
let name = tcx.item_name(id);
214214
hir::Path::from_ident(DUMMY_SP, hir::Ident::from_name(name))
215215
}

src/librustc/infer/bivariate.rs

+14-14
Original file line numberDiff line numberDiff line change
@@ -25,35 +25,35 @@
2525
//! In particular, it might be enough to say (A,B) are bivariant for
2626
//! all (A,B).
2727
28-
use super::combine::{self, CombineFields};
28+
use super::combine::CombineFields;
2929
use super::type_variable::{BiTo};
3030

3131
use ty::{self, Ty, TyCtxt};
3232
use ty::TyVar;
3333
use ty::relate::{Relate, RelateResult, TypeRelation};
3434

35-
pub struct Bivariate<'a, 'tcx: 'a> {
36-
fields: CombineFields<'a, 'tcx>
35+
pub struct Bivariate<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
36+
fields: CombineFields<'a, 'gcx, 'tcx>
3737
}
3838

39-
impl<'a, 'tcx> Bivariate<'a, 'tcx> {
40-
pub fn new(fields: CombineFields<'a, 'tcx>) -> Bivariate<'a, 'tcx> {
39+
impl<'a, 'gcx, 'tcx> Bivariate<'a, 'gcx, 'tcx> {
40+
pub fn new(fields: CombineFields<'a, 'gcx, 'tcx>) -> Bivariate<'a, 'gcx, 'tcx> {
4141
Bivariate { fields: fields }
4242
}
4343
}
4444

45-
impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> {
45+
impl<'a, 'gcx, 'tcx> TypeRelation<'a, 'gcx, 'tcx> for Bivariate<'a, 'gcx, 'tcx> {
4646
fn tag(&self) -> &'static str { "Bivariate" }
4747

48-
fn tcx(&self) -> &'a TyCtxt<'tcx> { self.fields.tcx() }
48+
fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> { self.fields.tcx() }
4949

5050
fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
5151

52-
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
53-
variance: ty::Variance,
54-
a: &T,
55-
b: &T)
56-
-> RelateResult<'tcx, T>
52+
fn relate_with_variance<T: Relate<'tcx>>(&mut self,
53+
variance: ty::Variance,
54+
a: &T,
55+
b: &T)
56+
-> RelateResult<'tcx, T>
5757
{
5858
match variance {
5959
// If we have Foo<A> and Foo is invariant w/r/t A,
@@ -96,7 +96,7 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> {
9696
}
9797

9898
_ => {
99-
combine::super_combine_tys(self.fields.infcx, self, a, b)
99+
self.fields.infcx.super_combine_tys(self, a, b)
100100
}
101101
}
102102
}
@@ -107,7 +107,7 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> {
107107

108108
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
109109
-> RelateResult<'tcx, ty::Binder<T>>
110-
where T: Relate<'a,'tcx>
110+
where T: Relate<'tcx>
111111
{
112112
let a1 = self.tcx().erase_late_bound_regions(a);
113113
let b1 = self.tcx().erase_late_bound_regions(b);

src/librustc/infer/combine.rs

+93-91
Original file line numberDiff line numberDiff line change
@@ -52,131 +52,133 @@ use syntax::ast;
5252
use syntax::codemap::Span;
5353

5454
#[derive(Clone)]
55-
pub struct CombineFields<'a, 'tcx: 'a> {
56-
pub infcx: &'a InferCtxt<'a, 'tcx>,
55+
pub struct CombineFields<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
56+
pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
5757
pub a_is_expected: bool,
5858
pub trace: TypeTrace<'tcx>,
5959
pub cause: Option<ty::relate::Cause>,
6060
pub obligations: PredicateObligations<'tcx>,
6161
}
6262

63-
pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,
64-
relation: &mut R,
65-
a: Ty<'tcx>,
66-
b: Ty<'tcx>)
67-
-> RelateResult<'tcx, Ty<'tcx>>
68-
where R: TypeRelation<'a,'tcx>
69-
{
70-
let a_is_expected = relation.a_is_expected();
71-
72-
match (&a.sty, &b.sty) {
73-
// Relate integral variables to other types
74-
(&ty::TyInfer(ty::IntVar(a_id)), &ty::TyInfer(ty::IntVar(b_id))) => {
75-
infcx.int_unification_table
76-
.borrow_mut()
77-
.unify_var_var(a_id, b_id)
78-
.map_err(|e| int_unification_error(a_is_expected, e))?;
79-
Ok(a)
80-
}
81-
(&ty::TyInfer(ty::IntVar(v_id)), &ty::TyInt(v)) => {
82-
unify_integral_variable(infcx, a_is_expected, v_id, IntType(v))
83-
}
84-
(&ty::TyInt(v), &ty::TyInfer(ty::IntVar(v_id))) => {
85-
unify_integral_variable(infcx, !a_is_expected, v_id, IntType(v))
86-
}
87-
(&ty::TyInfer(ty::IntVar(v_id)), &ty::TyUint(v)) => {
88-
unify_integral_variable(infcx, a_is_expected, v_id, UintType(v))
89-
}
90-
(&ty::TyUint(v), &ty::TyInfer(ty::IntVar(v_id))) => {
91-
unify_integral_variable(infcx, !a_is_expected, v_id, UintType(v))
92-
}
63+
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
64+
pub fn super_combine_tys<R>(&self,
65+
relation: &mut R,
66+
a: Ty<'tcx>,
67+
b: Ty<'tcx>)
68+
-> RelateResult<'tcx, Ty<'tcx>>
69+
where R: TypeRelation<'a, 'gcx, 'tcx>
70+
{
71+
let a_is_expected = relation.a_is_expected();
72+
73+
match (&a.sty, &b.sty) {
74+
// Relate integral variables to other types
75+
(&ty::TyInfer(ty::IntVar(a_id)), &ty::TyInfer(ty::IntVar(b_id))) => {
76+
self.int_unification_table
77+
.borrow_mut()
78+
.unify_var_var(a_id, b_id)
79+
.map_err(|e| int_unification_error(a_is_expected, e))?;
80+
Ok(a)
81+
}
82+
(&ty::TyInfer(ty::IntVar(v_id)), &ty::TyInt(v)) => {
83+
self.unify_integral_variable(a_is_expected, v_id, IntType(v))
84+
}
85+
(&ty::TyInt(v), &ty::TyInfer(ty::IntVar(v_id))) => {
86+
self.unify_integral_variable(!a_is_expected, v_id, IntType(v))
87+
}
88+
(&ty::TyInfer(ty::IntVar(v_id)), &ty::TyUint(v)) => {
89+
self.unify_integral_variable(a_is_expected, v_id, UintType(v))
90+
}
91+
(&ty::TyUint(v), &ty::TyInfer(ty::IntVar(v_id))) => {
92+
self.unify_integral_variable(!a_is_expected, v_id, UintType(v))
93+
}
9394

94-
// Relate floating-point variables to other types
95-
(&ty::TyInfer(ty::FloatVar(a_id)), &ty::TyInfer(ty::FloatVar(b_id))) => {
96-
infcx.float_unification_table
97-
.borrow_mut()
98-
.unify_var_var(a_id, b_id)
99-
.map_err(|e| float_unification_error(relation.a_is_expected(), e))?;
100-
Ok(a)
101-
}
102-
(&ty::TyInfer(ty::FloatVar(v_id)), &ty::TyFloat(v)) => {
103-
unify_float_variable(infcx, a_is_expected, v_id, v)
104-
}
105-
(&ty::TyFloat(v), &ty::TyInfer(ty::FloatVar(v_id))) => {
106-
unify_float_variable(infcx, !a_is_expected, v_id, v)
107-
}
95+
// Relate floating-point variables to other types
96+
(&ty::TyInfer(ty::FloatVar(a_id)), &ty::TyInfer(ty::FloatVar(b_id))) => {
97+
self.float_unification_table
98+
.borrow_mut()
99+
.unify_var_var(a_id, b_id)
100+
.map_err(|e| float_unification_error(relation.a_is_expected(), e))?;
101+
Ok(a)
102+
}
103+
(&ty::TyInfer(ty::FloatVar(v_id)), &ty::TyFloat(v)) => {
104+
self.unify_float_variable(a_is_expected, v_id, v)
105+
}
106+
(&ty::TyFloat(v), &ty::TyInfer(ty::FloatVar(v_id))) => {
107+
self.unify_float_variable(!a_is_expected, v_id, v)
108+
}
108109

109-
// All other cases of inference are errors
110-
(&ty::TyInfer(_), _) |
111-
(_, &ty::TyInfer(_)) => {
112-
Err(TypeError::Sorts(ty::relate::expected_found(relation, &a, &b)))
113-
}
110+
// All other cases of inference are errors
111+
(&ty::TyInfer(_), _) |
112+
(_, &ty::TyInfer(_)) => {
113+
Err(TypeError::Sorts(ty::relate::expected_found(relation, &a, &b)))
114+
}
114115

115116

116-
_ => {
117-
ty::relate::super_relate_tys(relation, a, b)
117+
_ => {
118+
ty::relate::super_relate_tys(relation, a, b)
119+
}
118120
}
119121
}
120-
}
121122

122-
fn unify_integral_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
123-
vid_is_expected: bool,
124-
vid: ty::IntVid,
125-
val: ty::IntVarValue)
126-
-> RelateResult<'tcx, Ty<'tcx>>
127-
{
128-
infcx.int_unification_table
129-
.borrow_mut()
130-
.unify_var_value(vid, val)
131-
.map_err(|e| int_unification_error(vid_is_expected, e))?;
132-
match val {
133-
IntType(v) => Ok(infcx.tcx.mk_mach_int(v)),
134-
UintType(v) => Ok(infcx.tcx.mk_mach_uint(v)),
123+
fn unify_integral_variable(&self,
124+
vid_is_expected: bool,
125+
vid: ty::IntVid,
126+
val: ty::IntVarValue)
127+
-> RelateResult<'tcx, Ty<'tcx>>
128+
{
129+
self.int_unification_table
130+
.borrow_mut()
131+
.unify_var_value(vid, val)
132+
.map_err(|e| int_unification_error(vid_is_expected, e))?;
133+
match val {
134+
IntType(v) => Ok(self.tcx.mk_mach_int(v)),
135+
UintType(v) => Ok(self.tcx.mk_mach_uint(v)),
136+
}
135137
}
136-
}
137138

138-
fn unify_float_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
139-
vid_is_expected: bool,
140-
vid: ty::FloatVid,
141-
val: ast::FloatTy)
142-
-> RelateResult<'tcx, Ty<'tcx>>
143-
{
144-
infcx.float_unification_table
145-
.borrow_mut()
146-
.unify_var_value(vid, val)
147-
.map_err(|e| float_unification_error(vid_is_expected, e))?;
148-
Ok(infcx.tcx.mk_mach_float(val))
139+
fn unify_float_variable(&self,
140+
vid_is_expected: bool,
141+
vid: ty::FloatVid,
142+
val: ast::FloatTy)
143+
-> RelateResult<'tcx, Ty<'tcx>>
144+
{
145+
self.float_unification_table
146+
.borrow_mut()
147+
.unify_var_value(vid, val)
148+
.map_err(|e| float_unification_error(vid_is_expected, e))?;
149+
Ok(self.tcx.mk_mach_float(val))
150+
}
149151
}
150152

151-
impl<'a, 'tcx> CombineFields<'a, 'tcx> {
152-
pub fn tcx(&self) -> &'a TyCtxt<'tcx> {
153+
impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
154+
pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
153155
self.infcx.tcx
154156
}
155157

156-
pub fn switch_expected(&self) -> CombineFields<'a, 'tcx> {
158+
pub fn switch_expected(&self) -> CombineFields<'a, 'gcx, 'tcx> {
157159
CombineFields {
158160
a_is_expected: !self.a_is_expected,
159161
..(*self).clone()
160162
}
161163
}
162164

163-
pub fn equate(&self) -> Equate<'a, 'tcx> {
165+
pub fn equate(&self) -> Equate<'a, 'gcx, 'tcx> {
164166
Equate::new(self.clone())
165167
}
166168

167-
pub fn bivariate(&self) -> Bivariate<'a, 'tcx> {
169+
pub fn bivariate(&self) -> Bivariate<'a, 'gcx, 'tcx> {
168170
Bivariate::new(self.clone())
169171
}
170172

171-
pub fn sub(&self) -> Sub<'a, 'tcx> {
173+
pub fn sub(&self) -> Sub<'a, 'gcx, 'tcx> {
172174
Sub::new(self.clone())
173175
}
174176

175-
pub fn lub(&self) -> Lub<'a, 'tcx> {
177+
pub fn lub(&self) -> Lub<'a, 'gcx, 'tcx> {
176178
Lub::new(self.clone())
177179
}
178180

179-
pub fn glb(&self) -> Glb<'a, 'tcx> {
181+
pub fn glb(&self) -> Glb<'a, 'gcx, 'tcx> {
180182
Glb::new(self.clone())
181183
}
182184

@@ -289,16 +291,16 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
289291
}
290292
}
291293

292-
struct Generalizer<'cx, 'tcx:'cx> {
293-
infcx: &'cx InferCtxt<'cx, 'tcx>,
294+
struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
295+
infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
294296
span: Span,
295297
for_vid: ty::TyVid,
296298
make_region_vars: bool,
297299
cycle_detected: bool,
298300
}
299301

300-
impl<'cx, 'tcx> ty::fold::TypeFolder<'tcx> for Generalizer<'cx, 'tcx> {
301-
fn tcx(&self) -> &TyCtxt<'tcx> {
302+
impl<'cx, 'gcx, 'tcx> ty::fold::TypeFolder<'gcx, 'tcx> for Generalizer<'cx, 'gcx, 'tcx> {
303+
fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx> {
302304
self.infcx.tcx
303305
}
304306

0 commit comments

Comments
 (0)