Skip to content

Commit cf1039f

Browse files
committed
Reduce the number of RefCells in InferCtxt.
`InferCtxt` contains six structures within `RefCell`s. Every time we create and dispose of (commit or rollback) a snapshot we have to `borrow_mut` each one of them. This commit moves the six structures under a single `RefCell`, which gives significant speed-ups by reducing the number of `borrow_mut` calls. To avoid runtime errors I had to reduce the lifetimes of dynamic borrows in a couple of places.
1 parent eed12bc commit cf1039f

File tree

20 files changed

+319
-242
lines changed

20 files changed

+319
-242
lines changed

src/librustc/infer/canonical/canonicalizer.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,9 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
306306
let r = self
307307
.infcx
308308
.unwrap()
309-
.borrow_region_constraints()
309+
.inner
310+
.borrow_mut()
311+
.unwrap_region_constraints()
310312
.opportunistic_resolve_var(self.tcx, vid);
311313
debug!(
312314
"canonical: region var found with vid {:?}, \
@@ -610,7 +612,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
610612

611613
/// Returns the universe in which `vid` is defined.
612614
fn region_var_universe(&self, vid: ty::RegionVid) -> ty::UniverseIndex {
613-
self.infcx.unwrap().borrow_region_constraints().var_universe(vid)
615+
self.infcx.unwrap().inner.borrow_mut().unwrap_region_constraints().var_universe(vid)
614616
}
615617

616618
/// Creates a canonical variable (with the given `info`)

src/librustc/infer/combine.rs

+30-20
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
7474
match (&a.kind, &b.kind) {
7575
// Relate integral variables to other types
7676
(&ty::Infer(ty::IntVar(a_id)), &ty::Infer(ty::IntVar(b_id))) => {
77-
self.int_unification_table
77+
self.inner
7878
.borrow_mut()
79+
.int_unification_table
7980
.unify_var_var(a_id, b_id)
8081
.map_err(|e| int_unification_error(a_is_expected, e))?;
8182
Ok(a)
@@ -95,8 +96,9 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
9596

9697
// Relate floating-point variables to other types
9798
(&ty::Infer(ty::FloatVar(a_id)), &ty::Infer(ty::FloatVar(b_id))) => {
98-
self.float_unification_table
99+
self.inner
99100
.borrow_mut()
101+
.float_unification_table
100102
.unify_var_var(a_id, b_id)
101103
.map_err(|e| float_unification_error(relation.a_is_expected(), e))?;
102104
Ok(a)
@@ -131,8 +133,8 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
131133
return Ok(a);
132134
}
133135

134-
let a = replace_if_possible(self.const_unification_table.borrow_mut(), a);
135-
let b = replace_if_possible(self.const_unification_table.borrow_mut(), b);
136+
let a = replace_if_possible(&mut self.inner.borrow_mut().const_unification_table, a);
137+
let b = replace_if_possible(&mut self.inner.borrow_mut().const_unification_table, b);
136138

137139
let a_is_expected = relation.a_is_expected();
138140

@@ -141,8 +143,9 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
141143
ty::ConstKind::Infer(InferConst::Var(a_vid)),
142144
ty::ConstKind::Infer(InferConst::Var(b_vid)),
143145
) => {
144-
self.const_unification_table
146+
self.inner
145147
.borrow_mut()
148+
.const_unification_table
146149
.unify_var_var(a_vid, b_vid)
147150
.map_err(|e| const_unification_error(a_is_expected, e))?;
148151
return Ok(a);
@@ -174,8 +177,9 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
174177
vid: ty::ConstVid<'tcx>,
175178
value: &'tcx ty::Const<'tcx>,
176179
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
177-
self.const_unification_table
180+
self.inner
178181
.borrow_mut()
182+
.const_unification_table
179183
.unify_var_value(
180184
vid,
181185
ConstVarValue {
@@ -196,8 +200,9 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
196200
vid: ty::IntVid,
197201
val: ty::IntVarValue,
198202
) -> RelateResult<'tcx, Ty<'tcx>> {
199-
self.int_unification_table
203+
self.inner
200204
.borrow_mut()
205+
.int_unification_table
201206
.unify_var_value(vid, Some(val))
202207
.map_err(|e| int_unification_error(vid_is_expected, e))?;
203208
match val {
@@ -212,8 +217,9 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
212217
vid: ty::FloatVid,
213218
val: ast::FloatTy,
214219
) -> RelateResult<'tcx, Ty<'tcx>> {
215-
self.float_unification_table
220+
self.inner
216221
.borrow_mut()
222+
.float_unification_table
217223
.unify_var_value(vid, Some(ty::FloatVarValue(val)))
218224
.map_err(|e| float_unification_error(vid_is_expected, e))?;
219225
Ok(self.tcx.mk_mach_float(val))
@@ -260,7 +266,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
260266
use self::RelationDir::*;
261267

262268
// Get the actual variable that b_vid has been inferred to
263-
debug_assert!(self.infcx.type_variables.borrow_mut().probe(b_vid).is_unknown());
269+
debug_assert!(self.infcx.inner.borrow_mut().type_variables.probe(b_vid).is_unknown());
264270

265271
debug!("instantiate(a_ty={:?} dir={:?} b_vid={:?})", a_ty, dir, b_vid);
266272

@@ -280,7 +286,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
280286
"instantiate(a_ty={:?}, dir={:?}, b_vid={:?}, generalized b_ty={:?})",
281287
a_ty, dir, b_vid, b_ty
282288
);
283-
self.infcx.type_variables.borrow_mut().instantiate(b_vid, b_ty);
289+
self.infcx.inner.borrow_mut().type_variables.instantiate(b_vid, b_ty);
284290

285291
if needs_wf {
286292
self.obligations.push(Obligation::new(
@@ -338,7 +344,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
338344

339345
debug!("generalize: ambient_variance = {:?}", ambient_variance);
340346

341-
let for_universe = match self.infcx.type_variables.borrow_mut().probe(for_vid) {
347+
let for_universe = match self.infcx.inner.borrow_mut().type_variables.probe(for_vid) {
342348
v @ TypeVariableValue::Known { .. } => {
343349
panic!("instantiating {:?} which has a known value {:?}", for_vid, v,)
344350
}
@@ -350,7 +356,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
350356
let mut generalize = Generalizer {
351357
infcx: self.infcx,
352358
span: self.trace.cause.span,
353-
for_vid_sub_root: self.infcx.type_variables.borrow_mut().sub_root_var(for_vid),
359+
for_vid_sub_root: self.infcx.inner.borrow_mut().type_variables.sub_root_var(for_vid),
354360
for_universe,
355361
ambient_variance,
356362
needs_wf: false,
@@ -502,17 +508,16 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
502508
// us from creating infinitely sized types.
503509
match t.kind {
504510
ty::Infer(ty::TyVar(vid)) => {
505-
let mut variables = self.infcx.type_variables.borrow_mut();
506-
let vid = variables.root_var(vid);
507-
let sub_vid = variables.sub_root_var(vid);
511+
let vid = self.infcx.inner.borrow_mut().type_variables.root_var(vid);
512+
let sub_vid = self.infcx.inner.borrow_mut().type_variables.sub_root_var(vid);
508513
if sub_vid == self.for_vid_sub_root {
509514
// If sub-roots are equal, then `for_vid` and
510515
// `vid` are related via subtyping.
511516
Err(TypeError::CyclicTy(self.root_ty))
512517
} else {
513-
match variables.probe(vid) {
518+
let probe = self.infcx.inner.borrow_mut().type_variables.probe(vid);
519+
match probe {
514520
TypeVariableValue::Known { value: u } => {
515-
drop(variables);
516521
debug!("generalize: known value {:?}", u);
517522
self.relate(&u, &u)
518523
}
@@ -536,8 +541,13 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
536541
ty::Covariant | ty::Contravariant => (),
537542
}
538543

539-
let origin = *variables.var_origin(vid);
540-
let new_var_id = variables.new_var(self.for_universe, false, origin);
544+
let origin =
545+
*self.infcx.inner.borrow_mut().type_variables.var_origin(vid);
546+
let new_var_id = self.infcx.inner.borrow_mut().type_variables.new_var(
547+
self.for_universe,
548+
false,
549+
origin,
550+
);
541551
let u = self.tcx().mk_ty_var(new_var_id);
542552
debug!("generalize: replacing original vid={:?} with new={:?}", vid, u);
543553
Ok(u)
@@ -612,7 +622,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
612622

613623
match c.val {
614624
ty::ConstKind::Infer(InferConst::Var(vid)) => {
615-
let mut variable_table = self.infcx.const_unification_table.borrow_mut();
625+
let variable_table = &mut self.infcx.inner.borrow_mut().const_unification_table;
616626
let var_value = variable_table.probe_value(vid);
617627
match var_value.val {
618628
ConstVariableValue::Known { value: u } => self.relate(&u, &u),

src/librustc/infer/equate.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
7272
}
7373

7474
let infcx = self.fields.infcx;
75-
let a = infcx.type_variables.borrow_mut().replace_if_possible(a);
76-
let b = infcx.type_variables.borrow_mut().replace_if_possible(b);
75+
let a = infcx.inner.borrow_mut().type_variables.replace_if_possible(a);
76+
let b = infcx.inner.borrow_mut().type_variables.replace_if_possible(b);
7777

7878
debug!("{}.tys: replacements ({:?}, {:?})", self.tag(), a, b);
7979

8080
match (&a.kind, &b.kind) {
8181
(&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => {
82-
infcx.type_variables.borrow_mut().equate(a_id, b_id);
82+
infcx.inner.borrow_mut().type_variables.equate(a_id, b_id);
8383
}
8484

8585
(&ty::Infer(TyVar(a_id)), _) => {
@@ -105,7 +105,12 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
105105
) -> RelateResult<'tcx, ty::Region<'tcx>> {
106106
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
107107
let origin = Subtype(box self.fields.trace.clone());
108-
self.fields.infcx.borrow_region_constraints().make_eqregion(origin, a, b);
108+
self.fields
109+
.infcx
110+
.inner
111+
.borrow_mut()
112+
.unwrap_region_constraints()
113+
.make_eqregion(origin, a, b);
109114
Ok(a)
110115
}
111116

src/librustc/infer/error_reporting/need_type_info.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,12 @@ impl<'a, 'tcx> FindLocalByTypeVisitor<'a, 'tcx> {
4747
if ty.walk().any(|inner_ty| {
4848
inner_ty == self.target_ty
4949
|| match (&inner_ty.kind, &self.target_ty.kind) {
50-
(&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => {
51-
self.infcx.type_variables.borrow_mut().sub_unified(a_vid, b_vid)
52-
}
50+
(&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => self
51+
.infcx
52+
.inner
53+
.borrow_mut()
54+
.type_variables
55+
.sub_unified(a_vid, b_vid),
5356
_ => false,
5457
}
5558
}) {
@@ -166,7 +169,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
166169
highlight: Option<ty::print::RegionHighlightMode>,
167170
) -> (String, Option<Span>, Cow<'static, str>, Option<String>, Option<&'static str>) {
168171
if let ty::Infer(ty::TyVar(ty_vid)) = ty.kind {
169-
let ty_vars = self.type_variables.borrow();
172+
let ty_vars = &self.inner.borrow().type_variables;
170173
let var_origin = ty_vars.var_origin(ty_vid);
171174
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind {
172175
let parent_def_id = def_id.and_then(|def_id| self.tcx.parent(def_id));
@@ -224,7 +227,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
224227
let ty_to_string = |ty: Ty<'tcx>| -> String {
225228
let mut s = String::new();
226229
let mut printer = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS);
227-
let ty_vars = self.type_variables.borrow();
230+
let ty_vars = &self.inner.borrow().type_variables;
228231
let getter = move |ty_vid| {
229232
let var_origin = ty_vars.var_origin(ty_vid);
230233
if let TypeVariableOriginKind::TypeParameterDefinition(name, _) = var_origin.kind {

src/librustc/infer/freshen.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,15 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
154154

155155
match t.kind {
156156
ty::Infer(ty::TyVar(v)) => {
157-
let opt_ty = self.infcx.type_variables.borrow_mut().probe(v).known();
157+
let opt_ty = self.infcx.inner.borrow_mut().type_variables.probe(v).known();
158158
self.freshen_ty(opt_ty, ty::TyVar(v), ty::FreshTy)
159159
}
160160

161161
ty::Infer(ty::IntVar(v)) => self.freshen_ty(
162162
self.infcx
163-
.int_unification_table
163+
.inner
164164
.borrow_mut()
165+
.int_unification_table
165166
.probe_value(v)
166167
.map(|v| v.to_type(tcx)),
167168
ty::IntVar(v),
@@ -170,8 +171,9 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
170171

171172
ty::Infer(ty::FloatVar(v)) => self.freshen_ty(
172173
self.infcx
173-
.float_unification_table
174+
.inner
174175
.borrow_mut()
176+
.float_unification_table
175177
.probe_value(v)
176178
.map(|v| v.to_type(tcx)),
177179
ty::FloatVar(v),
@@ -225,8 +227,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
225227
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
226228
match ct.val {
227229
ty::ConstKind::Infer(ty::InferConst::Var(v)) => {
228-
let opt_ct =
229-
self.infcx.const_unification_table.borrow_mut().probe_value(v).val.known();
230+
let opt_ct = self
231+
.infcx
232+
.inner
233+
.borrow_mut()
234+
.const_unification_table
235+
.probe_value(v)
236+
.val
237+
.known();
230238
return self.freshen_const(
231239
opt_ct,
232240
ty::InferConst::Var(v),

src/librustc/infer/fudge.rs

+14-18
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ use super::{ConstVariableOrigin, RegionVariableOrigin};
88
use rustc_data_structures::unify as ut;
99
use ut::UnifyKey;
1010

11-
use std::cell::RefMut;
1211
use std::ops::Range;
1312

1413
fn const_vars_since_snapshot<'tcx>(
15-
mut table: RefMut<'_, ut::UnificationTable<ut::InPlace<ConstVid<'tcx>>>>,
14+
table: &mut ut::UnificationTable<ut::InPlace<ConstVid<'tcx>>>,
1615
snapshot: &ut::Snapshot<ut::InPlace<ConstVid<'tcx>>>,
1716
) -> (Range<ConstVid<'tcx>>, Vec<ConstVariableOrigin>) {
1817
let range = table.vars_since_snapshot(snapshot);
@@ -82,23 +81,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
8281
// going to be popped, so we will have to
8382
// eliminate any references to them.
8483

85-
let type_vars = self
86-
.type_variables
87-
.borrow_mut()
88-
.vars_since_snapshot(&snapshot.type_snapshot);
89-
let int_vars = self
90-
.int_unification_table
91-
.borrow_mut()
92-
.vars_since_snapshot(&snapshot.int_snapshot);
93-
let float_vars = self
94-
.float_unification_table
95-
.borrow_mut()
96-
.vars_since_snapshot(&snapshot.float_snapshot);
97-
let region_vars = self
98-
.borrow_region_constraints()
84+
let mut inner = self.inner.borrow_mut();
85+
let type_vars =
86+
inner.type_variables.vars_since_snapshot(&snapshot.type_snapshot);
87+
let int_vars =
88+
inner.int_unification_table.vars_since_snapshot(&snapshot.int_snapshot);
89+
let float_vars =
90+
inner.float_unification_table.vars_since_snapshot(&snapshot.float_snapshot);
91+
let region_vars = inner
92+
.unwrap_region_constraints()
9993
.vars_since_snapshot(&snapshot.region_constraints_snapshot);
10094
let const_vars = const_vars_since_snapshot(
101-
self.const_unification_table.borrow_mut(),
95+
&mut inner.const_unification_table,
10296
&snapshot.const_snapshot,
10397
);
10498

@@ -166,7 +160,9 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
166160
// variables to their binding anyhow, we know
167161
// that it is unbound, so we can just return
168162
// it.
169-
debug_assert!(self.infcx.type_variables.borrow_mut().probe(vid).is_unknown());
163+
debug_assert!(
164+
self.infcx.inner.borrow_mut().type_variables.probe(vid).is_unknown()
165+
);
170166
ty
171167
}
172168
}

src/librustc/infer/glb.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
6666
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
6767

6868
let origin = Subtype(box self.fields.trace.clone());
69-
Ok(self.fields.infcx.borrow_region_constraints().glb_regions(self.tcx(), origin, a, b))
69+
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions(
70+
self.tcx(),
71+
origin,
72+
a,
73+
b,
74+
))
7075
}
7176

7277
fn consts(

src/librustc/infer/higher_ranked/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
128128
placeholder_map: &PlaceholderMap<'tcx>,
129129
snapshot: &CombinedSnapshot<'_, 'tcx>,
130130
) -> RelateResult<'tcx, ()> {
131-
self.borrow_region_constraints().leak_check(
131+
self.inner.borrow_mut().unwrap_region_constraints().leak_check(
132132
self.tcx,
133133
overly_polymorphic,
134134
placeholder_map,

src/librustc/infer/lattice.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ where
5656
}
5757

5858
let infcx = this.infcx();
59-
let a = infcx.type_variables.borrow_mut().replace_if_possible(a);
60-
let b = infcx.type_variables.borrow_mut().replace_if_possible(b);
59+
let a = infcx.inner.borrow_mut().type_variables.replace_if_possible(a);
60+
let b = infcx.inner.borrow_mut().type_variables.replace_if_possible(b);
6161
match (&a.kind, &b.kind) {
6262
// If one side is known to be a variable and one is not,
6363
// create a variable (`v`) to represent the LUB. Make sure to

src/librustc/infer/lub.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
6666
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
6767

6868
let origin = Subtype(box self.fields.trace.clone());
69-
Ok(self.fields.infcx.borrow_region_constraints().lub_regions(self.tcx(), origin, a, b))
69+
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions(
70+
self.tcx(),
71+
origin,
72+
a,
73+
b,
74+
))
7075
}
7176

7277
fn consts(

0 commit comments

Comments
 (0)