]> git.lizzy.rs Git - rust.git/commitdiff
Nit: rework region obligations to a snapshotted vector
authorNiko Matsakis <niko@alum.mit.edu>
Tue, 14 Nov 2017 20:12:36 +0000 (15:12 -0500)
committerNiko Matsakis <niko@alum.mit.edu>
Thu, 16 Nov 2017 10:57:56 +0000 (05:57 -0500)
src/librustc/infer/mod.rs
src/librustc/infer/outlives/obligations.rs
src/librustc/lib.rs
src/librustc/traits/mod.rs

index 2b080c54da1f311e0436cf08d847e7a2732dcdbb..f734ff84f639eadb2cca80f29dc4dbc1c2346178 100644 (file)
@@ -35,7 +35,7 @@
 use syntax::ast;
 use errors::DiagnosticBuilder;
 use syntax_pos::{self, Span, DUMMY_SP};
-use util::nodemap::{NodeMap, FxHashMap};
+use util::nodemap::FxHashMap;
 use arena::DroplessArena;
 
 use self::combine::CombineFields;
@@ -179,7 +179,7 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     // for each body-id in this map, which will process the
     // obligations within. This is expected to be done 'late enough'
     // that all type inference variables have been bound and so forth.
-    region_obligations: RefCell<NodeMap<Vec<RegionObligation<'tcx>>>>,
+    region_obligations: RefCell<Vec<(ast::NodeId, RegionObligation<'tcx>)>>,
 }
 
 /// A map returned by `skolemize_late_bound_regions()` indicating the skolemized
@@ -450,7 +450,7 @@ pub fn enter<F, R>(&'tcx mut self, f: F) -> R
             tainted_by_errors_flag: Cell::new(false),
             err_count_on_creation: tcx.sess.err_count(),
             in_snapshot: Cell::new(false),
-            region_obligations: RefCell::new(NodeMap()),
+            region_obligations: RefCell::new(vec![]),
         }))
     }
 }
@@ -478,6 +478,7 @@ pub struct CombinedSnapshot<'a, 'tcx:'a> {
     int_snapshot: unify::Snapshot<ty::IntVid>,
     float_snapshot: unify::Snapshot<ty::FloatVid>,
     region_constraints_snapshot: RegionSnapshot,
+    region_obligations_snapshot: usize,
     was_in_snapshot: bool,
     _in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
 }
@@ -786,6 +787,7 @@ fn start_snapshot<'b>(&'b self) -> CombinedSnapshot<'b, 'tcx> {
             int_snapshot: self.int_unification_table.borrow_mut().snapshot(),
             float_snapshot: self.float_unification_table.borrow_mut().snapshot(),
             region_constraints_snapshot: self.borrow_region_constraints().start_snapshot(),
+            region_obligations_snapshot: self.region_obligations.borrow().len(),
             was_in_snapshot: in_snapshot,
             // Borrow tables "in progress" (i.e. during typeck)
             // to ban writes from within a snapshot to them.
@@ -802,6 +804,7 @@ fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot) {
                                int_snapshot,
                                float_snapshot,
                                region_constraints_snapshot,
+                               region_obligations_snapshot,
                                was_in_snapshot,
                                _in_progress_tables } = snapshot;
 
@@ -819,6 +822,9 @@ fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot) {
         self.float_unification_table
             .borrow_mut()
             .rollback_to(float_snapshot);
+        self.region_obligations
+            .borrow_mut()
+            .truncate(region_obligations_snapshot);
         self.borrow_region_constraints()
             .rollback_to(region_constraints_snapshot);
     }
@@ -830,6 +836,7 @@ fn commit_from(&self, snapshot: CombinedSnapshot) {
                                int_snapshot,
                                float_snapshot,
                                region_constraints_snapshot,
+                               region_obligations_snapshot: _,
                                was_in_snapshot,
                                _in_progress_tables } = snapshot;
 
index 2fb085bc1d86fb33d263b1ff5bd120d340be5b52..32f09795668bf50d2032ed0dd8448e327af29577 100644 (file)
@@ -86,9 +86,7 @@ pub fn register_region_obligation(
     ) {
         self.region_obligations
             .borrow_mut()
-            .entry(body_id)
-            .or_insert(vec![])
-            .push(obligation);
+            .push((body_id, obligation));
     }
 
     /// Process the region obligations that must be proven (during
@@ -131,10 +129,16 @@ pub fn process_registered_region_obligations(
         param_env: ty::ParamEnv<'tcx>,
         body_id: ast::NodeId,
     ) {
-        let region_obligations = match self.region_obligations.borrow_mut().remove(&body_id) {
-            None => vec![],
-            Some(vec) => vec,
-        };
+        assert!(!self.in_snapshot.get(), "cannot process registered region obligations in a snapshot");
+
+        // pull out the region obligations with the given `body_id` (leaving the rest)
+        let mut my_region_obligations = Vec::with_capacity(self.region_obligations.borrow().len());
+        {
+            let mut r_o = self.region_obligations.borrow_mut();
+            for (_, obligation) in r_o.drain_filter(|(ro_body_id, _)| *ro_body_id == body_id) {
+                my_region_obligations.push(obligation);
+            }
+        }
 
         let outlives =
             TypeOutlives::new(self, region_bound_pairs, implicit_region_bound, param_env);
@@ -143,7 +147,7 @@ pub fn process_registered_region_obligations(
             sup_type,
             sub_region,
             cause,
-        } in region_obligations
+        } in my_region_obligations
         {
             let origin = SubregionOrigin::from_obligation_cause(
                 &cause,
@@ -170,11 +174,13 @@ pub fn type_must_outlive(
         outlives.type_must_outlive(origin, ty, region);
     }
 
-    /// Ignore the region obligations for a given `body_id`, not bothering to
-    /// prove them. This function should not really exist; it is used to accommodate some older
-    /// code for the time being.
-    pub fn ignore_region_obligations(&self, body_id: ast::NodeId) {
-        self.region_obligations.borrow_mut().remove(&body_id);
+    /// Ignore the region obligations, not bothering to prove
+    /// them. This function should not really exist; it is used to
+    /// accommodate some older code for the time being.
+    pub fn ignore_region_obligations(&self) {
+        assert!(!self.in_snapshot.get(), "cannot ignore registered region obligations in a snapshot");
+
+        self.region_obligations.borrow_mut().clear();
     }
 }
 
index 66113ffef3d65b751ceb886504d703d9d2792653..5e9019c92c5b73be37503504310f8b5eb5c04de6 100644 (file)
@@ -45,6 +45,7 @@
 #![feature(conservative_impl_trait)]
 #![feature(const_fn)]
 #![feature(core_intrinsics)]
+#![feature(drain_filter)]
 #![feature(i128_type)]
 #![feature(match_default_bindings)]
 #![feature(inclusive_range_syntax)]
index 9314c9d051de71a6bbdf51ccbcaa796f8f27d507..55b1a913f0d1de6da737053e7b7edd95ff6ed97e 100644 (file)
@@ -511,7 +511,6 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                            unnormalized_env.reveal);
 
     tcx.infer_ctxt().enter(|infcx| {
-        let body_id = cause.body_id;
         let predicates = match fully_normalize(
             &infcx,
             cause,
@@ -546,7 +545,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         // properly, and that code is currently largely confined to
         // regionck (though I made some efforts to extract it
         // out). -nmatsakis
-        let _ = infcx.ignore_region_obligations(body_id);
+        let _ = infcx.ignore_region_obligations();
 
         infcx.resolve_regions_and_report_errors(region_context, &region_scope_tree, &free_regions);
         let predicates = match infcx.fully_resolve(&predicates) {