diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2017-11-05 07:22:39 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2017-11-16 05:57:43 -0500 |
| commit | adf1519941deb21bd12b5923a45fdd0c21f79140 (patch) | |
| tree | f64e7d5ceb5a6c377537429757e3bb597eb9683f | |
| parent | 326ec52eacf34a0a446ca1775e514cf7e6016de4 (diff) | |
| download | rust-adf1519941deb21bd12b5923a45fdd0c21f79140.tar.gz rust-adf1519941deb21bd12b5923a45fdd0c21f79140.zip | |
make the `region_constraints` field an `Option`
This way, we can `take()` ownership of it when we are going to resolve regions.
| -rw-r--r-- | src/librustc/infer/equate.rs | 3 | ||||
| -rw-r--r-- | src/librustc/infer/fudge.rs | 2 | ||||
| -rw-r--r-- | src/librustc/infer/glb.rs | 2 | ||||
| -rw-r--r-- | src/librustc/infer/higher_ranked/mod.rs | 24 | ||||
| -rw-r--r-- | src/librustc/infer/lub.rs | 2 | ||||
| -rw-r--r-- | src/librustc/infer/mod.rs | 54 | ||||
| -rw-r--r-- | src/librustc/infer/resolve.rs | 4 | ||||
| -rw-r--r-- | src/librustc/infer/sub.rs | 3 |
8 files changed, 54 insertions, 40 deletions
diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs index 0c59fa703bb..2ae8f8ae933 100644 --- a/src/librustc/infer/equate.rs +++ b/src/librustc/infer/equate.rs @@ -104,7 +104,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> a, b); let origin = Subtype(self.fields.trace.clone()); - self.fields.infcx.region_constraints.borrow_mut().make_eqregion(origin, a, b); + self.fields.infcx.borrow_region_constraints() + .make_eqregion(origin, a, b); Ok(a) } diff --git a/src/librustc/infer/fudge.rs b/src/librustc/infer/fudge.rs index 729e67437ba..756a6947ee3 100644 --- a/src/librustc/infer/fudge.rs +++ b/src/librustc/infer/fudge.rs @@ -78,7 +78,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.type_variables.borrow_mut().types_created_since_snapshot( &snapshot.type_snapshot); let region_vars = - self.region_constraints.borrow().vars_created_since_snapshot( + self.borrow_region_constraints().vars_created_since_snapshot( &snapshot.region_constraints_snapshot); Ok((type_variables, region_vars, value)) diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs index d63036eecff..8b42314ed97 100644 --- a/src/librustc/infer/glb.rs +++ b/src/librustc/infer/glb.rs @@ -67,7 +67,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> b); let origin = Subtype(self.fields.trace.clone()); - Ok(self.fields.infcx.region_constraints.borrow_mut().glb_regions(self.tcx(), origin, a, b)) + Ok(self.fields.infcx.borrow_region_constraints().glb_regions(self.tcx(), origin, a, b)) } fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>) diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs index 2aef9fece87..c49b3b4b9c8 100644 --- a/src/librustc/infer/higher_ranked/mod.rs +++ b/src/librustc/infer/higher_ranked/mod.rs @@ -176,9 +176,10 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { .filter(|&r| r != representative) { let origin = SubregionOrigin::Subtype(self.trace.clone()); - self.infcx.region_constraints.borrow_mut().make_eqregion(origin, - *representative, - *region); + self.infcx.borrow_region_constraints() + .make_eqregion(origin, + *representative, + *region); } } @@ -427,7 +428,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> { fn fresh_bound_variable<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>, debruijn: ty::DebruijnIndex) -> ty::Region<'tcx> { - infcx.region_constraints.borrow_mut().new_bound(infcx.tcx, debruijn) + infcx.borrow_region_constraints().new_bound(infcx.tcx, debruijn) } } } @@ -481,7 +482,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { r: ty::Region<'tcx>, directions: TaintDirections) -> FxHashSet<ty::Region<'tcx>> { - self.region_constraints.borrow().tainted( + self.borrow_region_constraints().tainted( self.tcx, &snapshot.region_constraints_snapshot, r, @@ -543,7 +544,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { */ let mut region_vars = - self.region_constraints.borrow().vars_created_since_snapshot( + self.borrow_region_constraints().vars_created_since_snapshot( &snapshot.region_constraints_snapshot); let escaping_types = @@ -586,9 +587,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { where T : TypeFoldable<'tcx> { let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| { - self.region_constraints.borrow_mut().push_skolemized(self.tcx, - br, - &snapshot.region_constraints_snapshot) + self.borrow_region_constraints() + .push_skolemized(self.tcx, br, &snapshot.region_constraints_snapshot) }); debug!("skolemize_bound_regions(binder={:?}, result={:?}, map={:?})", @@ -773,10 +773,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { { debug!("pop_skolemized({:?})", skol_map); let skol_regions: FxHashSet<_> = skol_map.values().cloned().collect(); - self.region_constraints.borrow_mut().pop_skolemized( - self.tcx, - &skol_regions, - &snapshot.region_constraints_snapshot); + self.borrow_region_constraints() + .pop_skolemized(self.tcx, &skol_regions, &snapshot.region_constraints_snapshot); if !skol_map.is_empty() { self.projection_cache.borrow_mut().rollback_skolemized( &snapshot.projection_cache_snapshot); diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs index 0c4f4efe994..4a2a7a6bdfe 100644 --- a/src/librustc/infer/lub.rs +++ b/src/librustc/infer/lub.rs @@ -67,7 +67,7 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> b); let origin = Subtype(self.fields.trace.clone()); - Ok(self.fields.infcx.region_constraints.borrow_mut().lub_regions(self.tcx(), origin, a, b)) + Ok(self.fields.infcx.borrow_region_constraints().lub_regions(self.tcx(), origin, a, b)) } fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index d42419d7dc6..a5cae839aa7 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -31,7 +31,7 @@ use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use ty::relate::RelateResult; use traits::{self, ObligationCause, PredicateObligations, Reveal}; use rustc_data_structures::unify::{self, UnificationTable}; -use std::cell::{Cell, RefCell, Ref}; +use std::cell::{Cell, RefCell, Ref, RefMut}; use std::fmt; use syntax::ast; use errors::DiagnosticBuilder; @@ -103,8 +103,12 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { // Map from floating variable to the kind of float it represents float_unification_table: RefCell<UnificationTable<ty::FloatVid>>, - // For region variables. - region_constraints: RefCell<RegionConstraintCollector<'tcx>>, + // Tracks the set of region variables and the constraints between + // them. This is initially `Some(_)` but when + // `resolve_regions_and_report_errors` is invoked, this gets set + // to `None` -- further attempts to perform unification etc may + // fail if new region constraints would've been added. + region_constraints: RefCell<Option<RegionConstraintCollector<'tcx>>>, // Once region inference is done, the values for each variable. lexical_region_resolutions: RefCell<Option<LexicalRegionResolutions<'tcx>>>, @@ -424,7 +428,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> { type_variables: RefCell::new(type_variable::TypeVariableTable::new()), int_unification_table: RefCell::new(UnificationTable::new()), float_unification_table: RefCell::new(UnificationTable::new()), - region_constraints: RefCell::new(RegionConstraintCollector::new()), + region_constraints: RefCell::new(Some(RegionConstraintCollector::new())), lexical_region_resolutions: RefCell::new(None), selection_cache: traits::SelectionCache::new(), evaluation_cache: traits::EvaluationCache::new(), @@ -767,7 +771,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { type_snapshot: self.type_variables.borrow_mut().snapshot(), int_snapshot: self.int_unification_table.borrow_mut().snapshot(), float_snapshot: self.float_unification_table.borrow_mut().snapshot(), - region_constraints_snapshot: self.region_constraints.borrow_mut().start_snapshot(), + region_constraints_snapshot: self.borrow_region_constraints().start_snapshot(), was_in_snapshot: in_snapshot, // Borrow tables "in progress" (i.e. during typeck) // to ban writes from within a snapshot to them. @@ -801,8 +805,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.float_unification_table .borrow_mut() .rollback_to(float_snapshot); - self.region_constraints - .borrow_mut() + self.borrow_region_constraints() .rollback_to(region_constraints_snapshot); } @@ -830,8 +833,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.float_unification_table .borrow_mut() .commit(float_snapshot); - self.region_constraints - .borrow_mut() + self.borrow_region_constraints() .commit(region_constraints_snapshot); } @@ -887,7 +889,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { sub: ty::Region<'tcx>, sup: ty::RegionVid) { - self.region_constraints.borrow_mut().add_given(sub, sup); + self.borrow_region_constraints().add_given(sub, sup); } pub fn can_sub<T>(&self, @@ -927,7 +929,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { a: ty::Region<'tcx>, b: ty::Region<'tcx>) { debug!("sub_regions({:?} <: {:?})", a, b); - self.region_constraints.borrow_mut().make_subregion(origin, a, b); + self.borrow_region_constraints().make_subregion(origin, a, b); } pub fn equality_predicate(&self, @@ -1030,7 +1032,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { pub fn next_region_var(&self, origin: RegionVariableOrigin) -> ty::Region<'tcx> { - self.tcx.mk_region(ty::ReVar(self.region_constraints.borrow_mut().new_region_var(origin))) + self.tcx.mk_region(ty::ReVar(self.borrow_region_constraints().new_region_var(origin))) } /// Create a region inference variable for the given @@ -1114,6 +1116,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { self.tainted_by_errors_flag.set(true) } + /// Process the region constraints and report any errors that + /// result. After this, no more unification operations should be + /// done -- or the compiler will panic -- but it is legal to use + /// `resolve_type_vars_if_possible` as well as `fully_resolve`. pub fn resolve_regions_and_report_errors(&self, region_context: DefId, region_map: ®ion::ScopeTree, @@ -1126,8 +1132,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { region_context, region_map, free_regions); - let (lexical_region_resolutions, errors) = - self.region_constraints.borrow_mut().resolve_regions(®ion_rels); + let mut region_constraints = self.region_constraints.borrow_mut() + .take() + .expect("regions already resolved"); + let (lexical_region_resolutions, errors) = region_constraints.resolve_regions(®ion_rels); let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions)); assert!(old_value.is_none()); @@ -1365,7 +1373,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { a, bound); - self.region_constraints.borrow_mut().verify_generic_bound(origin, kind, a, bound); + self.borrow_region_constraints().verify_generic_bound(origin, kind, a, bound); } pub fn type_moves_by_default(&self, @@ -1446,11 +1454,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { /// Normalizes associated types in `value`, potentially returning /// new obligations that must further be processed. pub fn partially_normalize_associated_types_in<T>(&self, - span: Span, - body_id: ast::NodeId, - param_env: ty::ParamEnv<'tcx>, - value: &T) - -> InferOk<'tcx, T> + span: Span, + body_id: ast::NodeId, + param_env: ty::ParamEnv<'tcx>, + value: &T) + -> InferOk<'tcx, T> where T : TypeFoldable<'tcx> { debug!("partially_normalize_associated_types_in(value={:?})", value); @@ -1463,6 +1471,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { obligations); InferOk { value, obligations } } + + fn borrow_region_constraints(&self) -> RefMut<'_, RegionConstraintCollector<'tcx>> { + RefMut::map( + self.region_constraints.borrow_mut(), + |c| c.as_mut().expect("region constraints already solved")) + } } impl<'a, 'gcx, 'tcx> TypeTrace<'tcx> { diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index 53d96383242..5e70c0ce368 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -75,8 +75,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReVar(rid) => - self.infcx.region_constraints.borrow_mut() - .opportunistic_resolve_var(self.tcx(), rid), + self.infcx.borrow_region_constraints() + .opportunistic_resolve_var(self.tcx(), rid), _ => r, } diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs index bc4bb0c4712..f891f692c7d 100644 --- a/src/librustc/infer/sub.rs +++ b/src/librustc/infer/sub.rs @@ -137,7 +137,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx> // from the "cause" field, we could perhaps give more tailored // error messages. let origin = SubregionOrigin::Subtype(self.fields.trace.clone()); - self.fields.infcx.region_constraints.borrow_mut().make_subregion(origin, a, b); + self.fields.infcx.borrow_region_constraints() + .make_subregion(origin, a, b); Ok(a) } |
