]> git.lizzy.rs Git - rust.git/commitdiff
make the `region_constraints` field an `Option`
authorNiko Matsakis <niko@alum.mit.edu>
Sun, 5 Nov 2017 12:22:39 +0000 (07:22 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Thu, 16 Nov 2017 10:57:43 +0000 (05:57 -0500)
This way, we can `take()` ownership of it when we are going to resolve regions.

src/librustc/infer/equate.rs
src/librustc/infer/fudge.rs
src/librustc/infer/glb.rs
src/librustc/infer/higher_ranked/mod.rs
src/librustc/infer/lub.rs
src/librustc/infer/mod.rs
src/librustc/infer/resolve.rs
src/librustc/infer/sub.rs

index 0c59fa703bb667da8b708ea9567f68d59b2485b4..2ae8f8ae9335711f41a9d693f764b4bf30c82e86 100644 (file)
@@ -104,7 +104,8 @@ fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'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)
     }
 
index 729e67437ba3e0b098e6cf0fdeb9fc677b73bfd1..756a6947ee3f850d489f8f6f6f6f6a65f2cb8d96 100644 (file)
@@ -78,7 +78,7 @@ pub fn fudge_regions_if_ok<T, E, F>(&self,
                         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))
index d63036eecff9f11e406b9335f83feeeb62061807..8b42314ed97cf31f1c028b6662468b8626eeacc3 100644 (file)
@@ -67,7 +67,7 @@ fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'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>)
index 2aef9fece87a5aa9daf228826eff36110505b8d3..c49b3b4b9c87365ed039dedba95226cc81269ed1 100644 (file)
@@ -176,9 +176,10 @@ pub fn higher_ranked_match<T, U>(&mut self,
                                      .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 @@ fn rev_lookup<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'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 @@ fn tainted_regions(&self,
                        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 @@ fn region_vars_confined_to_snapshot(&self,
          */
 
         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 @@ pub fn skolemize_late_bound_regions<T>(&self,
         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 @@ pub fn pop_skolemized(&self,
     {
         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);
index 0c4f4efe9947ca41fdf165dc5ec5f1b20ef9698e..4a2a7a6bdfeca944388582197e2bd10f7ffed28e 100644 (file)
@@ -67,7 +67,7 @@ fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'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>)
index d42419d7dc64d487df152d93d34bec2c5d268185..a5cae839aa70be86f3a6298fb583428486e81a9a 100644 (file)
@@ -31,7 +31,7 @@
 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 @@ pub fn enter<F, R>(&'tcx mut self, f: F) -> R
             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 @@ fn start_snapshot<'b>(&'b self) -> CombinedSnapshot<'b, '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 @@ fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot) {
         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 @@ fn commit_from(&self, snapshot: CombinedSnapshot) {
         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 @@ pub fn add_given(&self,
                      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 @@ pub fn sub_regions(&self,
                        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 @@ pub fn next_float_var_id(&self) -> FloatVid {
 
     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 @@ pub fn set_tainted_by_errors(&self) {
         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: &region::ScopeTree,
@@ -1126,8 +1132,10 @@ pub fn resolve_regions_and_report_errors(&self,
                                                region_context,
                                                region_map,
                                                free_regions);
-        let (lexical_region_resolutions, errors) =
-            self.region_constraints.borrow_mut().resolve_regions(&region_rels);
+        let mut region_constraints = self.region_constraints.borrow_mut()
+                                                            .take()
+                                                            .expect("regions already resolved");
+        let (lexical_region_resolutions, errors) = region_constraints.resolve_regions(&region_rels);
 
         let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
         assert!(old_value.is_none());
@@ -1365,7 +1373,7 @@ pub fn verify_generic_bound(&self,
                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 @@ pub fn generator_sig(&self, def_id: DefId) -> Option<ty::PolyGenSig<'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 @@ pub fn partially_normalize_associated_types_in<T>(&self,
             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> {
index 53d963832426bb7a2588a11e0eff3c0abdd6a495..5e70c0ce368fc667c6d1915d9b06eccef0c56cea 100644 (file)
@@ -75,8 +75,8 @@ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
     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,
         }
index bc4bb0c4712fa80bf4a6d1b6b108d380a342395b..f891f692c7d8208a356ef698eb5ec0f5d4b2a0dd 100644 (file)
@@ -137,7 +137,8 @@ fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'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)
     }