Skip to content

Commit 8a5c361

Browse files
committed
make the region_constraints field an Option
This way, we can `take()` ownership of it when we are going to resolve regions.
1 parent 43ad4c2 commit 8a5c361

File tree

8 files changed

+54
-40
lines changed

8 files changed

+54
-40
lines changed

src/librustc/infer/equate.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
104104
a,
105105
b);
106106
let origin = Subtype(self.fields.trace.clone());
107-
self.fields.infcx.region_constraints.borrow_mut().make_eqregion(origin, a, b);
107+
self.fields.infcx.borrow_region_constraints()
108+
.make_eqregion(origin, a, b);
108109
Ok(a)
109110
}
110111

src/librustc/infer/fudge.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
7878
self.type_variables.borrow_mut().types_created_since_snapshot(
7979
&snapshot.type_snapshot);
8080
let region_vars =
81-
self.region_constraints.borrow().vars_created_since_snapshot(
81+
self.borrow_region_constraints().vars_created_since_snapshot(
8282
&snapshot.region_constraints_snapshot);
8383

8484
Ok((type_variables, region_vars, value))

src/librustc/infer/glb.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
6767
b);
6868

6969
let origin = Subtype(self.fields.trace.clone());
70-
Ok(self.fields.infcx.region_constraints.borrow_mut().glb_regions(self.tcx(), origin, a, b))
70+
Ok(self.fields.infcx.borrow_region_constraints().glb_regions(self.tcx(), origin, a, b))
7171
}
7272

7373
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)

src/librustc/infer/higher_ranked/mod.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,10 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
176176
.filter(|&r| r != representative)
177177
{
178178
let origin = SubregionOrigin::Subtype(self.trace.clone());
179-
self.infcx.region_constraints.borrow_mut().make_eqregion(origin,
180-
*representative,
181-
*region);
179+
self.infcx.borrow_region_constraints()
180+
.make_eqregion(origin,
181+
*representative,
182+
*region);
182183
}
183184
}
184185

@@ -427,7 +428,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
427428
fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
428429
debruijn: ty::DebruijnIndex)
429430
-> ty::Region<'tcx> {
430-
infcx.region_constraints.borrow_mut().new_bound(infcx.tcx, debruijn)
431+
infcx.borrow_region_constraints().new_bound(infcx.tcx, debruijn)
431432
}
432433
}
433434
}
@@ -481,7 +482,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
481482
r: ty::Region<'tcx>,
482483
directions: TaintDirections)
483484
-> FxHashSet<ty::Region<'tcx>> {
484-
self.region_constraints.borrow().tainted(
485+
self.borrow_region_constraints().tainted(
485486
self.tcx,
486487
&snapshot.region_constraints_snapshot,
487488
r,
@@ -543,7 +544,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
543544
*/
544545

545546
let mut region_vars =
546-
self.region_constraints.borrow().vars_created_since_snapshot(
547+
self.borrow_region_constraints().vars_created_since_snapshot(
547548
&snapshot.region_constraints_snapshot);
548549

549550
let escaping_types =
@@ -586,9 +587,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
586587
where T : TypeFoldable<'tcx>
587588
{
588589
let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| {
589-
self.region_constraints.borrow_mut().push_skolemized(self.tcx,
590-
br,
591-
&snapshot.region_constraints_snapshot)
590+
self.borrow_region_constraints()
591+
.push_skolemized(self.tcx, br, &snapshot.region_constraints_snapshot)
592592
});
593593

594594
debug!("skolemize_bound_regions(binder={:?}, result={:?}, map={:?})",
@@ -773,10 +773,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
773773
{
774774
debug!("pop_skolemized({:?})", skol_map);
775775
let skol_regions: FxHashSet<_> = skol_map.values().cloned().collect();
776-
self.region_constraints.borrow_mut().pop_skolemized(
777-
self.tcx,
778-
&skol_regions,
779-
&snapshot.region_constraints_snapshot);
776+
self.borrow_region_constraints()
777+
.pop_skolemized(self.tcx, &skol_regions, &snapshot.region_constraints_snapshot);
780778
if !skol_map.is_empty() {
781779
self.projection_cache.borrow_mut().rollback_skolemized(
782780
&snapshot.projection_cache_snapshot);

src/librustc/infer/lub.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
6767
b);
6868

6969
let origin = Subtype(self.fields.trace.clone());
70-
Ok(self.fields.infcx.region_constraints.borrow_mut().lub_regions(self.tcx(), origin, a, b))
70+
Ok(self.fields.infcx.borrow_region_constraints().lub_regions(self.tcx(), origin, a, b))
7171
}
7272

7373
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)

src/librustc/infer/mod.rs

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
3131
use ty::relate::RelateResult;
3232
use traits::{self, ObligationCause, PredicateObligations, Reveal};
3333
use rustc_data_structures::unify::{self, UnificationTable};
34-
use std::cell::{Cell, RefCell, Ref};
34+
use std::cell::{Cell, RefCell, Ref, RefMut};
3535
use std::fmt;
3636
use syntax::ast;
3737
use errors::DiagnosticBuilder;
@@ -103,8 +103,12 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
103103
// Map from floating variable to the kind of float it represents
104104
float_unification_table: RefCell<UnificationTable<ty::FloatVid>>,
105105

106-
// For region variables.
107-
region_constraints: RefCell<RegionConstraintCollector<'tcx>>,
106+
// Tracks the set of region variables and the constraints between
107+
// them. This is initially `Some(_)` but when
108+
// `resolve_regions_and_report_errors` is invoked, this gets set
109+
// to `None` -- further attempts to perform unification etc may
110+
// fail if new region constraints would've been added.
111+
region_constraints: RefCell<Option<RegionConstraintCollector<'tcx>>>,
108112

109113
// Once region inference is done, the values for each variable.
110114
lexical_region_resolutions: RefCell<Option<LexicalRegionResolutions<'tcx>>>,
@@ -424,7 +428,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
424428
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
425429
int_unification_table: RefCell::new(UnificationTable::new()),
426430
float_unification_table: RefCell::new(UnificationTable::new()),
427-
region_constraints: RefCell::new(RegionConstraintCollector::new()),
431+
region_constraints: RefCell::new(Some(RegionConstraintCollector::new())),
428432
lexical_region_resolutions: RefCell::new(None),
429433
selection_cache: traits::SelectionCache::new(),
430434
evaluation_cache: traits::EvaluationCache::new(),
@@ -767,7 +771,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
767771
type_snapshot: self.type_variables.borrow_mut().snapshot(),
768772
int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
769773
float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
770-
region_constraints_snapshot: self.region_constraints.borrow_mut().start_snapshot(),
774+
region_constraints_snapshot: self.borrow_region_constraints().start_snapshot(),
771775
was_in_snapshot: in_snapshot,
772776
// Borrow tables "in progress" (i.e. during typeck)
773777
// to ban writes from within a snapshot to them.
@@ -801,8 +805,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
801805
self.float_unification_table
802806
.borrow_mut()
803807
.rollback_to(float_snapshot);
804-
self.region_constraints
805-
.borrow_mut()
808+
self.borrow_region_constraints()
806809
.rollback_to(region_constraints_snapshot);
807810
}
808811

@@ -830,8 +833,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
830833
self.float_unification_table
831834
.borrow_mut()
832835
.commit(float_snapshot);
833-
self.region_constraints
834-
.borrow_mut()
836+
self.borrow_region_constraints()
835837
.commit(region_constraints_snapshot);
836838
}
837839

@@ -887,7 +889,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
887889
sub: ty::Region<'tcx>,
888890
sup: ty::RegionVid)
889891
{
890-
self.region_constraints.borrow_mut().add_given(sub, sup);
892+
self.borrow_region_constraints().add_given(sub, sup);
891893
}
892894

893895
pub fn can_sub<T>(&self,
@@ -927,7 +929,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
927929
a: ty::Region<'tcx>,
928930
b: ty::Region<'tcx>) {
929931
debug!("sub_regions({:?} <: {:?})", a, b);
930-
self.region_constraints.borrow_mut().make_subregion(origin, a, b);
932+
self.borrow_region_constraints().make_subregion(origin, a, b);
931933
}
932934

933935
pub fn equality_predicate(&self,
@@ -1030,7 +1032,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10301032

10311033
pub fn next_region_var(&self, origin: RegionVariableOrigin)
10321034
-> ty::Region<'tcx> {
1033-
self.tcx.mk_region(ty::ReVar(self.region_constraints.borrow_mut().new_region_var(origin)))
1035+
self.tcx.mk_region(ty::ReVar(self.borrow_region_constraints().new_region_var(origin)))
10341036
}
10351037

10361038
/// Create a region inference variable for the given
@@ -1114,6 +1116,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
11141116
self.tainted_by_errors_flag.set(true)
11151117
}
11161118

1119+
/// Process the region constraints and report any errors that
1120+
/// result. After this, no more unification operations should be
1121+
/// done -- or the compiler will panic -- but it is legal to use
1122+
/// `resolve_type_vars_if_possible` as well as `fully_resolve`.
11171123
pub fn resolve_regions_and_report_errors(&self,
11181124
region_context: DefId,
11191125
region_map: &region::ScopeTree,
@@ -1126,8 +1132,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
11261132
region_context,
11271133
region_map,
11281134
free_regions);
1129-
let (lexical_region_resolutions, errors) =
1130-
self.region_constraints.borrow_mut().resolve_regions(&region_rels);
1135+
let mut region_constraints = self.region_constraints.borrow_mut()
1136+
.take()
1137+
.expect("regions already resolved");
1138+
let (lexical_region_resolutions, errors) = region_constraints.resolve_regions(&region_rels);
11311139

11321140
let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
11331141
assert!(old_value.is_none());
@@ -1365,7 +1373,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
13651373
a,
13661374
bound);
13671375

1368-
self.region_constraints.borrow_mut().verify_generic_bound(origin, kind, a, bound);
1376+
self.borrow_region_constraints().verify_generic_bound(origin, kind, a, bound);
13691377
}
13701378

13711379
pub fn type_moves_by_default(&self,
@@ -1446,11 +1454,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
14461454
/// Normalizes associated types in `value`, potentially returning
14471455
/// new obligations that must further be processed.
14481456
pub fn partially_normalize_associated_types_in<T>(&self,
1449-
span: Span,
1450-
body_id: ast::NodeId,
1451-
param_env: ty::ParamEnv<'tcx>,
1452-
value: &T)
1453-
-> InferOk<'tcx, T>
1457+
span: Span,
1458+
body_id: ast::NodeId,
1459+
param_env: ty::ParamEnv<'tcx>,
1460+
value: &T)
1461+
-> InferOk<'tcx, T>
14541462
where T : TypeFoldable<'tcx>
14551463
{
14561464
debug!("partially_normalize_associated_types_in(value={:?})", value);
@@ -1463,6 +1471,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
14631471
obligations);
14641472
InferOk { value, obligations }
14651473
}
1474+
1475+
fn borrow_region_constraints(&self) -> RefMut<'_, RegionConstraintCollector<'tcx>> {
1476+
RefMut::map(
1477+
self.region_constraints.borrow_mut(),
1478+
|c| c.as_mut().expect("region constraints already solved"))
1479+
}
14661480
}
14671481

14681482
impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> {

src/librustc/infer/resolve.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv
7575
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
7676
match *r {
7777
ty::ReVar(rid) =>
78-
self.infcx.region_constraints.borrow_mut()
79-
.opportunistic_resolve_var(self.tcx(), rid),
78+
self.infcx.borrow_region_constraints()
79+
.opportunistic_resolve_var(self.tcx(), rid),
8080
_ =>
8181
r,
8282
}

src/librustc/infer/sub.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
137137
// from the "cause" field, we could perhaps give more tailored
138138
// error messages.
139139
let origin = SubregionOrigin::Subtype(self.fields.trace.clone());
140-
self.fields.infcx.region_constraints.borrow_mut().make_subregion(origin, a, b);
140+
self.fields.infcx.borrow_region_constraints()
141+
.make_subregion(origin, a, b);
141142

142143
Ok(a)
143144
}

0 commit comments

Comments
 (0)