From 5242e8d2bad01beec7c841d20952cb230bc9fd84 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 24 Jun 2013 17:19:28 -0400 Subject: [PATCH 1/4] remove the redundant `each` method from OptVec --- src/librustc/metadata/encoder.rs | 4 ++-- src/librustc/middle/resolve.rs | 8 ++++---- src/librustc/middle/typeck/astconv.rs | 2 +- src/librustc/middle/typeck/collect.rs | 4 ++-- src/librustc/middle/typeck/rscope.rs | 2 +- src/libsyntax/ast_util.rs | 4 ++-- src/libsyntax/ext/deriving/generic.rs | 4 ++-- src/libsyntax/ext/pipes/pipec.rs | 4 ++-- src/libsyntax/opt_vec.rs | 7 ------- src/libsyntax/print/pprust.rs | 2 +- src/libsyntax/visit.rs | 4 ++-- 11 files changed, 19 insertions(+), 26 deletions(-) diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index d08342d8687dd..9c28da10e40d5 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -731,8 +731,8 @@ fn encode_info_for_method(ecx: &EncodeContext, } let mut combined_ty_params = opt_vec::Empty; - for owner_generics.ty_params.each |x| { combined_ty_params.push(copy *x) } - for method_generics.ty_params.each |x| { combined_ty_params.push(copy *x) } + for owner_generics.ty_params.iter().advance |x| { combined_ty_params.push(copy *x) } + for method_generics.ty_params.iter().advance |x| { combined_ty_params.push(copy *x) } let len = combined_ty_params.len(); encode_type_param_bounds(ebml_w, ecx, &combined_ty_params); diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index a8b837d869d30..3a54c224b5236 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3834,8 +3834,8 @@ impl Resolver { pub fn resolve_type_parameters(@mut self, type_parameters: &OptVec, visitor: ResolveVisitor) { - for type_parameters.each |type_parameter| { - for type_parameter.bounds.each |bound| { + for type_parameters.iter().advance |type_parameter| { + for type_parameter.bounds.iter().advance |bound| { self.resolve_type_parameter_bound(bound, visitor); } } @@ -4181,13 +4181,13 @@ impl Resolver { } } - for bounds.each |bound| { + for bounds.iter().advance |bound| { self.resolve_type_parameter_bound(bound, visitor); } } ty_closure(c) => { - for c.bounds.each |bound| { + for c.bounds.iter().advance |bound| { self.resolve_type_parameter_bound(bound, visitor); } visit_ty(ty, ((), visitor)); diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 3b651451db847..5e6574850f1b8 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -752,7 +752,7 @@ fn conv_builtin_bounds(tcx: ty::ctxt, //! legal. let mut builtin_bounds = ty::EmptyBuiltinBounds(); - for ast_bounds.each |ast_bound| { + for ast_bounds.iter().advance |ast_bound| { match *ast_bound { ast::TraitTyParamBound(b) => { match lookup_def_tcx(tcx, b.path.span, b.ref_id) { diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 3554376902cb7..7812a0ed0ebac 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -775,7 +775,7 @@ pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt, span: span, generics: &ast::Generics, thing: &'static str) { - for generics.ty_params.each |ty_param| { + for generics.ty_params.iter().advance |ty_param| { if ty_param.bounds.len() > 0 { ccx.tcx.sess.span_err( span, @@ -1172,7 +1172,7 @@ pub fn ty_generics(ccx: &CrateCtxt, builtin_bounds: ty::EmptyBuiltinBounds(), trait_bounds: ~[] }; - for ast_bounds.each |ast_bound| { + for ast_bounds.iter().advance |ast_bound| { match *ast_bound { TraitTyParamBound(b) => { let ty = ty::mk_param(ccx.tcx, param_ty.idx, param_ty.def_id); diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs index 16b490cd478d4..dc9fc264f85dc 100644 --- a/src/librustc/middle/typeck/rscope.rs +++ b/src/librustc/middle/typeck/rscope.rs @@ -57,7 +57,7 @@ impl RegionParamNames { } fn has_ident(&self, ident: ast::ident) -> bool { - for self.each |region_param_name| { + for self.iter().advance |region_param_name| { if *region_param_name == ident { return true; } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 227d700452b6c..a233c330b64d5 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -394,10 +394,10 @@ impl id_range { pub fn id_visitor(vfn: @fn(node_id, T)) -> visit::vt { let visit_generics: @fn(&Generics, T) = |generics, t| { - for generics.ty_params.each |p| { + for generics.ty_params.iter().advance |p| { vfn(p.id, copy t); } - for generics.lifetimes.each |p| { + for generics.lifetimes.iter().advance |p| { vfn(p.id, copy t); } }; diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 981b28afd0227..83e446fa4c688 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -324,11 +324,11 @@ impl<'self> TraitDef<'self> { let mut trait_generics = self.generics.to_generics(cx, span, type_ident, generics); // Copy the lifetimes - for generics.lifetimes.each |l| { + for generics.lifetimes.iter().advance |l| { trait_generics.lifetimes.push(copy *l) }; // Create the type parameters. - for generics.ty_params.each |ty_param| { + for generics.ty_params.iter().advance |ty_param| { // I don't think this can be moved out of the loop, since // a TyParamBound requires an ast id let mut bounds = opt_vec::from( diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs index 55ac9c5ec1c82..da5455d433279 100644 --- a/src/libsyntax/ext/pipes/pipec.rs +++ b/src/libsyntax/ext/pipes/pipec.rs @@ -374,7 +374,7 @@ impl gen_init for protocol { fn buffer_ty_path(&self, cx: @ExtCtxt) -> @ast::Ty { let mut params: OptVec = opt_vec::Empty; for (copy self.states).iter().advance |s| { - for s.generics.ty_params.each |tp| { + for s.generics.ty_params.iter().advance |tp| { match params.iter().find_(|tpp| tp.ident == tpp.ident) { None => params.push(*tp), _ => () @@ -392,7 +392,7 @@ impl gen_init for protocol { let ext_cx = cx; let mut params: OptVec = opt_vec::Empty; let fields = do (copy self.states).iter().transform |s| { - for s.generics.ty_params.each |tp| { + for s.generics.ty_params.iter().advance |tp| { match params.iter().find_(|tpp| tp.ident == tpp.ident) { None => params.push(*tp), _ => () diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 8917b481dc726..22b1d040d42e0 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -38,13 +38,6 @@ pub fn from(t: ~[T]) -> OptVec { } impl OptVec { - fn each(&self, blk: &fn(v: &T) -> bool) -> bool { - match *self { - Empty => true, - Vec(ref v) => v.iter().advance(blk) - } - } - fn push(&mut self, t: T) { match *self { Vec(ref mut v) => { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 1a3155337a5e3..d7b5e57a57f0d 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1743,7 +1743,7 @@ pub fn print_bounds(s: @ps, bounds: @OptVec) { if !bounds.is_empty() { word(s.s, ":"); let mut first = true; - for bounds.each |bound| { + for bounds.iter().advance |bound| { nbsp(s); if first { first = false; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index d7914832835ac..5e409be3e6cce 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -334,7 +334,7 @@ pub fn visit_foreign_item(ni: @foreign_item, (e, v): (E, vt)) { pub fn visit_ty_param_bounds(bounds: &OptVec, (e, v): (E, vt)) { - for bounds.each |bound| { + for bounds.iter().advance |bound| { match *bound { TraitTyParamBound(ty) => visit_trait_ref(ty, (copy e, v)), RegionTyParamBound => {} @@ -343,7 +343,7 @@ pub fn visit_ty_param_bounds(bounds: &OptVec, } pub fn visit_generics(generics: &Generics, (e, v): (E, vt)) { - for generics.ty_params.each |tp| { + for generics.ty_params.iter().advance |tp| { visit_ty_param_bounds(tp.bounds, (copy e, v)); } } From 64ee9668a2e3d4d75b859fd3bca1466a97fae2d8 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 24 Jun 2013 17:45:00 -0400 Subject: [PATCH 2/4] container: remove internal iterators from Map the maps are being migrated to external iterators --- src/libextra/smallintmap.rs | 64 +++++++++---------- src/libextra/treemap.rs | 40 ++++++------ src/libstd/container.rs | 12 ---- src/libstd/hashmap.rs | 56 ++++++++-------- src/libstd/trie.rs | 48 +++++++------- .../class-impl-very-parameterized-trait.rs | 21 ------ 6 files changed, 104 insertions(+), 137 deletions(-) diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index 17126f0d32b53..1d163922955d0 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -56,38 +56,6 @@ impl Map for SmallIntMap { self.find(key).is_some() } - /// Visit all key-value pairs in order - fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool { - for uint::range(0, self.v.len()) |i| { - match self.v[i] { - Some(ref elt) => if !it(&i, elt) { return false; }, - None => () - } - } - return true; - } - - /// Visit all keys in order - fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool { - self.each(|k, _| blk(k)) - } - - /// Visit all values in order - fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool { - self.each(|_, v| blk(v)) - } - - /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool { - for uint::range(0, self.v.len()) |i| { - match self.v[i] { - Some(ref mut elt) => if !it(&i, elt) { return false; }, - None => () - } - } - return true; - } - /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, key: &uint) -> Option<&'a V> { if *key < self.v.len() { @@ -156,6 +124,38 @@ impl SmallIntMap { /// Create an empty SmallIntMap pub fn new() -> SmallIntMap { SmallIntMap{v: ~[]} } + /// Visit all key-value pairs in order + pub fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool { + for uint::range(0, self.v.len()) |i| { + match self.v[i] { + Some(ref elt) => if !it(&i, elt) { return false; }, + None => () + } + } + return true; + } + + /// Visit all keys in order + pub fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool { + self.each(|k, _| blk(k)) + } + + /// Visit all values in order + pub fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool { + self.each(|_, v| blk(v)) + } + + /// Iterate over the map and mutate the contained values + pub fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool { + for uint::range(0, self.v.len()) |i| { + match self.v[i] { + Some(ref mut elt) => if !it(&i, elt) { return false; }, + None => () + } + } + return true; + } + /// Visit all key-value pairs in reverse order pub fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) -> bool { for uint::range_rev(self.v.len(), 0) |i| { diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 4929dea9045bf..fd83fd1991674 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -107,26 +107,6 @@ impl Map for TreeMap { self.find(key).is_some() } - /// Visit all key-value pairs in order - fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool { - each(&self.root, f) - } - - /// Visit all keys in order - fn each_key(&self, f: &fn(&K) -> bool) -> bool { - self.each(|k, _| f(k)) - } - - /// Visit all values in order - fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool { - self.each(|_, v| f(v)) - } - - /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool { - mutate_values(&mut self.root, f) - } - /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, key: &K) -> Option<&'a V> { let mut current: &'a Option<~TreeNode> = &self.root; @@ -184,6 +164,26 @@ impl TreeMap { /// Create an empty TreeMap pub fn new() -> TreeMap { TreeMap{root: None, length: 0} } + /// Visit all key-value pairs in order + pub fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool { + each(&self.root, f) + } + + /// Visit all keys in order + pub fn each_key(&self, f: &fn(&K) -> bool) -> bool { + self.each(|k, _| f(k)) + } + + /// Visit all values in order + pub fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool { + self.each(|_, v| f(v)) + } + + /// Iterate over the map and mutate the contained values + pub fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool { + mutate_values(&mut self.root, f) + } + /// Visit all key-value pairs in reverse order pub fn each_reverse<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool { each_reverse(&self.root, f) diff --git a/src/libstd/container.rs b/src/libstd/container.rs index c1b656f1cd9e6..d6f4c26715a4f 100644 --- a/src/libstd/container.rs +++ b/src/libstd/container.rs @@ -34,18 +34,6 @@ pub trait Map: Mutable { /// Return true if the map contains a value for the specified key fn contains_key(&self, key: &K) -> bool; - /// Visits all keys and values - fn each<'a>(&'a self, f: &fn(&K, &'a V) -> bool) -> bool; - - /// Visit all keys - fn each_key(&self, f: &fn(&K) -> bool) -> bool; - - /// Visit all values - fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool; - - /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool; - /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, key: &K) -> Option<&'a V>; diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 7d55947e81881..962025915d24c 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -307,34 +307,6 @@ impl Map for HashMap { } } - /// Visit all key-value pairs - fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool { - self.iter().advance(|(k, v)| blk(k, v)) - } - - /// Visit all keys - fn each_key(&self, blk: &fn(k: &K) -> bool) -> bool { - self.iter().advance(|(k, _)| blk(k)) - } - - /// Visit all values - fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) -> bool { - self.iter().advance(|(_, v)| blk(v)) - } - - /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, blk: &fn(&K, &mut V) -> bool) -> bool { - for uint::range(0, self.buckets.len()) |i| { - match self.buckets[i] { - Some(Bucket{key: ref key, value: ref mut value, _}) => { - if !blk(key, value) { return false; } - } - None => () - } - } - return true; - } - /// Return a reference to the value corresponding to the key fn find<'a>(&'a self, k: &K) -> Option<&'a V> { match self.bucket_for_key(k) { @@ -516,6 +488,34 @@ impl HashMap { } } + /// Visit all key-value pairs + pub fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool { + self.iter().advance(|(k, v)| blk(k, v)) + } + + /// Visit all keys + pub fn each_key(&self, blk: &fn(k: &K) -> bool) -> bool { + self.iter().advance(|(k, _)| blk(k)) + } + + /// Visit all values + pub fn each_value<'a>(&'a self, blk: &fn(v: &'a V) -> bool) -> bool { + self.iter().advance(|(_, v)| blk(v)) + } + + /// Iterate over the map and mutate the contained values + pub fn mutate_values(&mut self, blk: &fn(&K, &mut V) -> bool) -> bool { + for uint::range(0, self.buckets.len()) |i| { + match self.buckets[i] { + Some(Bucket{key: ref key, value: ref mut value, _}) => { + if !blk(key, value) { return false; } + } + None => () + } + } + return true; + } + /// An iterator visiting all key-value pairs in arbitrary order. /// Iterator element type is (&'a K, &'a V). pub fn iter<'a>(&'a self) -> HashMapIterator<'a, K, V> { diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index e6449ef49229c..8f70c75439a01 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -58,30 +58,6 @@ impl Map for TrieMap { self.find(key).is_some() } - /// Visit all key-value pairs in order - #[inline] - fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { - self.root.each(f) - } - - /// Visit all keys in order - #[inline] - fn each_key(&self, f: &fn(&uint) -> bool) -> bool { - self.each(|k, _| f(k)) - } - - /// Visit all values in order - #[inline] - fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) -> bool { - self.each(|_, v| f(v)) - } - - /// Iterate over the map and mutate the contained values - #[inline] - fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool { - self.root.mutate_values(f) - } - /// Return a reference to the value corresponding to the key #[inline] fn find<'a>(&'a self, key: &uint) -> Option<&'a T> { @@ -158,6 +134,30 @@ impl TrieMap { self.root.each_reverse(f) } + /// Visit all key-value pairs in order + #[inline] + pub fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { + self.root.each(f) + } + + /// Visit all keys in order + #[inline] + pub fn each_key(&self, f: &fn(&uint) -> bool) -> bool { + self.each(|k, _| f(k)) + } + + /// Visit all values in order + #[inline] + pub fn each_value<'a>(&'a self, f: &fn(&'a T) -> bool) -> bool { + self.each(|_, v| f(v)) + } + + /// Iterate over the map and mutate the contained values + #[inline] + pub fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool { + self.root.mutate_values(f) + } + /// Visit all keys in reverse order #[inline] pub fn each_key_reverse(&self, f: &fn(&uint) -> bool) -> bool { diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs index c54b8db46c889..2805fec6fce2c 100644 --- a/src/test/run-pass/class-impl-very-parameterized-trait.rs +++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs @@ -61,29 +61,8 @@ impl Mutable for cat { } impl Map for cat { - fn each<'a>(&'a self, f: &fn(&int, &'a T) -> bool) -> bool { - let mut n = int::abs(self.meows); - while n > 0 { - if !f(&n, &self.name) { return false; } - n -= 1; - } - return true; - } - fn contains_key(&self, k: &int) -> bool { *k <= self.meows } - fn each_key(&self, f: &fn(v: &int) -> bool) -> bool { - self.each(|k, _| f(k)) - } - - fn each_value<'a>(&'a self, f: &fn(v: &'a T) -> bool) -> bool { - self.each(|_, v| f(v)) - } - - fn mutate_values(&mut self, _f: &fn(&int, &mut T) -> bool) -> bool { - fail!("nope") - } - fn insert(&mut self, k: int, _: T) -> bool { self.meows += k; true From e67c48a5912b85c286113e0d039aae85f18da1d7 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Mon, 24 Jun 2013 18:34:20 -0400 Subject: [PATCH 3/4] remove `each` from vec, HashMap and HashSet --- doc/tutorial.md | 57 ++++++-- src/compiletest/runtest.rs | 2 +- src/libextra/arc.rs | 11 +- src/libextra/getopts.rs | 5 +- src/libextra/json.rs | 8 +- src/libextra/net_url.rs | 2 +- src/libextra/serialize.rs | 4 +- src/libextra/sync.rs | 3 +- src/libextra/workcache.rs | 4 +- src/librustc/metadata/cstore.rs | 2 +- src/librustc/middle/kind.rs | 3 +- src/librustc/middle/lang_items.rs | 2 +- src/librustc/middle/lint.rs | 7 +- src/librustc/middle/region.rs | 2 +- src/librustc/middle/resolve.rs | 24 ++-- src/librustc/middle/trans/_match.rs | 2 +- src/librustc/middle/trans/base.rs | 2 +- src/librustc/middle/trans/callee.rs | 4 +- src/librustc/middle/trans/type_use.rs | 3 +- .../middle/typeck/infer/region_inference.rs | 2 +- src/librustc/rustc.rs | 2 +- src/librusti/program.rs | 8 +- src/libstd/hashmap.rs | 11 -- src/libstd/task/spawn.rs | 2 +- src/libstd/vec.rs | 122 +----------------- src/test/bench/graph500-bfs.rs | 4 +- src/test/bench/msgsend-pipes-shared.rs | 2 +- src/test/bench/msgsend-pipes.rs | 2 +- src/test/bench/shootout-chameneos-redux.rs | 4 +- src/test/bench/shootout-k-nucleotide-pipes.rs | 2 +- .../block-must-not-have-result-for.rs | 4 +- .../borrowck-insert-during-each.rs | 2 +- src/test/compile-fail/issue-2151.rs | 7 +- src/test/compile-fail/liveness-issue-2163.rs | 2 +- src/test/run-pass/assignability-trait.rs | 6 +- src/test/run-pass/auto-loop.rs | 5 +- src/test/run-pass/block-arg.rs | 2 +- .../run-pass/borrowck-mut-vec-as-imm-slice.rs | 6 +- src/test/run-pass/break.rs | 6 +- src/test/run-pass/const-vec-of-fns.rs | 4 +- src/test/run-pass/for-destruct.rs | 3 +- src/test/run-pass/rcvr-borrowed-to-slice.rs | 2 +- src/test/run-pass/trait-generic.rs | 5 +- 43 files changed, 139 insertions(+), 223 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 9c61a04930ace..9e54622688b04 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1552,13 +1552,6 @@ fn each(v: &[int], op: &fn(v: &int)) { } ~~~~ -As an aside, the reason we pass in a *pointer* to an integer rather -than the integer itself is that this is how the actual `each()` -function for vectors works. `vec::each` though is a -[generic](#generics) function, so must be efficient to use for all -types. Passing the elements by pointer avoids copying potentially -large objects. - As a caller, if we use a closure to provide the final operator argument, we can write it in a way that has a pleasant, block-like structure. @@ -1616,6 +1609,9 @@ To enable `debug!` logging, set the RUST_LOG environment variable to the name of ## For loops +> ***Note:*** The closure-based protocol used `for` loop is on the way out. The `for` loop will +> use iterator objects in the future instead. + The most common way to express iteration in Rust is with a `for` loop. Like `do`, `for` is a nice syntax for describing control flow with closures. Additionally, within a `for` loop, `break`, `loop`, @@ -1640,7 +1636,16 @@ fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { And using this function to iterate over a vector: ~~~~ -# use each = std::vec::each; +# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { +# let mut n = 0; +# while n < v.len() { +# if !op(&v[n]) { +# return false; +# } +# n += 1; +# } +# return true; +# } each([2, 4, 8, 5, 16], |n| { if *n % 2 != 0 { println("found odd number!"); @@ -1656,7 +1661,16 @@ out of the loop, you just write `break`. To skip ahead to the next iteration, write `loop`. ~~~~ -# use each = std::vec::each; +# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { +# let mut n = 0; +# while n < v.len() { +# if !op(&v[n]) { +# return false; +# } +# n += 1; +# } +# return true; +# } for each([2, 4, 8, 5, 16]) |n| { if *n % 2 != 0 { println("found odd number!"); @@ -1671,7 +1685,16 @@ normally allowed in closures, in a block that appears as the body of a the enclosing function, not just the loop body. ~~~~ -# use each = std::vec::each; +# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { +# let mut n = 0; +# while n < v.len() { +# if !op(&v[n]) { +# return false; +# } +# n += 1; +# } +# return true; +# } fn contains(v: &[int], elt: int) -> bool { for each(v) |x| { if (*x == elt) { return true; } @@ -1686,7 +1709,16 @@ In these situations it can be convenient to lean on Rust's argument patterns to bind `x` to the actual value, not the pointer. ~~~~ -# use each = std::vec::each; +# fn each(v: &[int], op: &fn(v: &int) -> bool) -> bool { +# let mut n = 0; +# while n < v.len() { +# if !op(&v[n]) { +# return false; +# } +# n += 1; +# } +# return true; +# } # fn contains(v: &[int], elt: int) -> bool { for each(v) |&x| { if (x == elt) { return true; } @@ -1841,10 +1873,9 @@ vector consisting of the result of applying `function` to each element of `vector`: ~~~~ -# use std::vec; fn map(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] { let mut accumulator = ~[]; - for vec::each(vector) |element| { + for vector.iter().advance |element| { accumulator.push(function(element)); } return accumulator; diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index fd56031ccf942..3e2f484ee53d4 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -529,7 +529,7 @@ fn compose_and_run_compiler( let extra_link_args = ~[~"-L", aux_output_dir_name(config, testfile).to_str()]; - for vec::each(props.aux_builds) |rel_ab| { + for props.aux_builds.iter().advance |rel_ab| { let abs_ab = config.aux_base.push_rel(&Path(*rel_ab)); let aux_args = make_compile_args(config, props, ~[~"--lib"] + extra_link_args, diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs index 32114f4037ecc..c5fe07f21875b 100644 --- a/src/libextra/arc.rs +++ b/src/libextra/arc.rs @@ -521,6 +521,7 @@ mod tests { use core::cell::Cell; use core::comm; use core::task; + use core::uint; #[test] fn manually_share_arc() { @@ -790,18 +791,20 @@ mod tests { } assert_eq!(*state, 42); *state = 31337; + // FIXME: #7372: hits type inference bug with iterators // send to other readers - for vec::each(reader_convos) |x| { - match *x { + for uint::range(0, reader_convos.len()) |i| { + match reader_convos[i] { (ref rc, _) => rc.send(()), } } } let read_mode = arc.downgrade(write_mode); do (&read_mode).read |state| { + // FIXME: #7372: hits type inference bug with iterators // complete handshake with other readers - for vec::each(reader_convos) |x| { - match *x { + for uint::range(0, reader_convos.len()) |i| { + match reader_convos[i] { (_, ref rp) => rp.recv(), } } diff --git a/src/libextra/getopts.rs b/src/libextra/getopts.rs index d97804722f259..9c416550eb787 100644 --- a/src/libextra/getopts.rs +++ b/src/libextra/getopts.rs @@ -418,10 +418,11 @@ pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str { */ pub fn opt_strs(mm: &Matches, nm: &str) -> ~[~str] { let mut acc: ~[~str] = ~[]; - for vec::each(opt_vals(mm, nm)) |v| { + let r = opt_vals(mm, nm); + for r.iter().advance |v| { match *v { Val(ref s) => acc.push(copy *s), _ => () } } - return acc; + acc } /// Returns the string argument supplied to a matching option or none diff --git a/src/libextra/json.rs b/src/libextra/json.rs index 24c4c5b27c49f..15553b035f65e 100644 --- a/src/libextra/json.rs +++ b/src/libextra/json.rs @@ -1123,7 +1123,7 @@ impl Eq for Json { &Object(ref d1) => { if d0.len() == d1.len() { let mut equal = true; - for d0.each |k, v0| { + for d0.iter().advance |(k, v0)| { match d1.find(k) { Some(v1) if v0 == v1 => { }, _ => { equal = false; break } @@ -1186,12 +1186,12 @@ impl Ord for Json { let mut d1_flat = ~[]; // FIXME #4430: this is horribly inefficient... - for d0.each |k, v| { + for d0.iter().advance |(k, v)| { d0_flat.push((@copy *k, @copy *v)); } d0_flat.qsort(); - for d1.each |k, v| { + for d1.iter().advance |(k, v)| { d1_flat.push((@copy *k, @copy *v)); } d1_flat.qsort(); @@ -1326,7 +1326,7 @@ impl ToJson for ~[A] { impl ToJson for HashMap<~str, A> { fn to_json(&self) -> Json { let mut d = HashMap::new(); - for self.each |key, value| { + for self.iter().advance |(key, value)| { d.insert(copy *key, value.to_json()); } Object(~d) diff --git a/src/libextra/net_url.rs b/src/libextra/net_url.rs index dda4b85df4bf7..5d3d31fdec47e 100644 --- a/src/libextra/net_url.rs +++ b/src/libextra/net_url.rs @@ -207,7 +207,7 @@ pub fn encode_form_urlencoded(m: &HashMap<~str, ~[~str]>) -> ~str { let mut out = ~""; let mut first = true; - for m.each |key, values| { + for m.iter().advance |(key, values)| { let key = encode_plus(*key); for values.iter().advance |value| { diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs index 34fd7e9f1ec12..345b217871cc5 100644 --- a/src/libextra/serialize.rs +++ b/src/libextra/serialize.rs @@ -710,7 +710,7 @@ impl< fn encode(&self, e: &mut E) { do e.emit_map(self.len()) |e| { let mut i = 0; - for self.each |key, val| { + for self.iter().advance |(key, val)| { e.emit_map_elt_key(i, |e| key.encode(e)); e.emit_map_elt_val(i, |e| val.encode(e)); i += 1; @@ -744,7 +744,7 @@ impl< fn encode(&self, s: &mut S) { do s.emit_seq(self.len()) |s| { let mut i = 0; - for self.each |e| { + for self.iter().advance |e| { s.emit_seq_elt(i, |s| e.encode(s)); i += 1; } diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 6990d35f06132..5cb52a7b9dfb4 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -1094,7 +1094,8 @@ mod tests { }; assert!(result.is_err()); // child task must have finished by the time try returns - for vec::each(p.recv()) |p| { p.recv(); } // wait on all its siblings + let r = p.recv(); + for r.iter().advance |p| { p.recv(); } // wait on all its siblings do m.lock_cond |cond| { let woken = cond.broadcast(); assert_eq!(woken, 0); diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index ed675bf99e9dd..a014293f0630d 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -146,7 +146,7 @@ impl WorkMap { impl Encodable for WorkMap { fn encode(&self, s: &mut S) { let mut d = ~[]; - for self.each |k, v| { + for self.iter().advance |(k, v)| { d.push((copy *k, copy *v)) } sort::tim_sort(d); @@ -320,7 +320,7 @@ impl TPrep for Prep { } fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool { - for map.each |k, v| { + for map.iter().advance |(k, v)| { if ! self.is_fresh(cat, k.kind, k.name, *v) { return false; } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index c6c1ac720e8e0..b0a955fef8f7f 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -86,7 +86,7 @@ pub fn have_crate_data(cstore: &CStore, cnum: ast::crate_num) -> bool { pub fn iter_crate_data(cstore: &CStore, i: &fn(ast::crate_num, @crate_metadata)) { - for cstore.metas.each |&k, &v| { + for cstore.metas.iter().advance |(&k, &v)| { i(k, v); } } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index 7f7a81fa974a6..b0b2a16cf8939 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -240,7 +240,8 @@ fn check_fn( // Check kinds on free variables: do with_appropriate_checker(cx, fn_id) |chk| { - for vec::each(*freevars::get_freevars(cx.tcx, fn_id)) |fv| { + let r = freevars::get_freevars(cx.tcx, fn_id); + for r.iter().advance |fv| { chk(cx, *fv); } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index d73b019c1ea76..9d4064e99bdb1 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -436,7 +436,7 @@ impl LanguageItemCollector { } pub fn check_completeness(&self) { - for self.item_refs.each |&key, &item_ref| { + for self.item_refs.iter().advance |(&key, &item_ref)| { match self.items.items[item_ref] { None => { self.session.err(fmt!("no item found for `%s`", key)); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 5c36ab7750c8c..6da10b7c27749 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -361,7 +361,7 @@ impl Context { } fn lint_to_str(&self, lint: lint) -> &'static str { - for self.dict.each |k, v| { + for self.dict.iter().advance |(k, v)| { if v.lint == lint { return *k; } @@ -742,7 +742,8 @@ fn check_item_ctypes(cx: &Context, it: @ast::item) { fn check_foreign_fn(cx: &Context, decl: &ast::fn_decl) { let tys = vec::map(decl.inputs, |a| a.ty ); - for vec::each(vec::append_one(tys, decl.output)) |ty| { + let r = vec::append_one(tys, decl.output); + for r.iter().advance |ty| { check_ty(cx, *ty); } } @@ -1171,7 +1172,7 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::crate) { // If we missed any lints added to the session, then there's a bug somewhere // in the iteration code. - for tcx.sess.lints.each |_, v| { + for tcx.sess.lints.iter().advance |(_, v)| { for v.iter().advance |t| { match *t { (lint, span, ref msg) => diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 0e6d8617ba424..7d3e895a0edd5 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -948,7 +948,7 @@ pub fn determine_rp_in_crate(sess: Session, debug!("%s", { debug!("Region variance results:"); let region_paramd_items = cx.region_paramd_items; - for region_paramd_items.each |&key, &value| { + for region_paramd_items.iter().advance |(&key, &value)| { debug!("item %? (%s) is parameterized with variance %?", key, ast_map::node_id_to_str(ast_map, key, diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 3a54c224b5236..096ab71e42466 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1386,7 +1386,7 @@ impl Resolver { } let def_id = local_def(item.id); - for method_names.each |name, _| { + for method_names.iter().advance |(name, _)| { if !self.method_map.contains_key(name) { self.method_map.insert(*name, HashSet::new()); } @@ -1704,7 +1704,7 @@ impl Resolver { interned_method_names.insert(method_name); } } - for interned_method_names.each |name| { + for interned_method_names.iter().advance |name| { if !self.method_map.contains_key(name) { self.method_map.insert(*name, HashSet::new()); } @@ -2470,8 +2470,8 @@ impl Resolver { assert_eq!(containing_module.glob_count, 0); // Add all resolved imports from the containing module. - for containing_module.import_resolutions.each - |ident, target_import_resolution| { + for containing_module.import_resolutions.iter().advance + |(ident, target_import_resolution)| { debug!("(resolving glob import) writing module resolution \ %? into `%s`", @@ -2555,13 +2555,13 @@ impl Resolver { }; // Add all children from the containing module. - for containing_module.children.each |&ident, name_bindings| { + for containing_module.children.iter().advance |(&ident, name_bindings)| { merge_import_resolution(ident, *name_bindings); } // Add external module children from the containing module. - for containing_module.external_module_children.each - |&ident, module| { + for containing_module.external_module_children.iter().advance + |(&ident, module)| { let name_bindings = @mut Resolver::create_name_bindings_from_module(*module); merge_import_resolution(ident, name_bindings); @@ -3251,7 +3251,7 @@ impl Resolver { pub fn add_exports_for_module(@mut self, exports2: &mut ~[Export2], module_: @mut Module) { - for module_.children.each |ident, namebindings| { + for module_.children.iter().advance |(ident, namebindings)| { debug!("(computing exports) maybe export '%s'", self.session.str_of(*ident)); self.add_exports_of_namebindings(&mut *exports2, @@ -3266,7 +3266,7 @@ impl Resolver { false); } - for module_.import_resolutions.each |ident, importresolution| { + for module_.import_resolutions.iter().advance |(ident, importresolution)| { if importresolution.privacy != Public { debug!("(computing exports) not reexporting private `%s`", self.session.str_of(*ident)); @@ -4039,7 +4039,7 @@ impl Resolver { for arm.pats.iter().enumerate().advance |(i, p)| { let map_i = self.binding_mode_map(*p); - for map_0.each |&key, &binding_0| { + for map_0.iter().advance |(&key, &binding_0)| { match map_i.find(&key) { None => { self.session.span_err( @@ -4060,7 +4060,7 @@ impl Resolver { } } - for map_i.each |&key, &binding| { + for map_i.iter().advance |(&key, &binding)| { if !map_0.contains_key(&key) { self.session.span_err( binding.span, @@ -5355,7 +5355,7 @@ impl Resolver { } debug!("Import resolutions:"); - for module_.import_resolutions.each |name, import_resolution| { + for module_.import_resolutions.iter().advance |(name, import_resolution)| { let value_repr; match import_resolution.target_for_namespace(ValueNS) { None => { value_repr = ~""; } diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 71b416ffe85ff..63b39b8fe763e 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1673,7 +1673,7 @@ pub fn trans_match_inner(scope_cx: block, let mut arm_datas = ~[]; let mut matches = ~[]; - for vec::each(arms) |arm| { + for arms.iter().advance |arm| { let body = scope_block(bcx, arm.body.info(), "case_body"); let bindings_map = create_bindings_map(bcx, arm.pats[0]); let arm_data = @ArmData {bodycx: body, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 0e322c187af2b..5bf0e596ca051 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2945,7 +2945,7 @@ pub fn trans_crate(sess: session::Session, } if ccx.sess.count_llvm_insns() { - for ccx.stats.llvm_insns.each |&k, &v| { + for ccx.stats.llvm_insns.iter().advance |(&k, &v)| { io::println(fmt!("%-7u %s", v, k)); } } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 593d0beb88c76..cb47555063843 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -704,11 +704,11 @@ pub fn trans_args(cx: block, // now that all arguments have been successfully built, we can revoke any // temporary cleanups, as they are only needed if argument construction // should fail (for example, cleanup of copy mode args). - for vec::each(temp_cleanups) |c| { + for temp_cleanups.iter().advance |c| { revoke_clean(bcx, *c) } - return bcx; + bcx } pub enum AutorefArg { diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index f2446d1a11536..8cd776c99d697 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -213,7 +213,8 @@ pub fn type_needs_inner(cx: Context, ty::ty_enum(did, ref substs) => { if list::find(enums_seen, |id| *id == did).is_none() { let seen = @Cons(did, enums_seen); - for vec::each(*ty::enum_variants(cx.ccx.tcx, did)) |v| { + let r = ty::enum_variants(cx.ccx.tcx, did); + for r.iter().advance |v| { for v.args.iter().advance |aty| { let t = ty::subst(cx.ccx.tcx, &(*substs), *aty); type_needs_inner(cx, use_, t, seen); diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index d9add22479cce..0aad161a6788f 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -1285,7 +1285,7 @@ impl RegionVarBindings { // It would be nice to write this using map(): let mut edges = vec::with_capacity(num_edges); - for self.constraints.each |constraint, span| { + for self.constraints.iter().advance |(constraint, span)| { edges.push(GraphEdge { next_edge: [uint::max_value, uint::max_value], constraint: *constraint, diff --git a/src/librustc/rustc.rs b/src/librustc/rustc.rs index 20705b3d79750..ca49d143d4809 100644 --- a/src/librustc/rustc.rs +++ b/src/librustc/rustc.rs @@ -166,7 +166,7 @@ Available lint options: padded(max_key, "name"), "default", "meaning")); io::println(fmt!(" %s %7.7s %s\n", padded(max_key, "----"), "-------", "-------")); - for lint_dict.each |k, v| { + for lint_dict.iter().advance |(k, v)| { let k = k.replace("_", "-"); io::println(fmt!(" %s %7.7s %s", padded(max_key, k), diff --git a/src/librusti/program.rs b/src/librusti/program.rs index 91fde3e21ae0b..f17777559deb5 100644 --- a/src/librusti/program.rs +++ b/src/librusti/program.rs @@ -96,7 +96,7 @@ impl Program { code.push_str("fn main() {\n"); // It's easy to initialize things if we don't run things... - for self.local_vars.each |name, var| { + for self.local_vars.iter().advance |(name, var)| { let mt = var.mt(); code.push_str(fmt!("let%s %s: %s = fail!();\n", mt, *name, var.ty)); var.alter(*name, &mut code); @@ -149,7 +149,7 @@ impl Program { // Using this __tls_map handle, deserialize each variable binding that // we know about - for self.local_vars.each |name, var| { + for self.local_vars.iter().advance |(name, var)| { let mt = var.mt(); code.push_str(fmt!("let%s %s: %s = { let data = __tls_map.get_copy(&~\"%s\"); @@ -175,7 +175,7 @@ impl Program { // After the input code is run, we can re-serialize everything back out // into tls map (to be read later on by this task) - for self.local_vars.each |name, var| { + for self.local_vars.iter().advance |(name, var)| { code.push_str(fmt!("{ let local: %s = %s; let bytes = do ::std::io::with_bytes_writer |io| { @@ -237,7 +237,7 @@ impl Program { /// program starts pub fn set_cache(&self) { let map = @mut HashMap::new(); - for self.local_vars.each |name, value| { + for self.local_vars.iter().advance |(name, value)| { map.insert(copy *name, @copy value.data); } unsafe { diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 962025915d24c..bfa0f2fa124d2 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -488,11 +488,6 @@ impl HashMap { } } - /// Visit all key-value pairs - pub fn each<'a>(&'a self, blk: &fn(&K, &'a V) -> bool) -> bool { - self.iter().advance(|(k, v)| blk(k, v)) - } - /// Visit all keys pub fn each_key(&self, blk: &fn(k: &K) -> bool) -> bool { self.iter().advance(|(k, _)| blk(k)) @@ -718,12 +713,6 @@ impl HashSet { self.map.contains_key_equiv(value) } - /// Visit all elements in arbitrary order - /// FIXME: #6978: Remove when all callers are converted - pub fn each(&self, f: &fn(&T) -> bool) -> bool { - self.iter().advance(f) - } - /// An iterator visiting all elements in arbitrary order. /// Iterator element type is &'a T. pub fn iter<'a>(&'a self) -> HashSetIterator<'a, T> { diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 77053f3967793..04c0dd79deda9 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -111,7 +111,7 @@ fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) { assert!(was_present); } pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) -> bool { - tasks.each(|k| blk(*k)) + tasks.iter().advance(|k| blk(*k)) } // One of these per group of linked-failure tasks. diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 72b583078496f..2e18a588fae31 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -444,7 +444,7 @@ pub fn partitioned(v: &[T], f: &fn(&T) -> bool) -> (~[T], ~[T]) { let mut lefts = ~[]; let mut rights = ~[]; - for each(v) |elt| { + for v.iter().advance |elt| { if f(elt) { lefts.push(copy *elt); } else { @@ -850,7 +850,7 @@ pub fn grow_set(v: &mut ~[T], index: uint, initval: &T, val: T) { /// Apply a function to each element of a vector and return the results pub fn map(v: &[T], f: &fn(t: &T) -> U) -> ~[U] { let mut result = with_capacity(v.len()); - for each(v) |elem| { + for v.iter().advance |elem| { result.push(f(elem)); } result @@ -886,7 +886,7 @@ pub fn mapi(v: &[T], f: &fn(uint, t: &T) -> U) -> ~[U] { */ pub fn flat_map(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] { let mut result = ~[]; - for each(v) |elem| { result.push_all_move(f(elem)); } + for v.iter().advance |elem| { result.push_all_move(f(elem)); } result } @@ -939,7 +939,7 @@ pub fn filter_mapped( */ let mut result = ~[]; - for each(v) |elem| { + for v.iter().advance |elem| { match f(elem) { None => {/* no-op */ } Some(result_elem) => { result.push(result_elem); } @@ -974,7 +974,7 @@ pub fn filter(v: ~[T], f: &fn(t: &T) -> bool) -> ~[T] { */ pub fn filtered(v: &[T], f: &fn(t: &T) -> bool) -> ~[T] { let mut result = ~[]; - for each(v) |elem| { + for v.iter().advance |elem| { if f(elem) { result.push(copy *elem); } } result @@ -1058,7 +1058,7 @@ impl<'self, T:Copy> VectorVector for &'self [&'self [T]] { /// Return true if a vector contains an element with the given value pub fn contains(v: &[T], x: &T) -> bool { - for each(v) |elt| { if *x == *elt { return true; } } + for v.iter().advance |elt| { if *x == *elt { return true; } } false } @@ -1209,7 +1209,7 @@ pub fn bsearch_elem(v: &[T], x: &T) -> Option { */ pub fn unzip_slice(v: &[(T, U)]) -> (~[T], ~[U]) { let mut (ts, us) = (~[], ~[]); - for each(v) |p| { + for v.iter().advance |p| { let (t, u) = copy *p; ts.push(t); us.push(u); @@ -1347,69 +1347,6 @@ pub fn reversed(v: &const [T]) -> ~[T] { rs } -/** - * Iterates over a vector, yielding each element to a closure. - * - * # Arguments - * - * * `v` - A vector, to be iterated over - * * `f` - A closure to do the iterating. Within this closure, return true to - * * continue iterating, false to break. - * - * # Examples - * - * ~~~ {.rust} - * [1,2,3].each(|&i| { - * io::println(int::str(i)); - * true - * }); - * ~~~ - * - * ~~~ {.rust} - * [1,2,3,4,5].each(|&i| { - * if i < 4 { - * io::println(int::str(i)); - * true - * } - * else { - * false - * } - * }); - * ~~~ - * - * You probably will want to use each with a `for`/`do` expression, depending - * on your iteration needs: - * - * ~~~ {.rust} - * for [1,2,3].each |&i| { - * io::println(int::str(i)); - * } - * ~~~ - */ -#[inline] -pub fn each<'r,T>(v: &'r [T], f: &fn(&'r T) -> bool) -> bool { - // ^^^^ - // NB---this CANNOT be &const [T]! The reason - // is that you are passing it to `f()` using - // an immutable. - - let mut broke = false; - do as_imm_buf(v) |p, n| { - let mut n = n; - let mut p = p; - while n > 0u { - unsafe { - let q = cast::copy_lifetime_vec(v, &*p); - if !f(q) { break; } - p = ptr::offset(p, 1u); - } - n -= 1u; - } - broke = n > 0; - } - return !broke; -} - /** * Iterate over all permutations of vector `v`. * @@ -3069,36 +3006,6 @@ mod tests { assert_eq!(v, ~[1, 3, 5]); } - #[test] - fn test_each_empty() { - for each::([]) |_v| { - fail!(); // should never be executed - } - } - - #[test] - fn test_each_nonempty() { - let mut i = 0; - for each([1, 2, 3]) |v| { - i += *v; - } - assert_eq!(i, 6); - } - - #[test] - fn test_each_ret_len0() { - let a0 : [int, .. 0] = []; - assert_eq!(each(a0, |_p| fail!()), true); - } - - #[test] - fn test_each_ret_len1() { - let a1 = [17]; - assert_eq!(each(a1, |_p| true), true); - assert_eq!(each(a1, |_p| false), false); - } - - #[test] fn test_each_permutation() { let mut results: ~[~[int]]; @@ -3854,21 +3761,6 @@ mod tests { }; } - #[test] - #[ignore(windows)] - #[should_fail] - fn test_each_fail() { - let v = [(~0, @0), (~0, @0), (~0, @0), (~0, @0)]; - let mut i = 0; - do each(v) |_elt| { - if i == 2 { - fail!() - } - i += 0; - false - }; - } - #[test] #[ignore(windows)] #[should_fail] diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs index 14aa65219cd28..d21888f12ec67 100644 --- a/src/test/bench/graph500-bfs.rs +++ b/src/test/bench/graph500-bfs.rs @@ -86,7 +86,7 @@ fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph { HashSet::new() }; - for vec::each(edges) |e| { + for edges.iter().advance |e| { match *e { (i, j) => { graph[i].insert(j); @@ -441,7 +441,7 @@ fn main() { let stop = time::precise_time_s(); let mut total_edges = 0; - vec::each(graph, |edges| { total_edges += edges.len(); true }); + for graph.iter().advance |edges| { total_edges += edges.len(); } io::stdout().write_line(fmt!("Generated graph with %? edges in %? seconds.", total_edges / 2, diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs index 7a9be75488494..102f7f1706592 100644 --- a/src/test/bench/msgsend-pipes-shared.rs +++ b/src/test/bench/msgsend-pipes-shared.rs @@ -83,7 +83,7 @@ fn run(args: &[~str]) { server(&from_parent, &to_parent); } - for vec::each(worker_results) |r| { + for worker_results.iter().advance |r| { r.recv(); } diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs index 796072c848587..b8d91bb93e2e3 100644 --- a/src/test/bench/msgsend-pipes.rs +++ b/src/test/bench/msgsend-pipes.rs @@ -79,7 +79,7 @@ fn run(args: &[~str]) { server(&from_parent, &to_parent); } - for vec::each(worker_results) |r| { + for worker_results.iter().advance |r| { r.recv(); } diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index 3ff123b027ab9..96c7e4e9b375b 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -188,7 +188,7 @@ fn rendezvous(nn: uint, set: ~[color]) { // save each creature's meeting stats let mut report = ~[]; - for vec::each(to_creature) |_to_one| { + for to_creature.iter().advance |_to_one| { report.push(from_creatures_log.recv()); } @@ -196,7 +196,7 @@ fn rendezvous(nn: uint, set: ~[color]) { io::println(show_color_list(set)); // print each creature's stats - for vec::each(report) |rep| { + for report.iter().advance |rep| { io::println(*rep); } diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index c33c2258864fa..20042aa0e918a 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -56,7 +56,7 @@ fn sort_and_fmt(mm: &HashMap<~[u8], uint>, total: uint) -> ~str { let mut pairs = ~[]; // map -> [(k,%)] - for mm.each |&key, &val| { + for mm.iter().advance |(&key, &val)| { pairs.push((key, pct(val, total))); } diff --git a/src/test/compile-fail/block-must-not-have-result-for.rs b/src/test/compile-fail/block-must-not-have-result-for.rs index 778309122cba1..1aa05a9477de9 100644 --- a/src/test/compile-fail/block-must-not-have-result-for.rs +++ b/src/test/compile-fail/block-must-not-have-result-for.rs @@ -8,10 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::vec; - fn main() { - for vec::each(~[0]) |_i| { //~ ERROR A for-loop body must return (), but + for 2.times { //~ ERROR A for-loop body must return (), but true } } diff --git a/src/test/compile-fail/borrowck-insert-during-each.rs b/src/test/compile-fail/borrowck-insert-during-each.rs index 1a0bec7d723b3..189a0ef9d700b 100644 --- a/src/test/compile-fail/borrowck-insert-during-each.rs +++ b/src/test/compile-fail/borrowck-insert-during-each.rs @@ -16,7 +16,7 @@ struct Foo { impl Foo { pub fn foo(&mut self, fun: &fn(&int)) { - for self.n.each |f| { + for self.n.iter().advance |f| { fun(f); } } diff --git a/src/test/compile-fail/issue-2151.rs b/src/test/compile-fail/issue-2151.rs index 8f4bbe4eabc74..5559ba344ed17 100644 --- a/src/test/compile-fail/issue-2151.rs +++ b/src/test/compile-fail/issue-2151.rs @@ -8,10 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::vec; - fn main() { - for vec::each(fail!()) |i| { - let _ = i * 2; //~ ERROR the type of this value must be known - }; + let x = fail!(); + x.clone(); //~ ERROR the type of this value must be known in this context } diff --git a/src/test/compile-fail/liveness-issue-2163.rs b/src/test/compile-fail/liveness-issue-2163.rs index ec4f3f9a3fdba..fbb6d03b22002 100644 --- a/src/test/compile-fail/liveness-issue-2163.rs +++ b/src/test/compile-fail/liveness-issue-2163.rs @@ -12,7 +12,7 @@ use std::vec; fn main() { let a: ~[int] = ~[]; - vec::each(a, |_| -> bool { + a.iter().advance(|_| -> bool { //~^ ERROR mismatched types }); } diff --git a/src/test/run-pass/assignability-trait.rs b/src/test/run-pass/assignability-trait.rs index 5d2341ae42d3f..b65b18e1ab3af 100644 --- a/src/test/run-pass/assignability-trait.rs +++ b/src/test/run-pass/assignability-trait.rs @@ -12,21 +12,19 @@ // making method calls, but only if there aren't any matches without // it. -use std::vec; - trait iterable { fn iterate(&self, blk: &fn(x: &A) -> bool) -> bool; } impl<'self,A> iterable for &'self [A] { fn iterate(&self, f: &fn(x: &A) -> bool) -> bool { - vec::each(*self, f) + self.iter().advance(f) } } impl iterable for ~[A] { fn iterate(&self, f: &fn(x: &A) -> bool) -> bool { - vec::each(*self, f) + self.iter().advance(f) } } diff --git a/src/test/run-pass/auto-loop.rs b/src/test/run-pass/auto-loop.rs index f148c509d4d0f..185a5a6407c7d 100644 --- a/src/test/run-pass/auto-loop.rs +++ b/src/test/run-pass/auto-loop.rs @@ -8,11 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::vec; - pub fn main() { let mut sum = 0; - for vec::each(~[1, 2, 3, 4, 5]) |x| { + let xs = ~[1, 2, 3, 4, 5]; + for xs.iter().advance |x| { sum += *x; } assert_eq!(sum, 15); diff --git a/src/test/run-pass/block-arg.rs b/src/test/run-pass/block-arg.rs index d860c84dfcec1..ff5d0e9f05c65 100644 --- a/src/test/run-pass/block-arg.rs +++ b/src/test/run-pass/block-arg.rs @@ -15,7 +15,7 @@ pub fn main() { let v = ~[-1f, 0f, 1f, 2f, 3f]; // Statement form does not require parentheses: - for vec::each(v) |i| { + for v.iter().advance |i| { info!("%?", *i); } diff --git a/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs b/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs index d63ebf7d24d41..8f74e6cdc299f 100644 --- a/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs +++ b/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs @@ -8,12 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::vec; - fn want_slice(v: &[int]) -> int { let mut sum = 0; - for vec::each(v) |i| { sum += *i; } - return sum; + for v.iter().advance |i| { sum += *i; } + sum } fn has_mut_vec(v: ~[int]) -> int { diff --git a/src/test/run-pass/break.rs b/src/test/run-pass/break.rs index 2edb270762cc3..85c6f90a742be 100644 --- a/src/test/run-pass/break.rs +++ b/src/test/run-pass/break.rs @@ -16,7 +16,8 @@ pub fn main() { assert_eq!(i, 10); loop { i += 1; if i == 20 { break; } } assert_eq!(i, 20); - for vec::each(~[1, 2, 3, 4, 5, 6]) |x| { + let xs = [1, 2, 3, 4, 5, 6]; + for xs.iter().advance |x| { if *x == 3 { break; } assert!((*x <= 3)); } i = 0; @@ -26,7 +27,8 @@ pub fn main() { i += 1; if i % 2 == 0 { loop; } assert!((i % 2 != 0)); if i >= 10 { break; } } - for vec::each(~[1, 2, 3, 4, 5, 6]) |x| { + let ys = ~[1, 2, 3, 4, 5, 6]; + for ys.iter().advance |x| { if *x % 2 == 0 { loop; } assert!((*x % 2 != 0)); } diff --git a/src/test/run-pass/const-vec-of-fns.rs b/src/test/run-pass/const-vec-of-fns.rs index 9fc68cd112751..a87d8f30e3ac3 100644 --- a/src/test/run-pass/const-vec-of-fns.rs +++ b/src/test/run-pass/const-vec-of-fns.rs @@ -23,6 +23,6 @@ struct S<'self>(&'self fn()); static closures: &'static [S<'static>] = &[S(f), S(f)]; pub fn main() { - for std::vec::each(bare_fns) |&bare_fn| { bare_fn() } - for std::vec::each(closures) |&closure| { (*closure)() } + for bare_fns.iter().advance |&bare_fn| { bare_fn() } + for closures.iter().advance |&closure| { (*closure)() } } diff --git a/src/test/run-pass/for-destruct.rs b/src/test/run-pass/for-destruct.rs index 4926dbd008670..dd1cda22e6538 100644 --- a/src/test/run-pass/for-destruct.rs +++ b/src/test/run-pass/for-destruct.rs @@ -8,10 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// xfail-test: #3511: does not currently compile, due to rvalue issues + use std::vec; struct Pair { x: int, y: int } - pub fn main() { for vec::each(~[Pair {x: 10, y: 20}, Pair {x: 30, y: 0}]) |elt| { assert_eq!(elt.x + elt.y, 30); diff --git a/src/test/run-pass/rcvr-borrowed-to-slice.rs b/src/test/run-pass/rcvr-borrowed-to-slice.rs index 5eaf12f6a5182..b62475ded54fe 100644 --- a/src/test/run-pass/rcvr-borrowed-to-slice.rs +++ b/src/test/run-pass/rcvr-borrowed-to-slice.rs @@ -18,7 +18,7 @@ trait sum { impl<'self> sum for &'self [int] { fn sum(self) -> int { let mut sum = 0; - for vec::each(self) |e| { sum += *e; } + for self.iter().advance |e| { sum += *e; } return sum; } } diff --git a/src/test/run-pass/trait-generic.rs b/src/test/run-pass/trait-generic.rs index c25cdc85cb6ae..dc6bdbf5c1a5c 100644 --- a/src/test/run-pass/trait-generic.rs +++ b/src/test/run-pass/trait-generic.rs @@ -31,7 +31,10 @@ trait map { impl map for ~[T] { fn map(&self, f: &fn(&T) -> U) -> ~[U] { let mut r = ~[]; - for std::vec::each(*self) |x| { r += ~[f(x)]; } + // FIXME: #7355 generates bad code with Iterator + for std::uint::range(0, self.len()) |i| { + r += ~[f(&self[i])]; + } r } } From e44e33dfa999f4e3ce0b1811bc2ccdd5907b4a42 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Tue, 25 Jun 2013 16:31:17 -0400 Subject: [PATCH 4/4] xfail test hitting a codegen bug (issue #7385) --- src/test/run-pass/const-vec-of-fns.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/run-pass/const-vec-of-fns.rs b/src/test/run-pass/const-vec-of-fns.rs index a87d8f30e3ac3..45302363c380c 100644 --- a/src/test/run-pass/const-vec-of-fns.rs +++ b/src/test/run-pass/const-vec-of-fns.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// xfail-fast +// xfail-test +// FIXME: #7385: hits a codegen bug on OS X x86_64 /*! * Try to double-check that static fns have the right size (with or