about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-07-21 00:55:46 +0000
committerbors <bors@rust-lang.org>2018-07-21 00:55:46 +0000
commitbf7afee52a2e92a509eae1e9530ee75da8f9f621 (patch)
tree43b9756cb02b5446fabc857fde11e29c15980a3d
parentee8d23d54445f8d3e62a5e2bd6fde9ac3ff2cf24 (diff)
parente3d14c4c564ede79383ca88a4a8a6ce590786835 (diff)
downloadrust-bf7afee52a2e92a509eae1e9530ee75da8f9f621.tar.gz
rust-bf7afee52a2e92a509eae1e9530ee75da8f9f621.zip
Auto merge of #52438 - ljedrz:rustc_vec_capacity, r=eddyb
Calculate Vec capacities in librustc

Calculate the required capacity of a few vectors in rustc based on the number of elements they are populated with.
-rw-r--r--src/librustc/infer/mod.rs37
-rw-r--r--src/librustc/middle/dead.rs16
-rw-r--r--src/librustc_codegen_llvm/abi.rs8
-rw-r--r--src/librustc_typeck/astconv.rs47
4 files changed, 49 insertions, 59 deletions
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 5b5ae6473f8..9283705b7b7 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -562,36 +562,25 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     }
 
     pub fn unsolved_variables(&self) -> Vec<Ty<'tcx>> {
-        let mut variables = Vec::new();
-
-        {
-            let mut type_variables = self.type_variables.borrow_mut();
-            variables.extend(
-                type_variables
-                    .unsolved_variables()
-                    .into_iter()
-                    .map(|t| self.tcx.mk_var(t)));
-        }
-
-        {
-            let mut int_unification_table = self.int_unification_table.borrow_mut();
-            variables.extend(
+        let mut type_variables = self.type_variables.borrow_mut();
+        let mut int_unification_table = self.int_unification_table.borrow_mut();
+        let mut float_unification_table = self.float_unification_table.borrow_mut();
+
+        type_variables
+            .unsolved_variables()
+            .into_iter()
+            .map(|t| self.tcx.mk_var(t))
+            .chain(
                 (0..int_unification_table.len())
                     .map(|i| ty::IntVid { index: i as u32 })
                     .filter(|&vid| int_unification_table.probe_value(vid).is_none())
-                    .map(|v| self.tcx.mk_int_var(v)));
-        }
-
-        {
-            let mut float_unification_table = self.float_unification_table.borrow_mut();
-            variables.extend(
+                    .map(|v| self.tcx.mk_int_var(v))
+            ).chain(
                 (0..float_unification_table.len())
                     .map(|i| ty::FloatVid { index: i as u32 })
                     .filter(|&vid| float_unification_table.probe_value(vid).is_none())
-                    .map(|v| self.tcx.mk_float_var(v)));
-        }
-
-        return variables;
+                    .map(|v| self.tcx.mk_float_var(v))
+            ).collect()
     }
 
     fn combine_fields(&'a self, trace: TypeTrace<'tcx>, param_env: ty::ParamEnv<'tcx>)
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 60b47dbbd19..e4fc1b09fce 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -391,16 +391,12 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
 fn create_and_seed_worklist<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                       access_levels: &privacy::AccessLevels,
                                       krate: &hir::Crate)
-                                      -> Vec<ast::NodeId> {
-    let mut worklist = Vec::new();
-    for (id, _) in &access_levels.map {
-        worklist.push(*id);
-    }
-
-    // Seed entry point
-    if let Some((id, _, _)) = *tcx.sess.entry_fn.borrow() {
-        worklist.push(id);
-    }
+                                      -> Vec<ast::NodeId>
+{
+    let worklist = access_levels.map.iter().map(|(&id, _)| id).chain(
+        // Seed entry point
+        tcx.sess.entry_fn.borrow().map(|(id, _, _)| id)
+    ).collect::<Vec<_>>();
 
     // Seed implemented trait items
     let mut life_seeder = LifeSeeder {
diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index b1502902079..f1a6e9913d6 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -565,7 +565,13 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
     }
 
     fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
-        let mut llargument_tys = Vec::new();
+        let args_capacity: usize = self.args.iter().map(|arg|
+            if arg.pad.is_some() { 1 } else { 0 } +
+            if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 }
+        ).sum();
+        let mut llargument_tys = Vec::with_capacity(
+            if let PassMode::Indirect(_) = self.ret.mode { 1 } else { 0 } + args_capacity
+        );
 
         let llreturn_ty = match self.ret.mode {
             PassMode::Ignore => Type::void(cx),
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 465faa1d477..a2dbf2aaca3 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1473,35 +1473,34 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
     pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>)
                       -> Vec<ty::Predicate<'tcx>>
     {
-        let mut vec = Vec::new();
-
         // If it could be sized, and is, add the sized predicate
-        if self.implicitly_sized {
-            if let Some(sized) = tcx.lang_items().sized_trait() {
+        let sized_predicate = if self.implicitly_sized {
+            tcx.lang_items().sized_trait().map(|sized| {
                 let trait_ref = ty::TraitRef {
                     def_id: sized,
                     substs: tcx.mk_substs_trait(param_ty, &[])
                 };
-                vec.push(trait_ref.to_predicate());
-            }
-        }
-
-        for &region_bound in &self.region_bounds {
-            // account for the binder being introduced below; no need to shift `param_ty`
-            // because, at present at least, it can only refer to early-bound regions
-            let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
-            vec.push(
-                ty::Binder::dummy(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate());
-        }
-
-        for bound_trait_ref in &self.trait_bounds {
-            vec.push(bound_trait_ref.to_predicate());
-        }
-
-        for projection in &self.projection_bounds {
-            vec.push(projection.to_predicate());
-        }
+                trait_ref.to_predicate()
+            })
+        } else {
+            None
+        };
 
-        vec
+        sized_predicate.into_iter().chain(
+            self.region_bounds.iter().map(|&region_bound| {
+                // account for the binder being introduced below; no need to shift `param_ty`
+                // because, at present at least, it can only refer to early-bound regions
+                let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
+                ty::Binder::dummy(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate()
+            }).chain(
+                self.trait_bounds.iter().map(|bound_trait_ref| {
+                    bound_trait_ref.to_predicate()
+                })
+            ).chain(
+                self.projection_bounds.iter().map(|projection| {
+                    projection.to_predicate()
+                })
+            )
+        ).collect()
     }
 }