]> git.lizzy.rs Git - rust.git/commitdiff
Make gathering generator interior types O(n log n)
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Sun, 20 Aug 2017 12:20:33 +0000 (14:20 +0200)
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Sun, 20 Aug 2017 12:20:33 +0000 (14:20 +0200)
src/librustc_typeck/check/generator_interior.rs

index f50fb7e4a1326c1749380197820449396e257b41..7b25a3739c3dd6c90b1f1e8e459b77580477d2c4 100644 (file)
@@ -23,9 +23,7 @@
 struct InteriorVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
     cache: FxHashMap<NodeId, Option<Span>>,
-
-    // FIXME: Use an ordered hash map here
-    types: Vec<Ty<'tcx>>,
+    types: FxHashMap<Ty<'tcx>, usize>,
     region_maps: Rc<RegionMaps>,
 }
 
@@ -46,9 +44,9 @@ fn record(&mut self, ty: Ty<'tcx>, scope: Option<CodeExtent>, expr: Option<&'tcx
                        expr, scope, ty, span);
             }
 
-            if !self.types.contains(&ty) {
-                self.types.push(ty);
-            }
+            // Map the type to the number of types added before it
+            let entries = self.types.len();
+            self.types.entry(&ty).or_insert(entries);
         } else {
             debug!("no type in expr = {:?}, span = {:?}", expr, expr.map(|e| e.span));
         }
@@ -62,13 +60,21 @@ pub fn resolve_interior<'a, 'gcx, 'tcx>(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
     let body = fcx.tcx.hir.body(body_id);
     let mut visitor = InteriorVisitor {
         fcx,
-        types: Vec::new(),
+        types: FxHashMap(),
         cache: FxHashMap(),
         region_maps: fcx.tcx.region_maps(def_id),
     };
     intravisit::walk_body(&mut visitor, body);
 
-    let tuple = fcx.tcx.intern_tup(&visitor.types, false);
+    let mut types: Vec<_> = visitor.types.drain().collect();
+
+    // Sort types by insertion order
+    types.sort_by_key(|t| t.1);
+
+    // Extract type components
+    let types: Vec<_> = types.into_iter().map(|t| t.0).collect();
+
+    let tuple = fcx.tcx.intern_tup(&types, false);
 
     debug!("Types in generator {:?}, span = {:?}", tuple, body.value.span);