about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMs2ger <ms2ger@gmail.com>2015-05-24 12:23:29 +0200
committerMs2ger <ms2ger@gmail.com>2015-05-24 17:30:42 +0200
commit37dd4174d56431e97adf06ecaf6395376ab2ebbc (patch)
tree388a68cd43ef6dd5664b07e599de0a68704385dc
parent8e039a887df4265e9f20b2a29f12d6708965cc63 (diff)
downloadrust-37dd4174d56431e97adf06ecaf6395376ab2ebbc.tar.gz
rust-37dd4174d56431e97adf06ecaf6395376ab2ebbc.zip
Return TaggedDocsIterator from reader::tagged_docs.
-rw-r--r--src/librbml/lib.rs8
-rw-r--r--src/librustc/metadata/decoder.rs403
2 files changed, 155 insertions, 256 deletions
diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs
index 0ee322b06c1..41ae0f2d5e2 100644
--- a/src/librbml/lib.rs
+++ b/src/librbml/lib.rs
@@ -436,13 +436,11 @@ pub mod reader {
         }
     }
 
-    pub fn tagged_docs<F>(d: Doc, tg: usize, it: F) -> bool where
-        F: FnMut(Doc) -> bool,
-    {
+    pub fn tagged_docs<'a>(d: Doc<'a>, tag: usize) -> TaggedDocsIterator<'a> {
         TaggedDocsIterator {
             iter: docs(d),
-            tag: tg,
-        }.all(it)
+            tag: tag,
+        }
     }
 
     pub struct TaggedDocsIterator<'a> {
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index ee5fd0202d6..13cee09b472 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -77,19 +77,12 @@ fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option<rbml:
     let pos = u32_from_be_bytes(&d.data[hash_pos..]) as usize;
     let tagged_doc = reader::doc_at(d.data, pos).unwrap();
 
-    let belt = tag_index_buckets_bucket_elt;
-
-    let mut ret = None;
-    reader::tagged_docs(tagged_doc.doc, belt, |elt| {
+    reader::tagged_docs(tagged_doc.doc, tag_index_buckets_bucket_elt).find(|elt| {
+        eq_fn(&elt.data[elt.start + 4 .. elt.end])
+    }).map(|elt| {
         let pos = u32_from_be_bytes(&elt.data[elt.start..]) as usize;
-        if eq_fn(&elt.data[elt.start + 4 .. elt.end]) {
-            ret = Some(reader::doc_at(d.data, pos).unwrap().doc);
-            false
-        } else {
-            true
-        }
-    });
-    ret
+        reader::doc_at(d.data, pos).unwrap().doc
+    })
 }
 
 pub fn maybe_find_item<'a>(item_id: ast::NodeId,
@@ -192,12 +185,9 @@ fn fn_constness(item: rbml::Doc) -> ast::Constness {
 }
 
 fn item_sort(item: rbml::Doc) -> Option<char> {
-    let mut ret = None;
-    reader::tagged_docs(item, tag_item_trait_item_sort, |doc| {
-        ret = Some(doc.as_str_slice().as_bytes()[0] as char);
-        false
-    });
-    ret
+    reader::tagged_docs(item, tag_item_trait_item_sort).nth(0).map(|doc| {
+        doc.as_str_slice().as_bytes()[0] as char
+    })
 }
 
 fn item_symbol(item: rbml::Doc) -> String {
@@ -211,12 +201,9 @@ fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> ast::DefId {
 }
 
 fn item_parent_item(cdata: Cmd, d: rbml::Doc) -> Option<ast::DefId> {
-    let mut ret = None;
-    reader::tagged_docs(d, tag_items_data_parent_item, |did| {
-        ret = Some(translated_def_id(cdata, did));
-        false
-    });
-    ret
+    reader::tagged_docs(d, tag_items_data_parent_item).nth(0).map(|did| {
+        translated_def_id(cdata, did)
+    })
 }
 
 fn item_require_parent_item(cdata: Cmd, d: rbml::Doc) -> ast::DefId {
@@ -233,10 +220,16 @@ fn get_provided_source(d: rbml::Doc, cdata: Cmd) -> Option<ast::DefId> {
     })
 }
 
-fn each_reexport<F>(d: rbml::Doc, f: F) -> bool where
+fn each_reexport<F>(d: rbml::Doc, mut f: F) -> bool where
     F: FnMut(rbml::Doc) -> bool,
 {
-    reader::tagged_docs(d, tag_items_data_item_reexport, f)
+    for doc in reader::tagged_docs(d, tag_items_data_item_reexport) {
+        if !f(doc) {
+            return false;
+        }
+    }
+
+    true
 }
 
 fn variant_disr_val(d: rbml::Doc) -> Option<ty::Disr> {
@@ -278,12 +271,9 @@ fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
 }
 
 fn enum_variant_ids(item: rbml::Doc, cdata: Cmd) -> Vec<ast::DefId> {
-    let mut ids = vec![];
-    reader::tagged_docs(item, tag_items_data_item_variant, |p| {
-        ids.push(translated_def_id(cdata, p));
-        true
-    });
-    ids
+    reader::tagged_docs(item, tag_items_data_item_variant)
+        .map(|p| translated_def_id(cdata, p))
+        .collect()
 }
 
 fn item_path(item_doc: rbml::Doc) -> Vec<ast_map::PathElem> {
@@ -400,13 +390,9 @@ fn parse_polarity(item_doc: rbml::Doc) -> ast::ImplPolarity {
 
 fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
     let names_doc = reader::get_doc(item_doc, tag_associated_type_names);
-    let mut names = Vec::new();
-    reader::tagged_docs(names_doc, tag_associated_type_name, |name_doc| {
-        let name = token::intern(name_doc.as_str_slice());
-        names.push(name);
-        true
-    });
-    names
+    reader::tagged_docs(names_doc, tag_associated_type_name)
+        .map(|name_doc| token::intern(name_doc.as_str_slice()))
+        .collect()
 }
 
 pub fn get_trait_def<'tcx>(cdata: Cmd,
@@ -552,7 +538,7 @@ pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
 {
     let root = rbml::Doc::new(cdata.data());
     let lang_items = reader::get_doc(root, tag_lang_items);
-    reader::tagged_docs(lang_items, tag_lang_items_item, |item_doc| {
+    reader::tagged_docs(lang_items, tag_lang_items_item).all(|item_doc| {
         let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
         let id = reader::doc_as_u32(id_doc) as usize;
         let node_id_doc = reader::get_doc(item_doc,
@@ -572,7 +558,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
     G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
 {
     // Iterate over all children.
-    let _ = reader::tagged_docs(item_doc, tag_mod_child, |child_info_doc| {
+    for child_info_doc in reader::tagged_docs(item_doc, tag_mod_child) {
         let child_def_id = translated_def_id(cdata, child_info_doc);
 
         // This item may be in yet another crate if it was the child of a
@@ -598,26 +584,20 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
                 let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
                 let visibility = item_visibility(child_item_doc);
                 callback(def_like, child_name, visibility);
-
             }
         }
-
-        true
-    });
+    }
 
     // As a special case, iterate over all static methods of
     // associated implementations too. This is a bit of a botch.
     // --pcwalton
-    let _ = reader::tagged_docs(item_doc,
-                                tag_items_data_item_inherent_impl,
-                                |inherent_impl_def_id_doc| {
-        let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc,
-                                               cdata);
+    for inherent_impl_def_id_doc in reader::tagged_docs(item_doc,
+                                                             tag_items_data_item_inherent_impl) {
+        let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc, cdata);
         let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
         if let Some(inherent_impl_doc) = maybe_find_item(inherent_impl_def_id.node, items) {
-            let _ = reader::tagged_docs(inherent_impl_doc,
-                                        tag_item_impl_item,
-                                        |impl_item_def_id_doc| {
+            for impl_item_def_id_doc in reader::tagged_docs(inherent_impl_doc,
+                                                                 tag_item_impl_item) {
                 let impl_item_def_id = item_def_id(impl_item_def_id_doc,
                                                    cdata);
                 if let Some(impl_method_doc) = maybe_find_item(impl_item_def_id.node, items) {
@@ -631,11 +611,9 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
                                  item_visibility(impl_method_doc));
                     }
                 }
-                true
-            });
+            }
         }
-        true
-    });
+    }
 
     // Iterate over all reexports.
     let _ = each_reexport(item_doc, |reexport_doc| {
@@ -847,22 +825,15 @@ fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
 /// Returns the def IDs of all the items in the given implementation.
 pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
                       -> Vec<ty::ImplOrTraitItemId> {
-    let mut impl_items = Vec::new();
-    reader::tagged_docs(lookup_item(impl_id, cdata.data()),
-                        tag_item_impl_item, |doc| {
+    reader::tagged_docs(lookup_item(impl_id, cdata.data()), tag_item_impl_item).map(|doc| {
         let def_id = item_def_id(doc, cdata);
         match item_sort(doc) {
-            Some('C') => impl_items.push(ty::ConstTraitItemId(def_id)),
-            Some('r') | Some('p') => {
-                impl_items.push(ty::MethodTraitItemId(def_id))
-            }
-            Some('t') => impl_items.push(ty::TypeTraitItemId(def_id)),
+            Some('C') => ty::ConstTraitItemId(def_id),
+            Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
+            Some('t') => ty::TypeTraitItemId(def_id),
             _ => panic!("unknown impl item sort"),
         }
-        true
-    });
-
-    impl_items
+    }).collect()
 }
 
 pub fn get_trait_name(intr: Rc<IdentInterner>,
@@ -948,20 +919,15 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
                               -> Vec<ty::ImplOrTraitItemId> {
     let data = cdata.data();
     let item = lookup_item(id, data);
-    let mut result = Vec::new();
-    reader::tagged_docs(item, tag_item_trait_item, |mth| {
+    reader::tagged_docs(item, tag_item_trait_item).map(|mth| {
         let def_id = item_def_id(mth, cdata);
         match item_sort(mth) {
-            Some('C') => result.push(ty::ConstTraitItemId(def_id)),
-            Some('r') | Some('p') => {
-                result.push(ty::MethodTraitItemId(def_id));
-            }
-            Some('t') => result.push(ty::TypeTraitItemId(def_id)),
+            Some('C') => ty::ConstTraitItemId(def_id),
+            Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
+            Some('t') => ty::TypeTraitItemId(def_id),
             _ => panic!("unknown trait item sort"),
         }
-        true
-    });
-    result
+    }).collect()
 }
 
 pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances {
@@ -979,9 +945,8 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
                                         -> Vec<Rc<ty::Method<'tcx>>> {
     let data = cdata.data();
     let item = lookup_item(id, data);
-    let mut result = Vec::new();
 
-    reader::tagged_docs(item, tag_item_trait_item, |mth_id| {
+    reader::tagged_docs(item, tag_item_trait_item).filter_map(|mth_id| {
         let did = item_def_id(mth_id, cdata);
         let mth = lookup_item(did.node, data);
 
@@ -991,13 +956,14 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
                                                     did.node,
                                                     tcx);
             if let ty::MethodTraitItem(ref method) = trait_item {
-                result.push((*method).clone())
+                Some((*method).clone())
+            } else {
+                None
             }
+        } else {
+            None
         }
-        true
-    });
-
-    return result;
+    }).collect()
 }
 
 pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
@@ -1007,10 +973,9 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
                                    -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
     let data = cdata.data();
     let item = lookup_item(id, data);
-    let mut result = Vec::new();
 
-    for &tag in &[tag_item_trait_item, tag_item_impl_item] {
-        reader::tagged_docs(item, tag, |ac_id| {
+    [tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| {
+        reader::tagged_docs(item, tag).filter_map(|ac_id| {
             let did = item_def_id(ac_id, cdata);
             let ac_doc = lookup_item(did.node, data);
 
@@ -1020,14 +985,15 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
                                                         did.node,
                                                         tcx);
                 if let ty::ConstTraitItem(ref ac) = trait_item {
-                    result.push((*ac).clone())
+                    Some((*ac).clone())
+                } else {
+                    None
                 }
+            } else {
+                None
             }
-            true
-        });
-    }
-
-    return result;
+        })
+    }).collect()
 }
 
 pub fn get_type_name_if_impl(cdata: Cmd,
@@ -1037,13 +1003,9 @@ pub fn get_type_name_if_impl(cdata: Cmd,
         return None;
     }
 
-    let mut ret = None;
-    reader::tagged_docs(item, tag_item_impl_type_basename, |doc| {
-        ret = Some(token::intern(doc.as_str_slice()));
-        false
-    });
-
-    ret
+    reader::tagged_docs(item, tag_item_impl_type_basename).nth(0).map(|doc| {
+        token::intern(doc.as_str_slice())
+    })
 }
 
 pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
@@ -1056,20 +1018,15 @@ pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
     }
 
     // If this impl implements a trait, don't consider it.
-    let ret = reader::tagged_docs(item, tag_item_trait_ref, |_doc| {
-        false
-    });
-
-    if !ret { return None }
+    if reader::tagged_docs(item, tag_item_trait_ref).next().is_some() {
+        return None;
+    }
 
-    let mut impl_method_ids = Vec::new();
-    reader::tagged_docs(item, tag_item_impl_item, |impl_method_doc| {
-        impl_method_ids.push(item_def_id(impl_method_doc, cdata));
-        true
-    });
+    let impl_method_ids = reader::tagged_docs(item, tag_item_impl_item)
+        .map(|impl_method_doc| item_def_id(impl_method_doc, cdata));
 
     let mut impl_methods = Vec::new();
-    for impl_method_id in &impl_method_ids {
+    for impl_method_id in impl_method_ids {
         let impl_method_doc = lookup_item(impl_method_id.node, cdata.data());
         let family = item_family(impl_method_doc);
         match family {
@@ -1094,12 +1051,9 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
     -> Option<ast::DefId>
 {
     let item = lookup_item(node_id, cdata.data());
-    let mut ret = None;
-    reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor, |_| {
-        ret = Some(item_require_parent_item(cdata, item));
-        false
-    });
-    ret
+    reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor).next().map(|_| {
+        item_require_parent_item(cdata, item)
+    })
 }
 
 pub fn get_item_attrs(cdata: Cmd,
@@ -1117,14 +1071,11 @@ pub fn get_item_attrs(cdata: Cmd,
 pub fn get_struct_field_attrs(cdata: Cmd) -> HashMap<ast::NodeId, Vec<ast::Attribute>> {
     let data = rbml::Doc::new(cdata.data());
     let fields = reader::get_doc(data, tag_struct_fields);
-    let mut map = HashMap::new();
-    reader::tagged_docs(fields, tag_struct_field, |field| {
+    reader::tagged_docs(fields, tag_struct_field).map(|field| {
         let id = reader::doc_as_u32(reader::get_doc(field, tag_struct_field_id));
         let attrs = get_attributes(field);
-        map.insert(id, attrs);
-        true
-    });
-    map
+        (id, attrs)
+    }).collect()
 }
 
 fn struct_field_family_to_visibility(family: Family) -> ast::Visibility {
@@ -1139,81 +1090,69 @@ pub fn get_struct_fields(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId)
     -> Vec<ty::field_ty> {
     let data = cdata.data();
     let item = lookup_item(id, data);
-    let mut result = Vec::new();
-    reader::tagged_docs(item, tag_item_field, |an_item| {
+    reader::tagged_docs(item, tag_item_field).filter_map(|an_item| {
         let f = item_family(an_item);
         if f == PublicField || f == InheritedField {
             let name = item_name(&*intr, an_item);
             let did = item_def_id(an_item, cdata);
             let tagdoc = reader::get_doc(an_item, tag_item_field_origin);
             let origin_id =  translated_def_id(cdata, tagdoc);
-            result.push(ty::field_ty {
+            Some(ty::field_ty {
                 name: name,
                 id: did,
                 vis: struct_field_family_to_visibility(f),
                 origin: origin_id,
-            });
+            })
+        } else {
+            None
         }
-        true
-    });
-    reader::tagged_docs(item, tag_item_unnamed_field, |an_item| {
+    }).chain(reader::tagged_docs(item, tag_item_unnamed_field).map(|an_item| {
         let did = item_def_id(an_item, cdata);
         let tagdoc = reader::get_doc(an_item, tag_item_field_origin);
         let f = item_family(an_item);
         let origin_id =  translated_def_id(cdata, tagdoc);
-        result.push(ty::field_ty {
+        ty::field_ty {
             name: special_idents::unnamed_field.name,
             id: did,
             vis: struct_field_family_to_visibility(f),
             origin: origin_id,
-        });
-        true
-    });
-    result
+        }
+    })).collect()
 }
 
 fn get_meta_items(md: rbml::Doc) -> Vec<P<ast::MetaItem>> {
-    let mut items: Vec<P<ast::MetaItem>> = Vec::new();
-    reader::tagged_docs(md, tag_meta_item_word, |meta_item_doc| {
+    reader::tagged_docs(md, tag_meta_item_word).map(|meta_item_doc| {
         let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
         let n = token::intern_and_get_ident(nd.as_str_slice());
-        items.push(attr::mk_word_item(n));
-        true
-    });
-    reader::tagged_docs(md, tag_meta_item_name_value, |meta_item_doc| {
+        attr::mk_word_item(n)
+    }).chain(reader::tagged_docs(md, tag_meta_item_name_value).map(|meta_item_doc| {
         let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
         let vd = reader::get_doc(meta_item_doc, tag_meta_item_value);
         let n = token::intern_and_get_ident(nd.as_str_slice());
         let v = token::intern_and_get_ident(vd.as_str_slice());
         // FIXME (#623): Should be able to decode MetaNameValue variants,
         // but currently the encoder just drops them
-        items.push(attr::mk_name_value_item_str(n, v));
-        true
-    });
-    reader::tagged_docs(md, tag_meta_item_list, |meta_item_doc| {
+        attr::mk_name_value_item_str(n, v)
+    })).chain(reader::tagged_docs(md, tag_meta_item_list).map(|meta_item_doc| {
         let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
         let n = token::intern_and_get_ident(nd.as_str_slice());
         let subitems = get_meta_items(meta_item_doc);
-        items.push(attr::mk_list_item(n, subitems.into_iter().collect()));
-        true
-    });
-    return items;
+        attr::mk_list_item(n, subitems)
+    })).collect()
 }
 
 fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
-    let mut attrs: Vec<ast::Attribute> = Vec::new();
     match reader::maybe_get_doc(md, tag_attributes) {
-      Some(attrs_d) => {
-        reader::tagged_docs(attrs_d, tag_attribute, |attr_doc| {
-            let is_sugared_doc = reader::doc_as_u8(
-                reader::get_doc(attr_doc, tag_attribute_is_sugared_doc)
-            ) == 1;
-            let meta_items = get_meta_items(attr_doc);
-            // Currently it's only possible to have a single meta item on
-            // an attribute
-            assert_eq!(meta_items.len(), 1);
-            let meta_item = meta_items.into_iter().nth(0).unwrap();
-            attrs.push(
+        Some(attrs_d) => {
+            reader::tagged_docs(attrs_d, tag_attribute).map(|attr_doc| {
+                let is_sugared_doc = reader::doc_as_u8(
+                    reader::get_doc(attr_doc, tag_attribute_is_sugared_doc)
+                ) == 1;
+                let meta_items = get_meta_items(attr_doc);
+                // Currently it's only possible to have a single meta item on
+                // an attribute
+                assert_eq!(meta_items.len(), 1);
+                let meta_item = meta_items.into_iter().nth(0).unwrap();
                 codemap::Spanned {
                     node: ast::Attribute_ {
                         id: attr::mk_attr_id(),
@@ -1222,13 +1161,11 @@ fn get_attributes(md: rbml::Doc) -> Vec<ast::Attribute> {
                         is_sugared_doc: is_sugared_doc,
                     },
                     span: codemap::DUMMY_SP
-                });
-            true
-        });
-      }
-      None => ()
+                }
+            }).collect()
+        },
+        None => vec![],
     }
-    return attrs;
 }
 
 fn list_crate_attributes(md: rbml::Doc, hash: &Svh,
@@ -1255,26 +1192,23 @@ pub struct CrateDep {
 }
 
 pub fn get_crate_deps(data: &[u8]) -> Vec<CrateDep> {
-    let mut deps: Vec<CrateDep> = Vec::new();
     let cratedoc = rbml::Doc::new(data);
     let depsdoc = reader::get_doc(cratedoc, tag_crate_deps);
-    let mut crate_num = 1;
+
     fn docstr(doc: rbml::Doc, tag_: usize) -> String {
         let d = reader::get_doc(doc, tag_);
         d.as_str_slice().to_string()
     }
-    reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| {
+
+    reader::tagged_docs(depsdoc, tag_crate_dep).enumerate().map(|(crate_num, depdoc)| {
         let name = docstr(depdoc, tag_crate_dep_crate_name);
         let hash = Svh::new(&docstr(depdoc, tag_crate_dep_hash));
-        deps.push(CrateDep {
-            cnum: crate_num,
+        CrateDep {
+            cnum: crate_num as u32 + 1,
             name: name,
             hash: hash,
-        });
-        crate_num += 1;
-        true
-    });
-    return deps;
+        }
+    }).collect()
 }
 
 fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> {
@@ -1366,14 +1300,11 @@ pub fn each_inherent_implementation_for_type<F>(cdata: Cmd,
     where F: FnMut(ast::DefId),
 {
     let item_doc = lookup_item(id, cdata.data());
-    reader::tagged_docs(item_doc,
-                        tag_items_data_item_inherent_impl,
-                        |impl_doc| {
+    for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_inherent_impl) {
         if reader::maybe_get_doc(impl_doc, tag_item_trait_ref).is_none() {
             callback(item_def_id(impl_doc, cdata));
         }
-        true
-    });
+    }
 }
 
 pub fn each_implementation_for_trait<F>(cdata: Cmd,
@@ -1383,12 +1314,9 @@ pub fn each_implementation_for_trait<F>(cdata: Cmd,
 {
     if cdata.cnum == def_id.krate {
         let item_doc = lookup_item(def_id.node, cdata.data());
-        let _ = reader::tagged_docs(item_doc,
-                                    tag_items_data_item_extension_impl,
-                                    |impl_doc| {
+        for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_extension_impl) {
             callback(item_def_id(impl_doc, cdata));
-            true
-        });
+        }
         return;
     }
 
@@ -1398,13 +1326,12 @@ pub fn each_implementation_for_trait<F>(cdata: Cmd,
         let def_id_u64 = def_to_u64(crate_local_did);
 
         let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls);
-        let _ = reader::tagged_docs(impls_doc, tag_impls_impl, |impl_doc| {
+        for impl_doc in reader::tagged_docs(impls_doc, tag_impls_impl) {
             let impl_trait = reader::get_doc(impl_doc, tag_impls_impl_trait_def_id);
             if reader::doc_as_u64(impl_trait) == def_id_u64 {
                 callback(item_def_id(impl_doc, cdata));
             }
-            true
-        });
+        }
     }
 }
 
@@ -1431,17 +1358,14 @@ pub fn get_native_libraries(cdata: Cmd)
                             -> Vec<(cstore::NativeLibraryKind, String)> {
     let libraries = reader::get_doc(rbml::Doc::new(cdata.data()),
                                     tag_native_libraries);
-    let mut result = Vec::new();
-    reader::tagged_docs(libraries, tag_native_libraries_lib, |lib_doc| {
+    reader::tagged_docs(libraries, tag_native_libraries_lib).map(|lib_doc| {
         let kind_doc = reader::get_doc(lib_doc, tag_native_libraries_kind);
         let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name);
         let kind: cstore::NativeLibraryKind =
             cstore::NativeLibraryKind::from_u32(reader::doc_as_u32(kind_doc)).unwrap();
         let name = name_doc.as_str().to_string();
-        result.push((kind, name));
-        true
-    });
-    return result;
+        (kind, name)
+    }).collect()
 }
 
 pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
@@ -1453,12 +1377,14 @@ pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner, mut f: F) where
     F: FnMut(ast::Name, Vec<ast::Attribute>, String) -> bool,
 {
     let macros = reader::get_doc(rbml::Doc::new(data), tag_macro_defs);
-    reader::tagged_docs(macros, tag_macro_def, |macro_doc| {
+    for macro_doc in reader::tagged_docs(macros, tag_macro_def) {
         let name = item_name(intr, macro_doc);
         let attrs = get_attributes(macro_doc);
         let body = reader::get_doc(macro_doc, tag_macro_def_body);
-        f(name, attrs, body.as_str().to_string())
-    });
+        if !f(name, attrs, body.as_str().to_string()) {
+            break;
+        }
+    }
 }
 
 pub fn get_dylib_dependency_formats(cdata: Cmd)
@@ -1491,43 +1417,32 @@ pub fn get_missing_lang_items(cdata: Cmd)
     -> Vec<lang_items::LangItem>
 {
     let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_lang_items);
-    let mut result = Vec::new();
-    reader::tagged_docs(items, tag_lang_items_missing, |missing_docs| {
-        let item: lang_items::LangItem =
-            lang_items::LangItem::from_u32(reader::doc_as_u32(missing_docs)).unwrap();
-        result.push(item);
-        true
-    });
-    return result;
+    reader::tagged_docs(items, tag_lang_items_missing).map(|missing_docs| {
+        lang_items::LangItem::from_u32(reader::doc_as_u32(missing_docs)).unwrap()
+    }).collect()
 }
 
 pub fn get_method_arg_names(cdata: Cmd, id: ast::NodeId) -> Vec<String> {
-    let mut ret = Vec::new();
     let method_doc = lookup_item(id, cdata.data());
     match reader::maybe_get_doc(method_doc, tag_method_argument_names) {
         Some(args_doc) => {
-            reader::tagged_docs(args_doc, tag_method_argument_name, |name_doc| {
-                ret.push(name_doc.as_str_slice().to_string());
-                true
-            });
-        }
-        None => {}
+            reader::tagged_docs(args_doc, tag_method_argument_name).map(|name_doc| {
+                name_doc.as_str_slice().to_string()
+            }).collect()
+        },
+        None => vec![],
     }
-    return ret;
 }
 
 pub fn get_reachable_extern_fns(cdata: Cmd) -> Vec<ast::DefId> {
-    let mut ret = Vec::new();
     let items = reader::get_doc(rbml::Doc::new(cdata.data()),
                                 tag_reachable_extern_fns);
-    reader::tagged_docs(items, tag_reachable_extern_fn_id, |doc| {
-        ret.push(ast::DefId {
+    reader::tagged_docs(items, tag_reachable_extern_fn_id).map(|doc| {
+        ast::DefId {
             krate: cdata.cnum,
             node: reader::doc_as_u32(doc),
-        });
-        true
-    });
-    return ret;
+        }
+    }).collect()
 }
 
 pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
@@ -1555,16 +1470,15 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
     let doc = reader::get_doc(base_doc, tag);
 
     let mut types = subst::VecPerParamSpace::empty();
-    reader::tagged_docs(doc, tag_type_param_def, |p| {
+    for p in reader::tagged_docs(doc, tag_type_param_def) {
         let bd = parse_type_param_def_data(
             p.data, p.start, cdata.cnum, tcx,
             |_, did| translate_def_id(cdata, did));
         types.push(bd.space, bd);
-        true
-    });
+    }
 
     let mut regions = subst::VecPerParamSpace::empty();
-    reader::tagged_docs(doc, tag_region_param_def, |rp_doc| {
+    for rp_doc in reader::tagged_docs(doc, tag_region_param_def) {
         let ident_str_doc = reader::get_doc(rp_doc,
                                             tag_region_param_def_ident);
         let name = item_name(&*token::get_ident_interner(), ident_str_doc);
@@ -1578,23 +1492,17 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
         let doc = reader::get_doc(rp_doc, tag_region_param_def_index);
         let index = reader::doc_as_u64(doc) as u32;
 
-        let mut bounds = Vec::new();
-        reader::tagged_docs(rp_doc, tag_items_data_region, |p| {
-            bounds.push(
-                parse_region_data(
-                    p.data, cdata.cnum, p.start, tcx,
-                    |_, did| translate_def_id(cdata, did)));
-            true
-        });
+        let bounds = reader::tagged_docs(rp_doc, tag_items_data_region).map(|p| {
+            parse_region_data(p.data, cdata.cnum, p.start, tcx,
+                              |_, did| translate_def_id(cdata, did))
+        }).collect();
 
         regions.push(space, ty::RegionParameterDef { name: name,
                                                      def_id: def_id,
                                                      space: space,
                                                      index: index,
                                                      bounds: bounds });
-
-        true
-    });
+    }
 
     ty::Generics { types: types, regions: regions }
 }
@@ -1608,7 +1516,7 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc,
     let doc = reader::get_doc(base_doc, tag);
 
     let mut predicates = subst::VecPerParamSpace::empty();
-    reader::tagged_docs(doc, tag_predicate, |predicate_doc| {
+    for predicate_doc in reader::tagged_docs(doc, tag_predicate) {
         let space_doc = reader::get_doc(predicate_doc, tag_predicate_space);
         let space = subst::ParamSpace::from_uint(reader::doc_as_u8(space_doc) as usize);
 
@@ -1617,8 +1525,7 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc,
                                         |_, did| translate_def_id(cdata, did));
 
         predicates.push(space, data);
-        true
-    });
+    }
 
     ty::GenericPredicates { predicates: predicates }
 }
@@ -1647,14 +1554,8 @@ pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
     let crate_doc = rbml::Doc::new(metadata);
     let cm_doc = reader::get_doc(crate_doc, tag_codemap);
 
-    let mut filemaps = vec![];
-
-    reader::tagged_docs(cm_doc, tag_codemap_filemap, |filemap_doc| {
+    reader::tagged_docs(cm_doc, tag_codemap_filemap).map(|filemap_doc| {
         let mut decoder = reader::Decoder::new(filemap_doc);
-        let filemap: codemap::FileMap = Decodable::decode(&mut decoder).unwrap();
-        filemaps.push(filemap);
-        true
-    });
-
-    return filemaps;
+        Decodable::decode(&mut decoder).unwrap()
+    }).collect()
 }