about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-05-03 13:08:08 -0400
committerAlex Crichton <alex@alexcrichton.com>2013-05-10 02:46:19 -0400
commita87db3e2cd0aaaa513b13391d3ad21861d16e480 (patch)
tree2cd1cf8eebc5276d0aa12a6d458bd3703b2e08ff
parent5eb6d19803ebcb5279f8a42b584a4d81152fa82d (diff)
downloadrust-a87db3e2cd0aaaa513b13391d3ad21861d16e480.tar.gz
rust-a87db3e2cd0aaaa513b13391d3ad21861d16e480.zip
rustc: Use the new `for` protocol
-rw-r--r--src/librustc/metadata/csearch.rs21
-rw-r--r--src/librustc/metadata/decoder.rs53
-rw-r--r--src/librustc/metadata/encoder.rs3
-rw-r--r--src/librustc/metadata/filesearch.rs28
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs60
-rw-r--r--src/librustc/middle/dataflow.rs61
-rw-r--r--src/librustc/middle/lang_items.rs5
-rw-r--r--src/librustc/middle/resolve.rs10
-rw-r--r--src/librustc/middle/resolve_stage0.rs10
-rw-r--r--src/librustc/middle/trans/common.rs29
-rw-r--r--src/librustc/middle/trans/datum.rs7
-rw-r--r--src/librustc/middle/ty.rs262
-rw-r--r--src/librustc/middle/typeck/check/mod.rs9
-rw-r--r--src/librustc/middle/typeck/coherence.rs22
-rw-r--r--src/librustc/middle/typeck/infer/region_inference.rs34
-rw-r--r--src/libstd/ebml.rs33
16 files changed, 628 insertions, 19 deletions
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 375989b0ebe..2f4a0d0b2a0 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -44,14 +44,24 @@ pub fn get_type_param_count(cstore: @mut cstore::CStore, def: ast::def_id)
 }
 
 /// Iterates over all the language items in the given crate.
+#[cfg(stage0)]
 pub fn each_lang_item(cstore: @mut cstore::CStore,
                       cnum: ast::crate_num,
                       f: &fn(ast::node_id, uint) -> bool) {
     let crate_data = cstore::get_crate_data(cstore, cnum);
     decoder::each_lang_item(crate_data, f)
 }
+/// Iterates over all the language items in the given crate.
+#[cfg(not(stage0))]
+pub fn each_lang_item(cstore: @mut cstore::CStore,
+                      cnum: ast::crate_num,
+                      f: &fn(ast::node_id, uint) -> bool) -> bool {
+    let crate_data = cstore::get_crate_data(cstore, cnum);
+    decoder::each_lang_item(crate_data, f)
+}
 
 /// Iterates over all the paths in the given crate.
+#[cfg(stage0)]
 pub fn each_path(cstore: @mut cstore::CStore,
                  cnum: ast::crate_num,
                  f: &fn(&str, decoder::def_like) -> bool) {
@@ -61,6 +71,17 @@ pub fn each_path(cstore: @mut cstore::CStore,
     };
     decoder::each_path(cstore.intr, crate_data, get_crate_data, f);
 }
+/// Iterates over all the paths in the given crate.
+#[cfg(not(stage0))]
+pub fn each_path(cstore: @mut cstore::CStore,
+                 cnum: ast::crate_num,
+                 f: &fn(&str, decoder::def_like) -> bool) -> bool {
+    let crate_data = cstore::get_crate_data(cstore, cnum);
+    let get_crate_data: decoder::GetCrateDataCb = |cnum| {
+        cstore::get_crate_data(cstore, cnum)
+    };
+    decoder::each_path(cstore.intr, crate_data, get_crate_data, f)
+}
 
 pub fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path {
     let cstore = tcx.cstore;
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index fd35a4425d8..c121ddafc4d 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -196,6 +196,7 @@ fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id {
                                                     |d| parse_def_id(d)));
 }
 
+#[cfg(stage0)]
 fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) {
     for reader::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| {
         if !f(reexport_doc) {
@@ -203,6 +204,15 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) {
         }
     }
 }
+#[cfg(not(stage0))]
+fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool {
+    for reader::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| {
+        if !f(reexport_doc) {
+            return false;
+        }
+    }
+    return true;
+}
 
 fn variant_disr_val(d: ebml::Doc) -> Option<int> {
     do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| {
@@ -454,6 +464,7 @@ fn def_like_to_def(def_like: def_like) -> ast::def {
 }
 
 /// Iterates over the language items in the given crate.
+#[cfg(stage0)]
 pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) {
     let root = reader::Doc(cdata.data);
     let lang_items = reader::get_doc(root, tag_lang_items);
@@ -469,11 +480,29 @@ pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) {
         }
     }
 }
+/// Iterates over the language items in the given crate.
+#[cfg(not(stage0))]
+pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) -> bool {
+    let root = reader::Doc(cdata.data);
+    let lang_items = reader::get_doc(root, tag_lang_items);
+    for reader::tagged_docs(lang_items, tag_lang_items_item) |item_doc| {
+        let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
+        let id = reader::doc_as_u32(id_doc) as uint;
+        let node_id_doc = reader::get_doc(item_doc,
+                                          tag_lang_items_item_node_id);
+        let node_id = reader::doc_as_u32(node_id_doc) as ast::node_id;
+
+        if !f(node_id, id) {
+            return false;
+        }
+    }
+    return true;
+}
 
 /// Iterates over all the paths in the given crate.
-pub fn each_path(intr: @ident_interner, cdata: cmd,
-                 get_crate_data: GetCrateDataCb,
-                 f: &fn(&str, def_like) -> bool) {
+pub fn _each_path(intr: @ident_interner, cdata: cmd,
+                  get_crate_data: GetCrateDataCb,
+                  f: &fn(&str, def_like) -> bool) -> bool {
     let root = reader::Doc(cdata.data);
     let items = reader::get_doc(root, tag_items);
     let items_data = reader::get_doc(items, tag_items_data);
@@ -555,10 +584,20 @@ pub fn each_path(intr: @ident_interner, cdata: cmd,
         }
     }
 
-    // If broken, stop here.
-    if broken {
-        return;
-    }
+    return broken;
+}
+
+#[cfg(stage0)]
+pub fn each_path(intr: @ident_interner, cdata: cmd,
+                 get_crate_data: GetCrateDataCb,
+                 f: &fn(&str, def_like) -> bool) {
+    _each_path(intr, cdata, get_crate_data, f);
+}
+#[cfg(not(stage0))]
+pub fn each_path(intr: @ident_interner, cdata: cmd,
+                 get_crate_data: GetCrateDataCb,
+                 f: &fn(&str, def_like) -> bool) -> bool {
+    _each_path(intr, cdata, get_crate_data, f)
 }
 
 pub fn get_item_path(intr: @ident_interner, cdata: cmd, id: ast::node_id)
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 6c02ece9289..7d25d5f3ec9 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -1391,11 +1391,10 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
     ecx.stats.total_bytes = *wr.pos;
 
     if (tcx.sess.meta_stats()) {
-        do wr.bytes.each |e| {
+        for wr.bytes.each |e| {
             if *e == 0 {
                 ecx.stats.zero_bytes += 1;
             }
-            true
         }
 
         io::println("metadata stats:");
diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs
index 7547f7f763a..0708b7d38d3 100644
--- a/src/librustc/metadata/filesearch.rs
+++ b/src/librustc/metadata/filesearch.rs
@@ -21,7 +21,10 @@ pub fn pick_file(file: Path, path: &Path) -> Option<Path> {
 
 pub trait FileSearch {
     fn sysroot(&self) -> @Path;
+    #[cfg(stage0)]
     fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool);
+    #[cfg(not(stage0))]
+    fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) -> bool;
     fn get_target_lib_path(&self) -> Path;
     fn get_target_lib_file_path(&self, file: &Path) -> Path;
 }
@@ -37,6 +40,7 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>,
     }
     impl FileSearch for FileSearchImpl {
         fn sysroot(&self) -> @Path { self.sysroot }
+        #[cfg(stage0)]
         fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) {
             debug!("filesearch: searching additional lib search paths");
             // a little weird
@@ -60,6 +64,30 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>,
               result::Err(_) => true
            };
         }
+        #[cfg(not(stage0))]
+        fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) -> bool {
+            debug!("filesearch: searching additional lib search paths");
+            // a little weird
+            self.addl_lib_search_paths.each(f);
+
+            debug!("filesearch: searching target lib path");
+            if !f(&make_target_lib_path(self.sysroot,
+                                        self.target_triple)) {
+                return false;
+            }
+            debug!("filesearch: searching rustpkg lib path nearest");
+            if match get_rustpkg_lib_path_nearest() {
+                    result::Ok(ref p) => f(p),
+                    result::Err(_) => true
+                } {
+                    return true;
+                }
+           debug!("filesearch: searching rustpkg lib path");
+           match get_rustpkg_lib_path() {
+              result::Ok(ref p) => f(p),
+              result::Err(_) => true
+           }
+        }
         fn get_target_lib_path(&self) -> Path {
             make_target_lib_path(self.sysroot, self.target_triple)
         }
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index ba719fe34d7..27f6ae33ba3 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -67,6 +67,7 @@ enum MoveError {
 pub impl<'self> CheckLoanCtxt<'self> {
     fn tcx(&self) -> ty::ctxt { self.bccx.tcx }
 
+    #[cfg(stage0)]
     fn each_issued_loan(&self,
                         scope_id: ast::node_id,
                         op: &fn(&Loan) -> bool)
@@ -84,7 +85,27 @@ pub impl<'self> CheckLoanCtxt<'self> {
             }
         }
     }
+    #[cfg(not(stage0))]
+    fn each_issued_loan(&self,
+                        scope_id: ast::node_id,
+                        op: &fn(&Loan) -> bool) -> bool
+    {
+        //! Iterates over each loan that that has been issued
+        //! on entrance to `scope_id`, regardless of whether it is
+        //! actually *in scope* at that point.  Sometimes loans
+        //! are issued for future scopes and thus they may have been
+        //! *issued* but not yet be in effect.
+
+        for self.dfcx.each_bit_on_entry(scope_id) |loan_index| {
+            let loan = &self.all_loans[loan_index];
+            if !op(loan) {
+                return false;
+            }
+        }
+        return true;
+    }
 
+    #[cfg(stage0)]
     fn each_in_scope_loan(&self,
                           scope_id: ast::node_id,
                           op: &fn(&Loan) -> bool)
@@ -101,7 +122,26 @@ pub impl<'self> CheckLoanCtxt<'self> {
             }
         }
     }
+    #[cfg(not(stage0))]
+    fn each_in_scope_loan(&self,
+                          scope_id: ast::node_id,
+                          op: &fn(&Loan) -> bool) -> bool
+    {
+        //! Like `each_issued_loan()`, but only considers loans that are
+        //! currently in scope.
 
+        let region_maps = self.tcx().region_maps;
+        for self.each_issued_loan(scope_id) |loan| {
+            if region_maps.is_subscope_of(scope_id, loan.kill_scope) {
+                if !op(loan) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    #[cfg(stage0)]
     fn each_in_scope_restriction(&self,
                                  scope_id: ast::node_id,
                                  loan_path: @LoanPath,
@@ -120,6 +160,26 @@ pub impl<'self> CheckLoanCtxt<'self> {
             }
         }
     }
+    #[cfg(not(stage0))]
+    fn each_in_scope_restriction(&self,
+                                 scope_id: ast::node_id,
+                                 loan_path: @LoanPath,
+                                 op: &fn(&Loan, &Restriction) -> bool) -> bool
+    {
+        //! Iterates through all the in-scope restrictions for the
+        //! given `loan_path`
+
+        for self.each_in_scope_loan(scope_id) |loan| {
+            for loan.restrictions.each |restr| {
+                if restr.loan_path == loan_path {
+                    if !op(loan, restr) {
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
 
     fn loans_generated_by(&self, scope_id: ast::node_id) -> ~[uint] {
         //! Returns a vector of the loans that are generated as
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index ccb34851046..f1fa5144f4c 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -182,6 +182,7 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
     }
 
 
+    #[cfg(stage0)]
     pub fn each_bit_on_entry(&self,
                              id: ast::node_id,
                              f: &fn(uint) -> bool) {
@@ -194,7 +195,21 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
                id, bits_to_str(on_entry));
         self.each_bit(on_entry, f);
     }
+    #[cfg(not(stage0))]
+    pub fn each_bit_on_entry(&self,
+                             id: ast::node_id,
+                             f: &fn(uint) -> bool) -> bool {
+        //! Iterates through each bit that is set on entry to `id`.
+        //! Only useful after `propagate()` has been called.
+
+        let (start, end) = self.compute_id_range(id);
+        let on_entry = vec::slice(self.on_entry, start, end);
+        debug!("each_bit_on_entry(id=%?, on_entry=%s)",
+               id, bits_to_str(on_entry));
+        self.each_bit(on_entry, f)
+    }
 
+    #[cfg(stage0)]
     pub fn each_gen_bit(&self,
                         id: ast::node_id,
                         f: &fn(uint) -> bool) {
@@ -206,7 +221,20 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
                id, bits_to_str(gens));
         self.each_bit(gens, f)
     }
+    #[cfg(not(stage0))]
+    pub fn each_gen_bit(&self,
+                        id: ast::node_id,
+                        f: &fn(uint) -> bool) -> bool {
+        //! Iterates through each bit in the gen set for `id`.
 
+        let (start, end) = self.compute_id_range(id);
+        let gens = vec::slice(self.gens, start, end);
+        debug!("each_gen_bit(id=%?, gens=%s)",
+               id, bits_to_str(gens));
+        self.each_bit(gens, f)
+    }
+
+    #[cfg(stage0)]
     fn each_bit(&self,
                 words: &[uint],
                 f: &fn(uint) -> bool) {
@@ -236,6 +264,39 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
             }
         }
     }
+    #[cfg(not(stage0))]
+    fn each_bit(&self,
+                words: &[uint],
+                f: &fn(uint) -> bool) -> bool {
+        //! Helper for iterating over the bits in a bit set.
+
+        for words.eachi |word_index, &word| {
+            if word != 0 {
+                let base_index = word_index * uint::bits;
+                for uint::range(0, uint::bits) |offset| {
+                    let bit = 1 << offset;
+                    if (word & bit) != 0 {
+                        // NB: we round up the total number of bits
+                        // that we store in any given bit set so that
+                        // it is an even multiple of uint::bits.  This
+                        // means that there may be some stray bits at
+                        // the end that do not correspond to any
+                        // actual value.  So before we callback, check
+                        // whether the bit_index is greater than the
+                        // actual value the user specified and stop
+                        // iterating if so.
+                        let bit_index = base_index + offset;
+                        if bit_index >= self.bits_per_id {
+                            return true;
+                        } else if !f(bit_index) {
+                            return false;
+                        }
+                    }
+                }
+            }
+        }
+        return true;
+    }
 }
 
 impl<O:DataFlowOperator+Copy+'static> DataFlowContext<O> {
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index c94dc3046df..e2b4684696a 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -86,6 +86,7 @@ pub impl LanguageItems {
         }
     }
 
+    #[cfg(stage0)]
     fn each_item(&self, f: &fn(def_id: def_id, i: uint) -> bool) {
         for self.items.eachi |i, &item| {
             if !f(item.get(), i) {
@@ -93,6 +94,10 @@ pub impl LanguageItems {
             }
         }
     }
+    #[cfg(not(stage0))]
+    fn each_item(&self, f: &fn(def_id: def_id, i: uint) -> bool) -> bool {
+        self.items.eachi(|i, &item| f(item.get(), i))
+    }
 
     pub fn item_name(index: uint) -> &'static str {
         match index {
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 5c3bb6ca401..e1e74f7a847 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -2408,14 +2408,14 @@ pub impl Resolver {
         let merge_import_resolution = |ident,
                                        name_bindings: @mut NameBindings| {
             let dest_import_resolution;
-            match module_.import_resolutions.find(ident) {
+            match module_.import_resolutions.find(&ident) {
                 None => {
                     // Create a new import resolution from this child.
                     dest_import_resolution = @mut ImportResolution(privacy,
                                                                    span,
                                                                    state);
                     module_.import_resolutions.insert
-                        (*ident, dest_import_resolution);
+                        (ident, dest_import_resolution);
                 }
                 Some(&existing_import_resolution) => {
                     dest_import_resolution = existing_import_resolution;
@@ -2424,7 +2424,7 @@ pub impl Resolver {
 
             debug!("(resolving glob import) writing resolution `%s` in `%s` \
                     to `%s`, privacy=%?",
-                   *self.session.str_of(*ident),
+                   *self.session.str_of(ident),
                    self.module_to_str(containing_module),
                    self.module_to_str(module_),
                    copy dest_import_resolution.privacy);
@@ -2443,13 +2443,13 @@ pub impl Resolver {
         };
 
         // Add all children from the containing module.
-        for containing_module.children.each |ident, name_bindings| {
+        for containing_module.children.each |&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| {
+                |&ident, module| {
             let name_bindings =
                 @mut Resolver::create_name_bindings_from_module(*module);
             merge_import_resolution(ident, name_bindings);
diff --git a/src/librustc/middle/resolve_stage0.rs b/src/librustc/middle/resolve_stage0.rs
index 3a6424efe1d..a0fe66ead04 100644
--- a/src/librustc/middle/resolve_stage0.rs
+++ b/src/librustc/middle/resolve_stage0.rs
@@ -2424,14 +2424,14 @@ pub impl Resolver {
         let merge_import_resolution = |ident,
                                        name_bindings: @mut NameBindings| {
             let dest_import_resolution;
-            match module_.import_resolutions.find(ident) {
+            match module_.import_resolutions.find(&ident) {
                 None => {
                     // Create a new import resolution from this child.
                     dest_import_resolution = @mut ImportResolution(privacy,
                                                                    span,
                                                                    state);
                     module_.import_resolutions.insert
-                        (*ident, dest_import_resolution);
+                        (ident, dest_import_resolution);
                 }
                 Some(existing_import_resolution) => {
                     dest_import_resolution = *existing_import_resolution;
@@ -2440,7 +2440,7 @@ pub impl Resolver {
 
             debug!("(resolving glob import) writing resolution `%s` in `%s` \
                     to `%s`, privacy=%?",
-                   *self.session.str_of(*ident),
+                   *self.session.str_of(ident),
                    self.module_to_str(containing_module),
                    self.module_to_str(module_),
                    copy dest_import_resolution.privacy);
@@ -2459,13 +2459,13 @@ pub impl Resolver {
         };
 
         // Add all children from the containing module.
-        for containing_module.children.each |ident, name_bindings| {
+        for containing_module.children.each |&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| {
+                |&ident, module| {
             let name_bindings =
                 @mut Resolver::create_name_bindings_from_module(*module);
             merge_import_resolution(ident, name_bindings);
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index c1309b42288..d8db5bac24d 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -1369,6 +1369,7 @@ pub struct mono_id_ {
 
 pub type mono_id = @mono_id_;
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for mono_param_id {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         match *self {
@@ -1382,18 +1383,46 @@ impl to_bytes::IterBytes for mono_param_id {
         }
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for mono_param_id {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        match *self {
+            mono_precise(t, ref mids) =>
+                to_bytes::iter_bytes_3(&0u8, &ty::type_id(t), mids, lsb0, f),
+
+            mono_any => 1u8.iter_bytes(lsb0, f),
 
+            mono_repr(ref a, ref b, ref c, ref d) =>
+                to_bytes::iter_bytes_5(&2u8, a, b, c, d, lsb0, f)
+        }
+    }
+}
+
+#[cfg(stage0)]
 impl to_bytes::IterBytes for MonoDataClass {
     fn iter_bytes(&self, lsb0: bool, f:to_bytes::Cb) {
         (*self as u8).iter_bytes(lsb0, f)
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for MonoDataClass {
+    fn iter_bytes(&self, lsb0: bool, f:to_bytes::Cb) -> bool {
+        (*self as u8).iter_bytes(lsb0, f)
+    }
+}
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for mono_id_ {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f);
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for mono_id_ {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f)
+    }
+}
 
 pub fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef {
     let cond = build::ICmp(cx, lib::llvm::IntULT, a, b);
diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs
index 64b29fd8573..374bb23f2cb 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -155,11 +155,18 @@ pub impl DatumMode {
     }
 }
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for DatumMode {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         (*self as uint).iter_bytes(lsb0, f)
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for DatumMode {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        (*self as uint).iter_bytes(lsb0, f)
+    }
+}
 
 /// See `Datum cleanup styles` section at the head of this module.
 #[deriving(Eq)]
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index c31843870e8..1c2c02b21e6 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -121,11 +121,18 @@ pub struct creader_cache_key {
 
 type creader_cache = @mut HashMap<creader_cache_key, t>;
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for creader_cache_key {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f);
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for creader_cache_key {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f)
+    }
+}
 
 struct intern_key {
     sty: *sty,
@@ -145,6 +152,7 @@ impl cmp::Eq for intern_key {
     }
 }
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for intern_key {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         unsafe {
@@ -152,6 +160,14 @@ impl to_bytes::IterBytes for intern_key {
         }
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for intern_key {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        unsafe {
+            (*self.sty).iter_bytes(lsb0, f)
+        }
+    }
+}
 
 pub enum ast_ty_to_ty_cache_entry {
     atttce_unresolved,  /* not resolved yet */
@@ -382,18 +398,33 @@ pub struct FnSig {
     output: t
 }
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for BareFnTy {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         to_bytes::iter_bytes_3(&self.purity, &self.abis, &self.sig, lsb0, f)
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for BareFnTy {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        to_bytes::iter_bytes_3(&self.purity, &self.abis, &self.sig, lsb0, f)
+    }
+}
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for ClosureTy {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         to_bytes::iter_bytes_5(&self.purity, &self.sigil, &self.onceness,
                                &self.region, &self.sig, lsb0, f)
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for ClosureTy {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        to_bytes::iter_bytes_5(&self.purity, &self.sigil, &self.onceness,
+                               &self.region, &self.sig, lsb0, f)
+    }
+}
 
 #[deriving(Eq, IterBytes)]
 pub struct param_ty {
@@ -705,6 +736,7 @@ pub enum InferTy {
     FloatVar(FloatVid)
 }
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for InferTy {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         match *self {
@@ -714,6 +746,16 @@ impl to_bytes::IterBytes for InferTy {
         }
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for InferTy {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        match *self {
+          TyVar(ref tv) => to_bytes::iter_bytes_2(&0u8, tv, lsb0, f),
+          IntVar(ref iv) => to_bytes::iter_bytes_2(&1u8, iv, lsb0, f),
+          FloatVar(ref fv) => to_bytes::iter_bytes_2(&2u8, fv, lsb0, f),
+        }
+    }
+}
 
 #[auto_encode]
 #[auto_decode]
@@ -722,6 +764,7 @@ pub enum InferRegion {
     ReSkolemized(uint, bound_region)
 }
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for InferRegion {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         match *self {
@@ -730,6 +773,15 @@ impl to_bytes::IterBytes for InferRegion {
         }
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for InferRegion {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        match *self {
+            ReVar(ref rv) => to_bytes::iter_bytes_2(&0u8, rv, lsb0, f),
+            ReSkolemized(ref v, _) => to_bytes::iter_bytes_2(&1u8, v, lsb0, f)
+        }
+    }
+}
 
 impl cmp::Eq for InferRegion {
     fn eq(&self, other: &InferRegion) -> bool {
@@ -810,29 +862,57 @@ impl ToStr for IntVarValue {
     }
 }
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for TyVid {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         self.to_uint().iter_bytes(lsb0, f)
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for TyVid {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        self.to_uint().iter_bytes(lsb0, f)
+    }
+}
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for IntVid {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         self.to_uint().iter_bytes(lsb0, f)
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for IntVid {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        self.to_uint().iter_bytes(lsb0, f)
+    }
+}
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for FloatVid {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         self.to_uint().iter_bytes(lsb0, f)
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for FloatVid {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        self.to_uint().iter_bytes(lsb0, f)
+    }
+}
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for RegionVid {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         self.to_uint().iter_bytes(lsb0, f)
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for RegionVid {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        self.to_uint().iter_bytes(lsb0, f)
+    }
+}
 
 pub struct TypeParameterDef {
     def_id: ast::def_id,
@@ -2637,6 +2717,7 @@ impl cmp::TotalEq for bound_region {
     }
 }
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for vstore {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         match *self {
@@ -2651,7 +2732,23 @@ impl to_bytes::IterBytes for vstore {
         }
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for vstore {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        match *self {
+          vstore_fixed(ref u) =>
+          to_bytes::iter_bytes_2(&0u8, u, lsb0, f),
 
+          vstore_uniq => 1u8.iter_bytes(lsb0, f),
+          vstore_box => 2u8.iter_bytes(lsb0, f),
+
+          vstore_slice(ref r) =>
+          to_bytes::iter_bytes_2(&3u8, r, lsb0, f),
+        }
+    }
+}
+
+#[cfg(stage0)]
 impl to_bytes::IterBytes for substs {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
           to_bytes::iter_bytes_3(&self.self_r,
@@ -2659,21 +2756,46 @@ impl to_bytes::IterBytes for substs {
                                  &self.tps, lsb0, f)
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for substs {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+          to_bytes::iter_bytes_3(&self.self_r,
+                                 &self.self_ty,
+                                 &self.tps, lsb0, f)
+    }
+}
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for mt {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
           to_bytes::iter_bytes_2(&self.ty,
                                  &self.mutbl, lsb0, f)
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for mt {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+          to_bytes::iter_bytes_2(&self.ty,
+                                 &self.mutbl, lsb0, f)
+    }
+}
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for field {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
           to_bytes::iter_bytes_2(&self.ident,
                                  &self.mt, lsb0, f)
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for field {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+          to_bytes::iter_bytes_2(&self.ident,
+                                 &self.mt, lsb0, f)
+    }
+}
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for FnSig {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         to_bytes::iter_bytes_2(&self.inputs,
@@ -2681,7 +2803,16 @@ impl to_bytes::IterBytes for FnSig {
                                lsb0, f);
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for FnSig {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        to_bytes::iter_bytes_2(&self.inputs,
+                               &self.output,
+                               lsb0, f)
+    }
+}
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for sty {
     fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         match *self {
@@ -2756,6 +2887,81 @@ impl to_bytes::IterBytes for sty {
         }
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for sty {
+    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        match *self {
+          ty_nil => 0u8.iter_bytes(lsb0, f),
+          ty_bool => 1u8.iter_bytes(lsb0, f),
+
+          ty_int(ref t) =>
+          to_bytes::iter_bytes_2(&2u8, t, lsb0, f),
+
+          ty_uint(ref t) =>
+          to_bytes::iter_bytes_2(&3u8, t, lsb0, f),
+
+          ty_float(ref t) =>
+          to_bytes::iter_bytes_2(&4u8, t, lsb0, f),
+
+          ty_estr(ref v) =>
+          to_bytes::iter_bytes_2(&5u8, v, lsb0, f),
+
+          ty_enum(ref did, ref substs) =>
+          to_bytes::iter_bytes_3(&6u8, did, substs, lsb0, f),
+
+          ty_box(ref mt) =>
+          to_bytes::iter_bytes_2(&7u8, mt, lsb0, f),
+
+          ty_evec(ref mt, ref v) =>
+          to_bytes::iter_bytes_3(&8u8, mt, v, lsb0, f),
+
+          ty_unboxed_vec(ref mt) =>
+          to_bytes::iter_bytes_2(&9u8, mt, lsb0, f),
+
+          ty_tup(ref ts) =>
+          to_bytes::iter_bytes_2(&10u8, ts, lsb0, f),
+
+          ty_bare_fn(ref ft) =>
+          to_bytes::iter_bytes_2(&12u8, ft, lsb0, f),
+
+          ty_self(ref did) => to_bytes::iter_bytes_2(&13u8, did, lsb0, f),
+
+          ty_infer(ref v) =>
+          to_bytes::iter_bytes_2(&14u8, v, lsb0, f),
+
+          ty_param(ref p) =>
+          to_bytes::iter_bytes_2(&15u8, p, lsb0, f),
+
+          ty_type => 16u8.iter_bytes(lsb0, f),
+          ty_bot => 17u8.iter_bytes(lsb0, f),
+
+          ty_ptr(ref mt) =>
+          to_bytes::iter_bytes_2(&18u8, mt, lsb0, f),
+
+          ty_uniq(ref mt) =>
+          to_bytes::iter_bytes_2(&19u8, mt, lsb0, f),
+
+          ty_trait(ref did, ref substs, ref v, ref mutbl) =>
+          to_bytes::iter_bytes_5(&20u8, did, substs, v, mutbl, lsb0, f),
+
+          ty_opaque_closure_ptr(ref ck) =>
+          to_bytes::iter_bytes_2(&21u8, ck, lsb0, f),
+
+          ty_opaque_box => 22u8.iter_bytes(lsb0, f),
+
+          ty_struct(ref did, ref substs) =>
+          to_bytes::iter_bytes_3(&23u8, did, substs, lsb0, f),
+
+          ty_rptr(ref r, ref mt) =>
+          to_bytes::iter_bytes_3(&24u8, r, mt, lsb0, f),
+
+          ty_err => 25u8.iter_bytes(lsb0, f),
+
+          ty_closure(ref ct) =>
+          to_bytes::iter_bytes_2(&26u8, ct, lsb0, f),
+        }
+    }
+}
 
 pub fn node_id_to_trait_ref(cx: ctxt, id: ast::node_id) -> @ty::TraitRef {
     match cx.trait_refs.find(&id) {
@@ -4284,6 +4490,7 @@ pub fn determine_inherited_purity(parent: (ast::purity, ast::node_id),
 // Here, the supertraits are the transitive closure of the supertrait
 // relation on the supertraits from each bounded trait's constraint
 // list.
+#[cfg(stage0)]
 pub fn each_bound_trait_and_supertraits(tcx: ctxt,
                                         bounds: &ParamBounds,
                                         f: &fn(@TraitRef) -> bool) {
@@ -4323,6 +4530,61 @@ pub fn each_bound_trait_and_supertraits(tcx: ctxt,
         }
     }
 }
+// Iterate over a type parameter's bounded traits and any supertraits
+// of those traits, ignoring kinds.
+// Here, the supertraits are the transitive closure of the supertrait
+// relation on the supertraits from each bounded trait's constraint
+// list.
+#[cfg(not(stage0))]
+pub fn each_bound_trait_and_supertraits(tcx: ctxt,
+                                        bounds: param_bounds,
+                                        f: &fn(&TraitRef) -> bool) -> bool {
+    for bounds.each |bound| {
+        let bound_trait_ref = match *bound {
+            ty::bound_trait(bound_t) => bound_t,
+
+            ty::bound_copy | ty::bound_owned |
+            ty::bound_const | ty::bound_durable => {
+                loop; // skip non-trait bounds
+            }
+        };
+
+        let mut supertrait_set = HashMap::new();
+        let mut trait_refs = ~[];
+        let mut i = 0;
+
+        // Seed the worklist with the trait from the bound
+        supertrait_set.insert(bound_trait_ref.def_id, ());
+        trait_refs.push(bound_trait_ref);
+
+        // Add the given trait ty to the hash map
+        while i < trait_refs.len() {
+            debug!("each_bound_trait_and_supertraits(i=%?, trait_ref=%s)",
+                   i, trait_refs[i].repr(tcx));
+
+            if !f(trait_refs[i]) {
+                return false;
+            }
+
+            // Add supertraits to supertrait_set
+            let supertrait_refs = trait_ref_supertraits(tcx, trait_refs[i]);
+            for supertrait_refs.each |&supertrait_ref| {
+                debug!("each_bound_trait_and_supertraits(supertrait_ref=%s)",
+                       supertrait_ref.repr(tcx));
+
+                let d_id = supertrait_ref.def_id;
+                if !supertrait_set.contains_key(&d_id) {
+                    // FIXME(#5527) Could have same trait multiple times
+                    supertrait_set.insert(d_id, ());
+                    trait_refs.push(supertrait_ref);
+                }
+            }
+
+            i += 1;
+        }
+    }
+    return true;
+}
 
 pub fn count_traits_and_supertraits(tcx: ctxt,
                                     type_param_defs: &[TypeParameterDef]) -> uint {
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 89eef1c7cb7..1c3890e2e17 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -828,6 +828,7 @@ pub impl FnCtxt {
         }
     }
 
+    #[cfg(stage0)]
     fn opt_node_ty_substs(&self, id: ast::node_id,
                           f: &fn(&ty::substs) -> bool) {
         match self.inh.node_type_substs.find(&id) {
@@ -835,6 +836,14 @@ pub impl FnCtxt {
             None => ()
         }
     }
+    #[cfg(not(stage0))]
+    fn opt_node_ty_substs(&self, id: ast::node_id,
+                          f: &fn(&ty::substs) -> bool) -> bool {
+        match self.inh.node_type_substs.find(&id) {
+            Some(s) => f(s),
+            None => true
+        }
+    }
 
     fn mk_subty(&self,
                 a_is_expected: bool,
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index 6a83db6baee..260d3f440f9 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -524,6 +524,7 @@ pub impl CoherenceChecker {
         }
     }
 
+    #[cfg(stage0)]
     fn each_provided_trait_method(&self,
             trait_did: ast::def_id,
             f: &fn(x: @ty::method) -> bool) {
@@ -543,6 +544,27 @@ pub impl CoherenceChecker {
             }
         }
     }
+    #[cfg(not(stage0))]
+    fn each_provided_trait_method(&self,
+            trait_did: ast::def_id,
+            f: &fn(x: @ty::method) -> bool) -> bool {
+        // Make a list of all the names of the provided methods.
+        // XXX: This is horrible.
+        let mut provided_method_idents = HashSet::new();
+        let tcx = self.crate_context.tcx;
+        for ty::provided_trait_methods(tcx, trait_did).each |ident| {
+            provided_method_idents.insert(*ident);
+        }
+
+        for ty::trait_methods(tcx, trait_did).each |&method| {
+            if provided_method_idents.contains(&method.ident) {
+                if !f(method) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
 
     fn polytypes_unify(&self, polytype_a: ty_param_bounds_and_ty,
                        polytype_b: ty_param_bounds_and_ty)
diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs
index 8349e16d2c4..73c120ad35d 100644
--- a/src/librustc/middle/typeck/infer/region_inference.rs
+++ b/src/librustc/middle/typeck/infer/region_inference.rs
@@ -560,6 +560,7 @@ enum Constraint {
     ConstrainVarSubReg(RegionVid, Region)
 }
 
+#[cfg(stage0)]
 impl to_bytes::IterBytes for Constraint {
    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
         match *self {
@@ -574,6 +575,21 @@ impl to_bytes::IterBytes for Constraint {
         }
     }
 }
+#[cfg(not(stage0))]
+impl to_bytes::IterBytes for Constraint {
+   fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
+        match *self {
+          ConstrainVarSubVar(ref v0, ref v1) =>
+          to_bytes::iter_bytes_3(&0u8, v0, v1, lsb0, f),
+
+          ConstrainRegSubVar(ref ra, ref va) =>
+          to_bytes::iter_bytes_3(&1u8, ra, va, lsb0, f),
+
+          ConstrainVarSubReg(ref va, ref ra) =>
+          to_bytes::iter_bytes_3(&2u8, va, ra, lsb0, f)
+        }
+    }
+}
 
 #[deriving(Eq, IterBytes)]
 struct TwoRegions {
@@ -1756,6 +1772,7 @@ pub impl RegionVarBindings {
         }
     }
 
+    #[cfg(stage0)]
     fn each_edge(&mut self,
                  graph: &Graph,
                  node_idx: RegionVid,
@@ -1771,6 +1788,23 @@ pub impl RegionVarBindings {
             edge_idx = edge_ptr.next_edge[dir as uint];
         }
     }
+    #[cfg(not(stage0))]
+    fn each_edge(&mut self,
+                 graph: &Graph,
+                 node_idx: RegionVid,
+                 dir: Direction,
+                 op: &fn(edge: &GraphEdge) -> bool) -> bool {
+        let mut edge_idx =
+            graph.nodes[node_idx.to_uint()].head_edge[dir as uint];
+        while edge_idx != uint::max_value {
+            let edge_ptr = &graph.edges[edge_idx];
+            if !op(edge_ptr) {
+                return false;
+            }
+            edge_idx = edge_ptr.next_edge[dir as uint];
+        }
+        return true;
+    }
 }
 
 fn iterate_until_fixed_point(
diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs
index 5e4f708f52f..8bf81a090cf 100644
--- a/src/libstd/ebml.rs
+++ b/src/libstd/ebml.rs
@@ -199,6 +199,7 @@ pub mod reader {
         }
     }
 
+    #[cfg(stage0)]
     pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) {
         let mut pos = d.start;
         while pos < d.end {
@@ -211,7 +212,22 @@ pub mod reader {
             }
         }
     }
+    #[cfg(not(stage0))]
+    pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) -> bool {
+        let mut pos = d.start;
+        while pos < d.end {
+            let elt_tag = vuint_at(*d.data, pos);
+            let elt_size = vuint_at(*d.data, elt_tag.next);
+            pos = elt_size.next + elt_size.val;
+            let doc = Doc { data: d.data, start: elt_size.next, end: pos };
+            if !it(elt_tag.val, doc) {
+                return false;
+            }
+        }
+        return true;
+    }
 
+    #[cfg(stage0)]
     pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) {
         let mut pos = d.start;
         while pos < d.end {
@@ -227,6 +243,23 @@ pub mod reader {
             }
         }
     }
+    #[cfg(not(stage0))]
+    pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) -> bool {
+        let mut pos = d.start;
+        while pos < d.end {
+            let elt_tag = vuint_at(*d.data, pos);
+            let elt_size = vuint_at(*d.data, elt_tag.next);
+            pos = elt_size.next + elt_size.val;
+            if elt_tag.val == tg {
+                let doc = Doc { data: d.data, start: elt_size.next,
+                                end: pos };
+                if !it(doc) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
 
     pub fn doc_data(d: Doc) -> ~[u8] {
         vec::slice::<u8>(*d.data, d.start, d.end).to_vec()