]> git.lizzy.rs Git - rust.git/commitdiff
Merge pull request #2164 from grahame/floatinfstr
authorBrian Anderson <andersrb@gmail.com>
Sun, 8 Apr 2012 20:55:22 +0000 (13:55 -0700)
committerBrian Anderson <andersrb@gmail.com>
Sun, 8 Apr 2012 20:55:22 +0000 (13:55 -0700)
write out "inf"/"-inf" in float::to_str_common

212 files changed:
doc/rust.md
doc/tutorial.md
mk/tests.mk
src/cargo/cargo.rc
src/cargo/cargo.rs
src/cargo/pgp.rs
src/compiletest/compiletest.rc
src/compiletest/compiletest.rs
src/compiletest/header.rs
src/compiletest/runtest.rs
src/etc/indenter [new file with mode: 0755]
src/fuzzer/fuzzer.rc
src/fuzzer/fuzzer.rs
src/libcore/comm.rs
src/libcore/core.rc
src/libcore/core.rs
src/libcore/iter.rs
src/libcore/option.rs
src/libcore/os.rs
src/libcore/priv.rs [new file with mode: 0644]
src/libcore/str.rs
src/libcore/task.rs
src/libcore/vec.rs
src/librustsyntax/ast.rs
src/librustsyntax/ast_util.rs
src/librustsyntax/attr.rs
src/librustsyntax/codemap.rs
src/librustsyntax/diagnostic.rs
src/librustsyntax/ext/build.rs
src/librustsyntax/ext/concat_idents.rs
src/librustsyntax/ext/fmt.rs
src/librustsyntax/ext/qquote.rs
src/librustsyntax/ext/simplext.rs
src/librustsyntax/fold.rs
src/librustsyntax/parse/eval.rs
src/librustsyntax/parse/parser.rs
src/librustsyntax/print/pprust.rs
src/librustsyntax/rustsyntax.rc
src/librustsyntax/visit.rs
src/libstd/smallintmap.rs
src/libstd/std.rc
src/libstd/test.rs
src/libstd/time.rs
src/libstd/uv.rs
src/libstd/uv_hl.rs [new file with mode: 0644]
src/libstd/uv_ll.rs [new file with mode: 0644]
src/rt/rust_builtin.cpp
src/rt/rust_kernel.cpp
src/rt/rust_kernel.h
src/rt/rust_scheduler.cpp
src/rt/rust_uv.cpp
src/rt/rustrt.def.in
src/rustc/back/link.rs
src/rustc/back/rpath.rs
src/rustc/back/upcall.rs
src/rustc/driver/driver.rs
src/rustc/driver/rustc.rs
src/rustc/front/config.rs
src/rustc/front/test.rs
src/rustc/lib/llvm.rs
src/rustc/metadata/astencode.rs
src/rustc/metadata/common.rs
src/rustc/metadata/creader.rs
src/rustc/metadata/csearch.rs
src/rustc/metadata/cstore.rs
src/rustc/metadata/decoder.rs
src/rustc/metadata/encoder.rs
src/rustc/metadata/tydecode.rs
src/rustc/metadata/tyencode.rs
src/rustc/middle/alias.rs
src/rustc/middle/ast_map.rs
src/rustc/middle/block_use.rs
src/rustc/middle/check_alt.rs
src/rustc/middle/check_const.rs
src/rustc/middle/check_loop.rs
src/rustc/middle/fn_usage.rs
src/rustc/middle/infer.rs
src/rustc/middle/kind.rs
src/rustc/middle/last_use.rs
src/rustc/middle/lint.rs
src/rustc/middle/mutbl.rs
src/rustc/middle/pairwise.rs [new file with mode: 0644]
src/rustc/middle/pat_util.rs
src/rustc/middle/region.rs
src/rustc/middle/regionck.rs
src/rustc/middle/resolve.rs
src/rustc/middle/trans/base.rs
src/rustc/middle/trans/closure.rs
src/rustc/middle/trans/common.rs
src/rustc/middle/trans/debuginfo.rs
src/rustc/middle/trans/reachable.rs
src/rustc/middle/trans/shape.rs
src/rustc/middle/trans/type_use.rs
src/rustc/middle/tstate/annotate.rs
src/rustc/middle/tstate/auxiliary.rs
src/rustc/middle/tstate/bitvectors.rs
src/rustc/middle/tstate/ck.rs
src/rustc/middle/tstate/collect_locals.rs
src/rustc/middle/tstate/pre_post_conditions.rs
src/rustc/middle/tstate/states.rs
src/rustc/middle/ty.rs
src/rustc/middle/typeck.rs
src/rustc/rustc.rc
src/rustc/util/common.rs
src/rustc/util/filesearch.rs
src/rustc/util/ppaux.rs
src/rustdoc/config.rs
src/rustdoc/markdown_pass.rs
src/rustdoc/par.rs
src/rustdoc/reexport_pass.rs
src/rustdoc/rustdoc.rc
src/rustdoc/sectionalize_pass.rs
src/test/auxiliary/cci_nested_lib.rs
src/test/auxiliary/crateresolve1-1.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve1-2.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve1-3.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve2-1.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve2-2.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve2-3.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve3-1.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve3-2.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve4a-1.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve4a-2.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve4b-1.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve4b-2.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve5-1.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve5-2.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve6-1.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve6-2.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve7-1.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve7-2.rs [new file with mode: 0644]
src/test/auxiliary/crateresolve7x.rs [new file with mode: 0644]
src/test/bench/msgsend.rs
src/test/bench/shootout-fasta.rs
src/test/bench/shootout-pfib.rs
src/test/bench/task-perf-word-count-generic.rs
src/test/bench/task-perf-word-count.rs
src/test/compile-fail/bad-bang-ann-3.rs
src/test/compile-fail/bad-bang-ann.rs
src/test/compile-fail/bang-tailexpr.rs
src/test/compile-fail/block-must-not-have-result-for.rs
src/test/compile-fail/crateresolve1.rs [new file with mode: 0644]
src/test/compile-fail/crateresolve2.rs [new file with mode: 0644]
src/test/compile-fail/crateresolve5.rs [new file with mode: 0644]
src/test/compile-fail/issue-2149.rs [new file with mode: 0644]
src/test/compile-fail/issue-2150.rs [new file with mode: 0644]
src/test/compile-fail/issue-2151.rs [new file with mode: 0644]
src/test/compile-fail/issue-897-2.rs
src/test/compile-fail/issue-897.rs
src/test/compile-fail/loop-does-not-diverge.rs
src/test/compile-fail/rec-expected.rs [new file with mode: 0644]
src/test/compile-fail/regions-leaking-ptr.rs [new file with mode: 0644]
src/test/compile-fail/regions-nested-fns.rs [new file with mode: 0644]
src/test/compile-fail/terr-in-field.rs [new file with mode: 0644]
src/test/compile-fail/terr-sorts.rs [new file with mode: 0644]
src/test/compile-fail/tps-invariant-class.rs [new file with mode: 0644]
src/test/compile-fail/tps-invariant-enum.rs [new file with mode: 0644]
src/test/compile-fail/tps-invariant-iface.rs [new file with mode: 0644]
src/test/compile-fail/unreachable-code-1.rs [new file with mode: 0644]
src/test/compile-fail/unsafe-for.rs [deleted file]
src/test/compile-fail/vec-add.rs [new file with mode: 0644]
src/test/compile-fail/vec-concat-bug.rs
src/test/pretty/disamb-stmt-expr.rs
src/test/run-pass/argv.rs
src/test/run-pass/auto-loop.rs
src/test/run-pass/bind-native-fn.rs
src/test/run-pass/block-iter-1.rs
src/test/run-pass/block-iter-2.rs
src/test/run-pass/break.rs
src/test/run-pass/crateresolve1.rs [new file with mode: 0644]
src/test/run-pass/crateresolve2.rs [new file with mode: 0644]
src/test/run-pass/crateresolve3.rs [new file with mode: 0644]
src/test/run-pass/crateresolve4.rs [new file with mode: 0644]
src/test/run-pass/crateresolve5.rs [new file with mode: 0644]
src/test/run-pass/crateresolve6.rs [new file with mode: 0644]
src/test/run-pass/crateresolve7.rs [new file with mode: 0644]
src/test/run-pass/early-ret-binop-add.rs
src/test/run-pass/for-destruct.rs
src/test/run-pass/for-implicit-copy.rs [deleted file]
src/test/run-pass/for-loop-fail.rs
src/test/run-pass/hashmap-memory.rs
src/test/run-pass/iface-generic.rs
src/test/run-pass/linear-for-loop.rs
src/test/run-pass/loop-scope.rs
src/test/run-pass/lots-a-fail.rs
src/test/run-pass/main-ivec.rs
src/test/run-pass/maybe-mutable.rs
src/test/run-pass/monad.rs
src/test/run-pass/morestack6.rs
src/test/run-pass/option-ext.rs [new file with mode: 0644]
src/test/run-pass/osmain.rs
src/test/run-pass/region-param.rs [deleted file]
src/test/run-pass/regions-bot.rs [new file with mode: 0644]
src/test/run-pass/regions-params.rs [new file with mode: 0644]
src/test/run-pass/send-iloop.rs
src/test/run-pass/shadow.rs
src/test/run-pass/static-impl.rs
src/test/run-pass/task-comm-12.rs
src/test/run-pass/task-comm-3.rs
src/test/run-pass/task-comm-9.rs
src/test/run-pass/task-comm.rs
src/test/run-pass/task-killjoin.rs
src/test/run-pass/too-much-recursion.rs
src/test/run-pass/unreachable-code.rs
src/test/run-pass/unwind-box.rs
src/test/run-pass/unwind-resource.rs
src/test/run-pass/unwind-resource2.rs
src/test/run-pass/unwind-unique.rs
src/test/run-pass/use-crate-name-alias.rs [new file with mode: 0644]
src/test/run-pass/utf8.rs
src/test/run-pass/yield.rs
src/test/run-pass/yield1.rs

index b27befedd6bec1041efa2cf16135905ff84d9023..afe55bf159eafa91d7e0efd85bd60628661b533d 100644 (file)
@@ -1000,11 +1000,11 @@ the function name.
 
 ~~~~
 fn iter<T>(seq: [T], f: fn(T)) {
-    for elt: T in seq { f(elt); }
+    for seq.each {|elt| f(elt); }
 }
 fn map<T, U>(seq: [T], f: fn(T) -> U) -> [U] {
     let mut acc = [];
-    for elt in seq { acc += [f(elt)]; }
+    for seq.each {|elt| acc += [f(elt)]; }
     acc
 }
 ~~~~
@@ -1617,9 +1617,9 @@ is bounds-checked at run-time. When the check fails, it will put the
 task in a _failing state_.
 
 ~~~~
-# let builder = task::task_builder();
-# task::unsupervise(builder);
-# task::run(builder) {||
+# let buildr = task::builder();
+# task::unsupervise(buildr);
+# task::run(buildr) {||
 
 [1, 2, 3, 4][0];
 [mut 'x', 'y'][1] = 'z';
@@ -2113,7 +2113,7 @@ An example a for loop:
 
 let v: [foo] = [a, b, c];
 
-for e: foo in v {
+for v.each {|e|
     bar(e);
 }
 ~~~~
@@ -2228,7 +2228,7 @@ fn main() {
 ~~~~
 
 Multiple alternative patterns may be joined with the `|` operator.  A
-range of values may be specified with `to`.  For example:
+range of values may be specified with `to`. For example:
 
 ~~~~
 # let x = 2;
index 66f3070de6c4ea81c39a6b11277e3d40ee9a5af9..5ce05b2b50230cfb7716f3dd8f60dc6166f7b6f9 100644 (file)
@@ -690,19 +690,6 @@ do {
 } while any_cake_left();
 ~~~~
 
-When iterating over a vector, use `for` instead.
-
-~~~~
-for elt in ["red", "green", "blue"] {
-    io::println(elt);
-}
-~~~~
-
-This will go over each element in the given vector (a three-element
-vector of strings, in this case), and repeatedly execute the body with
-`elt` bound to the current element. You may add an optional type
-declaration (`elt: str`) for the iteration variable if you want.
-
 For more involved iteration, such as going over the elements of a hash
 table, Rust uses higher-order functions. We'll come back to those in a
 moment.
@@ -1095,8 +1082,8 @@ enum color {
 ~~~~
 
 If an explicit discriminator is not specified for a variant, the value
-defaults to the value of the previous variant plus one.  If the first
-variant does not have a discriminator, it defaults to 0.  For example,
+defaults to the value of the previous variant plus one. If the first
+variant does not have a discriminator, it defaults to 0. For example,
 the value of `north` is 0, `east` is 1, etc.
 
 When an enum is C-like the `as` cast operator can be used to get the
@@ -1399,7 +1386,7 @@ not sure.
 
 ~~~~
 fn for_each(v: [mut @int], iter: fn(@int)) {
-   for elt in v { iter(elt); }
+   for v.each {|elt| iter(elt); }
 }
 ~~~~
 
@@ -1422,7 +1409,7 @@ with the `copy` operator:
 ~~~~
 type mutrec = {mut x: int};
 fn for_each(v: [mut mutrec], iter: fn(mutrec)) {
-   for elt in v { iter(copy elt); }
+   for v.each {|elt| iter(copy elt); }
 }
 ~~~~
 
@@ -1509,7 +1496,7 @@ fn for_rev<T>(v: [T], act: fn(T)) {
 
 fn map<T, U>(v: [T], f: fn(T) -> U) -> [U] {
     let mut acc = [];
-    for elt in v { acc += [f(elt)]; }
+    for v.each {|elt| acc += [f(elt)]; }
     ret acc;
 }
 ~~~~
@@ -1551,7 +1538,7 @@ programs that just can't be typed.
 
 ~~~~
 let n = option::none;
-# option::with_option_do(n, fn&(&&x:int) {})
+# option::iter(n, fn&(&&x:int) {})
 ~~~~
 
 If you never do anything else with `n`, the compiler will not be able
@@ -1686,6 +1673,7 @@ purpose, you create a `.rc` crate file, which references any number of
 
 ~~~~ {.ignore}
 #[link(name = "farm", vers = "2.5", author = "mjh")];
+#[crate_type = "lib"];
 mod cow;
 mod chicken;
 mod horse;
@@ -1694,7 +1682,9 @@ mod horse;
 Compiling this file will cause `rustc` to look for files named
 `cow.rs`, `chicken.rs`, `horse.rs` in the same directory as the `.rc`
 file, compile them all together, and, depending on the presence of the
-`--lib` switch, output a shared library or an executable.
+`crate_type = "lib"` attribute, output a shared library or an executable.
+(If the line `#[crate_type = "lib"];` was omitted, `rustc` would create an
+executable.)
 
 The `#[link(...)]` part provides meta information about the module,
 which other crates can use to load the right module. More about that
@@ -1717,9 +1707,9 @@ content to the `poultry` module itself.
 
 ## Using other crates
 
-Having compiled a crate with `--lib`, you can use it in another crate
-with a `use` directive. We've already seen `use std` in several of the
-examples, which loads in the [standard library][std].
+Having compiled a crate that contains the `#[crate_type = "lib"]` attribute,
+you can use it in another crate with a `use` directive. We've already seen
+`use std` in several of the examples, which loads in the [standard library][std].
 
 [std]: http://doc.rust-lang.org/doc/std/index/General.html
 
@@ -1984,7 +1974,7 @@ parameters.
 # iface to_str { fn to_str() -> str; }
 fn comma_sep<T: to_str>(elts: [T]) -> str {
     let mut result = "", first = true;
-    for elt in elts {
+    for elts.each {|elt|
         if first { first = false; }
         else { result += ", "; }
         result += elt.to_str();
@@ -2014,7 +2004,7 @@ iface seq<T> {
 impl <T> of seq<T> for [T] {
     fn len() -> uint { vec::len(self) }
     fn iter(b: fn(T)) {
-        for elt in self { b(elt); }
+        for self.each {|elt| b(elt); }
     }
 }
 ~~~~
@@ -2034,7 +2024,7 @@ However, consider this function:
 ~~~~
 # iface drawable { fn draw(); }
 fn draw_all<T: drawable>(shapes: [T]) {
-    for shape in shapes { shape.draw(); }
+    for shapes.each {|shape| shape.draw(); }
 }
 ~~~~
 
@@ -2048,7 +2038,7 @@ the function to be written simply like this:
 ~~~~
 # iface drawable { fn draw(); }
 fn draw_all(shapes: [drawable]) {
-    for shape in shapes { shape.draw(); }
+    for shapes.each {|shape| shape.draw(); }
 }
 ~~~~
 
@@ -2133,7 +2123,7 @@ native mod crypto {
 
 fn as_hex(data: [u8]) -> str {
     let mut acc = "";
-    for byte in data { acc += #fmt("%02x", byte as uint); }
+    for data.each {|byte| acc += #fmt("%02x", byte as uint); }
     ret acc;
 }
 
index fd547b808205fb43dde701bb4eb5b4908b426abc..4b9efcf147a6470ea59a945f64cbfbd3705ef486 100644 (file)
@@ -522,7 +522,7 @@ $(3)/test/$$(FT_DRIVER)-$(2)$$(X): \
                $$(TLIB2_T_$(2)_H_$(3))/$$(FT_LIB) \
                $$(SREQ2_T_$(2)_H_$(3))
        @$$(call E, compile_and_link: $$@ $$<)
-       $$(STAGE2_T_$(2)_H_$(3)) -L $$(TLIB2_T_$(2)_H_$(3)) -o $$@ $$<
+       $$(STAGE2_T_$(2)_H_$(3)) -o $$@ $$<
 
 $(3)/test/$$(FT_DRIVER)-$(2).out: \
                $(3)/test/$$(FT_DRIVER)-$(2)$$(X) \
index 29c6a27d41caa8ee41f84a9582cd16964306fe85..7a426a44cbb9610075eace5e413c0e03b4068432 100644 (file)
 
 #[crate_type = "bin"];
 
+#[no_core];
+
+use core(vers = "0.2");
+use std(vers = "0.2");
+use rustc(vers = "0.2");
+
+import core::*;
+
 mod pgp;
index aa8aa706778ca9d9b2f74242670806d5d716d533..5c135423b8b45411fc21c2ec919fa678aac6dd74 100644 (file)
@@ -1,8 +1,5 @@
 // cargo.rs - Rust package manager
 
-use rustc;
-use std;
-
 import rustc::syntax::{ast, codemap};
 import rustc::syntax::parse::parser;
 import rustc::util::filesearch::{get_cargo_root, get_cargo_root_nearest,
@@ -96,7 +93,7 @@ fn load_link(mis: [@ast::meta_item]) -> (option<str>,
     let mut name = none;
     let mut vers = none;
     let mut uuid = none;
-    for a: @ast::meta_item in mis {
+    for mis.each {|a|
         alt a.node {
             ast::meta_name_value(v, {node: ast::lit_str(s), span: _}) {
                 alt v {
@@ -131,7 +128,7 @@ fn load_pkg(filename: str) -> option<pkg> {
     let mut sigs = none;
     let mut crate_type = none;
 
-    for a in c.node.attrs {
+    for c.node.attrs.each {|a|
         alt a.node.value.node {
             ast::meta_name_value(v, {node: ast::lit_str(s), span: _}) {
                 alt v {
@@ -276,7 +273,7 @@ fn load_one_source_package(&src: source, p: map::hashmap<str, json::json>) {
     let mut tags = [];
     alt p.find("tags") {
         some(json::list(js)) {
-            for j in js {
+            for js.each {|j|
                 alt j {
                     json::string(_j) { vec::grow(tags, 1u, _j); }
                     _ { }
@@ -316,7 +313,7 @@ fn load_source_packages(&c: cargo, &src: source) {
     let pkgstr = io::read_whole_file_str(pkgfile);
     alt json::from_str(result::get(pkgstr)) {
         ok(json::list(js)) {
-            for _j: json::json in js {
+            for js.each {|_j|
                 alt _j {
                     json::dict(_p) {
                         load_one_source_package(src, _p);
@@ -426,7 +423,7 @@ fn configure(opts: options) -> cargo {
 
 fn for_each_package(c: cargo, b: fn(source, package)) {
     c.sources.values({ |v|
-        for p in copy v.packages {
+        for vec::each(copy v.packages) {|p|
             b(v, p);
         }
     })
@@ -435,7 +432,7 @@ fn for_each_package(c: cargo, b: fn(source, package)) {
 // Runs all programs in directory <buildpath>
 fn run_programs(buildpath: str) {
     let newv = os::list_dir_path(buildpath);
-    for ct: str in newv {
+    for newv.each {|ct|
         run::run_program(ct, []);
     }
 }
@@ -473,7 +470,7 @@ fn install_one_crate(c: cargo, path: str, cf: str) {
     };
     let newv = os::list_dir_path(buildpath);
     let exec_suffix = os::exe_suffix();
-    for ct: str in newv {
+    for newv.each {|ct|
         if (exec_suffix != "" && str::ends_with(ct, exec_suffix)) ||
             (exec_suffix == "" && !str::starts_with(path::basename(ct),
                                                     "lib")) {
@@ -531,7 +528,7 @@ fn install_source(c: cargo, path: str) {
         fail "This doesn't look like a rust package (no .rc files).";
     }
 
-    for cf: str in cratefiles {
+    for cratefiles.each {|cf|
         let p = load_pkg(cf);
         alt p {
             none { cont; }
@@ -621,7 +618,8 @@ fn install_uuid(c: cargo, wd: str, uuid: str) {
         ret;
     }
     error("Found multiple packages:");
-    for (s,p) in ps {
+    for ps.each {|elt|
+        let (s,p) = elt;
         info("  " + s.name + "/" + p.uuid + " (" + p.name + ")");
     }
 }
@@ -642,7 +640,8 @@ fn install_named(c: cargo, wd: str, name: str) {
         ret;
     }
     error("Found multiple packages:");
-    for (s,p) in ps {
+    for ps.each {|elt|
+        let (s,p) = elt;
         info("  " + s.name + "/" + p.uuid + " (" + p.name + ")");
     }
 }
index 7756f08e8f440d26defe3dbc00e7a413c55b43dd..1dcb3b3fe5add38b0e1fdd173ecc76d5223417ad 100644 (file)
@@ -1,5 +1,3 @@
-use std;
-
 fn gpg(args: [str]) -> { status: int, out: str, err: str } {
     ret run::program_output("gpg", args);
 }
@@ -91,10 +89,9 @@ fn verify(root: str, data: str, sig: str, keyfp: str) -> bool {
     let p = gpg(["--homedir", path, "--with-fingerprint", "--verify", sig,
                  data]);
     let res = "Primary key fingerprint: " + keyfp;
-    for line in str::split_char(p.err, '\n') {
-        if line == res {
-            ret true;
-        }
+    let mut rslt = false;
+    for str::split_char(p.err, '\n').each {|line|
+        if line == res { rslt = true; }
     }
-    ret false;
+    ret rslt;
 }
index c652c593c8bb89d99fd0269729bf408bc7ba880f..ba04952df5d5f9a0c5d70988853157b966974ec6 100644 (file)
@@ -1,6 +1,11 @@
 #[crate_type = "bin"];
 
-use std;
+#[no_core];
+
+use core(vers = "0.2");
+use std(vers = "0.2");
+
+import core::*;
 
 mod procsrv;
 mod util;
index efe5db13d0ac74a5c59e200bb254c87a76c04a3a..079fba0ba652d7393de93e828b78166ee5579b91 100644 (file)
@@ -135,7 +135,7 @@ fn test_opts(config: config) -> test::test_opts {
 fn make_tests(config: config) -> [test::test_desc] {
     #debug("making tests from %s", config.src_base);
     let mut tests = [];
-    for file: str in os::list_dir_path(config.src_base) {
+    for os::list_dir_path(config.src_base).each {|file|
         let file = file;
         #debug("inspecting file %s", file);
         if is_test(config, file) {
@@ -154,11 +154,11 @@ fn is_test(config: config, testfile: str) -> bool {
 
     let mut valid = false;
 
-    for ext in valid_extensions {
+    for valid_extensions.each {|ext|
         if str::ends_with(name, ext) { valid = true; }
     }
 
-    for pre in invalid_prefixes {
+    for invalid_prefixes.each {|pre|
         if str::starts_with(name, pre) { valid = false; }
     }
 
index 004fa08960fac373ab629a76435111f87b3aceb3..75f4eb98050c689c374e81a04dd6afcce6390e41 100644 (file)
@@ -40,7 +40,7 @@ fn load_props(testfile: str) -> test_props {
             pp_exact = parse_pp_exact(ln, testfile);
         }
 
-        option::with_option_do(parse_aux_build(ln)) {|ab|
+        option::iter(parse_aux_build(ln)) {|ab|
             aux_builds += [ab];
         }
     };
index 776ba074c12044e8781da81b50c9da74122ecc8d..8b04bc8fb050d19b78c7b613767fbe654ad252f5 100644 (file)
@@ -196,17 +196,20 @@ fn check_error_patterns(props: test_props,
 
     let mut next_err_idx = 0u;
     let mut next_err_pat = props.error_patterns[next_err_idx];
-    for line: str in str::split_char(procres.stderr, '\n') {
+    let mut done = false;
+    for str::split_char(procres.stderr, '\n').each {|line|
         if str::contains(line, next_err_pat) {
             #debug("found error pattern %s", next_err_pat);
             next_err_idx += 1u;
             if next_err_idx == vec::len(props.error_patterns) {
                 #debug("found all error patterns");
-                ret;
+                done = true;
+                break;
             }
             next_err_pat = props.error_patterns[next_err_idx];
         }
     }
+    if done { ret; }
 
     let missing_patterns =
         vec::slice(props.error_patterns, next_err_idx,
@@ -215,7 +218,7 @@ fn check_error_patterns(props: test_props,
         fatal_procres(#fmt["error pattern '%s' not found!",
                            missing_patterns[0]], procres);
     } else {
-        for pattern: str in missing_patterns {
+        for missing_patterns.each {|pattern|
             error(#fmt["error pattern '%s' not found!", pattern]);
         }
         fatal_procres("multiple error patterns not found", procres);
@@ -244,9 +247,9 @@ fn check_expected_errors(expected_errors: [errors::expected_error],
     //    filename:line1:col1: line2:col2: *warning:* msg
     // where line1:col1: is the starting point, line2:col2:
     // is the ending point, and * represents ANSI color codes.
-    for line: str in str::split_char(procres.stderr, '\n') {
+    for str::split_char(procres.stderr, '\n').each {|line|
         let mut was_expected = false;
-        vec::iteri(expected_errors) {|i, ee|
+        for vec::eachi(expected_errors) {|i, ee|
             if !found_flags[i] {
                 #debug["prefix=%s ee.kind=%s ee.msg=%s line=%s",
                        prefixes[i], ee.kind, ee.msg, line];
@@ -255,6 +258,7 @@ fn check_expected_errors(expected_errors: [errors::expected_error],
                     str::contains(line, ee.msg)) {
                     found_flags[i] = true;
                     was_expected = true;
+                    break;
                 }
             }
         }
diff --git a/src/etc/indenter b/src/etc/indenter
new file mode 100755 (executable)
index 0000000..db0009f
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/perl -w
+
+$ident = 0;
+while (<>) {
+    if (/^rust: ">>/) {
+        $indent += 1;
+    } elsif (/^rust: "<</) {
+        $indent -= 1;
+    }
+
+    printf "%03d  ", $indent;
+    for ($i = 0; $i < $indent; $i++) {
+        printf("  ");
+    }
+    print;
+}
+
index 39d9779827abcde30040e9f5ff83498dad26a6e1..be3352a6ab2c880a4c06aca55ee76a32159ad0f7 100644 (file)
@@ -2,8 +2,13 @@
 
 #[crate_type = "bin"];
 
-use std;
-use rustc;
+#[no_core];
+
+use core(vers = "0.2");
+use std(vers = "0.2");
+use rustc(vers = "0.2");
+
+import core::*;
 
 // Local Variables:
 // fill-column: 78;
index 87dece998b0dda63569e8a4cdf5d62af51dcc7cf..7b76487baf746066bce5e863c6458a60cab64cb6 100644 (file)
@@ -25,7 +25,7 @@ fn find_rust_files(&files: [str], path: str) {
     } else if os::path_is_dir(path)
         && !contains(path, "compile-fail")
         && !contains(path, "build") {
-        for p in os::list_dir_path(path) {
+        for os::list_dir_path(path).each {|p|
             find_rust_files(files, p);
         }
     }
@@ -71,7 +71,6 @@ fn dsl(l: ast::lit_) -> ast::lit {
           ast::expr_if_check(_, _, _) { false }
           ast::expr_block(_) { false }
           ast::expr_alt(_, _, _) { false }
-          ast::expr_for(_, _, _) { false }
           ast::expr_while(_, _) { false }
 
           // https://github.com/mozilla/rust/issues/955
@@ -439,7 +438,7 @@ fn content_is_dangerous_to_run(code: str) -> bool {
          "unsafe",
          "log"];    // python --> rust pipe deadlock?
 
-    for p: str in dangerous_patterns { if contains(code, p) { ret true; } }
+    for dangerous_patterns.each {|p| if contains(code, p) { ret true; } }
     ret false;
 }
 
@@ -447,7 +446,7 @@ fn content_is_dangerous_to_compile(code: str) -> bool {
     let dangerous_patterns =
         ["xfail-test"];
 
-    for p: str in dangerous_patterns { if contains(code, p) { ret true; } }
+    for dangerous_patterns.each {|p| if contains(code, p) { ret true; } }
     ret false;
 }
 
@@ -462,7 +461,7 @@ fn content_might_not_converge(code: str) -> bool {
          "\n\n\n\n\n"  // https://github.com/mozilla/rust/issues/850
         ];
 
-    for p: str in confusing_patterns { if contains(code, p) { ret true; } }
+    for confusing_patterns.each {|p| if contains(code, p) { ret true; } }
     ret false;
 }
 
@@ -475,7 +474,7 @@ fn file_might_not_converge(filename: str) -> bool {
     ];
 
 
-    for f in confusing_files { if contains(filename, f) { ret true; } }
+    for confusing_files.each {|f| if contains(filename, f) { ret true; } }
 
     ret false;
 }
@@ -509,7 +508,7 @@ fn check_roundtrip_convergence(code: @str, maxIters: uint) {
 
 fn check_convergence(files: [str]) {
     #error("pp convergence tests: %u files", vec::len(files));
-    for file in files {
+    for files.each {|file|
         if !file_might_not_converge(file) {
             let s = @result::get(io::read_whole_file_str(file));
             if !content_might_not_converge(*s) {
@@ -522,7 +521,7 @@ fn check_convergence(files: [str]) {
 }
 
 fn check_variants(files: [str], cx: context) {
-    for file in files {
+    for files.each {|file|
         if cx.mode == tm_converge && file_might_not_converge(file) {
             #error("Skipping convergence test based on file_might_not_converge");
             cont;
index 69fd09e618c13313ff4ae18981b24d4408c19cfd..1a86ccf367151fbfc2d7d41015bec3493bae43f1 100644 (file)
@@ -37,8 +37,7 @@ enum rust_port {}
 
 #[abi = "cdecl"]
 native mod rustrt {
-    fn rust_port_id_send<T: send>(t: *sys::type_desc,
-                                  target_port: port_id,
+    fn rust_port_id_send<T: send>(target_port: port_id,
                                   data: T) -> libc::uintptr_t;
 
     fn new_port(unit_sz: libc::size_t) -> *rust_port;
@@ -114,7 +113,7 @@ enum port<T: send> { port_t(@port_ptr<T>) }
 "]
 fn send<T: send>(ch: chan<T>, -data: T) {
     let chan_t(p) = ch;
-    let res = rustrt::rust_port_id_send(sys::get_type_desc::<T>(), p, data);
+    let res = rustrt::rust_port_id_send(p, data);
     if res != 0u unsafe {
         // Data sent successfully
         unsafe::forget(data);
index 4a03247c642227f376da7ca4a7add8f299990ff1..c0d46a9fad506ae12fbc6e856e5f6c46beea2353 100644 (file)
@@ -37,6 +37,11 @@ export extfmt;
 export tuple;
 export to_str;
 
+// FIXME: This creates some APIs that I do not want to commit to. It is
+// currently exported for the uv code in std, but when that code moves into
+// core this should become unexported
+export priv;
+
 // Built-in-type support modules
 
 mod box;
@@ -61,7 +66,8 @@ mod bool;
 
 // For internal use by char, not exported
 mod unicode;
-
+// Do not export
+mod priv;
 
 // Ubiquitous-utility-type modules
 
index 92310166426f9ccee1c568995e66591d2ab53858..39781df0ef0c8a2071b8d89037a64b1560d54e19 100644 (file)
@@ -40,7 +40,7 @@ mod core {
 // Similar to above. Some magic to make core testable.
 #[cfg(test)]
 mod std {
-    use std;
+    use std(vers = "0.2");
     import std::test;
 }
 
index 9e8abefb4a04a43f0845368a677cfee6d536641a..1eca3daa18c21b2ee65c4e382f69ea2b85b39c01 100644 (file)
@@ -29,7 +29,7 @@ fn iter(blk: fn(A)) {
 
 impl<A> of iterable<A> for option<A> {
     fn iter(blk: fn(A)) {
-        option::with_option_do(self, blk)
+        option::iter(self, blk)
     }
 }
 
index daf9a2293542f3a074e43e28c27d8918de05513d..a20e985023033ebb417a4461844b0646aaa21ae3 100644 (file)
@@ -58,13 +58,13 @@ fn chain<T, U>(opt: option<T>, f: fn(T) -> option<U>) -> option<U> {
     alt opt { some(x) { x } none { def } }
 }
 
-fn with_option<T, U: copy>(opt: option<T>, def: U, f: fn(T) -> U) -> U {
+fn map_default<T, U: copy>(opt: option<T>, def: U, f: fn(T) -> U) -> U {
     #[doc = "Applies a function to the contained value or returns a default"];
 
     alt opt { none { def } some(t) { f(t) } }
 }
 
-fn with_option_do<T>(opt: option<T>, f: fn(T)) {
+fn iter<T>(opt: option<T>, f: fn(T)) {
     #[doc = "Performs an operation on the contained value or does nothing"];
 
     alt opt { none { } some(t) { f(t); } }
@@ -96,10 +96,10 @@ fn chain<U>(f: fn(T) -> option<U>) -> option<U> { chain(self, f) }
     #[doc = "Returns the contained value or a default"]
     fn get_or_default(def: T) -> T { get_or_default(self, def) }
     #[doc = "Applies a function to the contained value or returns a default"]
-    fn with_option<U: copy>(def: U, f: fn(T) -> U) -> U
-        { with_option(self, def, f) }
+    fn map_default<U: copy>(def: U, f: fn(T) -> U) -> U
+        { map_default(self, def, f) }
     #[doc = "Performs an operation on the contained value or does nothing"]
-    fn with_option_do(f: fn(T)) { with_option_do(self, f) }
+    fn iter(f: fn(T)) { iter(self, f) }
     #[doc = "
     Gets the value out of an option
 
index c6ed037f37ac5c08f86bee099eea8b3f31627fe3..1df34e5f393d9d7d50919160d8ad4e27a0a276e5 100644 (file)
@@ -467,7 +467,7 @@ fn star(p: str) -> str {
     }
 
     rustrt::rust_list_files(star(p)).filter {|filename|
-        !str::eq(filename, ".") || !str::eq(filename, "..")
+        !str::eq(filename, ".") && !str::eq(filename, "..")
     }
 }
 
@@ -717,6 +717,7 @@ fn test_self_exe_path() {
     }
 
     #[test]
+    #[ignore]
     fn test_env_getenv() {
         let e = env();
         assert vec::len(e) > 0u;
@@ -766,7 +767,7 @@ fn homedir() {
         setenv("HOME", "");
         assert os::homedir() == none;
 
-        option::with_option_do(oldhome, {|s| setenv("HOME", s)});
+        option::iter(oldhome, {|s| setenv("HOME", s)});
     }
 
     #[test]
@@ -796,8 +797,8 @@ fn homedir() {
         setenv("USERPROFILE", "/home/PaloAlto");
         assert os::homedir() == some("/home/MountainView");
 
-        option::with_option_do(oldhome, {|s| setenv("HOME", s)});
-        option::with_option_do(olduserprofile,
+        option::iter(oldhome, {|s| setenv("HOME", s)});
+        option::iter(olduserprofile,
                                {|s| setenv("USERPROFILE", s)});
     }
 
@@ -849,7 +850,7 @@ fn copy_file_ok() {
       };
       assert (ostream as uint != 0u);
       let s = "hello";
-      let mut buf = str::bytes(s) + [0 as u8];
+      let mut buf = vec::to_mut(str::bytes(s) + [0 as u8]);
       vec::as_mut_buf(buf) {|b|
          assert (libc::fwrite(b as *c_void, 1u, str::len(s) + 1u, ostream) ==
                  buf.len())};
diff --git a/src/libcore/priv.rs b/src/libcore/priv.rs
new file mode 100644 (file)
index 0000000..b8e0848
--- /dev/null
@@ -0,0 +1,229 @@
+#[doc(hidden)];
+
+export chan_from_global_ptr;
+
+import compare_and_swap = rustrt::rust_compare_and_swap_ptr;
+
+type rust_port_id = uint;
+
+native mod rustrt {
+    fn rust_compare_and_swap_ptr(address: *libc::uintptr_t,
+                                 oldval: libc::uintptr_t,
+                                 newval: libc::uintptr_t) -> bool;
+    fn rust_task_weaken(ch: rust_port_id);
+    fn rust_task_unweaken(ch: rust_port_id);
+}
+
+type global_ptr<T: send> = *libc::uintptr_t;
+
+#[doc = "
+Atomically gets a channel from a pointer to a pointer-sized memory location
+or, if no channel exists creates and installs a new channel and sets up a new
+task to receive from it.
+"]
+unsafe fn chan_from_global_ptr<T: send>(
+    global: global_ptr<T>,
+    builder: fn() -> task::builder,
+    f: fn~(comm::port<T>)
+) -> comm::chan<T> {
+
+    enum msg {
+        proceed,
+        abort
+    }
+
+    let is_probably_zero = *global == 0u;
+    if is_probably_zero {
+        // There's no global channel. We must make it
+
+        let setup_po = comm::port();
+        let setup_ch = comm::chan(setup_po);
+        let setup_ch = task::run_listener(builder()) {|setup_po|
+            let po = comm::port::<T>();
+            let ch = comm::chan(po);
+            comm::send(setup_ch, ch);
+
+            // Wait to hear if we are the official instance of
+            // this global task
+            alt comm::recv::<msg>(setup_po) {
+              proceed { f(po); }
+              abort { }
+            }
+        };
+
+        // This is the proposed global channel
+        let ch = comm::recv(setup_po);
+        // 0 is our sentinal value. It is not a valid channel
+        assert unsafe::reinterpret_cast(ch) != 0u;
+
+        // Install the channel
+        let swapped = compare_and_swap(
+            global, 0u, unsafe::reinterpret_cast(ch));
+
+        if swapped {
+            // Success!
+            comm::send(setup_ch, proceed);
+            ch
+        } else {
+            // Somebody else got in before we did
+            comm::send(setup_ch, abort);
+            unsafe::reinterpret_cast(*global)
+        }
+    } else {
+        unsafe::reinterpret_cast(*global)
+    }
+}
+
+#[test]
+fn test_from_global_chan1() unsafe {
+
+    // This is unreadable, right?
+
+    // The global channel
+    let globchan = 0u;
+    let globchanp = ptr::addr_of(globchan);
+
+    // Create the global channel, attached to a new task
+    let ch = chan_from_global_ptr(globchanp, task::builder) {|po|
+        let ch = comm::recv(po);
+        comm::send(ch, true);
+        let ch = comm::recv(po);
+        comm::send(ch, true);
+    };
+    // Talk to it
+    let po = comm::port();
+    comm::send(ch, comm::chan(po));
+    assert comm::recv(po) == true;
+
+    // This one just reuses the previous channel
+    let ch = chan_from_global_ptr(globchanp, task::builder) {|po|
+        let ch = comm::recv(po);
+        comm::send(ch, false);
+    };
+
+    // Talk to the original global task
+    let po = comm::port();
+    comm::send(ch, comm::chan(po));
+    assert comm::recv(po) == true;
+}
+
+#[test]
+fn test_from_global_chan2() unsafe {
+
+    iter::repeat(100u) {||
+        // The global channel
+        let globchan = 0u;
+        let globchanp = ptr::addr_of(globchan);
+
+        let resultpo = comm::port();
+        let resultch = comm::chan(resultpo);
+
+        // Spawn a bunch of tasks that all want to compete to
+        // create the global channel
+        uint::range(0u, 10u) {|i|
+            task::spawn() {||
+                let ch = chan_from_global_ptr(
+                    globchanp, task::builder) {|po|
+
+                    uint::range(0u, 10u) {|_j|
+                        let ch = comm::recv(po);
+                        comm::send(ch, {i});
+                    }
+                };
+                let po = comm::port();
+                comm::send(ch, comm::chan(po));
+                // We are the winner if our version of the
+                // task was installed
+                let winner = comm::recv(po);
+                comm::send(resultch, winner == i);
+            }
+        }
+        // There should be only one winner
+        let mut winners = 0u;
+        uint::range(0u, 10u) {|_i|
+            let res = comm::recv(resultpo);
+            if res { winners += 1u };
+        }
+        assert winners == 1u;
+    }
+}
+
+#[doc = "
+Convert the current task to a 'weak' task temporarily
+
+As a weak task it will not be counted towards the runtime's set
+of live tasks. When there are no more outstanding live (non-weak) tasks
+the runtime will send an exit message on the provided channel.
+
+This function is super-unsafe. Do not use.
+
+# Safety notes
+
+* Weak tasks must either die on their own or exit upon receipt of
+  the exit message. Failure to do so will cause the runtime to never
+  exit
+* Tasks must not call `weaken_task` multiple times. This will
+  break the kernel's accounting of live tasks.
+* Weak tasks must not be supervised. A supervised task keeps
+  a reference to its parent, so the parent will not die.
+"]
+unsafe fn weaken_task(f: fn(comm::port<()>)) unsafe {
+    let po = comm::port();
+    let ch = comm::chan(po);
+    rustrt::rust_task_weaken(unsafe::reinterpret_cast(ch));
+    let _unweaken = unweaken(ch);
+    f(po);
+
+    resource unweaken(ch: comm::chan<()>) unsafe {
+        rustrt::rust_task_unweaken(unsafe::reinterpret_cast(ch));
+    }
+}
+
+#[test]
+fn test_weaken_task_then_unweaken() unsafe {
+    task::try {||
+        weaken_task {|_po|
+        }
+    };
+}
+
+#[test]
+fn test_weaken_task_wait() unsafe {
+    let builder = task::builder();
+    task::unsupervise(builder);
+    task::run(builder) {||
+        weaken_task {|po|
+            comm::recv(po);
+        }
+    }
+}
+
+#[test]
+fn test_weaken_task_stress() unsafe {
+    // Create a bunch of weak tasks
+    iter::repeat(100u) {||
+        task::spawn {||
+            weaken_task {|_po|
+            }
+        }
+        let builder = task::builder();
+        task::unsupervise(builder);
+        task::run(builder) {||
+            weaken_task {|po|
+                // Wait for it to tell us to die
+                comm::recv(po);
+            }
+        }
+    }
+}
+
+#[test]
+#[ignore(cfg(target_os = "win32"))]
+fn test_weaken_task_fail() unsafe {
+    let res = task::try {||
+        weaken_task {|_po|
+            fail;
+        }
+    };
+    assert result::is_failure(res);
+}
\ No newline at end of file
index 421eb5878620160c1ebfbe459cd7ca0619325858..50005c7b4865fb12e9a4a0bddc22ed692b4013f9 100644 (file)
@@ -1658,7 +1658,7 @@ unsafe fn from_c_str_len(c_str: *libc::c_char, len: uint) -> str {
    Does not verify that the vector contains valid UTF-8.
    "]
    unsafe fn from_bytes(v: [const u8]) -> str unsafe {
-       let mut vcopy: [u8] = v + [0u8];
+       let vcopy = v + [0u8];
        let scopy: str = ::unsafe::reinterpret_cast(vcopy);
        ::unsafe::forget(vcopy);
        ret scopy;
@@ -1783,6 +1783,9 @@ fn is_not_empty() -> bool { is_not_empty(self) }
     "]
     #[inline]
     fn is_whitespace() -> bool { is_whitespace(self) }
+    #[inline]
+    #[doc ="Returns the size in bytes not counting the null terminator"]
+    fn len() -> uint { len(self) }
     #[doc = "
     Returns a slice of the given string from the byte range [`begin`..`end`)
 
index 9bffb34da16aed5e7ab7bd18e741b326d454c128..b29d503dff8af1878bf5e2bc8ff6d0642f08ac1a 100644 (file)
@@ -30,7 +30,7 @@
 export sched_mode;
 export sched_opts;
 export task_opts;
-export task_builder::{};
+export builder::{};
 
 export default_task_opts;
 export get_opts;
@@ -162,8 +162,8 @@ enum sched_mode {
 // when you try to reuse the builder to spawn a new task. We'll just
 // sidestep that whole issue by making builder's uncopyable and making
 // the run function move them in.
-enum task_builder {
-    task_builder_({
+enum builder {
+    builder_({
         mut opts: task_opts,
         mut gen_body: fn@(+fn~()) -> fn~(),
         can_not_copy: option<comm::port<()>>
@@ -188,27 +188,27 @@ fn default_task_opts() -> task_opts {
     }
 }
 
-fn task_builder() -> task_builder {
-    #[doc = "Construct a task_builder"];
+fn builder() -> builder {
+    #[doc = "Construct a builder"];
 
     let body_identity = fn@(+body: fn~()) -> fn~() { body };
 
-    task_builder_({
+    builder_({
         mut opts: default_task_opts(),
         mut gen_body: body_identity,
         can_not_copy: none
     })
 }
 
-fn get_opts(builder: task_builder) -> task_opts {
-    #[doc = "Get the task_opts associated with a task_builder"];
+fn get_opts(builder: builder) -> task_opts {
+    #[doc = "Get the task_opts associated with a builder"];
 
     builder.opts
 }
 
-fn set_opts(builder: task_builder, opts: task_opts) {
+fn set_opts(builder: builder, opts: task_opts) {
     #[doc = "
-    Set the task_opts associated with a task_builder
+    Set the task_opts associated with a builder
 
     To update a single option use a pattern like the following:
 
@@ -221,7 +221,7 @@ fn set_opts(builder: task_builder, opts: task_opts) {
     builder.opts = opts;
 }
 
-fn add_wrapper(builder: task_builder, gen_body: fn@(+fn~()) -> fn~()) {
+fn add_wrapper(builder: builder, gen_body: fn@(+fn~()) -> fn~()) {
     #[doc = "
     Add a wrapper to the body of the spawned task.
 
@@ -241,7 +241,7 @@ fn add_wrapper(builder: task_builder, gen_body: fn@(+fn~()) -> fn~()) {
     };
 }
 
-fn run(-builder: task_builder, +f: fn~()) {
+fn run(-builder: builder, +f: fn~()) {
     #[doc = "
     Creates and exucutes a new child task
 
@@ -262,7 +262,7 @@ fn run(-builder: task_builder, +f: fn~()) {
 
 /* Builder convenience functions */
 
-fn future_result(builder: task_builder) -> future::future<task_result> {
+fn future_result(builder: builder) -> future::future<task_result> {
     #[doc = "
     Get a future representing the exit status of the task.
 
@@ -295,7 +295,7 @@ fn future_result(builder: task_builder) -> future::future<task_result> {
     }
 }
 
-fn future_task(builder: task_builder) -> future::future<task> {
+fn future_task(builder: builder) -> future::future<task> {
     #[doc = "Get a future representing the handle to the new task"];
 
     let mut po = comm::port();
@@ -309,7 +309,7 @@ fn future_task(builder: task_builder) -> future::future<task> {
     future::from_port(po)
 }
 
-fn unsupervise(builder: task_builder) {
+fn unsupervise(builder: builder) {
     #[doc = "Configures the new task to not propagate failure to its parent"];
 
     set_opts(builder, {
@@ -318,7 +318,7 @@ fn unsupervise(builder: task_builder) {
     });
 }
 
-fn run_listener<A:send>(-builder: task_builder,
+fn run_listener<A:send>(-builder: builder,
                         +f: fn~(comm::port<A>)) -> comm::chan<A> {
     #[doc = "
     Runs a new task while providing a channel from the parent to the child
@@ -355,10 +355,10 @@ fn spawn(+f: fn~()) {
     Sets up a new task with its own call stack and schedules it to run
     the provided unique closure.
 
-    This function is equivalent to `run(new_task_builder(), f)`.
+    This function is equivalent to `run(new_builder(), f)`.
     "];
 
-    run(task_builder(), f);
+    run(builder(), f);
 }
 
 fn spawn_listener<A:send>(+f: fn~(comm::port<A>)) -> comm::chan<A> {
@@ -384,10 +384,10 @@ fn spawn_listener<A:send>(+f: fn~(comm::port<A>)) -> comm::chan<A> {
         };
         // Likewise, the parent has both a 'po' and 'ch'
 
-    This function is equivalent to `run_listener(new_task_builder(), f)`.
+    This function is equivalent to `run_listener(new_builder(), f)`.
     "];
 
-    run_listener(task_builder(), f)
+    run_listener(builder(), f)
 }
 
 fn spawn_sched(mode: sched_mode, +f: fn~()) {
@@ -404,7 +404,7 @@ fn spawn_sched(mode: sched_mode, +f: fn~()) {
     greater than zero.
     "];
 
-    let mut builder = task_builder();
+    let mut builder = builder();
     set_opts(builder, {
         sched: some({
             mode: mode,
@@ -429,7 +429,7 @@ fn try<T:send>(+f: fn~() -> T) -> result<T,()> {
 
     let po = comm::port();
     let ch = comm::chan(po);
-    let mut builder = task_builder();
+    let mut builder = builder();
     unsupervise(builder);
     let result = future_result(builder);
     run(builder) {||
@@ -505,7 +505,7 @@ fn spawn_raw(opts: task_opts, +f: fn~()) unsafe {
       }
     };
 
-    option::with_option_do(opts.notify_chan) {|c|
+    option::iter(opts.notify_chan) {|c|
         // FIXME (1087): Would like to do notification in Rust
         rustrt::rust_task_config_notify(new_task, c);
     }
@@ -626,8 +626,8 @@ fn test_spawn_raw_notify() {
 fn test_run_basic() {
     let po = comm::port();
     let ch = comm::chan(po);
-    let builder = task_builder();
-    run(builder) {||
+    let buildr = builder();
+    run(buildr) {||
         comm::send(ch, ());
     }
     comm::recv(po);
@@ -637,29 +637,29 @@ fn test_run_basic() {
 fn test_add_wrapper() {
     let po = comm::port();
     let ch = comm::chan(po);
-    let builder = task_builder();
-    add_wrapper(builder) {|body|
+    let buildr = builder();
+    add_wrapper(buildr) {|body|
         fn~() {
             body();
             comm::send(ch, ());
         }
     }
-    run(builder) {||}
+    run(buildr) {||}
     comm::recv(po);
 }
 
 #[test]
 #[ignore(cfg(target_os = "win32"))]
 fn test_future_result() {
-    let builder = task_builder();
-    let result = future_result(builder);
-    run(builder) {||}
+    let buildr = builder();
+    let result = future_result(buildr);
+    run(buildr) {||}
     assert future::get(result) == success;
 
-    let builder = task_builder();
-    let result = future_result(builder);
-    unsupervise(builder);
-    run(builder) {|| fail }
+    let buildr = builder();
+    let result = future_result(buildr);
+    unsupervise(buildr);
+    run(buildr) {|| fail }
     assert future::get(result) == failure;
 }
 
@@ -667,9 +667,9 @@ fn test_future_result() {
 fn test_future_task() {
     let po = comm::port();
     let ch = comm::chan(po);
-    let builder = task_builder();
-    let task1 = future_task(builder);
-    run(builder) {|| comm::send(ch, get_task()) }
+    let buildr = builder();
+    let task1 = future_task(buildr);
+    run(buildr) {|| comm::send(ch, get_task()) }
     assert future::get(task1) == comm::recv(po);
 }
 
@@ -863,8 +863,8 @@ fn test_avoid_copying_the_body_spawn_listener() {
 #[test]
 fn test_avoid_copying_the_body_run() {
     avoid_copying_the_body {|f|
-        let builder = task_builder();
-        run(builder) {||
+        let buildr = builder();
+        run(buildr) {||
             f();
         }
     }
@@ -873,8 +873,8 @@ fn test_avoid_copying_the_body_run() {
 #[test]
 fn test_avoid_copying_the_body_run_listener() {
     avoid_copying_the_body {|f|
-        let builder = task_builder();
-        run_listener(builder, fn~[move f](_po: comm::port<int>) {
+        let buildr = builder();
+        run_listener(buildr, fn~[move f](_po: comm::port<int>) {
             f();
         });
     }
@@ -892,9 +892,9 @@ fn test_avoid_copying_the_body_try() {
 #[test]
 fn test_avoid_copying_the_body_future_task() {
     avoid_copying_the_body {|f|
-        let builder = task_builder();
-        future_task(builder);
-        run(builder) {||
+        let buildr = builder();
+        future_task(buildr);
+        run(buildr) {||
             f();
         }
     }
@@ -903,9 +903,9 @@ fn test_avoid_copying_the_body_future_task() {
 #[test]
 fn test_avoid_copying_the_body_unsupervise() {
     avoid_copying_the_body {|f|
-        let builder = task_builder();
-        unsupervise(builder);
-        run(builder) {||
+        let buildr = builder();
+        unsupervise(buildr);
+        run(buildr) {||
             f();
         }
     }
@@ -913,19 +913,19 @@ fn test_avoid_copying_the_body_unsupervise() {
 
 #[test]
 fn test_osmain() {
-    let builder = task_builder();
+    let buildr = builder();
     let opts = {
         sched: some({
             mode: osmain,
             native_stack_size: none
         })
-        with get_opts(builder)
+        with get_opts(buildr)
     };
-    set_opts(builder, opts);
+    set_opts(buildr, opts);
 
     let po = comm::port();
     let ch = comm::chan(po);
-    run(builder) {||
+    run(buildr) {||
         comm::send(ch, ());
     }
     comm::recv(po);
index 20f6323c9cf5f5ac10a77174f0070c3974b43b4f..96bdf9b77c931bfa451bb4f24fc757663b4902e6 100644 (file)
@@ -62,7 +62,7 @@
 export swap;
 export reverse;
 export reversed;
-export iter, each, eachi;
+export iter, iter_between, each, eachi;
 export iter2;
 export iteri;
 export riter;
index c6fe959e2902d44308ed97504848fc946c25a5da..b2e0583c61b1aa42022f9fd7d2065f54c0322859 100644 (file)
@@ -289,7 +289,6 @@ enum expr_ {
     expr_cast(@expr, @ty),
     expr_if(@expr, blk, option<@expr>),
     expr_while(@expr, blk),
-    expr_for(@local, @expr, blk),
     expr_do_while(blk, @expr),
     /* Conditionless loop (can be exited with break, cont, ret, or fail)
        Same semantics as while(true) { body }, but typestate knows that the
@@ -442,7 +441,8 @@ enum prim_ty {
 enum region_ {
     re_inferred,
     re_named(ident),
-    re_self
+    re_self,
+    re_static
 }
 
 #[auto_serialize]
index 5e0f1c898179bd53932948bd0319a92ef5a0e0dd..63c46b63341eb628b837f97c70777549a79c5b8a 100644 (file)
@@ -142,11 +142,11 @@ fn float_ty_to_str(t: float_ty) -> str {
 fn is_exported(i: ident, m: _mod) -> bool {
     let mut local = false;
     let mut parent_enum : option<ident> = none;
-    for it: @item in m.items {
+    for m.items.each {|it|
         if it.ident == i { local = true; }
         alt it.node {
           item_enum(variants, _) {
-            for v: variant in variants {
+            for variants.each {|v|
                 if v.node.name == i {
                    local = true;
                    parent_enum = some(it.ident);
@@ -158,11 +158,11 @@ fn is_exported(i: ident, m: _mod) -> bool {
         if local { break; }
     }
     let mut has_explicit_exports = false;
-    for vi: @view_item in m.view_items {
+    for m.view_items.each {|vi|
         alt vi.node {
           view_item_export(vps) {
             has_explicit_exports = true;
-            for vp in vps {
+            for vps.each {|vp|
                 alt vp.node {
                   ast::view_path_simple(id, _, _) {
                     if id == i { ret true; }
@@ -177,7 +177,7 @@ fn is_exported(i: ident, m: _mod) -> bool {
                   ast::view_path_list(path, ids, _) {
                     if vec::len(*path) == 1u {
                         if i == path[0] { ret true; }
-                        for id in ids {
+                        for ids.each {|id|
                             if id.node.name == i { ret true; }
                         }
                     } else {
@@ -278,14 +278,14 @@ fn public_methods(ms: [@method]) -> [@method] {
 
 fn split_class_items(cs: [@class_member]) -> ([ivar], [@method]) {
     let mut vs = [], ms = [];
-    for c in cs {
+    for cs.each {|c|
       alt c.node {
         instance_var(i, t, cm, id, privacy) {
           vs += [{ident: i, ty: t, cm: cm, id: id, privacy: privacy}];
         }
         class_method(m) { ms += [m]; }
       }
-    }
+    };
     (vs, ms)
 }
 
index 3736c2f374eda6a6775b9ffde9f01af51802993a..861e86ec0ee233567dd2ed38e3bf0db1737663ea 100644 (file)
@@ -7,6 +7,7 @@
 
 export attr_meta;
 export attr_metas;
+export find_linkage_attrs;
 export find_linkage_metas;
 export inline_attr;
 export find_inline_attr;
 // From a list of crate attributes get only the meta_items that impact crate
 // linkage
 fn find_linkage_metas(attrs: [ast::attribute]) -> [@ast::meta_item] {
-    let mut metas: [@ast::meta_item] = [];
-    for attr: ast::attribute in find_attrs_by_name(attrs, "link") {
+    find_linkage_attrs(attrs).flat_map {|attr|
+        alt check attr.node.value.node {
+          ast::meta_list(_, items) { items }
+        }
+    }
+}
+
+fn find_linkage_attrs(attrs: [ast::attribute]) -> [ast::attribute] {
+    let mut found = [];
+    for find_attrs_by_name(attrs, "link").each {|attr|
         alt attr.node.value.node {
-          ast::meta_list(_, items) { metas += items; }
+          ast::meta_list(_, _) { found += [attr] }
           _ { #debug("ignoring link attribute that has incorrect type"); }
         }
     }
-    ret metas;
+    ret found;
 }
 
 enum inline_attr {
@@ -141,7 +150,7 @@ fn attr_meta(attr: ast::attribute) -> @ast::meta_item { @attr.node.value }
 // Get the meta_items from inside a vector of attributes
 fn attr_metas(attrs: [ast::attribute]) -> [@ast::meta_item] {
     let mut mitems = [];
-    for a: ast::attribute in attrs { mitems += [attr_meta(a)]; }
+    for attrs.each {|a| mitems += [attr_meta(a)]; }
     ret mitems;
 }
 
@@ -169,7 +178,7 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool {
 fn contains(haystack: [@ast::meta_item], needle: @ast::meta_item) -> bool {
     #debug("looking for %s",
            print::pprust::meta_item_to_str(*needle));
-    for item: @ast::meta_item in haystack {
+    for haystack.each {|item|
         #debug("looking in %s",
                print::pprust::meta_item_to_str(*item));
         if eq(item, needle) { #debug("found it!"); ret true; }
@@ -198,12 +207,12 @@ fn key(m: @ast::meta_item) -> ast::ident {
 
     // This is sort of stupid here, converting to a vec of mutables and back
     let mut v: [mut @ast::meta_item] = [mut];
-    for mi: @ast::meta_item in items { v += [mut mi]; }
+    for items.each {|mi| v += [mut mi]; }
 
     std::sort::quick_sort(lteq, v);
 
     let mut v2: [@ast::meta_item] = [];
-    for mi: @ast::meta_item in v { v2 += [mi]; }
+    for v.each {|mi| v2 += [mi]; }
     ret v2;
 }
 
@@ -222,7 +231,7 @@ fn remove_meta_items_by_name(items: [@ast::meta_item], name: str) ->
 fn require_unique_names(diagnostic: span_handler,
                         metas: [@ast::meta_item]) {
     let map = map::str_hash();
-    for meta: @ast::meta_item in metas {
+    for metas.each {|meta|
         let name = get_meta_item_name(meta);
         if map.contains_key(name) {
             diagnostic.span_fatal(meta.span,
index a1a117201fb29aae99682bfcffc38ce238ce1784..8e034690167dc41403ae46e87be71c9efc80bcc4 100644 (file)
@@ -187,7 +187,7 @@ fn get_snippet(cm: codemap::codemap, fidx: uint, lo: uint, hi: uint) -> str
 }
 
 fn get_filemap(cm: codemap, filename: str) -> filemap {
-    for fm: filemap in cm.files { if fm.name == filename { ret fm; } }
+    for cm.files.each {|fm| if fm.name == filename { ret fm; } }
     //XXjdm the following triggers a mismatched type bug
     //      (or expected function, found _|_)
     fail; // ("asking for " + filename + " which we don't know about");
index e29c11cbb116fe6dba56d3923501a8f875aaf694..756a86030db5ab456ed67f2847e622f317b91df5 100644 (file)
@@ -201,7 +201,7 @@ fn highlight_lines(cm: codemap::codemap, sp: span,
         elided = true;
     }
     // Print the offending lines
-    for line: uint in display_lines {
+    for display_lines.each {|line|
         io::stderr().write_str(#fmt["%s:%u ", fm.name, line + 1u]);
         let s = codemap::get_line(fm, line as int) + "\n";
         io::stderr().write_str(s);
@@ -243,8 +243,8 @@ fn highlight_lines(cm: codemap::codemap, sp: span,
 }
 
 fn print_macro_backtrace(cm: codemap::codemap, sp: span) {
-    option::with_option_do (sp.expn_info) {|ei|
-        let ss = option::with_option(ei.callie.span, "",
+    option::iter (sp.expn_info) {|ei|
+        let ss = option::map_default(ei.callie.span, "",
                                bind codemap::span_to_str(_, cm));
         print_diagnostic(ss, note,
                          #fmt("in expansion of #%s", ei.callie.name));
index 238cf40a68564132c4e4f6efb34b5aecc2fe0329..a3b7f2ebbbb37f249dd703e013df0e71c46b36c4 100644 (file)
@@ -68,7 +68,7 @@ fn mk_rec_e(cx: ext_ctxt, sp: span,
             fields: [{ident: ast::ident, ex: @ast::expr}]) ->
     @ast::expr {
     let mut astfields: [ast::field] = [];
-    for field: {ident: ast::ident, ex: @ast::expr} in fields {
+    for fields.each {|field|
         let ident = field.ident;
         let val = field.ex;
         let astfield =
index f7bc95bd1815cc291e37c7ad4e5c1f4766f7e40c..58577eb2e08d5d1c16c650dd6ec88ef6d469201e 100644 (file)
@@ -11,7 +11,7 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
           }
         };
     let mut res: ast::ident = "";
-    for e: @ast::expr in args {
+    for args.each {|e|
         res += expr_to_ident(cx, e, "expected an ident");
     }
 
index 24657f8634b98502cee949cbec6d506fad08fcb9..6b00059080e3ae6af3855171c0a821f7c0820906 100644 (file)
@@ -57,7 +57,7 @@ fn make_rt_path_expr(cx: ext_ctxt, sp: span, ident: str) -> @ast::expr {
     fn make_rt_conv_expr(cx: ext_ctxt, sp: span, cnv: conv) -> @ast::expr {
         fn make_flags(cx: ext_ctxt, sp: span, flags: [flag]) -> @ast::expr {
             let mut flagexprs: [@ast::expr] = [];
-            for f: flag in flags {
+            for flags.each {|f|
                 let mut fstr;
                 alt f {
                   flag_left_justify { fstr = "flag_left_justify"; }
@@ -141,7 +141,7 @@ fn is_signed_type(cnv: conv) -> bool {
           option::none { }
           _ { cx.span_unimpl(sp, unsupported); }
         }
-        for f: flag in cnv.flags {
+        for cnv.flags.each {|f|
             alt f {
               flag_left_justify { }
               flag_sign_always {
@@ -197,7 +197,7 @@ fn log_conv(c: conv) {
           some(p) { log(debug, "param: " + int::to_str(p, 10u)); }
           _ { #debug("param: none"); }
         }
-        for f: flag in c.flags {
+        for c.flags.each {|f|
             alt f {
               flag_left_justify { #debug("flag: left justify"); }
               flag_left_zero_pad { #debug("flag: left zero pad"); }
@@ -252,7 +252,7 @@ fn log_conv(c: conv) {
     let mut n = 0u;
     let mut tmp_expr = mk_str(cx, sp, "");
     let nargs = vec::len::<@ast::expr>(args);
-    for pc: piece in pieces {
+    for pieces.each {|pc|
         alt pc {
           piece_string(s) {
             let s_expr = mk_str(cx, fmt_sp, s);
index b38dbccd7b1852f059c62ec34d9d5d9d4317a6ae..d307e11ca043b41ba22ae3a4565626aa588c0a68 100644 (file)
@@ -135,7 +135,7 @@ fn expand_ast(ecx: ext_ctxt, _sp: span,
     -> @ast::expr
 {
     let mut what = "expr";
-    option::with_option_do(arg) {|arg|
+    option::iter(arg) {|arg|
         let args: [@ast::expr] =
             alt arg.node {
               ast::expr_vec(elts, _) { elts }
index dfc7d5314fc6b6322f03e304c6f48a680b27f2e9..eb031cfaf542e644e9c12653e0fda633b498d385 100644 (file)
@@ -1,5 +1,3 @@
-use std;
-
 import codemap::span;
 import std::map::{hashmap, str_hash};
 
@@ -75,7 +73,7 @@ fn elts_to_ell(cx: ext_ctxt, elts: [@expr]) ->
    {pre: [@expr], rep: option<@expr>, post: [@expr]} {
     let mut idx: uint = 0u;
     let mut res = none;
-    for elt: @expr in elts {
+    for elts.each {|elt|
         alt elt.node {
           expr_mac(m) {
             alt m.node {
@@ -104,7 +102,7 @@ fn elts_to_ell(cx: ext_ctxt, elts: [@expr]) ->
 fn option_flatten_map<T: copy, U: copy>(f: fn@(T) -> option<U>, v: [T]) ->
    option<[U]> {
     let mut res = [];
-    for elem: T in v {
+    for v.each {|elem|
         alt f(elem) { none { ret none; } some(fv) { res += [fv]; } }
     }
     ret some(res);
@@ -165,7 +163,7 @@ fn pattern_to_selectors(cx: ext_ctxt, e: @expr) -> binders {
 fn use_selectors_to_bind(b: binders, e: @expr) -> option<bindings> {
     let res = str_hash::<arb_depth<matchable>>();
     //need to do this first, to check vec lengths.
-    for sel: selector in b.literal_ast_matchers {
+    for b.literal_ast_matchers.each {|sel|
         alt sel(match_expr(e)) { none { ret none; } _ { } }
     }
     let mut never_mind: bool = false;
@@ -211,7 +209,7 @@ fn new_span(cx: ext_ctxt, sp: span) -> span {
 fn follow(m: arb_depth<matchable>, idx_path: @mut [uint]) ->
    arb_depth<matchable> {
     let mut res: arb_depth<matchable> = m;
-    for idx: uint in *idx_path {
+    for vec::each(*idx_path) {|idx|
         alt res {
           leaf(_) { ret res;/* end of the line */ }
           seq(new_ms, _) { res = new_ms[idx]; }
@@ -679,7 +677,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
 
     let mut macro_name: option<str> = none;
     let mut clauses: [@clause] = [];
-    for arg: @expr in args {
+    for args.each {|arg|
         alt arg.node {
           expr_vec(elts, mutbl) {
             if vec::len(elts) != 2u {
@@ -755,7 +753,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
     fn generic_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
                          _body: ast::mac_body, clauses: [@clause]) -> @expr {
         let arg = get_mac_arg(cx,sp,arg);
-        for c: @clause in clauses {
+        for clauses.each {|c|
             alt use_selectors_to_bind(c.params, arg) {
               some(bindings) { ret transcribe(cx, bindings, c.body); }
               none { cont; }
index a24a08cdd09092bf787347701982e8d1c59be723..07411a3051d4aef02caa2ea1c7df9fe7b12550da 100644 (file)
@@ -338,7 +338,7 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ {
           }
           pat_rec(fields, etc) {
             let mut fs = [];
-            for f: ast::field_pat in fields {
+            for fields.each {|f|
                 fs += [{ident: f.ident, pat: fld.fold_pat(f.pat)}];
             }
             pat_rec(fs, etc)
@@ -416,10 +416,6 @@ fn fold_field_(field: field, fld: ast_fold) -> field {
           expr_while(cond, body) {
             expr_while(fld.fold_expr(cond), fld.fold_block(body))
           }
-          expr_for(decl, expr, blk) {
-            expr_for(fld.fold_local(decl), fld.fold_expr(expr),
-                     fld.fold_block(blk))
-          }
           expr_do_while(blk, expr) {
             expr_do_while(fld.fold_block(blk), fld.fold_expr(expr))
           }
index a9e0ce9845e604c50e5e98bfdd20073e1eeebe8f..d01667d10292277f00e7d87843aaa496fbbfc4c2 100644 (file)
@@ -13,7 +13,7 @@
 fn eval_crate_directives(cx: ctx, cdirs: [@ast::crate_directive], prefix: str,
                          &view_items: [@ast::view_item],
                          &items: [@ast::item]) {
-    for sub_cdir: @ast::crate_directive in cdirs {
+    for cdirs.each {|sub_cdir|
         eval_crate_directive(cx, sub_cdir, prefix, view_items, items);
     }
 }
index dfd682b9ae9a019e30836730b4112f2aec444a81..c2f1dd58096a5b51cd9bc86ce9d44e085ef7d181 100644 (file)
@@ -143,12 +143,13 @@ fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader,
 // interpreted as a specific kind of statement, which would be confusing.
 fn bad_expr_word_table() -> hashmap<str, ()> {
     let words = str_hash();
-    for word in ["alt", "assert", "be", "break", "check", "claim",
-                 "class", "const", "cont", "copy", "crust", "do", "else",
-                 "enum", "export", "fail", "fn", "for", "if",  "iface",
-                 "impl", "import", "let", "log", "loop", "mod", "mut",
-                 "mut", "native", "pure", "resource", "ret", "trait",
-                 "type", "unchecked", "unsafe", "while", "new"] {
+    let keys = ["alt", "assert", "be", "break", "check", "claim",
+                "class", "const", "cont", "copy", "crust", "do", "else",
+                "enum", "export", "fail", "fn", "for", "if",  "iface",
+                "impl", "import", "let", "log", "loop", "mod", "mut",
+                "mut", "native", "pure", "resource", "ret", "trait",
+                "type", "unchecked", "unsafe", "while", "new"];
+    for keys.each {|word|
         words.insert(word, ());
     }
     words
@@ -312,7 +313,7 @@ fn parse_ty_field(p: parser) -> ast::ty_field {
 // otherwise, fail
 fn ident_index(p: parser, args: [ast::arg], i: ast::ident) -> uint {
     let mut j = 0u;
-    for a: ast::arg in args { if a.ident == i { ret j; } j += 1u; }
+    for args.each {|a| if a.ident == i { ret j; } j += 1u; }
     p.fatal("unbound variable `" + i + "` in constraint arg");
 }
 
@@ -434,6 +435,8 @@ fn parse_region(p: parser) -> ast::region {
             p.bump(); p.bump();
             if string == "self" {
                 ast::re_self
+            } else if string == "static" {
+                ast::re_static
             } else {
                 ast::re_named(string)
             }
@@ -1228,7 +1231,7 @@ fn parse_more_binops(p: parser, plhs: pexpr, min_prec: int) ->
     let peeked = p.token;
     if peeked == token::BINOP(token::OR) &&
        p.restriction == RESTRICT_NO_BAR_OP { ret lhs; }
-    for cur: op_spec in *p.precs {
+    for vec::each(*p.precs) {|cur|
         if cur.prec > min_prec && cur.tok == peeked {
             p.bump();
             let expr = parse_prefix_expr(p);
@@ -1402,35 +1405,18 @@ fn parse_else_expr(p: parser) -> @ast::expr {
 
 fn parse_for_expr(p: parser) -> @ast::expr {
     let lo = p.last_span;
-    // FIXME remove this kludge after migration and snapshotting (#1619)
-    let new_style = alt p.token {
-      token::IDENT(_, false) { alt p.look_ahead(1u) {
-        token::DOT | token::LPAREN { true }
-        _ { false }
-      } }
-      token::IDENT(_, true) { true }
-      _ { false }
-    };
-    if new_style {
-        let call = parse_expr(p);
-        alt call.node {
-          ast::expr_call(f, args, true) {
-            let b_arg = vec::last(args);
-            let last = mk_expr(p, b_arg.span.lo, b_arg.span.hi,
-                               ast::expr_loop_body(b_arg));
-            @{node: ast::expr_call(f, vec::init(args) + [last], true)
-              with *call}
-          }
-          _ {
-            p.span_fatal(lo, "`for` must be followed by a block call");
-          }
-        }
-    } else {
-        let decl = parse_local(p, false, false);
-        expect_word(p, "in");
-        let seq = parse_expr(p);
-        let body = parse_block_no_value(p);
-        mk_expr(p, lo.lo, body.span.hi, ast::expr_for(decl, seq, body))
+    let call = parse_expr_res(p, RESTRICT_STMT_EXPR);
+    alt call.node {
+      ast::expr_call(f, args, true) {
+        let b_arg = vec::last(args);
+        let last = mk_expr(p, b_arg.span.lo, b_arg.span.hi,
+                           ast::expr_loop_body(b_arg));
+        @{node: ast::expr_call(f, vec::init(args) + [last], true)
+          with *call}
+      }
+      _ {
+        p.span_fatal(lo, "`for` must be followed by a block call");
+      }
     }
 }
 
@@ -1751,8 +1737,7 @@ fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool {
       ast::expr_if(_, _, _) | ast::expr_if_check(_, _, _)
       | ast::expr_alt(_, _, _) | ast::expr_block(_)
       | ast::expr_do_while(_, _) | ast::expr_while(_, _)
-      | ast::expr_loop(_) | ast::expr_for(_, _, _)
-      | ast::expr_call(_, _, true) {
+      | ast::expr_loop(_) | ast::expr_call(_, _, true) {
         false
       }
       _ { true }
@@ -2326,7 +2311,7 @@ fn parse_item_enum(p: parser, attrs: [ast::attribute]) -> @ast::item {
             let arg_tys = parse_seq(token::LPAREN, token::RPAREN,
                                     seq_sep(token::COMMA),
                                     {|p| parse_ty(p, false)}, p);
-            for ty in arg_tys.node {
+            for arg_tys.node.each {|ty|
                 args += [{ty: ty, id: p.get_id()}];
             }
         } else if eat(p, token::EQ) {
index 6f53344926b5e8bf222aea826892d44d85c6f489..fe9c9531d5ea621f9c2a04b3f9ce49978d86ebed 100644 (file)
@@ -269,7 +269,7 @@ fn synth_comment(s: ps, text: str) {
 fn commasep<IN>(s: ps, b: breaks, elts: [IN], op: fn(ps, IN)) {
     box(s, 0u, b);
     let mut first = true;
-    for elt: IN in elts {
+    for elts.each {|elt|
         if first { first = false; } else { word_space(s, ","); }
         op(s, elt);
     }
@@ -282,7 +282,7 @@ fn commasep_cmnt<IN>(s: ps, b: breaks, elts: [IN], op: fn(ps, IN),
     box(s, 0u, b);
     let len = vec::len::<IN>(elts);
     let mut i = 0u;
-    for elt: IN in elts {
+    for elts.each {|elt|
         maybe_print_comment(s, get_span(elt).hi);
         op(s, elt);
         i += 1u;
@@ -303,18 +303,18 @@ fn commasep_exprs(s: ps, b: breaks, exprs: [@ast::expr]) {
 
 fn print_mod(s: ps, _mod: ast::_mod, attrs: [ast::attribute]) {
     print_inner_attributes(s, attrs);
-    for vitem: @ast::view_item in _mod.view_items {
+    for _mod.view_items.each {|vitem|
         print_view_item(s, vitem);
     }
-    for item: @ast::item in _mod.items { print_item(s, item); }
+    for _mod.items.each {|item| print_item(s, item); }
 }
 
 fn print_native_mod(s: ps, nmod: ast::native_mod, attrs: [ast::attribute]) {
     print_inner_attributes(s, attrs);
-    for vitem: @ast::view_item in nmod.view_items {
+    for nmod.view_items.each {|vitem|
         print_view_item(s, vitem);
     }
-    for item: @ast::native_item in nmod.items { print_native_item(s, item); }
+    for nmod.items.each {|item| print_native_item(s, item); }
 }
 
 fn print_region(s: ps, region: ast::region) {
@@ -322,6 +322,7 @@ fn print_region(s: ps, region: ast::region) {
       ast::re_inferred { /* no-op */ }
       ast::re_named(name) { word(s.s, name); word(s.s, "."); }
       ast::re_self { word(s.s, "self"); word(s.s, "."); }
+      ast::re_static { word(s.s, "static"); word(s.s, "."); }
     }
 }
 
@@ -475,7 +476,7 @@ fn print_item(s: ps, &&item: @ast::item) {
             end(s);
         } else {
             bopen(s);
-            for v: ast::variant in variants {
+            for variants.each {|v|
                 space_if_not_bol(s);
                 maybe_print_comment(s, v.span.lo);
                 print_outer_attributes(s, v.node.attrs);
@@ -499,7 +500,7 @@ fn print_item(s: ps, &&item: @ast::item) {
           print_fn_args_and_ret(s, ctor.node.dec);
           space(s.s);
           print_block(s, ctor.node.body);
-          for ci in items {
+          for items.each {|ci|
                   /*
                      FIXME: collect all private items and print them
                      in a single "priv" section
@@ -555,7 +556,7 @@ fn print_item(s: ps, &&item: @ast::item) {
         print_type(s, ty);
         space(s.s);
         bopen(s);
-        for meth in methods {
+        for methods.each {|meth|
            print_method(s, meth);
         }
         bclose(s, item.span);
@@ -566,7 +567,7 @@ fn print_item(s: ps, &&item: @ast::item) {
         print_type_params(s, tps);
         word(s.s, " ");
         bopen(s);
-        for meth in methods { print_ty_method(s, meth); }
+        for methods.each {|meth| print_ty_method(s, meth); }
         bclose(s, item.span);
       }
       ast::item_res(decl, tps, body, dt_id, ct_id) {
@@ -628,7 +629,7 @@ fn print_method(s: ps, meth: @ast::method) {
 
 fn print_outer_attributes(s: ps, attrs: [ast::attribute]) {
     let mut count = 0;
-    for attr: ast::attribute in attrs {
+    for attrs.each {|attr|
         alt attr.node.style {
           ast::attr_outer { print_attribute(s, attr); count += 1; }
           _ {/* fallthrough */ }
@@ -639,7 +640,7 @@ fn print_outer_attributes(s: ps, attrs: [ast::attribute]) {
 
 fn print_inner_attributes(s: ps, attrs: [ast::attribute]) {
     let mut count = 0;
-    for attr: ast::attribute in attrs {
+    for attrs.each {|attr|
         alt attr.node.style {
           ast::attr_inner {
             print_attribute(s, attr);
@@ -715,8 +716,8 @@ fn print_possibly_embedded_block_(s: ps, blk: ast::blk, embedded: embed_type,
 
     print_inner_attributes(s, attrs);
 
-    for vi in blk.node.view_items { print_view_item(s, vi); }
-    for st: @ast::stmt in blk.node.stmts {
+    for blk.node.view_items.each {|vi| print_view_item(s, vi); }
+    for blk.node.stmts.each {|st|
         print_stmt(s, *st);
     }
     alt blk.node.expr {
@@ -792,7 +793,7 @@ fn print_mac(s: ps, m: ast::mac) {
           some(@{node: ast::expr_vec(_, _), _}) { }
           _ { word(s.s, " "); }
         }
-        option::with_option_do(arg, bind print_expr(s, _));
+        option::iter(arg, bind print_expr(s, _));
         // FIXME: extension 'body'
       }
       ast::mac_embed_type(ty) {
@@ -934,12 +935,6 @@ fn print_opt(s: ps, expr: option<@ast::expr>) {
         space(s.s);
         print_block(s, blk);
       }
-      ast::expr_for(decl, expr, blk) {
-        head(s, "for");
-        print_for_decl(s, decl, expr);
-        space(s.s);
-        print_block(s, blk);
-      }
       ast::expr_do_while(blk, expr) {
         head(s, "do");
         space(s.s);
@@ -956,12 +951,12 @@ fn print_opt(s: ps, expr: option<@ast::expr>) {
         print_maybe_parens_discrim(s, expr);
         space(s.s);
         bopen(s);
-        for arm: ast::arm in arms {
+        for arms.each {|arm|
             space(s.s);
             cbox(s, alt_indent_unit);
             ibox(s, 0u);
             let mut first = true;
-            for p: @ast::pat in arm.pats {
+            for arm.pats.each {|p|
                 if first {
                     first = false;
                 } else { space(s.s); word_space(s, "|"); }
@@ -1188,7 +1183,7 @@ fn print_path(s: ps, &&path: @ast::path, colons_before_params: bool) {
     maybe_print_comment(s, path.span.lo);
     if path.node.global { word(s.s, "::"); }
     let mut first = true;
-    for id: ast::ident in path.node.idents {
+    for path.node.idents.each {|id|
         if first { first = false; } else { word(s.s, "::"); }
         word(s.s, id);
     }
@@ -1358,7 +1353,7 @@ fn print_arg_mode(s: ps, m: ast::mode) {
 fn print_bounds(s: ps, bounds: @[ast::ty_param_bound]) {
     if vec::len(*bounds) > 0u {
         word(s.s, ":");
-        for bound in *bounds {
+        for vec::each(*bounds) {|bound|
             nbsp(s);
             alt bound {
               ast::bound_copy { word(s.s, "copy"); }
@@ -1402,7 +1397,7 @@ fn print_meta_item(s: ps, &&item: @ast::meta_item) {
 
 fn print_simple_path(s: ps, path: ast::simple_path) {
     let mut first = true;
-    for id in path {
+    for path.each {|id|
         if first { first = false; } else { word(s.s, "::"); }
         word(s.s, id);
     }
@@ -1471,7 +1466,7 @@ fn print_view_item(s: ps, item: @ast::view_item) {
 // FIXME: The fact that this builds up the table anew for every call is
 // not good. Eventually, table should be a const.
 fn operator_prec(op: ast::binop) -> int {
-    for spec: parse::parser::op_spec in *parse::parser::prec_table() {
+    for vec::each(*parse::parser::prec_table()) {|spec|
         if spec.op == op { ret spec.prec; }
     }
     core::unreachable();
@@ -1666,7 +1661,7 @@ fn print_comment(s: ps, cmnt: lexer::cmnt) {
       }
       lexer::isolated {
         pprust::hardbreak_if_not_bol(s);
-        for line: str in cmnt.lines {
+        for cmnt.lines.each {|line|
             // Don't print empty lines because they will end up as trailing
             // whitespace
             if str::is_not_empty(line) { word(s.s, line); }
@@ -1680,7 +1675,7 @@ fn print_comment(s: ps, cmnt: lexer::cmnt) {
             hardbreak(s.s);
         } else {
             ibox(s, 0u);
-            for line: str in cmnt.lines {
+            for cmnt.lines.each {|line|
                 if str::is_not_empty(line) { word(s.s, line); }
                 hardbreak(s.s);
             }
@@ -1751,7 +1746,7 @@ fn constr_args_to_str<T>(f: fn@(T) -> str, args: [@ast::sp_constr_arg<T>]) ->
    str {
     let mut comma = false;
     let mut s = "(";
-    for a: @ast::sp_constr_arg<T> in args {
+    for args.each {|a|
         if comma { s += ", "; } else { comma = true; }
         s += constr_arg_to_str::<T>(f, a.node);
     }
@@ -1794,7 +1789,7 @@ fn ty_constr_path_to_str(&&p: @ast::path) -> str { "*." + path_to_str(p) }
 
 fn constrs_str<T>(constrs: [T], elt: fn(T) -> str) -> str {
     let mut s = "", colon = true;
-    for c in constrs {
+    for constrs.each {|c|
         if colon { s += " : "; colon = false; } else { s += ", "; }
         s += elt(c);
     }
index 51b5ef1c32c3bf79246fa89d1a0f68244f62bcfb..101c08bd0872eaab22a46957c73c4af43c321d9e 100644 (file)
@@ -4,7 +4,12 @@
 
 #[crate_type = "lib"];
 
-use std;
+#[no_core];
+
+use core(vers = "0.2");
+use std(vers = "0.2");
+
+import core::*;
 
 mod attr;
 mod diagnostic;
index c4e5da667432edbe1c82f89a136f0b3221fb0b9a..6250c9dc7c9fce0594cffa7255886cec4f599d42 100644 (file)
@@ -84,7 +84,7 @@ fn visit_crate_directive<E>(cd: @crate_directive, e: E, v: vt<E>) {
     alt cd.node {
       cdir_src_mod(_, _) { }
       cdir_dir_mod(_, cdirs, _) {
-        for cdir: @crate_directive in cdirs {
+        for cdirs.each {|cdir|
             visit_crate_directive(cdir, e, v);
         }
       }
@@ -94,8 +94,8 @@ fn visit_crate_directive<E>(cd: @crate_directive, e: E, v: vt<E>) {
 }
 
 fn visit_mod<E>(m: _mod, _sp: span, _id: node_id, e: E, v: vt<E>) {
-    for vi: @view_item in m.view_items { v.visit_view_item(vi, e, v); }
-    for i: @item in m.items { v.visit_item(i, e, v); }
+    for m.view_items.each {|vi| v.visit_view_item(vi, e, v); }
+    for m.items.each {|i| v.visit_item(i, e, v); }
 }
 
 fn visit_view_item<E>(_vi: @view_item, _e: E, _v: vt<E>) { }
@@ -114,8 +114,8 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
       }
       item_mod(m) { v.visit_mod(m, i.span, i.id, e, v); }
       item_native_mod(nm) {
-        for vi: @view_item in nm.view_items { v.visit_view_item(vi, e, v); }
-        for ni: @native_item in nm.items { v.visit_native_item(ni, e, v); }
+        for nm.view_items.each {|vi| v.visit_view_item(vi, e, v); }
+        for nm.items.each {|ni| v.visit_native_item(ni, e, v); }
       }
       item_ty(t, tps) { v.visit_ty(t, e, v); v.visit_ty_params(tps, e, v); }
       item_res(decl, tps, body, dtor_id, _) {
@@ -124,21 +124,21 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
       }
       item_enum(variants, tps) {
         v.visit_ty_params(tps, e, v);
-        for vr: variant in variants {
-            for va: variant_arg in vr.node.args { v.visit_ty(va.ty, e, v); }
+        for variants.each {|vr|
+            for vr.node.args.each {|va| v.visit_ty(va.ty, e, v); }
         }
       }
       item_impl(tps, ifce, ty, methods) {
         v.visit_ty_params(tps, e, v);
         alt ifce { some(ty) { v.visit_ty(ty, e, v); } none {} }
         v.visit_ty(ty, e, v);
-        for m in methods {
+        for methods.each {|m|
             visit_method_helper(m, e, v)
         }
       }
       item_class(tps, members, ctor) {
           v.visit_ty_params(tps, e, v);
-          for m in members {
+          for members.each {|m|
              v.visit_class_item(m, e, v);
           }
           // make up a fake fn so as to call visit_fn on the ctor
@@ -147,8 +147,8 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
       }
       item_iface(tps, methods) {
         v.visit_ty_params(tps, e, v);
-        for m in methods {
-            for a in m.decl.inputs { v.visit_ty(a.ty, e, v); }
+        for methods.each {|m|
+            for m.decl.inputs.each {|a| v.visit_ty(a.ty, e, v); }
             v.visit_ty(m.decl.output, e, v);
         }
       }
@@ -176,12 +176,12 @@ fn visit_ty<E>(t: @ty, e: E, v: vt<E>) {
       ty_ptr(mt) { v.visit_ty(mt.ty, e, v); }
       ty_rptr(_, mt) { v.visit_ty(mt.ty, e, v); }
       ty_rec(flds) {
-        for f: ty_field in flds { v.visit_ty(f.node.mt.ty, e, v); }
+        for flds.each {|f| v.visit_ty(f.node.mt.ty, e, v); }
       }
-      ty_tup(ts) { for tt in ts { v.visit_ty(tt, e, v); } }
+      ty_tup(ts) { for ts.each {|tt| v.visit_ty(tt, e, v); } }
       ty_fn(_, decl) {
-        for a in decl.inputs { v.visit_ty(a.ty, e, v); }
-        for c: @constr in decl.constraints {
+        for decl.inputs.each {|a| v.visit_ty(a.ty, e, v); }
+        for decl.constraints.each {|c|
             v.visit_constr(c.node.path, c.span, c.node.id, e, v);
         }
         v.visit_ty(decl.output, e, v);
@@ -189,7 +189,7 @@ fn visit_ty<E>(t: @ty, e: E, v: vt<E>) {
       ty_path(p, _) { visit_path(p, e, v); }
       ty_constr(t, cs) {
         v.visit_ty(t, e, v);
-        for tc: @spanned<constr_general_<@path, node_id>> in cs {
+        for cs.each {|tc|
             v.visit_constr(tc.node.path, tc.span, tc.node.id, e, v);
         }
       }
@@ -207,25 +207,25 @@ fn visit_constr<E>(_operator: @path, _sp: span, _id: node_id, _e: E,
 }
 
 fn visit_path<E>(p: @path, e: E, v: vt<E>) {
-    for tp: @ty in p.node.types { v.visit_ty(tp, e, v); }
+    for p.node.types.each {|tp| v.visit_ty(tp, e, v); }
 }
 
 fn visit_pat<E>(p: @pat, e: E, v: vt<E>) {
     alt p.node {
       pat_enum(path, children) {
         visit_path(path, e, v);
-        for child: @pat in children { v.visit_pat(child, e, v); }
+        for children.each {|child| v.visit_pat(child, e, v); }
       }
       pat_rec(fields, _) {
-        for f: field_pat in fields { v.visit_pat(f.pat, e, v); }
+        for fields.each {|f| v.visit_pat(f.pat, e, v); }
       }
-      pat_tup(elts) { for elt in elts { v.visit_pat(elt, e, v); } }
+      pat_tup(elts) { for elts.each {|elt| v.visit_pat(elt, e, v); } }
       pat_box(inner) | pat_uniq(inner) {
         v.visit_pat(inner, e, v);
       }
       pat_ident(path, inner) {
           visit_path(path, e, v);
-          option::with_option_do(inner, {|subpat| v.visit_pat(subpat, e, v)});
+          option::iter(inner, {|subpat| v.visit_pat(subpat, e, v)});
       }
       pat_lit(ex) { v.visit_expr(ex, e, v); }
       pat_range(e1, e2) { v.visit_expr(e1, e, v); v.visit_expr(e2, e, v); }
@@ -243,8 +243,8 @@ fn visit_native_item<E>(ni: @native_item, e: E, v: vt<E>) {
 }
 
 fn visit_ty_params<E>(tps: [ty_param], e: E, v: vt<E>) {
-    for tp in tps {
-        for bound in *tp.bounds {
+    for tps.each {|tp|
+        for vec::each(*tp.bounds) {|bound|
             alt bound {
               bound_iface(t) { v.visit_ty(t, e, v); }
               bound_copy | bound_send { }
@@ -254,8 +254,8 @@ fn visit_ty_params<E>(tps: [ty_param], e: E, v: vt<E>) {
 }
 
 fn visit_fn_decl<E>(fd: fn_decl, e: E, v: vt<E>) {
-    for a: arg in fd.inputs { v.visit_ty(a.ty, e, v); }
-    for c: @constr in fd.constraints {
+    for fd.inputs.each {|a| v.visit_ty(a.ty, e, v); }
+    for fd.constraints.each {|c|
         v.visit_constr(c.node.path, c.span, c.node.id, e, v);
     }
     v.visit_ty(fd.output, e, v);
@@ -278,8 +278,8 @@ fn visit_fn<E>(fk: fn_kind, decl: fn_decl, body: blk, _sp: span,
 }
 
 fn visit_block<E>(b: ast::blk, e: E, v: vt<E>) {
-    for vi in b.node.view_items { v.visit_view_item(vi, e, v); }
-    for s in b.node.stmts { v.visit_stmt(s, e, v); }
+    for b.node.view_items.each {|vi| v.visit_view_item(vi, e, v); }
+    for b.node.stmts.each {|s| v.visit_stmt(s, e, v); }
     visit_expr_opt(b.node.expr, e, v);
 }
 
@@ -294,7 +294,7 @@ fn visit_stmt<E>(s: @stmt, e: E, v: vt<E>) {
 fn visit_decl<E>(d: @decl, e: E, v: vt<E>) {
     alt d.node {
       decl_local(locs) {
-        for loc in locs { v.visit_local(loc, e, v); }
+        for locs.each {|loc| v.visit_local(loc, e, v); }
       }
       decl_item(it) { v.visit_item(it, e, v); }
     }
@@ -305,7 +305,7 @@ fn visit_expr_opt<E>(eo: option<@expr>, e: E, v: vt<E>) {
 }
 
 fn visit_exprs<E>(exprs: [@expr], e: E, v: vt<E>) {
-    for ex: @expr in exprs { v.visit_expr(ex, e, v); }
+    for exprs.each {|ex| v.visit_expr(ex, e, v); }
 }
 
 fn visit_mac<E>(m: mac, e: E, v: vt<E>) {
@@ -328,17 +328,17 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
       }
       expr_vec(es, _) { visit_exprs(es, e, v); }
       expr_rec(flds, base) {
-        for f: field in flds { v.visit_expr(f.node.expr, e, v); }
+        for flds.each {|f| v.visit_expr(f.node.expr, e, v); }
         visit_expr_opt(base, e, v);
       }
-      expr_tup(elts) { for el in elts { v.visit_expr(el, e, v); } }
+      expr_tup(elts) { for elts.each {|el| v.visit_expr(el, e, v); } }
       expr_call(callee, args, _) {
         visit_exprs(args, e, v);
         v.visit_expr(callee, e, v);
       }
       expr_bind(callee, args) {
         v.visit_expr(callee, e, v);
-        for eo: option<@expr> in args { visit_expr_opt(eo, e, v); }
+        for args.each {|eo| visit_expr_opt(eo, e, v); }
       }
       expr_binary(_, a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); }
       expr_addr_of(_, x) | expr_unary(_, x) | expr_loop_body(x) |
@@ -359,15 +359,10 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
       }
       expr_while(x, b) { v.visit_expr(x, e, v); v.visit_block(b, e, v); }
       expr_loop(b) { v.visit_block(b, e, v); }
-      expr_for(dcl, x, b) {
-        v.visit_local(dcl, e, v);
-        v.visit_expr(x, e, v);
-        v.visit_block(b, e, v);
-      }
       expr_do_while(b, x) { v.visit_block(b, e, v); v.visit_expr(x, e, v); }
       expr_alt(x, arms, _) {
         v.visit_expr(x, e, v);
-        for a: arm in arms { v.visit_arm(a, e, v); }
+        for arms.each {|a| v.visit_arm(a, e, v); }
       }
       expr_fn(proto, decl, body, _) {
         v.visit_fn(fk_anon(proto), decl, body, ex.span, ex.id, e, v);
@@ -386,7 +381,7 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
       }
       expr_field(x, _, tys) {
         v.visit_expr(x, e, v);
-        for tp in tys { v.visit_ty(tp, e, v); }
+        for tys.each {|tp| v.visit_ty(tp, e, v); }
       }
       expr_index(a, b) { v.visit_expr(a, e, v); v.visit_expr(b, e, v); }
       expr_path(p) { visit_path(p, e, v); }
@@ -404,7 +399,7 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
 }
 
 fn visit_arm<E>(a: arm, e: E, v: vt<E>) {
-    for p: @pat in a.pats { v.visit_pat(p, e, v); }
+    for a.pats.each {|p| v.visit_pat(p, e, v); }
     visit_expr_opt(a.guard, e, v);
     v.visit_block(a.body, e, v);
 }
index a088cd52f68a0a696d0305a71a9f7e6478e80e7e..d5e59ead1f2aa9a4767b0bf1327f00ed5b0ca7d4 100644 (file)
@@ -67,7 +67,7 @@ fn max_key<T: copy>(m: smallintmap<T>) -> uint {
 impl <V: copy> of map::map<uint, V> for smallintmap<V> {
     fn size() -> uint {
         let mut sz = 0u;
-        for item in self.v {
+        for vec::each(self.v) {|item|
             alt item { some(_) { sz += 1u; } _ {} }
         }
         sz
@@ -90,11 +90,11 @@ fn get(&&key: uint) -> V { get(self, key) }
     fn find(&&key: uint) -> option<V> { find(self, key) }
     fn rehash() { fail }
     fn items(it: fn(&&uint, V)) {
-        let mut idx = 0u;
-        for item in self.v {
-            alt item {
+        let mut idx = 0u, l = self.v.len();
+        while idx < l {
+            alt self.v[idx] {
               some(elt) {
-                it(idx, elt);
+                it(idx, copy elt);
               }
               none { }
             }
@@ -102,16 +102,14 @@ fn items(it: fn(&&uint, V)) {
         }
     }
     fn keys(it: fn(&&uint)) {
-        let mut idx = 0u;
-        for item in self.v {
-            if item != none { it(idx); }
+        let mut idx = 0u, l = self.v.len();
+        while idx < l {
+            if self.v[idx] != none { it(idx); }
             idx += 1u;
         }
     }
     fn values(it: fn(V)) {
-        for item in self.v {
-            alt item { some(elt) { it(elt); } _ {} }
-        }
+        self.items({|_i, v| it(v)});
     }
 }
 
index 43b61e195e2a15b0d7e590038c837f1e1136ecce..b2486b41cdcfb955511d1d5c94c963552e530f8b 100644 (file)
@@ -8,6 +8,11 @@
 #[crate_type = "lib"];
 #[doc = "The Rust standard library"];
 
+#[no_core];
+
+use core(vers = "0.2");
+import core::*;
+
 export net, uv;
 export c_vec, four, tri, util;
 export bitv, deque, fun_treemap, list, map, smallintmap, sort, treemap, ufind;
@@ -15,11 +20,14 @@ export rope, arena;
 export ebml, dbg, getopts, json, rand, sha1, term, time, prettyprint;
 export test, tempfile, serialization;
 
-
 // General io and system-services modules
 
 mod net;
+
+// libuv modules
 mod uv;
+mod uv_ll;
+mod uv_hl;
 
 
 // Utility modules
index 353d57df231614237ef0178ba55f733e55ca3337..ad3ab9fef796960c4f94e852c3cbf53a651ef28c 100644 (file)
@@ -390,7 +390,7 @@ fn run_test(+test: test_desc, monitor_ch: comm::chan<monitor_msg>) {
 
     task::spawn {||
         let testfn = test.fn;
-        let mut builder = task::task_builder();
+        let mut builder = task::builder();
         let result_future = task::future_result(builder);
         task::unsupervise(builder);
         task::run(builder, testfn);
index b4c37a5d44df4ce9260bd3f4c7c7dfb1bbf3f57c..cbc18d32bc1d167a6fb9d888520a13aadbd783c8 100644 (file)
@@ -22,7 +22,7 @@
 
     // FIXME: The i64 values can be passed by-val when #2064 is fixed.
     fn rust_gmtime(&&sec: i64, &&nsec: i32, &&result: tm);
-    fn rust_localtime(&&sec: i64, &&nsec: i32, &result: tm);
+    fn rust_localtime(&&sec: i64, &&nsec: i32, &&result: tm);
     fn rust_timegm(&&tm: tm, &sec: i64);
     fn rust_mktime(&&tm: tm, &sec: i64);
 }
index f6f42de148a1ee17b7ba075f65cdb20a12cdd20b..d0e8c66d4b08e040d745672bc39460effa66abe0 100644 (file)
@@ -1,8 +1,79 @@
+#[doc = "
+Rust bindings to libuv
+
+This is the base-module for various levels of bindings to
+the libuv library.
+
+These modules are seeing heavy work, currently, and the final
+API layout should not be inferred from its current form.
+
+This base module currently contains a historical, rust-based
+implementation of a few libuv operations that hews closely to
+the patterns of the libuv C-API. It was used, mostly, to explore
+some implementation details and will most likely be deprecated
+in the near future.
+
+The `ll` module contains low-level mappings for working directly
+with the libuv C-API.
+
+The `hl` module contains a set of tools library developers can
+use for interacting with an active libuv loop. This modules's
+API is meant to be used to write high-level,
+rust-idiomatic abstractions for utilizes libuv's asynchronous IO
+facilities.
+"];
+
 import map::hashmap;
 export loop_new, loop_delete, run, close, run_in_bg;
 export async_init, async_send;
 export timer_init, timer_start, timer_stop;
 
+import ll = uv_ll;
+export ll;
+
+import hl = uv_hl;
+export hl;
+
+#[nolink]
+native mod rustrt {
+    fn rust_uv_loop_new() -> *libc::c_void;
+    fn rust_uv_loop_delete(lp: *libc::c_void);
+    fn rust_uv_loop_set_data(
+        lp: *libc::c_void,
+        data: *uv_loop_data);
+    fn rust_uv_bind_op_cb(lp: *libc::c_void, cb: *u8)
+        -> *libc::c_void;
+    fn rust_uv_stop_op_cb(handle: *libc::c_void);
+    fn rust_uv_run(loop_handle: *libc::c_void);
+    fn rust_uv_hilvl_close(handle: *libc::c_void, cb: *u8);
+    fn rust_uv_hilvl_close_async(handle: *libc::c_void);
+    fn rust_uv_hilvl_close_timer(handle: *libc::c_void);
+    fn rust_uv_async_send(handle: *ll::uv_async_t);
+    fn rust_uv_hilvl_async_init(
+        loop_handle: *libc::c_void,
+        cb: *u8,
+        id: *u8) -> *libc::c_void;
+    fn rust_uv_timer_init(
+        loop_handle: *libc::c_void,
+        cb: *u8,
+        id: *u8) -> *libc::c_void;
+    fn rust_uv_timer_start(
+        timer_handle: *libc::c_void,
+        timeout: libc::c_uint,
+        repeat: libc::c_uint);
+    fn rust_uv_timer_stop(handle: *libc::c_void);
+    fn rust_uv_free(ptr: *libc::c_void);
+    // sizeof testing helpers
+    fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
+    fn rust_uv_helper_uv_connect_t_size() -> libc::c_uint;
+    fn rust_uv_helper_uv_buf_t_size() -> libc::c_uint;
+    fn rust_uv_helper_uv_write_t_size() -> libc::c_uint;
+    fn rust_uv_helper_uv_err_t_size() -> libc::c_uint;
+    fn rust_uv_helper_sockaddr_in_size() -> libc::c_uint;
+    fn rust_uv_helper_uv_async_t_size() -> libc::c_uint;
+}
+
+
 // these are processed solely in the
 // process_operation() crust fn below
 enum uv_operation {
@@ -16,7 +87,7 @@ enum uv_operation {
 
 enum uv_handle {
     uv_async([u8], uv_loop),
-    uv_timer([u8], uv_loop)
+    uv_timer([u8], uv_loop),
 }
 
 enum uv_msg {
@@ -50,36 +121,6 @@ enum uv_loop {
     uv_loop_new(comm::chan<uv_msg>, *libc::c_void)
 }
 
-#[nolink]
-native mod rustrt {
-    fn rust_uv_loop_new() -> *libc::c_void;
-    fn rust_uv_loop_delete(lp: *libc::c_void);
-    fn rust_uv_loop_set_data(
-        lp: *libc::c_void,
-        data: *uv_loop_data);
-    fn rust_uv_bind_op_cb(lp: *libc::c_void, cb: *u8)
-        -> *libc::c_void;
-    fn rust_uv_stop_op_cb(handle: *libc::c_void);
-    fn rust_uv_run(loop_handle: *libc::c_void);
-    fn rust_uv_close(handle: *libc::c_void, cb: *u8);
-    fn rust_uv_close_async(handle: *libc::c_void);
-    fn rust_uv_close_timer(handle: *libc::c_void);
-    fn rust_uv_async_send(handle: *libc::c_void);
-    fn rust_uv_async_init(
-        loop_handle: *libc::c_void,
-        cb: *u8,
-        id: *u8) -> *libc::c_void;
-    fn rust_uv_timer_init(
-        loop_handle: *libc::c_void,
-        cb: *u8,
-        id: *u8) -> *libc::c_void;
-    fn rust_uv_timer_start(
-        timer_handle: *libc::c_void,
-        timeout: libc::c_uint,
-        repeat: libc::c_uint);
-    fn rust_uv_timer_stop(handle: *libc::c_void);
-}
-
 // public functions
 fn loop_new() -> uv_loop unsafe {
     let ret_recv_port: comm::port<uv_loop> =
@@ -406,7 +447,7 @@ fn pass_to_libuv(
     do_send(op_handle);
 }
 fn do_send(h: *libc::c_void) {
-    rustrt::rust_uv_async_send(h);
+    rustrt::rust_uv_async_send(h as *ll::uv_async_t);
 }
 fn gen_handle_id() -> [u8] {
     ret rand::rng().gen_bytes(16u);
@@ -471,7 +512,7 @@ fn get_id_from_handle(handle: uv_handle) -> [u8] {
         alt comm::recv(op_port) {
           op_async_init(id) {
             let id_ptr = vec::unsafe::to_ptr(id);
-            let async_handle = rustrt::rust_uv_async_init(
+            let async_handle = rustrt::rust_uv_hilvl_async_init(
                 lp,
                 process_async_send,
                 id_ptr);
@@ -517,12 +558,12 @@ fn handle_op_close(handle: uv_handle, handle_ptr: *libc::c_void) {
     alt handle {
       uv_async(id, lp) {
         let cb = process_close_async;
-        rustrt::rust_uv_close(
+        rustrt::rust_uv_hilvl_close(
             handle_ptr, cb);
       }
       uv_timer(id, lp) {
         let cb = process_close_timer;
-        rustrt::rust_uv_close(
+        rustrt::rust_uv_hilvl_close(
             handle_ptr, cb);
       }
       _ {
@@ -561,7 +602,7 @@ fn process_close_common(id: [u8], data: *uv_loop_data)
     data: *uv_loop_data)
     unsafe {
     let id = get_handle_id_from(id_buf);
-    rustrt::rust_uv_close_async(handle_ptr);
+    rustrt::rust_uv_hilvl_close_async(handle_ptr);
     // at this point, the handle and its data has been
     // released. notify the rust loop to remove the
     // handle and its data and call the user-supplied
@@ -575,7 +616,7 @@ fn process_close_common(id: [u8], data: *uv_loop_data)
     data: *uv_loop_data)
     unsafe {
     let id = get_handle_id_from(id_buf);
-    rustrt::rust_uv_close_timer(handle_ptr);
+    rustrt::rust_uv_hilvl_close_timer(handle_ptr);
     process_close_common(id, data);
 }
 
@@ -626,3 +667,587 @@ fn test_uv_timer() {
     assert comm::recv(exit_port);
     uv::loop_delete(test_loop);
 }
+
+enum tcp_read_data {
+    tcp_read_eof,
+    tcp_read_more([u8]),
+    tcp_read_error
+}
+
+type request_wrapper = {
+    write_req: *ll::uv_write_t,
+    req_buf: *[ll::uv_buf_t],
+    read_chan: *comm::chan<str>
+};
+
+crust fn after_close_cb(handle: *libc::c_void) {
+    log(debug, #fmt("after uv_close! handle ptr: %?",
+                    handle));
+}
+
+crust fn on_alloc_cb(handle: *libc::c_void,
+                     ++suggested_size: libc::size_t)
+    -> ll::uv_buf_t unsafe {
+    log(debug, "on_alloc_cb!");
+    let char_ptr = ll::malloc_buf_base_of(suggested_size);
+    log(debug, #fmt("on_alloc_cb h: %? char_ptr: %u sugsize: %u",
+                     handle,
+                     char_ptr as uint,
+                     suggested_size as uint));
+    ret ll::buf_init(char_ptr, suggested_size);
+}
+
+crust fn on_read_cb(stream: *ll::uv_stream_t,
+                    nread: libc::ssize_t,
+                    ++buf: ll::uv_buf_t) unsafe {
+    log(debug, #fmt("CLIENT entering on_read_cb nred: %d", nread));
+    if (nread > 0) {
+        // we have data
+        log(debug, #fmt("CLIENT read: data! nread: %d", nread));
+        ll::read_stop(stream);
+        let client_data = ll::
+            get_data_for_uv_handle(stream as *libc::c_void)
+              as *request_wrapper;
+        let buf_base = ll::get_base_from_buf(buf);
+        let buf_len = ll::get_len_from_buf(buf);
+        let bytes = vec::unsafe::from_buf(buf_base, buf_len);
+        let read_chan = *((*client_data).read_chan);
+        let msg_from_server = str::from_bytes(bytes);
+        comm::send(read_chan, msg_from_server);
+        ll::close(stream as *libc::c_void, after_close_cb)
+    }
+    else if (nread == -1) {
+        // err .. possibly EOF
+        log(debug, "read: eof!");
+    }
+    else {
+        // nread == 0 .. do nothing, just free buf as below
+        log(debug, "read: do nothing!");
+    }
+    // when we're done
+    ll::free_base_of_buf(buf);
+    log(debug, "CLIENT exiting on_read_cb");
+}
+
+crust fn on_write_complete_cb(write_req: *ll::uv_write_t,
+                              status: libc::c_int) unsafe {
+    log(debug, #fmt("CLIENT beginning on_write_complete_cb status: %d",
+                     status as int));
+    let stream = ll::get_stream_handle_from_write_req(write_req);
+    log(debug, #fmt("CLIENT on_write_complete_cb: tcp:%d write_handle:%d",
+        stream as int, write_req as int));
+    let result = ll::read_start(stream, on_alloc_cb, on_read_cb);
+    log(debug, #fmt("CLIENT ending on_write_complete_cb .. status: %d",
+                     result as int));
+}
+
+crust fn on_connect_cb(connect_req_ptr: *ll::uv_connect_t,
+                             status: libc::c_int) unsafe {
+    log(debug, #fmt("beginning on_connect_cb .. status: %d",
+                     status as int));
+    let stream =
+        ll::get_stream_handle_from_connect_req(connect_req_ptr);
+    if (status == 0i32) {
+        log(debug, "on_connect_cb: in status=0 if..");
+        let client_data = ll::get_data_for_req(
+            connect_req_ptr as *libc::c_void)
+            as *request_wrapper;
+        let write_handle = (*client_data).write_req as *libc::c_void;
+        log(debug, #fmt("on_connect_cb: tcp stream: %d write_handle addr %d",
+                        stream as int, write_handle as int));
+        let write_result = ll::write(write_handle,
+                          stream as *libc::c_void,
+                          (*client_data).req_buf,
+                          on_write_complete_cb);
+        log(debug, #fmt("on_connect_cb: ll::write() status: %d",
+                         write_result as int));
+    }
+    else {
+        let test_loop = ll::get_loop_for_uv_handle(
+            stream as *libc::c_void);
+        let err_msg = ll::get_last_err_info(test_loop);
+        log(debug, err_msg);
+        assert false;
+    }
+    log(debug, "finishing on_connect_cb");
+}
+
+fn impl_uv_tcp_request(ip: str, port: int, req_str: str,
+                      client_chan: *comm::chan<str>) unsafe {
+    let test_loop = ll::loop_new();
+    let tcp_handle = ll::tcp_t();
+    let tcp_handle_ptr = ptr::addr_of(tcp_handle);
+    let connect_handle = ll::connect_t();
+    let connect_req_ptr = ptr::addr_of(connect_handle);
+
+    // this is the persistent payload of data that we
+    // need to pass around to get this example to work.
+    // In C, this would be a malloc'd or stack-allocated
+    // struct that we'd cast to a void* and store as the
+    // data field in our uv_connect_t struct
+    let req_str_bytes = str::bytes(req_str);
+    let req_msg_ptr: *u8 = vec::unsafe::to_ptr(req_str_bytes);
+    log(debug, #fmt("req_msg ptr: %u", req_msg_ptr as uint));
+    let req_msg = [
+        ll::buf_init(req_msg_ptr, vec::len(req_str_bytes))
+    ];
+    // this is the enclosing record, we'll pass a ptr to
+    // this to C..
+    let write_handle = ll::write_t();
+    let write_handle_ptr = ptr::addr_of(write_handle);
+    log(debug, #fmt("tcp req: tcp stream: %d write_handle: %d",
+                     tcp_handle_ptr as int,
+                     write_handle_ptr as int));
+    let client_data = { writer_handle: write_handle_ptr,
+                req_buf: ptr::addr_of(req_msg),
+                read_chan: client_chan };
+
+    let tcp_init_result = ll::tcp_init(
+        test_loop as *libc::c_void, tcp_handle_ptr);
+    if (tcp_init_result == 0i32) {
+        log(debug, "sucessful tcp_init_result");
+
+        log(debug, "building addr...");
+        let addr = ll::ip4_addr(ip, port);
+        // FIXME ref #2064
+        let addr_ptr = ptr::addr_of(addr);
+        log(debug, #fmt("after build addr in rust. port: %u",
+                         addr.sin_port as uint));
+
+        // this should set up the connection request..
+        log(debug, #fmt("before calling tcp_connect .. connect cb ptr: %u ",
+                        on_connect_cb as uint));
+        let tcp_connect_result = ll::tcp_connect(
+            connect_req_ptr, tcp_handle_ptr,
+            addr_ptr, on_connect_cb);
+        if (tcp_connect_result == 0i32) {
+            // not set the data on the connect_req
+            // until its initialized
+            ll::set_data_for_req(
+                connect_req_ptr as *libc::c_void,
+                ptr::addr_of(client_data) as *libc::c_void);
+            ll::set_data_for_uv_handle(
+                tcp_handle_ptr as *libc::c_void,
+                ptr::addr_of(client_data) as *libc::c_void);
+            log(debug, "before run tcp req loop");
+            ll::run(test_loop);
+            log(debug, "after run tcp req loop");
+        }
+        else {
+           log(debug, "ll::tcp_connect() failure");
+           assert false;
+        }
+    }
+    else {
+        log(debug, "ll::tcp_init() failure");
+        assert false;
+    }
+    ll::loop_delete(test_loop);
+
+}
+
+crust fn server_after_close_cb(handle: *libc::c_void) unsafe {
+    log(debug, #fmt("SERVER server stream closed, should exit.. h: %?",
+               handle));
+}
+
+crust fn client_stream_after_close_cb(handle: *libc::c_void)
+    unsafe {
+    log(debug, "SERVER: closed client stream, now closing server stream");
+    let client_data = ll::get_data_for_uv_handle(
+        handle) as
+        *tcp_server_data;
+    ll::close((*client_data).server as *libc::c_void,
+                  server_after_close_cb);
+}
+
+crust fn after_server_resp_write(req: *ll::uv_write_t) unsafe {
+    let client_stream_ptr =
+        ll::get_stream_handle_from_write_req(req);
+    log(debug, "SERVER: resp sent... closing client stream");
+    ll::close(client_stream_ptr as *libc::c_void,
+                  client_stream_after_close_cb)
+}
+
+crust fn on_server_read_cb(client_stream_ptr: *ll::uv_stream_t,
+                           nread: libc::ssize_t,
+                           ++buf: ll::uv_buf_t) unsafe {
+    if (nread > 0) {
+        // we have data
+        log(debug, #fmt("SERVER read: data! nread: %d", nread));
+
+        // pull out the contents of the write from the client
+        let buf_base = ll::get_base_from_buf(buf);
+        let buf_len = ll::get_len_from_buf(buf);
+        log(debug, #fmt("SERVER buf base: %u, len: %u, nread: %d",
+                         buf_base as uint,
+                         buf_len as uint,
+                         nread));
+        let bytes = vec::unsafe::from_buf(buf_base, buf_len);
+        let request_str = str::from_bytes(bytes);
+
+        let client_data = ll::get_data_for_uv_handle(
+            client_stream_ptr as *libc::c_void) as *tcp_server_data;
+
+        let server_kill_msg = (*client_data).server_kill_msg;
+        let write_req = (*client_data).server_write_req;
+        if (str::contains(request_str, server_kill_msg)) {
+            log(debug, "SERVER: client request contains server_kill_msg!");
+            log(debug, "SERVER: sending response to client");
+            ll::read_stop(client_stream_ptr);
+            let server_chan = *((*client_data).server_chan);
+            comm::send(server_chan, request_str);
+            let write_result = ll::write(
+                write_req as *libc::c_void,
+                client_stream_ptr as *libc::c_void,
+                (*client_data).server_resp_buf,
+                after_server_resp_write);
+            log(debug, #fmt("SERVER: resp write result: %d",
+                        write_result as int));
+            if (write_result != 0i32) {
+                log(debug, "bad result for server resp ll::write()");
+                log(debug, ll::get_last_err_info(
+                    ll::get_loop_for_uv_handle(client_stream_ptr
+                        as *libc::c_void)));
+                assert false;
+            }
+        }
+        else {
+            log(debug, "SERVER: client req DOESNT contain server_kill_msg!");
+        }
+    }
+    else if (nread == -1) {
+        // err .. possibly EOF
+        log(debug, "read: eof!");
+    }
+    else {
+        // nread == 0 .. do nothing, just free buf as below
+        log(debug, "read: do nothing!");
+    }
+    // when we're done
+    ll::free_base_of_buf(buf);
+    log(debug, "SERVER exiting on_read_cb");
+}
+
+crust fn server_connection_cb(server_stream_ptr:
+                                *ll::uv_stream_t,
+                              status: libc::c_int) unsafe {
+    log(debug, "client connecting!");
+    let test_loop = ll::get_loop_for_uv_handle(
+                           server_stream_ptr as *libc::c_void);
+    if status != 0i32 {
+        let err_msg = ll::get_last_err_info(test_loop);
+        log(debug, #fmt("server_connect_cb: non-zero status: %?",
+                     err_msg));
+        ret;
+    }
+    let server_data = ll::get_data_for_uv_handle(
+        server_stream_ptr as *libc::c_void) as *tcp_server_data;
+    let client_stream_ptr = (*server_data).client;
+    let client_init_result = ll::tcp_init(test_loop,
+                                              client_stream_ptr);
+    ll::set_data_for_uv_handle(
+        client_stream_ptr as *libc::c_void,
+        server_data as *libc::c_void);
+    if (client_init_result == 0i32) {
+        log(debug, "successfully initialized client stream");
+        let accept_result = ll::accept(server_stream_ptr as
+                                             *libc::c_void,
+                                           client_stream_ptr as
+                                             *libc::c_void);
+        if (accept_result == 0i32) {
+            // start reading
+            let read_result = ll::read_start(
+                client_stream_ptr as *ll::uv_stream_t,
+                                                 on_alloc_cb,
+                                                 on_server_read_cb);
+            if (read_result == 0i32) {
+                log(debug, "successful server read start");
+            }
+            else {
+                log(debug, #fmt("server_connection_cb: bad read:%d",
+                                read_result as int));
+                assert false;
+            }
+        }
+        else {
+            log(debug, #fmt("server_connection_cb: bad accept: %d",
+                        accept_result as int));
+            assert false;
+        }
+    }
+    else {
+        log(debug, #fmt("server_connection_cb: bad client init: %d",
+                    client_init_result as int));
+        assert false;
+    }
+}
+
+type tcp_server_data = {
+    client: *ll::uv_tcp_t,
+    server: *ll::uv_tcp_t,
+    server_kill_msg: str,
+    server_resp_buf: *[ll::uv_buf_t],
+    server_chan: *comm::chan<str>,
+    server_write_req: *ll::uv_write_t
+};
+
+type async_handle_data = {
+    continue_chan: *comm::chan<bool>
+};
+
+crust fn async_close_cb(handle: *libc::c_void) {
+    log(debug, #fmt("SERVER: closing async cb... h: %?",
+               handle));
+}
+
+crust fn continue_async_cb(async_handle: *ll::uv_async_t,
+                           status: libc::c_int) unsafe {
+    // once we're in the body of this callback,
+    // the tcp server's loop is set up, so we
+    // can continue on to let the tcp client
+    // do its thang
+    let data = ll::get_data_for_uv_handle(
+        async_handle as *libc::c_void) as *async_handle_data;
+    let continue_chan = *((*data).continue_chan);
+    let should_continue = status == 0i32;
+    comm::send(continue_chan, should_continue);
+    ll::close(async_handle as *libc::c_void, async_close_cb);
+}
+
+fn impl_uv_tcp_server(server_ip: str,
+                      server_port: int,
+                      kill_server_msg: str,
+                      server_resp_msg: str,
+                      server_chan: *comm::chan<str>,
+                      continue_chan: *comm::chan<bool>) unsafe {
+    let test_loop = ll::loop_new();
+    let tcp_server = ll::tcp_t();
+    let tcp_server_ptr = ptr::addr_of(tcp_server);
+
+    let tcp_client = ll::tcp_t();
+    let tcp_client_ptr = ptr::addr_of(tcp_client);
+
+    let server_write_req = ll::write_t();
+    let server_write_req_ptr = ptr::addr_of(server_write_req);
+
+    let resp_str_bytes = str::bytes(server_resp_msg);
+    let resp_msg_ptr: *u8 = vec::unsafe::to_ptr(resp_str_bytes);
+    log(debug, #fmt("resp_msg ptr: %u", resp_msg_ptr as uint));
+    let resp_msg = [
+        ll::buf_init(resp_msg_ptr, vec::len(resp_str_bytes))
+    ];
+
+    let continue_async_handle = ll::async_t();
+    let continue_async_handle_ptr =
+        ptr::addr_of(continue_async_handle);
+    let async_data =
+        { continue_chan: continue_chan };
+    let async_data_ptr = ptr::addr_of(async_data);
+
+    let server_data: tcp_server_data = {
+        client: tcp_client_ptr,
+        server: tcp_server_ptr,
+        server_kill_msg: kill_server_msg,
+        server_resp_buf: ptr::addr_of(resp_msg),
+        server_chan: server_chan,
+        server_write_req: server_write_req_ptr
+    };
+    let server_data_ptr = ptr::addr_of(server_data);
+    ll::set_data_for_uv_handle(tcp_server_ptr as *libc::c_void,
+                                   server_data_ptr as *libc::c_void);
+
+    // uv_tcp_init()
+    let tcp_init_result = ll::tcp_init(
+        test_loop as *libc::c_void, tcp_server_ptr);
+    if (tcp_init_result == 0i32) {
+        let server_addr = ll::ip4_addr(server_ip, server_port);
+        // FIXME ref #2064
+        let server_addr_ptr = ptr::addr_of(server_addr);
+
+        // uv_tcp_bind()
+        let bind_result = ll::tcp_bind(tcp_server_ptr,
+                                           server_addr_ptr);
+        if (bind_result == 0i32) {
+            log(debug, "successful uv_tcp_bind, listening");
+
+            // uv_listen()
+            let listen_result = ll::listen(tcp_server_ptr as
+                                                 *libc::c_void,
+                                               128i32,
+                                               server_connection_cb);
+            if (listen_result == 0i32) {
+                // let the test know it can set up the tcp server,
+                // now.. this may still present a race, not sure..
+                let async_result = ll::async_init(test_loop,
+                                   continue_async_handle_ptr,
+                                   continue_async_cb);
+                if (async_result == 0i32) {
+                    ll::set_data_for_uv_handle(
+                        continue_async_handle_ptr as *libc::c_void,
+                        async_data_ptr as *libc::c_void);
+                    ll::async_send(continue_async_handle_ptr);
+                    // uv_run()
+                    ll::run(test_loop);
+                    log(debug, "server uv::run() has returned");
+                }
+                else {
+                    log(debug, #fmt("uv_async_init failure: %d",
+                            async_result as int));
+                    assert false;
+                }
+            }
+            else {
+                log(debug, #fmt("non-zero result on uv_listen: %d",
+                            listen_result as int));
+                assert false;
+            }
+        }
+        else {
+            log(debug, #fmt("non-zero result on uv_tcp_bind: %d",
+                        bind_result as int));
+            assert false;
+        }
+    }
+    else {
+        log(debug, #fmt("non-zero result on uv_tcp_init: %d",
+                    tcp_init_result as int));
+        assert false;
+    }
+    ll::loop_delete(test_loop);
+}
+
+// this is the impl for a test that is (maybe) ran on a
+// per-platform/arch basis below
+fn impl_uv_tcp_server_and_request() unsafe {
+    let bind_ip = "0.0.0.0";
+    let request_ip = "127.0.0.1";
+    let port = 8888;
+    let kill_server_msg = "does a dog have buddha nature?";
+    let server_resp_msg = "mu!";
+    let client_port = comm::port::<str>();
+    let client_chan = comm::chan::<str>(client_port);
+    let server_port = comm::port::<str>();
+    let server_chan = comm::chan::<str>(server_port);
+
+    let continue_port = comm::port::<bool>();
+    let continue_chan = comm::chan::<bool>(continue_port);
+    let continue_chan_ptr = ptr::addr_of(continue_chan);
+
+    task::spawn_sched(task::manual_threads(1u)) {||
+        impl_uv_tcp_server(bind_ip, port,
+                           kill_server_msg,
+                           server_resp_msg,
+                           ptr::addr_of(server_chan),
+                           continue_chan_ptr);
+    };
+
+    // block until the server up is.. possibly a race?
+    log(debug, "before receiving on server continue_port");
+    comm::recv(continue_port);
+    log(debug, "received on continue port, set up tcp client");
+
+    task::spawn_sched(task::manual_threads(1u)) {||
+        impl_uv_tcp_request(request_ip, port,
+                           kill_server_msg,
+                           ptr::addr_of(client_chan));
+    };
+
+    let msg_from_client = comm::recv(server_port);
+    let msg_from_server = comm::recv(client_port);
+
+    assert str::contains(msg_from_client, kill_server_msg);
+    assert str::contains(msg_from_server, server_resp_msg);
+}
+
+// don't run this test on fbsd or 32bit linux
+#[cfg(target_os="win32")]
+#[cfg(target_os="darwin")]
+#[cfg(target_os="linux")]
+mod tcp_and_server_client_test {
+    #[cfg(target_arch="x86_64")]
+    mod impl64 {
+        #[test]
+        fn test_uv_tcp_server_and_request() unsafe {
+            impl_uv_tcp_server_and_request();
+        }
+    }
+    #[cfg(target_arch="x86")]
+    mod impl32 {
+        #[test]
+        #[ignore(cfg(target_os = "linux"))]
+        fn test_uv_tcp_server_and_request() unsafe {
+            impl_uv_tcp_server_and_request();
+        }
+    }
+}
+
+// struct size tests
+#[test]
+#[ignore(cfg(target_os = "freebsd"))]
+fn test_uv_struct_size_uv_tcp_t() {
+    let native_handle_size = rustrt::rust_uv_helper_uv_tcp_t_size();
+    let rust_handle_size = sys::size_of::<ll::uv_tcp_t>();
+    let output = #fmt("uv_tcp_t -- native: %u rust: %u",
+                      native_handle_size as uint, rust_handle_size);
+    log(debug, output);
+    assert native_handle_size as uint == rust_handle_size;
+}
+#[test]
+#[ignore(cfg(target_os = "freebsd"))]
+fn test_uv_struct_size_uv_connect_t() {
+    let native_handle_size =
+        rustrt::rust_uv_helper_uv_connect_t_size();
+    let rust_handle_size = sys::size_of::<ll::uv_connect_t>();
+    let output = #fmt("uv_connect_t -- native: %u rust: %u",
+                      native_handle_size as uint, rust_handle_size);
+    log(debug, output);
+    assert native_handle_size as uint == rust_handle_size;
+}
+#[test]
+#[ignore(cfg(target_os = "freebsd"))]
+fn test_uv_struct_size_uv_buf_t() {
+    let native_handle_size =
+        rustrt::rust_uv_helper_uv_buf_t_size();
+    let rust_handle_size = sys::size_of::<ll::uv_buf_t>();
+    let output = #fmt("uv_buf_t -- native: %u rust: %u",
+                      native_handle_size as uint, rust_handle_size);
+    log(debug, output);
+    assert native_handle_size as uint == rust_handle_size;
+}
+#[test]
+#[ignore(cfg(target_os = "freebsd"))]
+fn test_uv_struct_size_uv_write_t() {
+    let native_handle_size =
+        rustrt::rust_uv_helper_uv_write_t_size();
+    let rust_handle_size = sys::size_of::<ll::uv_write_t>();
+    let output = #fmt("uv_write_t -- native: %u rust: %u",
+                      native_handle_size as uint, rust_handle_size);
+    log(debug, output);
+    assert native_handle_size as uint == rust_handle_size;
+}
+
+#[test]
+#[ignore(cfg(target_os = "freebsd"))]
+fn test_uv_struct_size_sockaddr_in() {
+    let native_handle_size =
+        rustrt::rust_uv_helper_sockaddr_in_size();
+    let rust_handle_size = sys::size_of::<ll::sockaddr_in>();
+    let output = #fmt("sockaddr_in -- native: %u rust: %u",
+                      native_handle_size as uint, rust_handle_size);
+    log(debug, output);
+    assert native_handle_size as uint == rust_handle_size;
+}
+
+#[test]
+#[ignore(cfg(target_os = "freebsd"))]
+fn test_uv_struct_size_uv_async_t() {
+    let native_handle_size =
+        rustrt::rust_uv_helper_uv_async_t_size();
+    let rust_handle_size = sys::size_of::<ll::uv_async_t>();
+    let output = #fmt("uv_async_t -- native: %u rust: %u",
+                      native_handle_size as uint, rust_handle_size);
+    log(debug, output);
+    assert native_handle_size as uint == rust_handle_size;
+}
+
diff --git a/src/libstd/uv_hl.rs b/src/libstd/uv_hl.rs
new file mode 100644 (file)
index 0000000..c716f7a
--- /dev/null
@@ -0,0 +1,103 @@
+#[doc = "
+High-level bindings to work with the libuv library.
+
+This module is geared towards library developers who want to
+provide a high-level, abstracted interface to some set of
+libuv functionality.
+"];
+
+import ll = uv_ll;
+
+export high_level_loop;
+export interact, prepare_loop;
+
+#[doc = "
+Used to abstract-away direct interaction with a libuv loop.
+
+# Fields
+
+* async_handle - a pointer to a uv_async_t struct used to 'poke'
+the C uv loop to process any pending callbacks
+
+* op_chan - a channel used to send function callbacks to be processed
+by the C uv loop
+"]
+type high_level_loop = {
+    async_handle: *ll::uv_async_t,
+    op_chan: comm::chan<fn~(*libc::c_void)>
+};
+
+#[doc = "
+Pass in a callback to be processed on the running libuv loop's thread
+
+# Fields
+
+* a_loop - a high_level_loop record that represents a channel of
+communication with an active libuv loop running on a thread
+somwhere in the current process
+
+* cb - a function callback to be processed on the running loop's
+thread. The only parameter is an opaque pointer to the running
+uv_loop_t. You can use this pointer to initiate or continue any
+operations against the loop
+"]
+unsafe fn interact(a_loop: high_level_loop,
+                      -cb: fn~(*libc::c_void)) {
+    comm::send(a_loop.op_chan, cb);
+    ll::async_send(a_loop.async_handle);
+}
+
+#[doc = "
+Prepares a clean, inactive uv_loop_t* to be used with any of the
+functions in the `uv::hl` module.
+
+Library developers can use this function to prepare a given
+`uv_loop_t*`, whose lifecycle they manage, to be used, ran
+and controlled with the tools in this module.
+
+After this is ran against a loop, a library developer can run
+the loop in its own thread and then use the returned
+`high_level_loop` to interact with it.
+
+# Fields
+
+* loop_ptr - a pointer to a newly created `uv_loop_t*` with no
+handles registered (this will interfere with the internal lifecycle
+management this module provides). Ideally, this should be called
+immediately after using `uv::ll::loop_new()`
+
+# Returns
+
+A `high_level_loop` record that can be used to interact with the
+loop (after you use `uv::ll::run()` on the `uv_loop_t*`, of course
+"]
+unsafe fn prepare_loop(loop_ptr: *libc::c_void)
+    -> high_level_loop {
+    // will probably need to stake out a data record
+    // here, as well, to keep whatever state we want to
+    // use with the loop
+
+    // move this into a malloc
+    let async = ll::async_t();
+    let async_ptr = ptr::addr_of(async);
+    let op_port = comm::port::<fn~(*libc::c_void)>();
+    let async_result = ll::async_init(loop_ptr,
+                                      async_ptr,
+                                      interact_poke);
+    if (async_result != 0i32) {
+        fail ll::get_last_err_info(loop_ptr);
+    }
+    // need to store the port and async_ptr in the top-level
+    // of the provided loop ..
+    ret { async_handle: async_ptr,
+         op_chan: comm::chan::<fn~(*libc::c_void)>(op_port)
+        };
+}
+
+// this will be invoked by a called to uv::hl::interact(), so
+// we'll drain the port of pending callbacks, processing each
+crust fn interact_poke(async_handle: *libc::c_void) {
+    // nothing here, yet.
+    log(debug, #fmt("interact_poke crust.. handle: %?",
+                     async_handle));
+}
\ No newline at end of file
diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs
new file mode 100644 (file)
index 0000000..85da168
--- /dev/null
@@ -0,0 +1,676 @@
+#[doc = "
+Low-level bindings to the libuv library.
+
+This module contains a set of direct, 'bare-metal' wrappers around
+the libuv C-API.
+
+Also contained herein are a set of rust records that map, in
+approximate memory-size, to the libuv data structures. The record
+implementations are adjusted, per-platform, to match their respective
+representations.
+
+There are also a collection of helper functions to ease interacting
+with the low-level API (such as a function to return the latest
+libuv error as a rust-formatted string).
+
+As new functionality, existant in uv.h, is added to the rust stdlib,
+the mappings should be added in this module.
+
+This module's implementation will hopefully be, eventually, replaced
+with per-platform, generated source files from rust-bindgen.
+"];
+
+// libuv struct mappings
+type uv_ip4_addr = {
+    ip: [u8],
+    port: int
+};
+type uv_ip6_addr = uv_ip4_addr;
+
+enum uv_handle_type {
+    UNKNOWN_HANDLE = 0,
+    UV_TCP,
+    UV_UDP,
+    UV_NAMED_PIPE,
+    UV_TTY,
+    UV_FILE,
+    UV_TIMER,
+    UV_PREPARE,
+    UV_CHECK,
+    UV_IDLE,
+    UV_ASYNC,
+    UV_ARES_TASK,
+    UV_ARES_EVENT,
+    UV_PROCESS,
+    UV_FS_EVENT
+}
+
+type handle_type = libc::c_uint;
+
+type uv_handle_fields = {
+   loop_handle: *libc::c_void,
+   type_: handle_type,
+   close_cb: *u8,
+   mut data: *libc::c_void,
+};
+
+// unix size: 8
+type uv_err_t = {
+    code: libc::c_int,
+    sys_errno_: libc::c_int
+};
+
+// don't create one of these directly. instead,
+// count on it appearing in libuv callbacks or embedded
+// in other types as a pointer to be used in other
+// operations (so mostly treat it as opaque, once you
+// have it in this form..)
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+#[cfg(target_os = "win32")]
+type uv_stream_t = {
+    fields: uv_handle_fields
+};
+
+// 64bit unix size: 272
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+type uv_tcp_t = {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+    a12: *u8, a13: *u8, a14: *u8, a15: *u8,
+    a16: *u8, a17: *u8, a18: *u8, a19: *u8,
+    a20: *u8, a21: *u8, a22: *u8, a23: *u8,
+    a24: *u8, a25: *u8, a26: *u8, a27: *u8,
+    a28: *u8,
+    a30: uv_tcp_t_32bit_unix_riders
+};
+// 32bit unix size: 328 (164)
+#[cfg(target_arch="x86_64")]
+type uv_tcp_t_32bit_unix_riders = {
+    a29: *u8
+};
+#[cfg(target_arch="x86")]
+type uv_tcp_t_32bit_unix_riders = {
+    a29: *u8, a30: *u8, a31: *u8,
+    a32: *u8, a33: *u8, a34: *u8,
+    a35: *u8, a36: *u8
+};
+
+// 32bit win32 size: 240 (120)
+#[cfg(target_os = "win32")]
+type uv_tcp_t = {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+    a12: *u8, a13: *u8, a14: *u8, a15: *u8,
+    a16: *u8, a17: *u8, a18: *u8, a19: *u8,
+    a20: *u8, a21: *u8, a22: *u8, a23: *u8,
+    a24: *u8, a25: *u8
+};
+
+// unix size: 48
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+type uv_connect_t = {
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8
+};
+// win32 size: 88 (44)
+#[cfg(target_os = "win32")]
+type uv_connect_t = {
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8
+};
+
+// unix size: 16
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+#[cfg(target_os = "win32")]
+type uv_buf_t = {
+    base: *u8,
+    len: libc::size_t
+};
+// no gen stub method.. should create
+// it via uv::direct::buf_init()
+
+// unix size: 144
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+type uv_write_t = {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+    a12: *u8,
+    a14: uv_write_t_32bit_unix_riders
+};
+#[cfg(target_arch="x86_64")]
+type uv_write_t_32bit_unix_riders = {
+    a13: *u8
+};
+#[cfg(target_arch="x86")]
+type uv_write_t_32bit_unix_riders = {
+    a13: *u8, a14: *u8
+};
+// win32 size: 136 (68)
+#[cfg(target_os = "win32")]
+type uv_write_t = {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+    a12: *u8
+};
+// 64bit unix size: 120
+// 32bit unix size: 152 (76)
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+type uv_async_t = {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8,
+    a11: uv_async_t_32bit_unix_riders
+};
+#[cfg(target_arch="x86_64")]
+type uv_async_t_32bit_unix_riders = {
+    a10: *u8
+};
+#[cfg(target_arch="x86")]
+type uv_async_t_32bit_unix_riders = {
+    a10: *u8, a11: *u8, a12: *u8, a13: *u8
+};
+// win32 size 132 (68)
+#[cfg(target_os = "win32")]
+type uv_async_t = {
+    fields: uv_handle_fields,
+    a00: *u8, a01: *u8, a02: *u8, a03: *u8,
+    a04: *u8, a05: *u8, a06: *u8, a07: *u8,
+    a08: *u8, a09: *u8, a10: *u8, a11: *u8,
+    a12: *u8
+};
+
+// unix size: 16
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+#[cfg(target_os = "win32")]
+type sockaddr_in = {
+    mut sin_family: u16,
+    mut sin_port: u16,
+    mut sin_addr: u32, // in_addr: this is an opaque, per-platform struct
+    mut sin_zero: (u8, u8, u8, u8, u8, u8, u8, u8)
+};
+
+// unix size: 28 .. make due w/ 32
+#[cfg(target_os = "linux")]
+#[cfg(target_os = "macos")]
+#[cfg(target_os = "freebsd")]
+#[cfg(target_os = "win32")]
+type sockaddr_in6 = {
+    a0: *u8, a1: *u8,
+    a2: *u8, a3: *u8
+};
+
+mod uv_ll_struct_stubgen {
+    fn gen_stub_uv_tcp_t() -> uv_tcp_t {
+        ret gen_stub_os();
+        #[cfg(target_os = "linux")]
+        #[cfg(target_os = "macos")]
+        #[cfg(target_os = "freebsd")]
+        fn gen_stub_os() -> uv_tcp_t {
+            ret gen_stub_arch();
+            #[cfg(target_arch="x86_64")]
+            fn gen_stub_arch() -> uv_tcp_t {
+                ret { fields: { loop_handle: ptr::null(), type_: 0u32,
+                                close_cb: ptr::null(),
+                                mut data: ptr::null() },
+                    a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                    a03: 0 as *u8,
+                    a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                    a07: 0 as *u8,
+                    a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                    a11: 0 as *u8,
+                    a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
+                    a15: 0 as *u8,
+                    a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
+                    a19: 0 as *u8,
+                    a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
+                    a23: 0 as *u8,
+                    a24: 0 as *u8, a25: 0 as *u8, a26: 0 as *u8,
+                    a27: 0 as *u8,
+                    a28: 0 as *u8,
+                    a30: {
+                        a29: 0 as *u8
+                    }
+                };
+            }
+            #[cfg(target_arch="x86")]
+            fn gen_stub_arch() -> uv_tcp_t {
+                ret { fields: { loop_handle: ptr::null(), type_: 0u32,
+                                close_cb: ptr::null(),
+                                mut data: ptr::null() },
+                    a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                    a03: 0 as *u8,
+                    a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                    a07: 0 as *u8,
+                    a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                    a11: 0 as *u8,
+                    a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
+                    a15: 0 as *u8,
+                    a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
+                    a19: 0 as *u8,
+                    a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
+                    a23: 0 as *u8,
+                    a24: 0 as *u8, a25: 0 as *u8, a26: 0 as *u8,
+                    a27: 0 as *u8,
+                    a28: 0 as *u8,
+                    a30: {
+                        a29: 0 as *u8, a30: 0 as *u8, a31: 0 as *u8,
+                        a32: 0 as *u8, a33: 0 as *u8, a34: 0 as *u8,
+                        a35: 0 as *u8, a36: 0 as *u8
+                    }
+                };
+            }
+        }
+        #[cfg(target_os = "win32")]
+        fn gen_stub_os() -> uv_tcp_t {
+            ret { fields: { loop_handle: ptr::null(), type_: 0u32,
+                            close_cb: ptr::null(),
+                            mut data: ptr::null() },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: 0 as *u8,
+                a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                a11: 0 as *u8,
+                a12: 0 as *u8, a13: 0 as *u8, a14: 0 as *u8,
+                a15: 0 as *u8,
+                a16: 0 as *u8, a17: 0 as *u8, a18: 0 as *u8,
+                a19: 0 as *u8,
+                a20: 0 as *u8, a21: 0 as *u8, a22: 0 as *u8,
+                a23: 0 as *u8,
+                a24: 0 as *u8, a25: 0 as *u8
+            };
+        }
+    }
+    #[cfg(target_os = "linux")]
+    #[cfg(target_os = "macos")]
+    #[cfg(target_os = "freebsd")]
+    fn gen_stub_uv_connect_t() -> uv_connect_t {
+        ret {
+            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+            a03: 0 as *u8,
+            a04: 0 as *u8, a05: 0 as *u8
+        };
+    }
+    #[cfg(target_os = "win32")]
+    fn gen_stub_uv_connect_t() -> uv_connect_t {
+        ret {
+            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+            a03: 0 as *u8,
+            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+            a07: 0 as *u8,
+            a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8
+        };
+    }
+    #[cfg(target_os = "linux")]
+    #[cfg(target_os = "macos")]
+    #[cfg(target_os = "freebsd")]
+    fn gen_stub_uv_async_t() -> uv_async_t {
+        ret gen_stub_arch();
+        #[cfg(target_arch = "x86_64")]
+        fn gen_stub_arch() -> uv_async_t {
+            ret { fields: { loop_handle: ptr::null(), type_: 0u32,
+                            close_cb: ptr::null(),
+                            mut data: ptr::null() },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: 0 as *u8,
+                a08: 0 as *u8, a09: 0 as *u8,
+                a11: {
+                    a10: 0 as *u8
+                }
+            };
+        }
+        #[cfg(target_arch = "x86")]
+        fn gen_stub_arch() -> uv_async_t {
+            ret { fields: { loop_handle: ptr::null(), type_: 0u32,
+                            close_cb: ptr::null(),
+                            mut data: ptr::null() },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: 0 as *u8,
+                a08: 0 as *u8, a09: 0 as *u8,
+                a11: {
+                    a10: 0 as *u8, a11: 0 as *u8,
+                    a12: 0 as *u8, a13: 0 as *u8
+                }
+            };
+        }
+    }
+    #[cfg(target_os = "win32")]
+    fn gen_stub_uv_async_t() -> uv_async_t {
+        ret { fields: { loop_handle: ptr::null(), type_: 0u32,
+                        close_cb: ptr::null(),
+                        mut data: ptr::null() },
+            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+            a03: 0 as *u8,
+            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+            a07: 0 as *u8,
+            a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+            a11: 0 as *u8,
+            a12: 0 as *u8
+        };
+    }
+    #[cfg(target_os = "linux")]
+    #[cfg(target_os = "macos")]
+    #[cfg(target_os = "freebsd")]
+    fn gen_stub_uv_write_t() -> uv_write_t {
+        ret gen_stub_arch();
+        #[cfg(target_arch="x86_64")]
+        fn gen_stub_arch() -> uv_write_t {
+            ret { fields: { loop_handle: ptr::null(), type_: 0u32,
+                            close_cb: ptr::null(),
+                            mut data: ptr::null() },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: 0 as *u8,
+                a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                a11: 0 as *u8,
+                a12: 0 as *u8, a14: { a13: 0 as *u8 }
+            };
+        }
+        #[cfg(target_arch="x86")]
+        fn gen_stub_arch() -> uv_write_t {
+            ret { fields: { loop_handle: ptr::null(), type_: 0u32,
+                            close_cb: ptr::null(),
+                            mut data: ptr::null() },
+                a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+                a03: 0 as *u8,
+                a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+                a07: 0 as *u8,
+                a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+                a11: 0 as *u8,
+                a12: 0 as *u8, a14: { a13: 0 as *u8, a14: 0 as *u8 }
+            };
+        }
+    }
+    #[cfg(target_os = "win32")]
+    fn gen_stub_uv_write_t() -> uv_write_t {
+        ret { fields: { loop_handle: ptr::null(), type_: 0u32,
+                        close_cb: ptr::null(),
+                        mut data: ptr::null() },
+            a00: 0 as *u8, a01: 0 as *u8, a02: 0 as *u8,
+            a03: 0 as *u8,
+            a04: 0 as *u8, a05: 0 as *u8, a06: 0 as *u8,
+            a07: 0 as *u8,
+            a08: 0 as *u8, a09: 0 as *u8, a10: 0 as *u8,
+            a11: 0 as *u8,
+            a12: 0 as *u8
+        };
+    }
+}
+
+#[nolink]
+native mod rustrt {
+    fn rust_uv_loop_new() -> *libc::c_void;
+    fn rust_uv_loop_delete(lp: *libc::c_void);
+    fn rust_uv_run(loop_handle: *libc::c_void);
+    fn rust_uv_close(handle: *libc::c_void, cb: *u8);
+    fn rust_uv_async_send(handle: *uv_async_t);
+    fn rust_uv_async_init(loop_handle: *libc::c_void,
+                          async_handle: *uv_async_t,
+                          cb: *u8) -> libc::c_int;
+    fn rust_uv_tcp_init(
+        loop_handle: *libc::c_void,
+        handle_ptr: *uv_tcp_t) -> libc::c_int;
+    // FIXME ref #2604 .. ?
+    fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8,
+                        len: libc::size_t);
+    fn rust_uv_last_error(loop_handle: *libc::c_void) -> uv_err_t;
+    // FIXME ref #2064
+    fn rust_uv_strerror(err: *uv_err_t) -> *libc::c_char;
+    // FIXME ref #2064
+    fn rust_uv_err_name(err: *uv_err_t) -> *libc::c_char;
+    fn rust_uv_ip4_addr(ip: *u8, port: libc::c_int)
+        -> sockaddr_in;
+    // FIXME ref #2064
+    fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
+                           tcp_handle_ptr: *uv_tcp_t,
+                           ++after_cb: *u8,
+                           ++addr: *sockaddr_in) -> libc::c_int;
+    // FIXME ref 2064
+    fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
+                        ++addr: *sockaddr_in) -> libc::c_int;
+    fn rust_uv_listen(stream: *libc::c_void, backlog: libc::c_int,
+                      cb: *u8) -> libc::c_int;
+    fn rust_uv_accept(server: *libc::c_void, client: *libc::c_void)
+        -> libc::c_int;
+    fn rust_uv_write(req: *libc::c_void, stream: *libc::c_void,
+             ++buf_in: *uv_buf_t, buf_cnt: libc::c_int,
+             cb: *u8) -> libc::c_int;
+    fn rust_uv_read_start(stream: *libc::c_void, on_alloc: *u8,
+                          on_read: *u8) -> libc::c_int;
+    fn rust_uv_read_stop(stream: *libc::c_void) -> libc::c_int;
+    fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
+    fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
+
+    // data accessors for rust-mapped uv structs
+    fn rust_uv_get_stream_handle_from_connect_req(
+        connect_req: *uv_connect_t)
+        -> *uv_stream_t;
+    fn rust_uv_get_stream_handle_from_write_req(
+        write_req: *uv_write_t)
+        -> *uv_stream_t;
+    fn rust_uv_get_loop_for_uv_handle(handle: *libc::c_void)
+        -> *libc::c_void;
+    fn rust_uv_get_data_for_uv_handle(handle: *libc::c_void)
+        -> *libc::c_void;
+    fn rust_uv_set_data_for_uv_handle(handle: *libc::c_void,
+                                      data: *libc::c_void);
+    fn rust_uv_get_data_for_req(req: *libc::c_void) -> *libc::c_void;
+    fn rust_uv_set_data_for_req(req: *libc::c_void,
+                                data: *libc::c_void);
+    fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
+    fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t;
+}
+
+unsafe fn loop_new() -> *libc::c_void {
+    ret rustrt::rust_uv_loop_new();
+}
+
+unsafe fn loop_delete(loop_handle: *libc::c_void) {
+    rustrt::rust_uv_loop_delete(loop_handle);
+}
+
+unsafe fn run(loop_handle: *libc::c_void) {
+    rustrt::rust_uv_run(loop_handle);
+}
+
+unsafe fn close(handle: *libc::c_void, cb: *u8) {
+    rustrt::rust_uv_close(handle, cb);
+}
+
+unsafe fn tcp_init(loop_handle: *libc::c_void, handle: *uv_tcp_t)
+    -> libc::c_int {
+    ret rustrt::rust_uv_tcp_init(loop_handle, handle);
+}
+// FIXME ref #2064
+unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
+                      tcp_handle_ptr: *uv_tcp_t,
+                      addr_ptr: *sockaddr_in,
+                      ++after_connect_cb: *u8)
+-> libc::c_int {
+    let address = *addr_ptr;
+    log(debug, #fmt("b4 native tcp_connect--addr port: %u cb: %u",
+                     address.sin_port as uint, after_connect_cb as uint));
+    ret rustrt::rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
+                                after_connect_cb, addr_ptr);
+}
+// FIXME ref #2064
+unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t,
+                   addr_ptr: *sockaddr_in) -> libc::c_int {
+    ret rustrt::rust_uv_tcp_bind(tcp_server_ptr,
+                                 addr_ptr);
+}
+
+unsafe fn listen(stream: *libc::c_void, backlog: libc::c_int,
+                 cb: *u8) -> libc::c_int {
+    ret rustrt::rust_uv_listen(stream, backlog, cb);
+}
+
+unsafe fn accept(server: *libc::c_void, client: *libc::c_void)
+    -> libc::c_int {
+    ret rustrt::rust_uv_accept(server, client);
+}
+
+unsafe fn write(req: *libc::c_void, stream: *libc::c_void,
+         buf_in: *[uv_buf_t], cb: *u8) -> libc::c_int {
+    let buf_ptr = vec::unsafe::to_ptr(*buf_in);
+    let buf_cnt = vec::len(*buf_in) as i32;
+    ret rustrt::rust_uv_write(req, stream, buf_ptr, buf_cnt, cb);
+}
+unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8,
+                     on_read: *u8) -> libc::c_int {
+    ret rustrt::rust_uv_read_start(stream as *libc::c_void,
+                                   on_alloc, on_read);
+}
+
+unsafe fn read_stop(stream: *uv_stream_t) -> libc::c_int {
+    ret rustrt::rust_uv_read_stop(stream as *libc::c_void);
+}
+
+unsafe fn last_error(loop_handle: *libc::c_void) -> uv_err_t {
+    ret rustrt::rust_uv_last_error(loop_handle);
+}
+
+unsafe fn strerror(err: *uv_err_t) -> *libc::c_char {
+    ret rustrt::rust_uv_strerror(err);
+}
+unsafe fn err_name(err: *uv_err_t) -> *libc::c_char {
+    ret rustrt::rust_uv_err_name(err);
+}
+
+unsafe fn async_init(loop_handle: *libc::c_void,
+                     async_handle: *uv_async_t,
+                     cb: *u8) -> libc::c_int {
+    ret rustrt::rust_uv_async_init(loop_handle,
+                                   async_handle,
+                                   cb);
+}
+
+unsafe fn async_send(async_handle: *uv_async_t) {
+    ret rustrt::rust_uv_async_send(async_handle);
+}
+
+// libuv struct initializers
+unsafe fn tcp_t() -> uv_tcp_t {
+    ret uv_ll_struct_stubgen::gen_stub_uv_tcp_t();
+}
+unsafe fn connect_t() -> uv_connect_t {
+    ret uv_ll_struct_stubgen::gen_stub_uv_connect_t();
+}
+unsafe fn write_t() -> uv_write_t {
+    ret uv_ll_struct_stubgen::gen_stub_uv_write_t();
+}
+unsafe fn async_t() -> uv_async_t {
+    ret uv_ll_struct_stubgen::gen_stub_uv_async_t();
+}
+unsafe fn get_loop_for_uv_handle(handle: *libc::c_void)
+    -> *libc::c_void {
+    ret rustrt::rust_uv_get_loop_for_uv_handle(handle);
+}
+unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t)
+    -> *uv_stream_t {
+    ret rustrt::rust_uv_get_stream_handle_from_connect_req(
+        connect);
+}
+unsafe fn get_stream_handle_from_write_req(
+    write_req: *uv_write_t)
+    -> *uv_stream_t {
+    ret rustrt::rust_uv_get_stream_handle_from_write_req(
+        write_req);
+}
+
+unsafe fn get_data_for_uv_handle(handle: *libc::c_void) -> *libc::c_void {
+    ret rustrt::rust_uv_get_data_for_uv_handle(handle);
+}
+unsafe fn set_data_for_uv_handle(handle: *libc::c_void,
+                    data: *libc::c_void) {
+    rustrt::rust_uv_set_data_for_uv_handle(handle, data);
+}
+unsafe fn get_data_for_req(req: *libc::c_void) -> *libc::c_void {
+    ret rustrt::rust_uv_get_data_for_req(req);
+}
+unsafe fn set_data_for_req(req: *libc::c_void,
+                    data: *libc::c_void) {
+    rustrt::rust_uv_set_data_for_req(req, data);
+}
+unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
+    ret rustrt::rust_uv_get_base_from_buf(buf);
+}
+unsafe fn get_len_from_buf(buf: uv_buf_t) -> libc::size_t {
+    ret rustrt::rust_uv_get_len_from_buf(buf);
+}
+unsafe fn buf_init(++input: *u8, len: uint) -> uv_buf_t {
+    let out_buf = { base: ptr::null(), len: 0 as libc::size_t };
+    let out_buf_ptr = ptr::addr_of(out_buf);
+    log(debug, #fmt("ll::buf_init - input %u len %u out_buf: %u",
+                     input as uint,
+                     len as uint,
+                     out_buf_ptr as uint));
+    // yuck :/
+    rustrt::rust_uv_buf_init(out_buf_ptr, input, len);
+    //let result = rustrt::rust_uv_buf_init_2(input, len);
+    log(debug, "after rust_uv_buf_init");
+    let res_base = get_base_from_buf(out_buf);
+    let res_len = get_len_from_buf(out_buf);
+    //let res_base = get_base_from_buf(result);
+    log(debug, #fmt("ll::buf_init - result %u len %u",
+                     res_base as uint,
+                     res_len as uint));
+    ret out_buf;
+    //ret result;
+}
+unsafe fn ip4_addr(ip: str, port: int)
+-> sockaddr_in {
+    let mut addr_vec = str::bytes(ip);
+    addr_vec += [0u8]; // add null terminator
+    let addr_vec_ptr = vec::unsafe::to_ptr(addr_vec);
+    let ip_back = str::from_bytes(addr_vec);
+    log(debug, #fmt("vec val: '%s' length: %u",
+                     ip_back, vec::len(addr_vec)));
+    ret rustrt::rust_uv_ip4_addr(addr_vec_ptr,
+                                 port as libc::c_int);
+}
+unsafe fn malloc_buf_base_of(suggested_size: libc::size_t)
+    -> *u8 {
+    ret rustrt::rust_uv_malloc_buf_base_of(suggested_size);
+}
+unsafe fn free_base_of_buf(buf: uv_buf_t) {
+    rustrt::rust_uv_free_base_of_buf(buf);
+}
+
+unsafe fn get_last_err_info(uv_loop: *libc::c_void) -> str {
+    let err = last_error(uv_loop);
+    let err_ptr = ptr::addr_of(err);
+    let err_name = str::unsafe::from_c_str(err_name(err_ptr));
+    let err_msg = str::unsafe::from_c_str(strerror(err_ptr));
+    ret #fmt("LIBUV ERROR: name: %s msg: %s",
+                    err_name, err_msg);
+}
\ No newline at end of file
index 9c2e2c3276c16a6dacc0b5ee3dcd732db8be2d32..f2714c4d7c332acc9db0ba6becf34bc1d623ec74 100644 (file)
@@ -669,22 +669,9 @@ get_port_id(rust_port *port) {
 }
 
 extern "C" CDECL uintptr_t
-rust_port_id_send(type_desc *t, rust_port_id target_port_id, void *sptr) {
-    bool sent = false;
+rust_port_id_send(rust_port_id target_port_id, void *sptr) {
     rust_task *task = rust_get_current_task();
-
-    LOG(task, comm, "rust_port_id*_send port: 0x%" PRIxPTR,
-        (uintptr_t) target_port_id);
-
-    rust_port *port = task->kernel->get_port_by_id(target_port_id);
-    if(port) {
-        port->send(sptr);
-        port->deref();
-        sent = true;
-    } else {
-        LOG(task, comm, "didn't get the port");
-    }
-    return (uintptr_t)sent;
+    return (uintptr_t)task->kernel->send_to_port(target_port_id, sptr);
 }
 
 // This is called by an intrinsic on the Rust stack and must run
@@ -776,6 +763,24 @@ rust_osmain_sched_id() {
     return task->kernel->osmain_sched_id();
 }
 
+extern "C" CDECL bool
+rust_compare_and_swap_ptr(intptr_t *address,
+                          intptr_t oldval, intptr_t newval) {
+    return sync::compare_and_swap(address, oldval, newval);
+}
+
+extern "C" CDECL void
+rust_task_weaken(rust_port_id chan) {
+    rust_task *task = rust_get_current_task();
+    task->kernel->weaken_task(chan);
+}
+
+extern "C" CDECL void
+rust_task_unweaken(rust_port_id chan) {
+    rust_task *task = rust_get_current_task();
+    task->kernel->unweaken_task(chan);
+}
+
 //
 // Local Variables:
 // mode: C++
index ff6b0e1056cc14ca6b14f6f87aa66800f86dce67..21422646f0d2d071a4fbaea703242310ebf5d6f6 100644 (file)
@@ -1,11 +1,11 @@
 
 
-
 #include "rust_kernel.h"
 #include "rust_port.h"
 #include "rust_util.h"
 #include "rust_scheduler.h"
 #include "rust_sched_launcher.h"
+#include <algorithm>
 
 #define KLOG_(...)                              \
     KLOG(this, kern, __VA_ARGS__)
@@ -21,6 +21,7 @@ rust_kernel::rust_kernel(rust_env *env) :
     max_sched_id(0),
     sched_reaper(this),
     osmain_driver(NULL),
+    non_weak_tasks(0),
     env(env)
 {
     // Create the single threaded scheduler that will run on the platform's
@@ -286,6 +287,84 @@ rust_kernel::set_exit_status(int code) {
     }
 }
 
+void
+rust_kernel::register_task() {
+    KLOG_("Registering task");
+    uintptr_t new_non_weak_tasks = sync::increment(non_weak_tasks);
+    KLOG_("New non-weak tasks %" PRIdPTR, new_non_weak_tasks);
+}
+
+void
+rust_kernel::unregister_task() {
+    KLOG_("Unregistering task");
+    uintptr_t new_non_weak_tasks = sync::decrement(non_weak_tasks);
+    KLOG_("New non-weak tasks %" PRIdPTR, new_non_weak_tasks);
+    if (new_non_weak_tasks == 0) {
+        end_weak_tasks();
+    }
+}
+
+void
+rust_kernel::weaken_task(rust_port_id chan) {
+    {
+        scoped_lock with(weak_task_lock);
+        KLOG_("Weakening task with channel %" PRIdPTR, chan);
+        weak_task_chans.push_back(chan);
+    }
+    uintptr_t new_non_weak_tasks = sync::decrement(non_weak_tasks);
+    KLOG_("New non-weak tasks %" PRIdPTR, new_non_weak_tasks);
+    if (new_non_weak_tasks == 0) {
+        end_weak_tasks();
+    }
+}
+
+void
+rust_kernel::unweaken_task(rust_port_id chan) {
+    uintptr_t new_non_weak_tasks = sync::increment(non_weak_tasks);
+    KLOG_("New non-weak tasks %" PRIdPTR, new_non_weak_tasks);
+    {
+        scoped_lock with(weak_task_lock);
+        KLOG_("Unweakening task with channel %" PRIdPTR, chan);
+        std::vector<rust_port_id>::iterator iter =
+            std::find(weak_task_chans.begin(), weak_task_chans.end(), chan);
+        if (iter != weak_task_chans.end()) {
+            weak_task_chans.erase(iter);
+        }
+    }
+}
+
+void
+rust_kernel::end_weak_tasks() {
+    std::vector<rust_port_id> chancopies;
+    {
+        //scoped_lock with(weak_task_lock);
+        chancopies = weak_task_chans;
+        weak_task_chans.clear();
+    }
+    while (!chancopies.empty()) {
+        rust_port_id chan = chancopies.back();
+        chancopies.pop_back();
+        KLOG_("Notifying weak task " PRIdPTR, chan);
+        uintptr_t token = 0;
+        send_to_port(chan, &token);
+    }
+}
+
+bool
+rust_kernel::send_to_port(rust_port_id chan, void *sptr) {
+    KLOG_("rust_port_id*_send port: 0x%" PRIxPTR, (uintptr_t) chan);
+
+    rust_port *port = get_port_by_id(chan);
+    if(port) {
+        port->send(sptr);
+        port->deref();
+        return true;
+    } else {
+        KLOG_("didn't get the port");
+        return false;
+    }
+}
+
 //
 // Local Variables:
 // mode: C++
index 6a7a7070c20812f8572b03b461806256b03f9065..1ccd423928d9a33264fab27695bd683264ead154 100644 (file)
@@ -63,7 +63,15 @@ class rust_kernel {
     // on the main thread
     rust_sched_driver *osmain_driver;
 
+    // An atomically updated count of the live, 'non-weak' tasks
+    uintptr_t non_weak_tasks;
+    // Protects weak_task_chans
+    lock_and_signal weak_task_lock;
+    // A list of weak tasks that need to be told when to exit
+    std::vector<rust_port_id> weak_task_chans;
+
     rust_scheduler* get_scheduler_by_id_nolock(rust_sched_id id);
+    void end_weak_tasks();
 
 public:
     struct rust_env *env;
@@ -102,6 +110,13 @@ public:
     void set_exit_status(int code);
 
     rust_sched_id osmain_sched_id() { return osmain_scheduler; }
+
+    void register_task();
+    void unregister_task();
+    void weaken_task(rust_port_id chan);
+    void unweaken_task(rust_port_id chan);
+
+    bool send_to_port(rust_port_id chan, void *sptr);
 };
 
 template <typename T> struct kernel_owned {
index 1b5978b5cfec17bb856d1de4acaae6cc4ae262b2..1f0b16a1d58d9520b7088ad2e3301109ef91b118 100644 (file)
@@ -92,6 +92,7 @@ rust_scheduler::create_task(rust_task *spawner, const char *name) {
         if (cur_thread >= num_threads)
             cur_thread = 0;
     }
+    kernel->register_task();
     rust_sched_launcher *thread = threads[thread_no];
     return thread->get_loop()->create_task(spawner, name);
 }
@@ -106,6 +107,7 @@ rust_scheduler::release_task() {
             need_exit = true;
         }
     }
+    kernel->unregister_task();
     if (need_exit) {
         exit();
     }
index e6d6c2e52ba1d97cf66e971701ce2968961f216d..2b1e5d1ca3c57c3cf635ba2871021aa5cdefe9dc 100644 (file)
@@ -9,18 +9,18 @@
 
 // crust fn pointers
 typedef void (*crust_async_op_cb)(uv_loop_t* loop, void* data,
-                                  uv_async_t* op_handle);
+        uv_async_t* op_handle);
 typedef void (*crust_simple_cb)(uint8_t* id_buf, void* loop_data);
 typedef void (*crust_close_cb)(uint8_t* id_buf, void* handle,
-                                                          void* data);
+        void* data);
 
 // data types
 #define RUST_UV_HANDLE_LEN 16
 
 struct handle_data {
-        uint8_t id_buf[RUST_UV_HANDLE_LEN];
-        crust_simple_cb cb;
-        crust_close_cb close_cb;
+    uint8_t id_buf[RUST_UV_HANDLE_LEN];
+    crust_simple_cb cb;
+    crust_close_cb close_cb;
 };
 
 // helpers
@@ -37,49 +37,53 @@ current_kernel_free(void* ptr) {
 
 static handle_data*
 new_handle_data_from(uint8_t* buf, crust_simple_cb cb) {
-        handle_data* data = (handle_data*)current_kernel_malloc(
-                sizeof(handle_data),
-                "handle_data");
-        memcpy(data->id_buf, buf, RUST_UV_HANDLE_LEN);
-        data->cb = cb;
-        return data;
+    handle_data* data = (handle_data*)current_kernel_malloc(
+            sizeof(handle_data),
+            "handle_data");
+    memcpy(data->id_buf, buf, RUST_UV_HANDLE_LEN);
+    data->cb = cb;
+    return data;
 }
 
 // libuv callback impls
 static void
 native_crust_async_op_cb(uv_async_t* handle, int status) {
     crust_async_op_cb cb = (crust_async_op_cb)handle->data;
-        void* loop_data = handle->loop->data;
-        cb(handle->loop, loop_data, handle);
+    void* loop_data = handle->loop->data;
+    cb(handle->loop, loop_data, handle);
 }
 
 static void
 native_async_cb(uv_async_t* handle, int status) {
-        handle_data* handle_d = (handle_data*)handle->data;
-        void* loop_data = handle->loop->data;
-        handle_d->cb(handle_d->id_buf, loop_data);
+    handle_data* handle_d = (handle_data*)handle->data;
+    void* loop_data = handle->loop->data;
+    handle_d->cb(handle_d->id_buf, loop_data);
 }
 
 static void
 native_timer_cb(uv_timer_t* handle, int status) {
-        handle_data* handle_d = (handle_data*)handle->data;
-        void* loop_data = handle->loop->data;
-        handle_d->cb(handle_d->id_buf, loop_data);
+    handle_data* handle_d = (handle_data*)handle->data;
+    void* loop_data = handle->loop->data;
+    handle_d->cb(handle_d->id_buf, loop_data);
 }
 
 static void
 native_close_cb(uv_handle_t* handle) {
-        handle_data* data = (handle_data*)handle->data;
-        data->close_cb(data->id_buf, handle, handle->loop->data);
+    handle_data* data = (handle_data*)handle->data;
+    data->close_cb(data->id_buf, handle, handle->loop->data);
 }
 
 static void
 native_close_op_cb(uv_handle_t* op_handle) {
-  current_kernel_free(op_handle);
-  // uv_run() should return after this..
+    current_kernel_free(op_handle);
+    // uv_run() should return after this..
 }
 
 // native fns bound in rust
+extern "C" void
+rust_uv_free(void* ptr) {
+    current_kernel_free(ptr);
+}
 extern "C" void*
 rust_uv_loop_new() {
     return (void*)uv_loop_new();
@@ -113,44 +117,49 @@ rust_uv_loop_set_data(uv_loop_t* loop, void* data) {
 
 extern "C" void*
 rust_uv_bind_op_cb(uv_loop_t* loop, crust_async_op_cb cb) {
-        uv_async_t* async = (uv_async_t*)current_kernel_malloc(
-                sizeof(uv_async_t),
-                "uv_async_t");
-        uv_async_init(loop, async, native_crust_async_op_cb);
-        async->data = (void*)cb;
-        // decrement the ref count, so that our async bind
-        // doesn't count towards keeping the loop alive
-        //uv_unref(loop);
-        return async;
+    uv_async_t* async = (uv_async_t*)current_kernel_malloc(
+            sizeof(uv_async_t),
+            "uv_async_t");
+    uv_async_init(loop, async, native_crust_async_op_cb);
+    async->data = (void*)cb;
+    // decrement the ref count, so that our async bind
+    // doesn't count towards keeping the loop alive
+    //uv_unref(loop);
+    return async;
 }
 
 extern "C" void
 rust_uv_stop_op_cb(uv_handle_t* op_handle) {
-  uv_close(op_handle, native_close_op_cb);
+    uv_close(op_handle, native_close_op_cb);
 }
 
 extern "C" void
 rust_uv_run(uv_loop_t* loop) {
-        uv_run(loop);
+    uv_run(loop);
+}
+
+extern "C" void
+rust_uv_close(uv_handle_t* handle, uv_close_cb cb) {
+    uv_close(handle, cb);
 }
 
 extern "C" void
-rust_uv_close(uv_handle_t* handle, crust_close_cb cb) {
-        handle_data* data = (handle_data*)handle->data;
-        data->close_cb = cb;
-        uv_close(handle, native_close_cb);
+rust_uv_hilvl_close(uv_handle_t* handle, crust_close_cb cb) {
+    handle_data* data = (handle_data*)handle->data;
+    data->close_cb = cb;
+    uv_close(handle, native_close_cb);
 }
 
 extern "C" void
-rust_uv_close_async(uv_async_t* handle) {
-  current_kernel_free(handle->data);
-  current_kernel_free(handle);
+rust_uv_hilvl_close_async(uv_async_t* handle) {
+    current_kernel_free(handle->data);
+    current_kernel_free(handle);
 }
 
 extern "C" void
-rust_uv_close_timer(uv_async_t* handle) {
-  current_kernel_free(handle->data);
-  current_kernel_free(handle);
+rust_uv_hilvl_close_timer(uv_async_t* handle) {
+    current_kernel_free(handle->data);
+    current_kernel_free(handle);
 }
 
 extern "C" void
@@ -158,40 +167,234 @@ rust_uv_async_send(uv_async_t* handle) {
     uv_async_send(handle);
 }
 
+extern "C" int
+rust_uv_async_init(uv_loop_t* loop_handle,
+        uv_async_t* async_handle,
+        uv_async_cb cb) {
+    return uv_async_init(loop_handle, async_handle, cb);
+}
+
 extern "C" void*
-rust_uv_async_init(uv_loop_t* loop, crust_simple_cb cb,
-                                                 uint8_t* buf) {
-        uv_async_t* async = (uv_async_t*)current_kernel_malloc(
-                sizeof(uv_async_t),
-                "uv_async_t");
-        uv_async_init(loop, async, native_async_cb);
-        handle_data* data = new_handle_data_from(buf, cb);
-        async->data = data;
+rust_uv_hilvl_async_init(uv_loop_t* loop, crust_simple_cb cb,
+        uint8_t* buf) {
+    uv_async_t* async = (uv_async_t*)current_kernel_malloc(
+            sizeof(uv_async_t),
+            "uv_async_t");
+    uv_async_init(loop, async, native_async_cb);
+    handle_data* data = new_handle_data_from(buf, cb);
+    async->data = data;
 
-        return async;
+    return async;
 }
 
 extern "C" void*
 rust_uv_timer_init(uv_loop_t* loop, crust_simple_cb cb,
-                                                 uint8_t* buf) {
-        uv_timer_t* new_timer = (uv_timer_t*)current_kernel_malloc(
-                sizeof(uv_timer_t),
-                "uv_timer_t");
-        uv_timer_init(loop, new_timer);
-        handle_data* data = new_handle_data_from(buf, cb);
-        new_timer->data = data;
+        uint8_t* buf) {
+    uv_timer_t* new_timer = (uv_timer_t*)current_kernel_malloc(
+            sizeof(uv_timer_t),
+            "uv_timer_t");
+    uv_timer_init(loop, new_timer);
+    handle_data* data = new_handle_data_from(buf, cb);
+    new_timer->data = data;
 
-        return new_timer;
+    return new_timer;
 }
 
 extern "C" void
 rust_uv_timer_start(uv_timer_t* the_timer, uint32_t timeout,
-                                                  uint32_t repeat) {
-        uv_timer_start(the_timer, native_timer_cb, timeout, repeat);
+        uint32_t repeat) {
+    uv_timer_start(the_timer, native_timer_cb, timeout, repeat);
 }
 
 extern "C" void
 rust_uv_timer_stop(uv_timer_t* the_timer) {
-  uv_timer_stop(the_timer);
+    uv_timer_stop(the_timer);
+}
+
+extern "C" int
+rust_uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
+    return uv_tcp_init(loop, handle);
+}
+
+extern "C" int
+rust_uv_tcp_connect(uv_connect_t* connect_ptr,
+        uv_tcp_t* tcp_ptr,
+        uv_connect_cb cb,
+        sockaddr_in* addr_ptr) {
+    printf("inside rust_uv_tcp_connect\n");
+    // FIXME ref #2064
+    sockaddr_in addr = *addr_ptr;
+    printf("before tcp_connect .. port: %d\n", addr.sin_port);
+    printf("before tcp_connect.. tcp stream: %lu cb ptr: %lu\n",
+            (unsigned long int)tcp_ptr, (unsigned long int)cb);
+    int result = uv_tcp_connect(connect_ptr, tcp_ptr, addr, cb);
+    printf ("leaving rust_uv_tcp_connect.. and result: %d\n",
+            result);
+    return result;
+}
+
+extern "C" int
+rust_uv_tcp_bind(uv_tcp_t* tcp_server, sockaddr_in* addr_ptr) {
+    // FIXME ref #2064
+    sockaddr_in addr = *addr_ptr;
+    printf("before uv_tcp_bind .. tcp_server: %lu port: %d\n",
+            (unsigned long int)tcp_server, addr.sin_port);
+    return uv_tcp_bind(tcp_server, addr);
+}
+
+extern "C" int
+rust_uv_listen(uv_stream_t* stream, int backlog,
+        uv_connection_cb cb) {
+    return uv_listen(stream, backlog, cb);
+}
+
+extern "C" int
+rust_uv_accept(uv_stream_t* server, uv_stream_t* client) {
+    return uv_accept(server, client);
 }
 
+extern "C" size_t
+rust_uv_helper_uv_tcp_t_size() {
+    return sizeof(uv_tcp_t);
+}
+extern "C" size_t
+rust_uv_helper_uv_connect_t_size() {
+    return sizeof(uv_connect_t);
+}
+extern "C" size_t
+rust_uv_helper_uv_buf_t_size() {
+    return sizeof(uv_buf_t);
+}
+extern "C" size_t
+rust_uv_helper_uv_write_t_size() {
+    return sizeof(uv_write_t);
+}
+extern "C" size_t
+rust_uv_helper_uv_err_t_size() {
+    return sizeof(uv_err_t);
+}
+extern "C" size_t
+rust_uv_helper_sockaddr_in_size() {
+    return sizeof(sockaddr_in);
+}
+extern "C" size_t
+rust_uv_helper_uv_async_t_size() {
+    return sizeof(uv_async_t);
+}
+
+extern "C" uv_stream_t*
+rust_uv_get_stream_handle_from_connect_req(uv_connect_t* connect) {
+    return connect->handle;
+}
+extern "C" uv_stream_t*
+rust_uv_get_stream_handle_from_write_req(uv_write_t* write_req) {
+    return write_req->handle;
+}
+
+extern "C" uv_buf_t
+current_kernel_malloc_alloc_cb(uv_handle_t* handle,
+        size_t suggested_size) {
+    char* base_ptr = (char*)current_kernel_malloc(sizeof(char)
+            * suggested_size,
+            "uv_buf_t_base_val");
+    return uv_buf_init(base_ptr, suggested_size);
+}
+
+extern "C" void
+rust_uv_buf_init(uv_buf_t* out_buf, char* base, size_t len) {
+    printf("rust_uv_buf_init: base: %lu len: %lu\n",
+        (long unsigned int)base,
+        (long unsigned int)len);
+    *out_buf = uv_buf_init(base, len);
+    printf("rust_uv_buf_init: after: result->base: %lu len: %lu\n",
+           (unsigned long int)(*out_buf).base,
+           (unsigned long int)(*out_buf).len);
+}
+
+extern "C" uv_loop_t*
+rust_uv_get_loop_for_uv_handle(uv_handle_t* handle) {
+    return handle->loop;
+}
+
+extern "C" void*
+rust_uv_get_data_for_uv_handle(uv_handle_t* handle) {
+    return handle->data;
+}
+
+extern "C" void
+rust_uv_set_data_for_uv_handle(uv_handle_t* handle,
+        void* data) {
+    handle->data = data;
+}
+
+extern "C" void*
+rust_uv_get_data_for_req(uv_req_t* req) {
+    return req->data;
+}
+
+extern "C" void
+rust_uv_set_data_for_req(uv_req_t* req, void* data) {
+    req->data = data;
+}
+
+extern "C" char*
+rust_uv_get_base_from_buf(uv_buf_t buf) {
+    return buf.base;
+}
+
+extern "C" size_t
+rust_uv_get_len_from_buf(uv_buf_t buf) {
+    return buf.len;
+}
+
+extern "C" uv_err_t
+rust_uv_last_error(uv_loop_t* loop) {
+    return uv_last_error(loop);
+}
+
+extern "C" const char*
+rust_uv_strerror(uv_err_t* err_ptr) {
+    uv_err_t err = *err_ptr;
+    return uv_strerror(err);
+}
+
+extern "C" const char*
+rust_uv_err_name(uv_err_t* err_ptr) {
+    uv_err_t err = *err_ptr;
+    return uv_err_name(err);
+}
+
+extern "C" int
+rust_uv_write(uv_write_t* req, uv_stream_t* handle,
+        uv_buf_t* bufs, int buf_cnt,
+        uv_write_cb cb) {
+    return uv_write(req, handle, bufs, buf_cnt, cb);
+}
+extern "C" int
+rust_uv_read_start(uv_stream_t* stream, uv_alloc_cb on_alloc,
+        uv_read_cb on_read) {
+    return uv_read_start(stream, on_alloc, on_read);
+}
+
+extern "C" int
+rust_uv_read_stop(uv_stream_t* stream) {
+    return uv_read_stop(stream);
+}
+
+extern "C" char*
+rust_uv_malloc_buf_base_of(size_t suggested_size) {
+    return (char*) current_kernel_malloc(sizeof(char)*suggested_size,
+            "uv_buf_t base");
+}
+extern "C" void
+rust_uv_free_base_of_buf(uv_buf_t buf) {
+    current_kernel_free(buf.base);
+}
+
+extern "C" struct sockaddr_in
+rust_uv_ip4_addr(const char* ip, int port) {
+    printf("before creating addr_ptr.. ip %s port %d\n", ip, port);
+    struct sockaddr_in addr = uv_ip4_addr(ip, port);
+    printf("after creating .. port: %d\n", addr.sin_port);
+    return addr;
+}
index c392b7142e15a19ac6a323192ff3e78adc5db94c..171718b64f23be6e531f809d5ba9a6cdac85df54 100644 (file)
@@ -54,6 +54,8 @@ rust_task_yield
 rust_task_is_unwinding
 rust_get_task
 rust_task_config_notify
+rust_task_weaken
+rust_task_unweaken
 sched_threads
 shape_log_str
 start_task
@@ -87,13 +89,47 @@ rust_uv_bind_op_cb
 rust_uv_stop_op_cb
 rust_uv_run
 rust_uv_close
-rust_uv_close_async
-rust_uv_close_timer
+rust_uv_hilvl_close
+rust_uv_hilvl_close_async
+rust_uv_hilvl_close_timer
 rust_uv_async_send
 rust_uv_async_init
+rust_uv_hilvl_async_init
 rust_uv_timer_init
 rust_uv_timer_start
 rust_uv_timer_stop
+rust_uv_free
+rust_uv_tcp_init
+rust_uv_buf_init
+rust_uv_last_error
+rust_uv_strerror
+rust_uv_err_name
+rust_uv_ip4_addr
+rust_uv_tcp_connect
+rust_uv_tcp_bind
+rust_uv_listen
+rust_uv_accept
+rust_uv_write
+rust_uv_read_start
+rust_uv_read_stop
+rust_uv_malloc_buf_base_of
+rust_uv_free_base_of_buf
+rust_uv_helper_uv_tcp_t_size
+rust_uv_helper_uv_connect_t_size
+rust_uv_helper_uv_buf_t_size
+rust_uv_helper_uv_write_t_size
+rust_uv_helper_uv_err_t_size
+rust_uv_helper_sockaddr_in_size
+rust_uv_helper_uv_async_t_size
+rust_uv_get_stream_handle_from_connect_req
+rust_uv_get_stream_handle_from_write_req
+rust_uv_get_loop_for_uv_handle
+rust_uv_get_data_for_uv_handle
+rust_uv_set_data_for_uv_handle
+rust_uv_get_data_for_req
+rust_uv_set_data_for_req
+rust_uv_get_base_from_buf
+rust_uv_get_len_from_buf
 rust_dbg_lock_create
 rust_dbg_lock_destroy
 rust_dbg_lock_lock
@@ -102,3 +138,4 @@ rust_dbg_lock_wait
 rust_dbg_lock_signal
 rust_dbg_call
 rust_osmain_sched_id
+rust_compare_and_swap_ptr
\ No newline at end of file
index 28bfcc04c4c013b52c729a9fcf1faa01f48d505b..114f02fd093fca03b7d92ba9d4148482d91210de 100644 (file)
@@ -303,7 +303,7 @@ fn provided_link_metas(sess: session, c: ast::crate) ->
         let mut cmh_items: [@ast::meta_item] = [];
         let linkage_metas = attr::find_linkage_metas(c.node.attrs);
         attr::require_unique_names(sess.diagnostic(), linkage_metas);
-        for meta: @ast::meta_item in linkage_metas {
+        for linkage_metas.each {|meta|
             if attr::get_meta_item_name(meta) == "name" {
                 alt attr::get_meta_item_value_str(meta) {
                   some(v) { name = some(v); }
@@ -334,7 +334,7 @@ fn len_and_str_lit(l: ast::lit) -> str {
         let cmh_items = attr::sort_meta_items(metas.cmh_items);
 
         sha.reset();
-        for m_: @ast::meta_item in cmh_items {
+        for cmh_items.each {|m_|
             let m = m_;
             alt m.node {
               ast::meta_name_value(key, value) {
@@ -349,7 +349,7 @@ fn len_and_str_lit(l: ast::lit) -> str {
             }
         }
 
-        for dh in dep_hashes {
+        for dep_hashes.each {|dh|
             sha.input_str(len_and_str(dh));
         }
 
@@ -420,8 +420,7 @@ fn symbol_hash(tcx: ty::ctxt, sha: sha1, t: ty::t, link_meta: link_meta) ->
     sha.reset();
     sha.input_str(link_meta.name);
     sha.input_str("-");
-    // FIXME: This wants to be link_meta.meta_hash
-    sha.input_str(link_meta.name);
+    sha.input_str(link_meta.extras_hash);
     sha.input_str("-");
     sha.input_str(encoder::encoded_ty(tcx, t));
     let hash = truncated_sha1_result(sha);
@@ -475,7 +474,7 @@ fn mangle(ss: path) -> str {
 
     let mut n = "_ZN"; // Begin name-sequence.
 
-    for s in ss {
+    for ss.each {|s|
         alt s { path_name(s) | path_mod(s) {
           let sani = sanitize(s);
           n += #fmt["%u%s", str::len(sani), sani];
@@ -485,10 +484,8 @@ fn mangle(ss: path) -> str {
     n
 }
 
-fn exported_name(path: path, hash: str, _vers: str) -> str {
-    // FIXME: versioning isn't working yet
-    ret mangle(path + [path_name(hash)]); //  + "@" + vers;
-
+fn exported_name(path: path, hash: str, vers: str) -> str {
+    ret mangle(path + [path_name(hash)] + [path_name(vers)]);
 }
 
 fn mangle_exported_name(ccx: @crate_ctxt, path: path, t: ty::t) -> str {
@@ -584,7 +581,7 @@ fn rmext(filename: str) -> str {
     } else { lib_cmd = "-shared"; }
 
     let cstore = sess.cstore;
-    for cratepath: str in cstore::get_used_crate_files(cstore) {
+    for cstore::get_used_crate_files(cstore).each {|cratepath|
         if str::ends_with(cratepath, ".rlib") {
             cc_args += [cratepath];
             cont;
@@ -597,10 +594,10 @@ fn rmext(filename: str) -> str {
     }
 
     let ula = cstore::get_used_link_args(cstore);
-    for arg: str in ula { cc_args += [arg]; }
+    for ula.each {|arg| cc_args += [arg]; }
 
     let used_libs = cstore::get_used_libraries(cstore);
-    for l: str in used_libs { cc_args += ["-l" + l]; }
+    for used_libs.each {|l| cc_args += ["-l" + l]; }
 
     if sess.building_library {
         cc_args += [lib_cmd];
index eb52a2884cb5899dfaeebc8ae1d9ba6cb70a6a63..a52482d11d24b0bdffecc23432ff952969362b8c 100644 (file)
@@ -55,7 +55,7 @@ fn get_rpaths(os: session::os, cwd: path::path, sysroot: path::path,
     #debug("sysroot: %s", sysroot);
     #debug("output: %s", output);
     #debug("libs:");
-    for libpath in libs {
+    for libs.each {|libpath|
         #debug("    %s", libpath);
     }
     #debug("target_triple: %s", target_triple);
@@ -74,7 +74,7 @@ fn get_rpaths(os: session::os, cwd: path::path, sysroot: path::path,
 
     fn log_rpaths(desc: str, rpaths: [str]) {
         #debug("%s rpaths:", desc);
-        for rpath in rpaths {
+        for rpaths.each {|rpath|
             #debug("    %s", rpath);
         }
     }
@@ -179,7 +179,7 @@ fn get_install_prefix_rpath(cwd: path::path, target_triple: str) -> str {
 fn minimize_rpaths(rpaths: [str]) -> [str] {
     let set = map::str_hash::<()>();
     let mut minimized = [];
-    for rpath in rpaths {
+    for rpaths.each {|rpath|
         if !set.contains_key(rpath) {
             minimized += [rpath];
             set.insert(rpath, ());
index 4158e881dccea7cd41c505cf50af539fb53ffc9f..b1b60c3b127e5f3346d34740b714f988e6636f92 100644 (file)
@@ -35,7 +35,7 @@ fn decl(llmod: ModuleRef, prefix: str, name: str,
             tys: [TypeRef], rv: TypeRef) ->
        ValueRef {
         let mut arg_tys: [TypeRef] = [];
-        for t: TypeRef in tys { arg_tys += [t]; }
+        for tys.each {|t| arg_tys += [t]; }
         let fn_ty = T_fn(arg_tys, rv);
         ret base::decl_cdecl_fn(llmod, prefix + name, fn_ty);
     }
index b467c396563e8864872ad37e38c093aee43e1276..8a5a88d91fa9a178345d7e9277a3fb8f03f3ff7c 100644 (file)
@@ -67,7 +67,7 @@ fn parse_cfgspecs(cfgspecs: [str]) -> ast::crate_cfg {
     // FIXME: It would be nice to use the parser to parse all varieties of
     // meta_item here. At the moment we just support the meta_word variant.
     let mut words = [];
-    for s: str in cfgspecs { words += [attr::mk_word_item(s)]; }
+    for cfgspecs.each {|s| words += [attr::mk_word_item(s)]; }
     ret words;
 }
 
index fe5587e0faff1e760b55933f36d4793976fefa29..dc3386acb735c670f944bc5bb5e97730ec818859 100644 (file)
@@ -1,5 +1,10 @@
-use std;
-use rustc;
+#[no_core];
+
+use core(vers = "0.2");
+use std(vers = "0.2");
+use rustc(vers = "0.2");
+
+import core::*;
 
 // -*- rust -*-
 import result::{ok, err};
index 9d0f9e3d3f0d39db95ba30060b399bd530bfb6f9..aee5347f07f73c631c2d52bff8e6172412cd16f3 100644 (file)
@@ -118,7 +118,7 @@ fn metas_in_cfg(cfg: ast::crate_cfg, metas: [@ast::meta_item]) -> bool {
     let has_cfg_metas = vec::len(cfg_metas) > 0u;
     if !has_cfg_metas { ret true; }
 
-    for cfg_mi: @ast::meta_item in cfg_metas {
+    for cfg_metas.each {|cfg_mi|
         if attr::contains(cfg, cfg_mi) { ret true; }
     }
 
index a9b36812bc857ca77cfd46f708e784c53cdb7c25..aa1090cb2ae178ad943d8335c411651c9a0d5bf0 100644 (file)
@@ -268,7 +268,7 @@ fn mk_test_desc_vec_ty(cx: test_ctxt) -> @ast::ty {
 fn mk_test_desc_vec(cx: test_ctxt) -> @ast::expr {
     #debug("building test vector from %u tests", vec::len(cx.testfns));
     let mut descs = [];
-    for test: test in cx.testfns {
+    for cx.testfns.each {|test|
         let test_ = test; // Satisfy alias analysis
         descs += [mk_test_desc_rec(cx, test_)];
     }
index d72bed20880f07234b8cfef8a6e70e3cf78f2172..0d9e91bf1f08a5707754c50ec901d48b0d8ca735 100644 (file)
@@ -967,7 +967,7 @@ fn type_to_str_inner(names: type_names, outer0: [TypeRef], ty: TypeRef) ->
     fn tys_str(names: type_names, outer: [TypeRef], tys: [TypeRef]) -> str {
         let mut s: str = "";
         let mut first: bool = true;
-        for t: TypeRef in tys {
+        for tys.each {|t|
             if first { first = false; } else { s += ", "; }
             s += type_to_str_inner(names, outer, t);
         }
@@ -1019,7 +1019,7 @@ fn tys_str(names: type_names, outer: [TypeRef], tys: [TypeRef]) -> str {
       }
       12 {
         let mut i: uint = 0u;
-        for tout: TypeRef in outer0 {
+        for outer0.each {|tout|
             i += 1u;
             if tout as int == ty as int {
                 let n: uint = vec::len::<TypeRef>(outer0) - i;
index 8bc96a45ed6d9465b9eec68ccd48d8be5a406532..b2aa4fe312f0833ff86bde853ea563e395306011 100644 (file)
@@ -142,7 +142,7 @@ fn visit_ids(item: ast::inlined_item, vfn: fn@(ast::node_id)) {
             vfn(i.id);
             alt i.node {
               ast::item_res(_, _, _, d_id, c_id) { vfn(d_id); vfn(c_id); }
-              ast::item_enum(vs, _) { for v in vs { vfn(v.node.id); } }
+              ast::item_enum(vs, _) { for vs.each {|v| vfn(v.node.id); } }
               _ {}
             }
         },
@@ -692,7 +692,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
 
     #debug["Encoding side tables for id %d", id];
 
-    option::with_option_do(tcx.def_map.find(id)) {|def|
+    option::iter(tcx.def_map.find(id)) {|def|
         ebml_w.tag(c::tag_table_def) {||
             ebml_w.id(id);
             ebml_w.tag(c::tag_table_val) {||
@@ -700,7 +700,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
             }
         }
     }
-    option::with_option_do((*tcx.node_types).find(id as uint)) {|ty|
+    option::iter((*tcx.node_types).find(id as uint)) {|ty|
         ebml_w.tag(c::tag_table_node_type) {||
             ebml_w.id(id);
             ebml_w.tag(c::tag_table_val) {||
@@ -709,7 +709,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
         }
     }
 
-    option::with_option_do(tcx.node_type_substs.find(id)) {|tys|
+    option::iter(tcx.node_type_substs.find(id)) {|tys|
         ebml_w.tag(c::tag_table_node_type_subst) {||
             ebml_w.id(id);
             ebml_w.tag(c::tag_table_val) {||
@@ -718,7 +718,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
         }
     }
 
-    option::with_option_do(tcx.freevars.find(id)) {|fv|
+    option::iter(tcx.freevars.find(id)) {|fv|
         ebml_w.tag(c::tag_table_freevars) {||
             ebml_w.id(id);
             ebml_w.tag(c::tag_table_val) {||
@@ -730,7 +730,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
     }
 
     let lid = {crate: ast::local_crate, node: id};
-    option::with_option_do(tcx.tcache.find(lid)) {|tpbt|
+    option::iter(tcx.tcache.find(lid)) {|tpbt|
         ebml_w.tag(c::tag_table_tcache) {||
             ebml_w.id(id);
             ebml_w.tag(c::tag_table_val) {||
@@ -739,7 +739,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
         }
     }
 
-    option::with_option_do(tcx.ty_param_bounds.find(id)) {|pbs|
+    option::iter(tcx.ty_param_bounds.find(id)) {|pbs|
         ebml_w.tag(c::tag_table_param_bounds) {||
             ebml_w.id(id);
             ebml_w.tag(c::tag_table_val) {||
@@ -753,7 +753,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
     // is what we actually use in trans, all modes will have been
     // resolved.
     //
-    //option::with_option_do(tcx.inferred_modes.find(id)) {|m|
+    //option::iter(tcx.inferred_modes.find(id)) {|m|
     //    ebml_w.tag(c::tag_table_inferred_modes) {||
     //        ebml_w.id(id);
     //        ebml_w.tag(c::tag_table_val) {||
@@ -762,25 +762,25 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
     //    }
     //}
 
-    option::with_option_do(ccx.maps.mutbl_map.find(id)) {|_m|
+    option::iter(ccx.maps.mutbl_map.find(id)) {|_m|
         ebml_w.tag(c::tag_table_mutbl) {||
             ebml_w.id(id);
         }
     }
 
-    option::with_option_do(ccx.maps.copy_map.find(id)) {|_m|
+    option::iter(ccx.maps.copy_map.find(id)) {|_m|
         ebml_w.tag(c::tag_table_copy) {||
             ebml_w.id(id);
         }
     }
 
-    option::with_option_do(ccx.maps.spill_map.find(id)) {|_m|
+    option::iter(ccx.maps.spill_map.find(id)) {|_m|
         ebml_w.tag(c::tag_table_spill) {||
             ebml_w.id(id);
         }
     }
 
-    option::with_option_do(ccx.maps.last_uses.find(id)) {|m|
+    option::iter(ccx.maps.last_uses.find(id)) {|m|
         ebml_w.tag(c::tag_table_last_use) {||
             ebml_w.id(id);
             ebml_w.tag(c::tag_table_val) {||
@@ -792,7 +792,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
     // impl_map is not used except when emitting metadata,
     // don't need to keep it.
 
-    option::with_option_do(ccx.maps.method_map.find(id)) {|mo|
+    option::iter(ccx.maps.method_map.find(id)) {|mo|
         ebml_w.tag(c::tag_table_method_map) {||
             ebml_w.id(id);
             ebml_w.tag(c::tag_table_val) {||
@@ -801,7 +801,7 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
         }
     }
 
-    option::with_option_do(ccx.maps.vtable_map.find(id)) {|dr|
+    option::iter(ccx.maps.vtable_map.find(id)) {|dr|
         ebml_w.tag(c::tag_table_vtable_map) {||
             ebml_w.id(id);
             ebml_w.tag(c::tag_table_val) {||
index 0146421c689b60658f161e0541fe1fbf984c839e..b74d1149d76d6580f49ef2c69186662debb6f92d 100644 (file)
 
 const tag_parent_item: uint = 0x29u;
 
+const tag_crate_dep_name: uint = 0x2au;
+const tag_crate_dep_hash: uint = 0x2bu;
+const tag_crate_dep_vers: uint = 0x2cu;
+
 const tag_mod_impl: uint = 0x30u;
 
 const tag_item_method: uint = 0x31u;
@@ -111,7 +115,7 @@ enum astencode_tag { // Reserves 0x50 -- 0x6f
 
 fn hash_path(&&s: str) -> uint {
     let mut h = 5381u;
-    for ch: u8 in str::bytes(s) { h = (h << 5u) + h ^ (ch as uint); }
+    for str::each(s) {|ch| h = (h << 5u) + h ^ (ch as uint); }
     ret h;
 }
 
index 1a38f04ef74634c3a0b8602016908d8833fa88c4..435a31994eadbd0602dddef976b385b1855d3285 100644 (file)
@@ -20,7 +20,7 @@
 // libraries necessary for later resolving, typechecking, linking, etc.
 fn read_crates(sess: session::session, crate: ast::crate) {
     let e = @{sess: sess,
-              crate_cache: std::map::str_hash::<int>(),
+              mut crate_cache: [],
               mut next_crate_num: 1};
     let v =
         visit::mk_simple_visitor(@{visit_view_item:
@@ -28,16 +28,57 @@ fn read_crates(sess: session::session, crate: ast::crate) {
                                    visit_item: bind visit_item(e, _)
                                       with *visit::default_simple_visitor()});
     visit::visit_crate(crate, (), v);
+    warn_if_multiple_versions(sess, copy e.crate_cache);
+}
+
+type cache_entry = {
+    cnum: int,
+    span: span,
+    hash: str,
+    metas: @[@ast::meta_item]
+};
+
+fn warn_if_multiple_versions(sess: session::session,
+                             crate_cache: [cache_entry]) {
+    import either::*;
+
+    if crate_cache.is_not_empty() {
+        let name = crate_name_from_metas(*crate_cache.last().metas);
+        let {lefts: matches, rights: non_matches} =
+            partition(crate_cache.map {|entry|
+                let othername = crate_name_from_metas(*entry.metas);
+                if name == othername {
+                    left(entry)
+                } else {
+                    right(entry)
+                }
+            });
+
+        assert matches.is_not_empty();
+
+        if matches.len() != 1u {
+            sess.warn(#fmt("using multiple versions of crate `%s`", name));
+            for matches.each {|match|
+                sess.span_note(match.span, "used here");
+                let attrs = [
+                    attr::mk_attr(attr::mk_list_item("link", *match.metas))
+                ];
+                note_linkage_attrs(sess, attrs);
+            }
+        }
+
+        warn_if_multiple_versions(sess, non_matches);
+    }
 }
 
 type env = @{sess: session::session,
-             crate_cache: hashmap<str, int>,
+             mut crate_cache: [cache_entry],
              mut next_crate_num: ast::crate_num};
 
 fn visit_view_item(e: env, i: @ast::view_item) {
     alt i.node {
       ast::view_item_use(ident, meta_items, id) {
-        let cnum = resolve_crate(e, ident, meta_items, i.span);
+        let cnum = resolve_crate(e, ident, meta_items, "", i.span);
         cstore::add_use_stmt_cnum(e.sess.cstore, id, cnum);
       }
       _ { }
@@ -77,7 +118,7 @@ fn visit_item(e: env, i: @ast::item) {
             e.sess.span_fatal(i.span, "library '" + native_name +
                               "' already added: can't specify link_args.");
         }
-        for a: ast::attribute in link_args {
+        for link_args.each {|a|
             alt attr::get_meta_item_value_str(attr::attr_meta(a)) {
               some(linkarg) {
                 cstore::add_used_link_args(cstore, linkarg);
@@ -100,21 +141,31 @@ fn list_file_metadata(sess: session::session, path: str, out: io::writer) {
     }
 }
 
-fn metadata_matches(crate_data: @[u8], metas: [@ast::meta_item]) -> bool {
+fn crate_matches(crate_data: @[u8], metas: [@ast::meta_item], hash: str) ->
+    bool {
     let attrs = decoder::get_crate_attributes(crate_data);
     let linkage_metas = attr::find_linkage_metas(attrs);
+    if hash.is_not_empty() {
+        let chash = decoder::get_crate_hash(crate_data);
+        if chash != hash { ret false; }
+    }
+    metadata_matches(linkage_metas, metas)
+}
+
+fn metadata_matches(extern_metas: [@ast::meta_item],
+                    local_metas: [@ast::meta_item]) -> bool {
 
     #debug("matching %u metadata requirements against %u items",
-           vec::len(metas), vec::len(linkage_metas));
+           vec::len(local_metas), vec::len(extern_metas));
 
     #debug("crate metadata:");
-    for have: @ast::meta_item in linkage_metas {
+    for extern_metas.each {|have|
         #debug("  %s", pprust::meta_item_to_str(*have));
     }
 
-    for needed: @ast::meta_item in metas {
+    for local_metas.each {|needed|
         #debug("looking for %s", pprust::meta_item_to_str(*needed));
-        if !attr::contains(linkage_metas, needed) {
+        if !attr::contains(extern_metas, needed) {
             #debug("missing %s", pprust::meta_item_to_str(*needed));
             ret false;
         }
@@ -133,49 +184,51 @@ fn default_native_lib_naming(sess: session::session, static: bool) ->
     }
 }
 
-fn find_library_crate(sess: session::session, ident: ast::ident,
-                      metas: [@ast::meta_item])
+fn crate_name_from_metas(metas: [@ast::meta_item]) -> str {
+    let name_items = attr::find_meta_items_by_name(metas, "name");
+    alt vec::last_opt(name_items) {
+      some(i) {
+        alt attr::get_meta_item_value_str(i) {
+          some(n) { n }
+          // FIXME: Probably want a warning here since the user
+          // is using the wrong type of meta item
+          _ { fail }
+        }
+      }
+      none { fail "expected to find the crate name" }
+    }
+}
+
+fn find_library_crate(sess: session::session, span: span,
+                      metas: [@ast::meta_item], hash: str)
    -> option<{ident: str, data: @[u8]}> {
 
     attr::require_unique_names(sess.diagnostic(), metas);
     let metas = metas;
 
-    let crate_name =
-        {
-            let name_items = attr::find_meta_items_by_name(metas, "name");
-            alt vec::last_opt(name_items) {
-              some(i) {
-                alt attr::get_meta_item_value_str(i) {
-                  some(n) { n }
-                  // FIXME: Probably want a warning here since the user
-                  // is using the wrong type of meta item
-                  _ { ident }
-                }
-              }
-              none { ident }
-            }
-        };
-
     let nn = default_native_lib_naming(sess, sess.opts.static);
     let x =
-        find_library_crate_aux(sess, nn, crate_name,
-                               metas, sess.filesearch);
+        find_library_crate_aux(sess, span, nn,
+                               metas, hash, sess.filesearch);
     if x != none || sess.opts.static { ret x; }
     let nn2 = default_native_lib_naming(sess, true);
-    ret find_library_crate_aux(sess, nn2, crate_name, metas,
+    ret find_library_crate_aux(sess, span, nn2, metas, hash,
                                sess.filesearch);
 }
 
 fn find_library_crate_aux(sess: session::session,
+                          span: span,
                           nn: {prefix: str, suffix: str},
-                          crate_name: str,
                           metas: [@ast::meta_item],
+                          hash: str,
                           filesearch: filesearch::filesearch) ->
    option<{ident: str, data: @[u8]}> {
+    let crate_name = crate_name_from_metas(metas);
     let prefix: str = nn.prefix + crate_name + "-";
     let suffix: str = nn.suffix;
 
-    ret filesearch::search(filesearch, { |path|
+    let mut matches = [];
+    filesearch::search(filesearch, { |path|
         #debug("inspecting file %s", path);
         let f: str = path::basename(path);
         if !(str::starts_with(f, prefix) && str::ends_with(f, suffix)) {
@@ -186,12 +239,13 @@ fn find_library_crate_aux(sess: session::session,
             #debug("%s is a candidate", path);
             alt get_metadata_section(sess, path) {
               option::some(cvec) {
-                if !metadata_matches(cvec, metas) {
+                if !crate_matches(cvec, metas, hash) {
                     #debug("skipping %s, metadata doesn't match", path);
                     option::none
                 } else {
                     #debug("found %s with matching metadata", path);
-                    option::some({ident: path, data: cvec})
+                    matches += [{ident: path, data: cvec}];
+                    option::none
                 }
               }
               _ {
@@ -201,6 +255,29 @@ fn find_library_crate_aux(sess: session::session,
             }
         }
     });
+
+    if matches.is_empty() {
+        none
+    } else if matches.len() == 1u {
+        some(matches[0])
+    } else {
+        sess.span_err(
+            span, #fmt("multiple matching crates for `%s`", crate_name));
+        sess.note("candidates:");
+        for matches.each {|match|
+            sess.note(#fmt("path: %s", match.ident));
+            let attrs = decoder::get_crate_attributes(match.data);
+            note_linkage_attrs(sess, attrs);
+        }
+        sess.abort_if_errors();
+        none
+    }
+}
+
+fn note_linkage_attrs(sess: session::session, attrs: [ast::attribute]) {
+    for attr::find_linkage_attrs(attrs).each {|attr|
+        sess.note(#fmt("meta: %s", pprust::attr_to_str(attr)));
+    }
 }
 
 fn get_metadata_section(sess: session::session,
@@ -230,12 +307,12 @@ fn get_metadata_section(sess: session::session,
     ret option::none::<@[u8]>;
 }
 
-fn load_library_crate(sess: session::session, span: span, ident: ast::ident,
-                      metas: [@ast::meta_item])
+fn load_library_crate(sess: session::session, ident: ast::ident, span: span,
+                      metas: [@ast::meta_item], hash: str)
    -> {ident: str, data: @[u8]} {
 
 
-    alt find_library_crate(sess, ident, metas) {
+    alt find_library_crate(sess, span, metas, hash) {
       some(t) { ret t; }
       none {
         sess.span_fatal(span, #fmt["can't find crate for '%s'", ident]);
@@ -243,31 +320,72 @@ fn load_library_crate(sess: session::session, span: span, ident: ast::ident,
     }
 }
 
+fn metas_with(ident: ast::ident, key: str,
+                    metas: [@ast::meta_item]) -> [@ast::meta_item] {
+    let name_items = attr::find_meta_items_by_name(metas, key);
+    if name_items.is_empty() {
+        metas + [attr::mk_name_value_item_str(key, ident)]
+    } else {
+        metas
+    }
+}
+
+fn metas_with_ident(ident: ast::ident,
+                    metas: [@ast::meta_item]) -> [@ast::meta_item] {
+    metas_with(ident, "name", metas)
+}
+
+fn existing_match(e: env, metas: [@ast::meta_item], hash: str) ->
+    option<int> {
+    let maybe_entry = e.crate_cache.find {|c|
+        metadata_matches(*c.metas, metas) &&
+            (hash.is_empty() || c.hash == hash)
+    };
+
+    maybe_entry.map {|c| c.cnum }
+}
+
 fn resolve_crate(e: env, ident: ast::ident, metas: [@ast::meta_item],
-                 span: span) -> ast::crate_num {
-    if !e.crate_cache.contains_key(ident) {
+                 hash: str, span: span) -> ast::crate_num {
+    let metas = metas_with_ident(ident, metas);
+
+    alt existing_match(e, metas, hash) {
+      none {
         let cinfo =
-            load_library_crate(e.sess, span, ident, metas);
+            load_library_crate(e.sess, ident, span, metas, hash);
 
         let cfilename = cinfo.ident;
         let cdata = cinfo.data;
 
+        let attrs = decoder::get_crate_attributes(cdata);
+        let linkage_metas = attr::find_linkage_metas(attrs);
+        let hash = decoder::get_crate_hash(cdata);
+
         // Claim this crate number and cache it
         let cnum = e.next_crate_num;
-        e.crate_cache.insert(ident, cnum);
+        e.crate_cache += [{cnum: cnum, span: span,
+                           hash: hash, metas: @linkage_metas}];
         e.next_crate_num += 1;
 
         // Now resolve the crates referenced by this crate
         let cnum_map = resolve_crate_deps(e, cdata);
 
-        let cmeta = @{name: ident, data: cdata,
+        let cname = alt attr::meta_item_value_from_list(metas, "name") {
+          option::some(v) { v }
+          option::none { ident }
+        };
+        let cmeta = @{name: cname, data: cdata,
                       cnum_map: cnum_map, cnum: cnum};
 
         let cstore = e.sess.cstore;
         cstore::set_crate_data(cstore, cnum, cmeta);
         cstore::add_used_crate_file(cstore, cfilename);
         ret cnum;
-    } else { ret e.crate_cache.get(ident); }
+      }
+      some(cnum) {
+        ret cnum;
+      }
+    }
 }
 
 // Go through the crate metadata and load any crates that it references
@@ -276,22 +394,27 @@ fn resolve_crate_deps(e: env, cdata: @[u8]) -> cstore::cnum_map {
     // The map from crate numbers in the crate we're resolving to local crate
     // numbers
     let cnum_map = int_hash::<ast::crate_num>();
-    for dep: decoder::crate_dep in decoder::get_crate_deps(cdata) {
+    for decoder::get_crate_deps(cdata).each {|dep|
         let extrn_cnum = dep.cnum;
-        let cname = dep.ident;
-        #debug("resolving dep %s", cname);
-        if e.crate_cache.contains_key(cname) {
+        let cname = dep.name;
+        let cmetas = metas_with(dep.vers, "vers", []);
+        #debug("resolving dep crate %s ver: %s hash: %s",
+               dep.name, dep.vers, dep.hash);
+        alt existing_match(e, metas_with_ident(cname, cmetas), dep.hash) {
+          some(local_cnum) {
             #debug("already have it");
             // We've already seen this crate
-            let local_cnum = e.crate_cache.get(cname);
             cnum_map.insert(extrn_cnum, local_cnum);
-        } else {
+          }
+          none {
             #debug("need to load it");
             // This is a new one so we've got to load it
             // FIXME: Need better error reporting than just a bogus span
             let fake_span = ast_util::dummy_sp();
-            let local_cnum = resolve_crate(e, cname, [], fake_span);
+            let local_cnum =
+                resolve_crate(e, cname, cmetas, dep.hash, fake_span);
             cnum_map.insert(extrn_cnum, local_cnum);
+          }
         }
     }
     ret cnum_map;
index bada0931953234df1e0af020e11f693783066c59..504f5890638290d9374754809960123693d09e32 100644 (file)
@@ -41,7 +41,8 @@ fn lookup_defs(cstore: cstore::cstore, cnum: ast::crate_num,
                path: [ast::ident]) -> [ast::def] {
     let mut result = [];
     #debug("lookup_defs: path = %? cnum = %?", path, cnum);
-    for (c, data, def) in resolve_path(cstore, cnum, path) {
+    for resolve_path(cstore, cnum, path).each {|elt|
+        let (c, data, def) = elt;
         result += [decoder::lookup_def(c, data, def)];
     }
     ret result;
@@ -64,7 +65,7 @@ fn resolve_path(cstore: cstore::cstore, cnum: ast::crate_num,
     #debug("resolve_path %s in crates[%d]:%s",
            str::connect(path, "::"), cnum, cm.name);
     let mut result = [];
-    for def in decoder::resolve_path(path, cm.data) {
+    for decoder::resolve_path(path, cm.data).each {|def|
         if def.crate == ast::local_crate {
             result += [(cnum, cm.data, def)];
         } else {
index 473bf8b4e54de29aa0550657f7b87e698308a920..370d09e00173dc06cfd937ce813820cbcc0d7f9a 100644 (file)
@@ -3,7 +3,7 @@
 
 import std::map;
 import std::map::hashmap;
-import syntax::ast;
+import syntax::{ast, attr};
 import util::common::*;
 
 export cstore::{};
@@ -12,6 +12,8 @@
 export mk_cstore;
 export get_crate_data;
 export set_crate_data;
+export get_crate_hash;
+export get_crate_vers;
 export have_crate_data;
 export iter_crate_data;
 export add_used_crate_file;
@@ -79,6 +81,16 @@ fn get_crate_data(cstore: cstore, cnum: ast::crate_num) -> crate_metadata {
     ret p(cstore).metas.get(cnum);
 }
 
+fn get_crate_hash(cstore: cstore, cnum: ast::crate_num) -> str {
+    let cdata = get_crate_data(cstore, cnum);
+    ret decoder::get_crate_hash(cdata.data);
+}
+
+fn get_crate_vers(cstore: cstore, cnum: ast::crate_num) -> str {
+    let cdata = get_crate_data(cstore, cnum);
+    ret decoder::get_crate_vers(cdata.data);
+}
+
 fn set_crate_data(cstore: cstore, cnum: ast::crate_num,
                   data: crate_metadata) {
     p(cstore).metas.insert(cnum, data);
@@ -154,7 +166,7 @@ fn lteq(a: crate_hash, b: crate_hash) -> bool {
     }
     let sorted = std::sort::merge_sort(lteq, result);
     #debug("sorted:");
-    for x in sorted {
+    for sorted.each {|x|
         #debug("  hash[%s]: %s", x.name, x.hash);
     }
     fn mapper(ch: crate_hash) -> str { ret ch.hash; }
@@ -163,7 +175,7 @@ fn lteq(a: crate_hash, b: crate_hash) -> bool {
 
 fn get_path(cstore: cstore, d: ast::def_id) -> [str] {
     // let f = bind str::split_str(_, "::");
-    option::with_option(p(cstore).mod_path_map.find(d), [],
+    option::map_default(p(cstore).mod_path_map.find(d), [],
                   {|ds| str::split_str(ds, "::")})
 }
 // Local Variables:
index 2a2438b52a7bde64aeb47080f92cc230174e24f8..015f9d27258da7789246d9700a38d2a48901f226 100644 (file)
@@ -33,6 +33,7 @@
 export crate_dep;
 export get_crate_deps;
 export get_crate_hash;
+export get_crate_vers;
 export get_impls_for_mod;
 export get_iface_methods;
 export get_crate_module_paths;
@@ -120,7 +121,7 @@ fn class_member_id(d: ebml::doc, cdata: cmd) -> ast::def_id {
 
 fn field_mutability(d: ebml::doc) -> ast::class_mutability {
     // Use maybe_get_doc in case it's a method
-    option::with_option(ebml::maybe_get_doc(d, tag_class_mut),
+    option::map_default(ebml::maybe_get_doc(d, tag_class_mut),
                   ast::class_immutable,
                   {|d|
                   alt ebml::doc_as_u8(d) as char {
@@ -204,7 +205,7 @@ fn eq_item(data: [u8], s: str) -> bool {
     let eqer = bind eq_item(_, s);
     let mut result: [ast::def_id] = [];
     #debug("resolve_path: looking up %s", s);
-    for doc: ebml::doc in lookup_hash(paths, eqer, hash_path(s)) {
+    for lookup_hash(paths, eqer, hash_path(s)).each {|doc|
         let did_doc = ebml::get_doc(doc, tag_def_id);
         result += [parse_def_id(ebml::doc_data(did_doc))];
     }
@@ -359,7 +360,7 @@ fn get_enum_variants(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
     let mut infos: [ty::variant_info] = [];
     let variant_ids = enum_variant_ids(item, cdata);
     let mut disr_val = 0;
-    for did: ast::def_id in variant_ids {
+    for variant_ids.each {|did|
         let item = find_item(did.node, items);
         let ctor_ty = item_type({crate: cdata.cnum, node: id}, item,
                                 tcx, cdata);
@@ -367,7 +368,7 @@ fn get_enum_variants(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
         let mut arg_tys: [ty::t] = [];
         alt ty::get(ctor_ty).struct {
           ty::ty_fn(f) {
-            for a: ty::arg in f.inputs { arg_tys += [a.ty]; }
+            for f.inputs.each {|a| arg_tys += [a.ty]; }
           }
           _ { /* Nullary enum variant. */ }
         }
@@ -560,7 +561,7 @@ fn get_attributes(md: ebml::doc) -> [ast::attribute] {
 }
 
 fn list_meta_items(meta_items: ebml::doc, out: io::writer) {
-    for mi: @ast::meta_item in get_meta_items(meta_items) {
+    for get_meta_items(meta_items).each {|mi|
         out.write_str(#fmt["%s\n", pprust::meta_item_to_str(*mi)]);
     }
 }
@@ -568,7 +569,7 @@ fn list_meta_items(meta_items: ebml::doc, out: io::writer) {
 fn list_crate_attributes(md: ebml::doc, hash: str, out: io::writer) {
     out.write_str(#fmt("=Crate Attributes (%s)=\n", hash));
 
-    for attr: ast::attribute in get_attributes(md) {
+    for get_attributes(md).each {|attr|
         out.write_str(#fmt["%s\n", pprust::attribute_to_str(attr)]);
     }
 
@@ -579,16 +580,22 @@ fn get_crate_attributes(data: @[u8]) -> [ast::attribute] {
     ret get_attributes(ebml::doc(data));
 }
 
-type crate_dep = {cnum: ast::crate_num, ident: str};
+type crate_dep = {cnum: ast::crate_num, name: ast::ident,
+                  vers: str, hash: str};
 
 fn get_crate_deps(data: @[u8]) -> [crate_dep] {
     let mut deps: [crate_dep] = [];
     let cratedoc = ebml::doc(data);
     let depsdoc = ebml::get_doc(cratedoc, tag_crate_deps);
     let mut crate_num = 1;
+    fn docstr(doc: ebml::doc, tag_: uint) -> str {
+        str::from_bytes(ebml::doc_data(ebml::get_doc(doc, tag_)))
+    }
     ebml::tagged_docs(depsdoc, tag_crate_dep) {|depdoc|
-        let depname = str::from_bytes(ebml::doc_data(depdoc));
-        deps += [{cnum: crate_num, ident: depname}];
+        deps += [{cnum: crate_num,
+                  name: docstr(depdoc, tag_crate_dep_name),
+                  vers: docstr(depdoc, tag_crate_dep_vers),
+                  hash: docstr(depdoc, tag_crate_dep_hash)}];
         crate_num += 1;
     };
     ret deps;
@@ -597,8 +604,9 @@ fn get_crate_deps(data: @[u8]) -> [crate_dep] {
 fn list_crate_deps(data: @[u8], out: io::writer) {
     out.write_str("=External Dependencies=\n");
 
-    for dep: crate_dep in get_crate_deps(data) {
-        out.write_str(#fmt["%d %s\n", dep.cnum, dep.ident]);
+    for get_crate_deps(data).each {|dep|
+        out.write_str(#fmt["%d %s-%s-%s\n",
+                           dep.cnum, dep.name, dep.hash, dep.vers]);
     }
 
     out.write_str("\n");
@@ -610,6 +618,15 @@ fn get_crate_hash(data: @[u8]) -> str {
     ret str::from_bytes(ebml::doc_data(hashdoc));
 }
 
+fn get_crate_vers(data: @[u8]) -> str {
+    let attrs = decoder::get_crate_attributes(data);
+    ret alt attr::meta_item_value_from_list(
+        attr::find_linkage_metas(attrs), "vers") {
+      some(ver) { ver }
+      none { "0.0" }
+    };
+}
+
 fn list_crate_items(bytes: @[u8], md: ebml::doc, out: io::writer) {
     out.write_str("=Items=\n");
     let items = ebml::get_doc(md, tag_items);
index ba9768f5a1a2e1f27f51c5b1c31b1494a7775136..197f8be6f02c385573973b1144d7615cd011b873 100644 (file)
@@ -58,7 +58,7 @@ fn encode_mutability(ebml_w: ebml::writer, mt: class_mutability) {
 
 fn encode_enum_variant_paths(ebml_w: ebml::writer, variants: [variant],
                             path: [str], &index: [entry<str>]) {
-    for variant: variant in variants {
+    for variants.each {|variant|
         add_to_index(ebml_w, path, index, variant.node.name);
         ebml_w.wr_tag(tag_paths_data_item) {||
             encode_name(ebml_w, variant.node.name);
@@ -76,7 +76,7 @@ fn add_to_index(ebml_w: ebml::writer, path: [str], &index: [entry<str>],
 
 fn encode_native_module_item_paths(ebml_w: ebml::writer, nmod: native_mod,
                                    path: [str], &index: [entry<str>]) {
-    for nitem: @native_item in nmod.items {
+    for nmod.items.each {|nitem|
         add_to_index(ebml_w, path, index, nitem.ident);
         encode_named_def_id(ebml_w, nitem.ident, local_def(nitem.id));
     }
@@ -84,7 +84,7 @@ fn encode_native_module_item_paths(ebml_w: ebml::writer, nmod: native_mod,
 
 fn encode_class_item_paths(ebml_w: ebml::writer,
      items: [@class_member], path: [str], &index: [entry<str>]) {
-    for it in items {
+    for items.each {|it|
      alt ast_util::class_member_privacy(it) {
           priv { cont; }
           pub {
@@ -102,7 +102,7 @@ fn encode_class_item_paths(ebml_w: ebml::writer,
 fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
                             module: _mod, path: [str], &index: [entry<str>]) {
     // FIXME factor out add_to_index/start/encode_name/encode_def_id/end ops
-    for it: @item in module.items {
+    for module.items.each {|it|
         if !ecx.ccx.reachable.contains_key(it.id) ||
            !ast_util::is_exported(it.ident, module) { cont; }
         alt it.node {
@@ -200,7 +200,7 @@ fn encode_reexport_paths(ebml_w: ebml::writer,
                          ecx: @encode_ctxt, &index: [entry<str>]) {
     let tcx = ecx.ccx.tcx;
     ecx.ccx.exp_map.items {|exp_id, defs|
-        for def in defs {
+        for defs.each {|def|
             if !def.reexp { cont; }
             let path = alt check tcx.items.get(exp_id) {
               ast_map::node_export(_, path) { ast_map::path_to_str(*path) }
@@ -230,7 +230,7 @@ fn encode_type_param_bounds(ebml_w: ebml::writer, ecx: @encode_ctxt,
                         tcx: ecx.ccx.tcx,
                         reachable: ecx.ccx.reachable,
                         abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
-    for param in params {
+    for params.each {|param|
         ebml_w.start_tag(tag_items_data_item_ty_param_bounds);
         let bs = ecx.ccx.tcx.ty_param_bounds.get(param.id);
         tyencode::enc_bounds(ebml_w.writer, ty_str_ctxt, bs);
@@ -295,7 +295,7 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
     let mut disr_val = 0;
     let mut i = 0;
     let vi = ty::enum_variants(ecx.ccx.tcx, {crate: local_crate, node: id});
-    for variant: variant in variants {
+    for variants.each {|variant|
         *index += [{val: variant.node.id, pos: ebml_w.writer.tell()}];
         ebml_w.start_tag(tag_items_data_item);
         encode_def_id(ebml_w, local_def(variant.node.id));
@@ -347,7 +347,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
     encode_name(ebml_w, name);
     alt ecx.ccx.maps.impl_map.get(id) {
       list::cons(impls, @list::nil) {
-        for i in *impls {
+        for vec::each(*impls) {|i|
             if ast_util::is_exported(i.ident, md) {
                 ebml_w.wr_tagged_str(tag_mod_impl, def_to_str(i.did));
             }
@@ -373,7 +373,7 @@ fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::writer,
  -> [entry<int>] {
     let index = @mut [];
     let tcx = ecx.ccx.tcx;
-    for ci in items {
+    for items.each {|ci|
      /* We encode both private and public fields -- need to include
         private fields to get the offsets right */
       alt ci.node {
@@ -409,7 +409,7 @@ fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::writer,
           }
         }
       }
-    }
+    };
     *index
 }
 
@@ -548,7 +548,7 @@ fn add_to_index_(item: @item, ebml_w: ebml::writer,
         encode_type_param_bounds(ebml_w, ecx, tps);
         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
         encode_name(ebml_w, item.ident);
-        for v: variant in variants {
+        for variants.each {|v|
             encode_variant_id(ebml_w, local_def(v.node.id));
         }
         astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
@@ -579,14 +579,14 @@ fn add_to_index_(item: @item, ebml_w: ebml::writer,
          for methods, write all the stuff get_iface_method
         needs to know*/
         let (fs,ms) = ast_util::split_class_items(items);
-        for f in fs {
+        for fs.each {|f|
            ebml_w.start_tag(tag_item_field);
            encode_privacy(ebml_w, f.privacy);
            encode_name(ebml_w, f.ident);
            encode_def_id(ebml_w, local_def(f.id));
            ebml_w.end_tag();
         }
-        for m in ms {
+        for ms.each {|m|
            alt m.privacy {
               priv { /* do nothing */ }
               pub {
@@ -637,7 +637,7 @@ fn add_to_index_(item: @item, ebml_w: ebml::writer,
         encode_type_param_bounds(ebml_w, ecx, tps);
         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
         encode_name(ebml_w, item.ident);
-        for m in methods {
+        for methods.each {|m|
             ebml_w.start_tag(tag_item_method);
             ebml_w.writer.write(str::bytes(def_to_str(local_def(m.id))));
             ebml_w.end_tag();
@@ -657,7 +657,7 @@ fn add_to_index_(item: @item, ebml_w: ebml::writer,
         ebml_w.end_tag();
 
         let impl_path = path + [ast_map::path_name(item.ident)];
-        for m in methods {
+        for methods.each {|m|
             *index += [{val: m.id, pos: ebml_w.writer.tell()}];
             encode_info_for_method(ecx, ebml_w, impl_path,
                    should_inline(m.attrs), item.id, m, tps + m.tps);
@@ -672,7 +672,7 @@ fn add_to_index_(item: @item, ebml_w: ebml::writer,
         encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
         encode_name(ebml_w, item.ident);
         let mut i = 0u;
-        for mty in *ty::iface_methods(tcx, local_def(item.id)) {
+        for vec::each(*ty::iface_methods(tcx, local_def(item.id))) {|mty|
             ebml_w.start_tag(tag_item_method);
             encode_name(ebml_w, mty.ident);
             encode_type_param_bounds(ebml_w, ecx, ms[i].tps);
@@ -765,13 +765,13 @@ fn create_index<T: copy>(index: [entry<T>], hash_fn: fn@(T) -> uint) ->
    [@[entry<T>]] {
     let mut buckets: [@mut [entry<T>]] = [];
     uint::range(0u, 256u) {|_i| buckets += [@mut []]; };
-    for elt: entry<T> in index {
+    for index.each {|elt|
         let h = hash_fn(elt.val);
         *buckets[h % 256u] += [elt];
     }
 
     let mut buckets_frozen = [];
-    for bucket: @mut [entry<T>] in buckets {
+    for buckets.each {|bucket|
         buckets_frozen += [@*bucket];
     }
     ret buckets_frozen;
@@ -783,10 +783,10 @@ fn encode_index<T>(ebml_w: ebml::writer, buckets: [@[entry<T>]],
     ebml_w.start_tag(tag_index);
     let mut bucket_locs: [uint] = [];
     ebml_w.start_tag(tag_index_buckets);
-    for bucket: @[entry<T>] in buckets {
+    for buckets.each {|bucket|
         bucket_locs += [ebml_w.writer.tell()];
         ebml_w.start_tag(tag_index_buckets_bucket);
-        for elt: entry<T> in *bucket {
+        for vec::each(*bucket) {|elt|
             ebml_w.start_tag(tag_index_buckets_bucket_elt);
             writer.write_be_uint(elt.pos, 4u);
             write_fn(writer, elt.val);
@@ -796,7 +796,7 @@ fn encode_index<T>(ebml_w: ebml::writer, buckets: [@[entry<T>]],
     }
     ebml_w.end_tag();
     ebml_w.start_tag(tag_index_table);
-    for pos: uint in bucket_locs { writer.write_be_uint(pos, 4u); }
+    for bucket_locs.each {|pos| writer.write_be_uint(pos, 4u); }
     ebml_w.end_tag();
     ebml_w.end_tag();
 }
@@ -836,7 +836,7 @@ fn encode_meta_item(ebml_w: ebml::writer, mi: meta_item) {
         ebml_w.start_tag(tag_meta_item_name);
         ebml_w.writer.write(str::bytes(name));
         ebml_w.end_tag();
-        for inner_item: @meta_item in items {
+        for items.each {|inner_item|
             encode_meta_item(ebml_w, *inner_item);
         }
         ebml_w.end_tag();
@@ -846,7 +846,7 @@ fn encode_meta_item(ebml_w: ebml::writer, mi: meta_item) {
 
 fn encode_attributes(ebml_w: ebml::writer, attrs: [attribute]) {
     ebml_w.start_tag(tag_attributes);
-    for attr: attribute in attrs {
+    for attrs.each {|attr|
         ebml_w.start_tag(tag_attribute);
         encode_meta_item(ebml_w, attr.node.value);
         ebml_w.end_tag();
@@ -885,7 +885,7 @@ fn synthesize_link_attr(ecx: @encode_ctxt, items: [@meta_item]) ->
 
     let mut attrs: [attribute] = [];
     let mut found_link_attr = false;
-    for attr: attribute in crate.node.attrs {
+    for crate.node.attrs.each {|attr|
         attrs +=
             if attr::get_attr_name(attr) != "link" {
                 [attr]
@@ -907,47 +907,59 @@ fn synthesize_link_attr(ecx: @encode_ctxt, items: [@meta_item]) ->
 
 fn encode_crate_deps(ebml_w: ebml::writer, cstore: cstore::cstore) {
 
-    fn get_ordered_names(cstore: cstore::cstore) -> [str] {
+    fn get_ordered_deps(cstore: cstore::cstore) -> [decoder::crate_dep] {
         type hashkv = @{key: crate_num, val: cstore::crate_metadata};
-        type numname = {crate: crate_num, ident: str};
+        type numdep = decoder::crate_dep;
 
-        // Pull the cnums and names out of cstore
-        let mut pairs: [mut numname] = [mut];
+        // Pull the cnums and name,vers,hash out of cstore
+        let mut deps: [mut numdep] = [mut];
         cstore::iter_crate_data(cstore) {|key, val|
-            pairs += [mut {crate: key, ident: val.name}];
+            let dep = {cnum: key, name: val.name,
+                       vers: decoder::get_crate_vers(val.data),
+                       hash:  decoder::get_crate_hash(val.data)};
+            deps += [mut dep];
         };
 
         // Sort by cnum
-        fn lteq(kv1: numname, kv2: numname) -> bool { kv1.crate <= kv2.crate }
-        std::sort::quick_sort(lteq, pairs);
+        fn lteq(kv1: numdep, kv2: numdep) -> bool { kv1.cnum <= kv2.cnum }
+        std::sort::quick_sort(lteq, deps);
 
         // Sanity-check the crate numbers
         let mut expected_cnum = 1;
-        for n: numname in pairs {
-            assert (n.crate == expected_cnum);
+        for deps.each {|n|
+            assert (n.cnum == expected_cnum);
             expected_cnum += 1;
         }
 
-        // Return just the names
-        fn name(kv: numname) -> str { kv.ident }
         // mut -> immutable hack for vec::map
-        let immpairs = vec::slice(pairs, 0u, vec::len(pairs));
-        ret vec::map(immpairs, name);
+        ret vec::slice(deps, 0u, vec::len(deps));
     }
 
-    // We're just going to write a list of crate names, with the assumption
-    // that they are numbered 1 to n.
+    // We're just going to write a list of crate 'name-hash-version's, with
+    // the assumption that they are numbered 1 to n.
     // FIXME: This is not nearly enough to support correct versioning
     // but is enough to get transitive crate dependencies working.
     ebml_w.start_tag(tag_crate_deps);
-    for cname: str in get_ordered_names(cstore) {
-        ebml_w.start_tag(tag_crate_dep);
-        ebml_w.writer.write(str::bytes(cname));
-        ebml_w.end_tag();
+    for get_ordered_deps(cstore).each {|dep|
+        encode_crate_dep(ebml_w, dep);
     }
     ebml_w.end_tag();
 }
 
+fn encode_crate_dep(ebml_w: ebml::writer, dep: decoder::crate_dep) {
+    ebml_w.start_tag(tag_crate_dep);
+    ebml_w.start_tag(tag_crate_dep_name);
+    ebml_w.writer.write(str::bytes(dep.name));
+    ebml_w.end_tag();
+    ebml_w.start_tag(tag_crate_dep_vers);
+    ebml_w.writer.write(str::bytes(dep.vers));
+    ebml_w.end_tag();
+    ebml_w.start_tag(tag_crate_dep_hash);
+    ebml_w.writer.write(str::bytes(dep.hash));
+    ebml_w.end_tag();
+    ebml_w.end_tag();
+}
+
 fn encode_hash(ebml_w: ebml::writer, hash: str) {
     ebml_w.start_tag(tag_crate_hash);
     ebml_w.writer.write(str::bytes(hash));
index b527b5d1f431e09906a3722fa5a22b13d6570804..7d8fd31d635bdbbf66be2856cdae7017153022a5 100644 (file)
@@ -392,25 +392,20 @@ fn parse_def_id(buf: [u8]) -> ast::def_id {
         #error("didn't find ':' when parsing def id");
         fail;
     }
-    let crate_part = vec::slice::<u8>(buf, 0u, colon_idx);
-    let def_part = vec::slice::<u8>(buf, colon_idx + 1u, len);
+    let crate_part = vec::slice(buf, 0u, colon_idx);
+    let def_part = vec::slice(buf, colon_idx + 1u, len);
 
-    let mut crate_part_vec = [];
-    let mut def_part_vec = [];
-    for b: u8 in crate_part { crate_part_vec += [b]; }
-    for b: u8 in def_part { def_part_vec += [b]; }
-
-    let crate_num = alt uint::parse_buf(crate_part_vec, 10u) {
+    let crate_num = alt uint::parse_buf(crate_part, 10u) {
        some(cn) { cn as int }
        none { fail (#fmt("internal error: parse_def_id: error parsing %? \
                          as crate",
-                         crate_part_vec)); }
+                         crate_part)); }
     };
-    let def_num = alt uint::parse_buf(def_part_vec, 10u) {
+    let def_num = alt uint::parse_buf(def_part, 10u) {
        some(dn) { dn as int }
        none { fail (#fmt("internal error: parse_def_id: error parsing %? \
                          as id",
-                         def_part_vec)); }
+                         def_part)); }
     };
     ret {crate: crate_num, node: def_num};
 }
index c5f23f37b865c6365b4d3d17471253a19c60f0b3..fb0a84b603fb399fc004321c2dd5b3daa480aef7 100644 (file)
@@ -140,6 +140,9 @@ fn enc_region(w: io::writer, r: ty::region) {
         w.write_uint(id.to_uint());
         w.write_char('|');
       }
+      ty::re_static {
+        w.write_char('t');
+      }
     }
 }
 fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
@@ -178,19 +181,19 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
         w.write_str("t[");
         w.write_str(cx.ds(def));
         w.write_char('|');
-        for t: ty::t in tys { enc_ty(w, cx, t); }
+        for tys.each {|t| enc_ty(w, cx, t); }
         w.write_char(']');
       }
       ty::ty_iface(def, tys) {
         w.write_str("x[");
         w.write_str(cx.ds(def));
         w.write_char('|');
-        for t: ty::t in tys { enc_ty(w, cx, t); }
+        for tys.each {|t| enc_ty(w, cx, t); }
         w.write_char(']');
       }
       ty::ty_tup(ts) {
         w.write_str("T[");
-        for t in ts { enc_ty(w, cx, t); }
+        for ts.each {|t| enc_ty(w, cx, t); }
         w.write_char(']');
       }
       ty::ty_box(mt) { w.write_char('@'); enc_mt(w, cx, mt); }
@@ -204,7 +207,7 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
       ty::ty_vec(mt) { w.write_char('I'); enc_mt(w, cx, mt); }
       ty::ty_rec(fields) {
         w.write_str("R[");
-        for field: ty::field in fields {
+        for fields.each {|field|
             w.write_str(field.ident);
             w.write_char('=');
             enc_mt(w, cx, field.mt);
@@ -220,7 +223,7 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
         w.write_str(cx.ds(def));
         w.write_char('|');
         enc_ty(w, cx, ty);
-        for t: ty::t in tps { enc_ty(w, cx, t); }
+        for tps.each {|t| enc_ty(w, cx, t); }
         w.write_char(']');
       }
       ty::ty_var(id) {
@@ -235,7 +238,7 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
       }
       ty::ty_self(tps) {
         w.write_str("s[");
-        for t in tps { enc_ty(w, cx, t); }
+        for tps.each {|t| enc_ty(w, cx, t); }
         w.write_char(']');
       }
       ty::ty_type { w.write_char('Y'); }
@@ -245,7 +248,7 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
       ty::ty_constr(ty, cs) {
         w.write_str("A[");
         enc_ty(w, cx, ty);
-        for tc: @ty::type_constr in cs { enc_ty_constr(w, cx, tc); }
+        for cs.each {|tc| enc_ty_constr(w, cx, tc); }
         w.write_char(']');
       }
       ty::ty_opaque_box { w.write_char('B'); }
@@ -257,7 +260,7 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
           w.write_str(s);
           #debug("~~~~ %s", "|");
           w.write_str("|");
-          for t: ty::t in tys { enc_ty(w, cx, t); }
+          for tys.each {|t| enc_ty(w, cx, t); }
           #debug("~~~~ %s", "]");
           w.write_char(']');
       }
@@ -285,13 +288,13 @@ fn enc_mode(w: io::writer, cx: @ctxt, m: mode) {
 
 fn enc_ty_fn(w: io::writer, cx: @ctxt, ft: ty::fn_ty) {
     w.write_char('[');
-    for arg: ty::arg in ft.inputs {
+    for ft.inputs.each {|arg|
         enc_mode(w, cx, arg.mode);
         enc_ty(w, cx, arg.ty);
     }
     w.write_char(']');
     let mut colon = true;
-    for c: @ty::constr in ft.constraints {
+    for ft.constraints.each {|c|
         if colon {
             w.write_char(':');
             colon = false;
@@ -311,7 +314,7 @@ fn enc_constr(w: io::writer, cx: @ctxt, c: @ty::constr) {
     w.write_str(cx.ds(c.node.id));
     w.write_char('|');
     let mut semi = false;
-    for a: @constr_arg in c.node.args {
+    for c.node.args.each {|a|
         if semi { w.write_char(';'); } else { semi = true; }
         alt a.node {
           carg_base { w.write_char('*'); }
@@ -328,7 +331,7 @@ fn enc_ty_constr(w: io::writer, cx: @ctxt, c: @ty::type_constr) {
     w.write_str(cx.ds(c.node.id));
     w.write_char('|');
     let mut semi = false;
-    for a: @ty::ty_constr_arg in c.node.args {
+    for c.node.args.each {|a|
         if semi { w.write_char(';'); } else { semi = true; }
         alt a.node {
           carg_base { w.write_char('*'); }
@@ -340,7 +343,7 @@ fn enc_ty_constr(w: io::writer, cx: @ctxt, c: @ty::type_constr) {
 }
 
 fn enc_bounds(w: io::writer, cx: @ctxt, bs: @[ty::param_bound]) {
-    for bound in *bs {
+    for vec::each(*bs) {|bound|
         alt bound {
           ty::bound_send { w.write_char('S'); }
           ty::bound_copy { w.write_char('C'); }
index 5ad5d42896f51142de360201cc14d5c35116d278..2dc09a9a60a58f590df498ef082bda6b0ed99f9a 100644 (file)
@@ -103,10 +103,6 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
         visit_expr(cx, f, sc, v);
       }
       ast::expr_alt(input, arms, _) { check_alt(*cx, input, arms, sc, v); }
-      ast::expr_for(decl, seq, blk) {
-        visit_expr(cx, seq, sc, v);
-        check_loop(*cx, sc) {|| check_for(*cx, decl, seq, blk, sc, v); }
-      }
       ast::expr_path(pt) {
         check_var(*cx, ex, pt, ex.id, false, sc);
         handled = false;
@@ -136,13 +132,13 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
 
 fn visit_block(cx: @ctx, b: ast::blk, sc: scope, v: vt<scope>) {
     let sc = sc;
-    for stmt in b.node.stmts {
+    for b.node.stmts.each {|stmt|
         alt stmt.node {
           ast::stmt_decl(@{node: ast::decl_item(it), _}, _) {
             v.visit_item(it, sc, v);
           }
           ast::stmt_decl(@{node: ast::decl_local(locs), _}, _) {
-            for loc in locs {
+            for locs.each {|loc|
                 alt loc.node.init {
                   some(init) {
                     if init.op == ast::init_move {
@@ -245,11 +241,11 @@ fn check_call(cx: @ctx, sc: scope, f: @ast::expr, args: [@ast::expr],
     };
     if f_may_close {
         let mut i = 0u;
-        for b in bindings {
+        for bindings.each {|b|
             let mut unsfe = vec::len(b.unsafe_tys) > 0u;
             alt b.root_var {
               some(rid) {
-                for o in sc.bs {
+                for sc.bs.each {|o|
                     if o.node_id == rid && vec::len(o.unsafe_tys) > 0u {
                         unsfe = true; break;
                     }
@@ -265,8 +261,8 @@ fn check_call(cx: @ctx, sc: scope, f: @ast::expr, args: [@ast::expr],
         }
     }
     let mut j = 0u;
-    for b in bindings {
-        for unsafe_ty in b.unsafe_tys {
+    for bindings.each {|b|
+        for b.unsafe_tys.each {|unsafe_ty|
             vec::iteri(arg_ts) {|i, arg_t|
                 let mut_alias =
                     (ast::by_mutbl_ref == ty::arg_mode(cx.tcx, arg_t));
@@ -288,13 +284,13 @@ fn check_call(cx: @ctx, sc: scope, f: @ast::expr, args: [@ast::expr],
     }
 
     // Ensure we're not passing a root by mut alias.
-    for {node: node, arg: arg} in mut_roots {
-        for b in bindings {
-            if b.node_id != arg.id {
+    for mut_roots.each {|mroot|
+        for bindings.each {|b|
+            if b.node_id != mroot.arg.id {
                 alt b.root_var {
                   some(root) {
-                    if node == root && cant_copy(*cx, b) {
-                        err(*cx, arg.span,
+                    if mroot.node == root && cant_copy(*cx, b) {
+                        err(*cx, mroot.arg.span,
                             "passing a mut reference to a \
                              variable that roots another reference");
                         break;
@@ -308,14 +304,14 @@ fn check_call(cx: @ctx, sc: scope, f: @ast::expr, args: [@ast::expr],
     // Check the bodies of block arguments against the current scope
     if blocks.len() > 0u {
         let inner_sc = {bs: bindings + sc.bs, invalid: sc.invalid};
-        for blk in blocks {
+        for blocks.each {|blk|
             alt check blk.node {
               ast::expr_fn_block(_, body) {
                 v.visit_block(body, inner_sc, v);
               }
             }
         }
-        for binding in bindings {
+        for bindings.each {|binding|
             test_scope(*cx, sc, binding, none);
         }
     }
@@ -327,7 +323,7 @@ fn check_alt(cx: ctx, input: @ast::expr, arms: [ast::arm], sc: scope,
     let orig_invalid = *sc.invalid;
     let mut all_invalid = orig_invalid;
     let root = expr_root(cx, input, true);
-    for a: ast::arm in arms {
+    for arms.each {|a|
         let mut new_bs = sc.bs;
         let root_var = path_def_id(cx, root.ex);
         let pat_id_map = pat_util::pat_id_map(cx.tcx.def_map, a.pats[0]);
@@ -336,8 +332,8 @@ fn check_alt(cx: ctx, input: @ast::expr, arms: [ast::arm], sc: scope,
             mut unsafe_tys: [unsafe_ty],
             span: span};
         let mut binding_info: [info] = [];
-        for pat in a.pats {
-            for proot in pattern_roots(cx.tcx, root.mutbl, pat) {
+        for a.pats.each {|pat|
+            for pattern_roots(cx.tcx, root.mutbl, pat).each {|proot|
                 let canon_id = pat_id_map.get(proot.name);
                 alt vec::find(binding_info, {|x| x.id == canon_id}) {
                   some(s) { s.unsafe_tys += unsafe_set(proot.mutbl); }
@@ -350,14 +346,14 @@ fn check_alt(cx: ctx, input: @ast::expr, arms: [ast::arm], sc: scope,
                 }
             }
         }
-        for info in binding_info {
+        for binding_info.each {|info|
             new_bs += [mk_binding(cx, info.id, info.span, root_var,
                                   copy info.unsafe_tys)];
-        }
+        };
         *sc.invalid = orig_invalid;
         visit::visit_arm(a, {bs: new_bs with sc}, v);
         all_invalid = join_invalid(all_invalid, *sc.invalid);
-    }
+    };
     *sc.invalid = all_invalid;
 }
 
@@ -378,7 +374,7 @@ fn check_for(cx: ctx, local: @ast::local, seq: @ast::expr, blk: ast::blk,
     }
     let root_var = path_def_id(cx, root.ex);
     let mut new_bs = sc.bs;
-    for proot in pattern_roots(cx.tcx, cur_mutbl, local.node.pat) {
+    for pattern_roots(cx.tcx, cur_mutbl, local.node.pat).each {|proot|
         new_bs += [mk_binding(cx, proot.id, proot.span, root_var,
                               unsafe_set(proot.mutbl))];
     }
@@ -392,10 +388,10 @@ fn check_var(cx: ctx, ex: @ast::expr, p: @ast::path, id: ast::node_id,
     let my_defnum = ast_util::def_id_of_def(def).node;
     let my_local_id = local_id_of_node(cx, my_defnum);
     let var_t = ty::expr_ty(cx.tcx, ex);
-    for b in sc.bs {
+    for sc.bs.each {|b|
         // excludes variables introduced since the alias was made
         if my_local_id < b.local_id {
-            for unsafe_ty in b.unsafe_tys {
+            for b.unsafe_tys.each {|unsafe_ty|
                 if ty_can_unsafely_include(cx, unsafe_ty, var_t, assign) {
                     let inv = @{reason: val_taken, node_id: b.node_id,
                                 sp: ex.span, path: p};
@@ -413,7 +409,7 @@ fn check_lval(cx: @ctx, dest: @ast::expr, sc: scope, v: vt<scope>) {
       ast::expr_path(p) {
         let def = cx.tcx.def_map.get(dest.id);
         let dnum = ast_util::def_id_of_def(def).node;
-        for b in sc.bs {
+        for sc.bs.each {|b|
             if b.root_var == some(dnum) {
                 let inv = @{reason: overwritten, node_id: b.node_id,
                             sp: dest.span, path: p};
@@ -454,7 +450,7 @@ fn test_scope(cx: ctx, sc: scope, b: binding, p: option<@ast::path>) {
     let mut prob = find_invalid(b.node_id, *sc.invalid);
     alt b.root_var {
       some(dn) {
-        for other in sc.bs {
+        for sc.bs.each {|other|
             if !is_none(prob) { break; }
             if other.node_id == dn {
                 prob = find_invalid(other.node_id, *sc.invalid);
@@ -507,7 +503,7 @@ fn helper(tcx: ty::ctxt, needle: unsafe_ty, haystack: ty::t, mutbl: bool)
         } { ret true; }
         alt ty::get(haystack).struct {
           ty::ty_enum(_, ts) {
-            for t: ty::t in ts {
+            for ts.each {|t|
                 if helper(tcx, needle, t, mutbl) { ret true; }
             }
             ret false;
@@ -516,7 +512,7 @@ fn helper(tcx: ty::ctxt, needle: unsafe_ty, haystack: ty::t, mutbl: bool)
             ret helper(tcx, needle, mt.ty, get_mutbl(mutbl, mt));
           }
           ty::ty_rec(fields) {
-            for f: ty::field in fields {
+            for fields.each {|f|
                 if helper(tcx, needle, f.mt.ty, get_mutbl(mutbl, f.mt)) {
                     ret true;
                 }
@@ -524,7 +520,7 @@ fn helper(tcx: ty::ctxt, needle: unsafe_ty, haystack: ty::t, mutbl: bool)
             ret false;
           }
           ty::ty_tup(ts) {
-            for t in ts { if helper(tcx, needle, t, mutbl) { ret true; } }
+            for ts.each {|t| if helper(tcx, needle, t, mutbl) { ret true; } }
             ret false;
           }
           ty::ty_fn({proto: ast::proto_bare, _}) { ret false; }
@@ -571,12 +567,12 @@ fn score_ty(tcx: ty::ctxt, ty: ty::t) -> uint {
           ty::ty_uniq(mt) { 1u + score_ty(tcx, mt.ty) }
           ty::ty_enum(_, ts) | ty::ty_tup(ts) {
             let mut sum = 0u;
-            for t in ts { sum += score_ty(tcx, t); }
+            for ts.each {|t| sum += score_ty(tcx, t); }
             sum
           }
           ty::ty_rec(fs) {
             let mut sum = 0u;
-            for f in fs { sum += score_ty(tcx, f.mt.ty); }
+            for fs.each {|f| sum += score_ty(tcx, f.mt.ty); }
             sum
           }
           _ {
@@ -608,11 +604,11 @@ fn walk(tcx: ty::ctxt, mutbl: option<unsafe_ty>, pat: @ast::pat,
           ast::pat_wild | ast::pat_lit(_) | ast::pat_range(_, _) |
           ast::pat_ident(_, _) {}
           ast::pat_enum(_, ps) | ast::pat_tup(ps) {
-            for p in ps { walk(tcx, mutbl, p, set); }
+            for ps.each {|p| walk(tcx, mutbl, p, set); }
           }
           ast::pat_rec(fs, _) {
             let ty = ty::node_id_to_type(tcx, pat.id);
-            for f in fs {
+            for fs.each {|f|
                 let m = ty::get_field(ty, f.ident).mt.mutbl != ast::m_imm,
                     c = if m { some(contains(ty)) } else { mutbl };
                 walk(tcx, c, f.pat, set);
@@ -649,7 +645,7 @@ fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool)
     -> {ex: @ast::expr, mutbl: option<unsafe_ty>} {
     let base_root = mutbl::expr_root_(cx.tcx, none, ex, autoderef);
     let mut unsafe_ty = none;
-    for d in *base_root.ds {
+    for vec::each(*base_root.ds) {|d|
         if d.mutbl { unsafe_ty = some(contains(d.outer_t)); break; }
     }
     ret {ex: base_root.ex, mutbl: unsafe_ty};
index 070787737a6f7bdd336ddbf322aeda2554bfb15f..46709abaa408a8f2d2725195611a6cde1d3b1d84 100644 (file)
@@ -115,7 +115,7 @@ fn map_decoded_item(sess: session, map: map, path: path, ii: inlined_item) {
 
 fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
           sp: codemap::span, id: node_id, cx: ctx, v: vt) {
-    for a in decl.inputs {
+    for decl.inputs.each {|a|
         cx.map.insert(a.id, node_arg(a, cx.local_id));
         cx.local_id += 1u;
     }
@@ -162,7 +162,7 @@ fn map_item(i: @item, cx: ctx, v: vt) {
     alt i.node {
       item_impl(_, _, _, ms) {
         let impl_did = ast_util::local_def(i.id);
-        for m in ms {
+        for ms.each {|m|
             map_method(impl_did, extend(cx, i.ident), m, cx);
         }
       }
@@ -171,7 +171,7 @@ fn map_item(i: @item, cx: ctx, v: vt) {
         cx.map.insert(dtor_id, node_item(i, item_path));
       }
       item_enum(vs, _) {
-        for v in vs {
+        for vs.each {|v|
             cx.map.insert(v.node.id, node_variant(
                 v, i, extend(cx, i.ident)));
         }
@@ -181,7 +181,7 @@ fn map_item(i: @item, cx: ctx, v: vt) {
           either::left(msg) { cx.sess.span_fatal(i.span, msg); }
           either::right(abi) { abi }
         };
-        for nitem in nm.items {
+        for nm.items.each {|nitem|
             cx.map.insert(nitem.id, node_native_item(nitem, abi, @cx.path));
         }
       }
@@ -189,7 +189,7 @@ fn map_item(i: @item, cx: ctx, v: vt) {
           cx.map.insert(ctor.node.id, node_ctor(i, item_path));
           let d_id = ast_util::local_def(i.id);
           let p = extend(cx, i.ident);
-          for ci in items {
+          for items.each {|ci|
            // only need to handle methods
            alt ci.node {
              class_method(m) { map_method(d_id, p, m, cx); }
@@ -212,7 +212,7 @@ fn map_item(i: @item, cx: ctx, v: vt) {
 fn map_view_item(vi: @view_item, cx: ctx, _v: vt) {
     alt vi.node {
       view_item_export(vps) {
-        for vp in vps {
+        for vps.each {|vp|
             let (id, name) = alt vp.node {
               view_path_simple(nm, _, id) { (id, nm) }
               view_path_glob(pth, id) | view_path_list(pth, _, id) {
index de14863368cfa850718377a20cec63a0d52b038e..d79568a5c5ddba93b2bd949d2a011851d9d8cf09 100644 (file)
@@ -27,7 +27,7 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
         cx.allow_block = true;
         v.visit_expr(f, cx, v);
         let mut i = 0u;
-        for arg_t in ty::ty_fn_args(ty::expr_ty(cx.tcx, f)) {
+        for ty::ty_fn_args(ty::expr_ty(cx.tcx, f)).each {|arg_t|
             cx.allow_block = (ty::arg_mode(cx.tcx, arg_t) == by_ref);
             v.visit_expr(args[i], cx, v);
             i += 1u;
index eacb5fef32ca28a859cd9641f41373ad83f4d018..6d5491a09eeb99cc7a0a8cafec9df6a6e529127d 100644 (file)
@@ -37,13 +37,13 @@ fn check_expr(tcx: ty::ctxt, ex: @expr, &&s: (), v: visit::vt<()>) {
 fn check_arms(tcx: ty::ctxt, arms: [arm]) {
     let mut i = 0;
     /* Check for unreachable patterns */
-    for arm: arm in arms {
-        for arm_pat: @pat in arm.pats {
+    for arms.each {|arm|
+        for arm.pats.each {|arm_pat|
             let mut reachable = true;
             let mut j = 0;
             while j < i {
                 if option::is_none(arms[j].guard) {
-                    for prev_pat: @pat in arms[j].pats {
+                    for vec::each(arms[j].pats) {|prev_pat|
                         if pattern_supersedes(tcx, prev_pat, arm_pat) {
                             reachable = false;
                         }
@@ -72,7 +72,7 @@ fn check_exhaustive(tcx: ty::ctxt, sp: span, pats: [@pat]) {
         ret;
     }
     // If there a non-refutable pattern in the set, we're okay.
-    for pat in pats { if !is_refutable(tcx, pat) { ret; } }
+    for pats.each {|pat| if !is_refutable(tcx, pat) { ret; } }
 
     alt ty::get(ty::node_id_to_type(tcx, pats[0].id)).struct {
       ty::ty_enum(id, _) {
@@ -90,7 +90,7 @@ fn check_exhaustive(tcx: ty::ctxt, sp: span, pats: [@pat]) {
       }
       ty::ty_tup(ts) {
         let cols = vec::to_mut(vec::from_elem(ts.len(), []));
-        for p in pats {
+        for pats.each {|p|
             alt raw_pat(p).node {
               pat_tup(sub) {
                 vec::iteri(sub) {|i, sp| cols[i] += [sp];}
@@ -103,7 +103,7 @@ fn check_exhaustive(tcx: ty::ctxt, sp: span, pats: [@pat]) {
       ty::ty_rec(fs) {
         let cols = vec::from_elem(fs.len(), {mut wild: false,
                                             mut pats: []});
-        for p in pats {
+        for pats.each {|p|
             alt raw_pat(p).node {
               pat_rec(sub, _) {
                 vec::iteri(fs) {|i, field|
@@ -122,7 +122,7 @@ fn check_exhaustive(tcx: ty::ctxt, sp: span, pats: [@pat]) {
       }
       ty::ty_bool {
         let mut saw_true = false, saw_false = false;
-        for p in pats {
+        for pats.each {|p|
             alt raw_pat(p).node {
               pat_lit(@{node: expr_lit(@{node: lit_bool(b), _}), _}) {
                 if b { saw_true = true; }
@@ -160,7 +160,7 @@ fn check_exhaustive_enum(tcx: ty::ctxt, enum_id: def_id, sp: span,
          cols: vec::to_mut(vec::from_elem(v.args.len(), []))}
     });
 
-    for pat in pats {
+    for pats.each {|pat|
         let pat = raw_pat(pat);
         alt tcx.def_map.get(pat.id) {
           def_variant(_, id) {
@@ -193,7 +193,7 @@ fn check_exhaustive_enum(tcx: ty::ctxt, enum_id: def_id, sp: span,
 fn pattern_supersedes(tcx: ty::ctxt, a: @pat, b: @pat) -> bool {
     fn patterns_supersede(tcx: ty::ctxt, as: [@pat], bs: [@pat]) -> bool {
         let mut i = 0;
-        for a: @pat in as {
+        for as.each {|a|
             if !pattern_supersedes(tcx, a, bs[i]) { ret false; }
             i += 1;
         }
@@ -202,9 +202,9 @@ fn patterns_supersede(tcx: ty::ctxt, as: [@pat], bs: [@pat]) -> bool {
     fn field_patterns_supersede(tcx: ty::ctxt, fas: [field_pat],
                                 fbs: [field_pat]) -> bool {
         let wild = @{id: 0, node: pat_wild, span: dummy_sp()};
-        for fa: field_pat in fas {
+        for fas.each {|fa|
             let mut pb = wild;
-            for fb: field_pat in fbs {
+            for fbs.each {|fb|
                 if fa.ident == fb.ident { pb = fb.pat; }
             }
             if !pattern_supersedes(tcx, fa.pat, pb) { ret false; }
@@ -301,17 +301,17 @@ fn is_refutable(tcx: ty::ctxt, pat: @pat) -> bool {
       pat_wild | pat_ident(_, none) { false }
       pat_lit(_) | pat_range(_, _) { true }
       pat_rec(fields, _) {
-        for it: field_pat in fields {
+        for fields.each {|it|
             if is_refutable(tcx, it.pat) { ret true; }
         }
         false
       }
       pat_tup(elts) {
-        for elt in elts { if is_refutable(tcx, elt) { ret true; } }
+        for elts.each {|elt| if is_refutable(tcx, elt) { ret true; } }
         false
       }
       pat_enum(_, args) {
-        for p: @pat in args { if is_refutable(tcx, p) { ret true; } }
+        for args.each {|p| if is_refutable(tcx, p) { ret true; } }
         false
       }
     }
index 29a1864c024f38a1cf5d679ac7abeab595044b1d..26e6c2bc4698f3fb46b11bb17d35e204a213314d 100644 (file)
@@ -23,8 +23,8 @@ fn check_item(sess: session, ast_map: ast_map::map, def_map: resolve::def_map,
         check_item_recursion(sess, ast_map, def_map, it);
       }
       item_enum(vs, _) {
-        for var in vs {
-            option::with_option_do(var.node.disr_expr) {|ex|
+        for vs.each {|var|
+            option::iter(var.node.disr_expr) {|ex|
                 v.visit_expr(ex, true, v);
             }
         }
index 4d69154aac8415ffc7eba804692947914602ba41..5082aba13948566b05d472bc68bb0ad39569684a 100644 (file)
@@ -11,7 +11,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
         },
         visit_expr: {|e: @expr, cx: ctx, v: visit::vt<ctx>|
             alt e.node {
-              expr_for(_, e, b) | expr_while(e, b) | expr_do_while(b, e) {
+              expr_while(e, b) | expr_do_while(b, e) {
                 v.visit_expr(e, cx, v);
                 v.visit_block(b, {in_loop: true with cx}, v);
               }
index 332b316b986dd097ab736304f16567d09294db28..6d710db5f2a63e0575e5659cb65d8b40defcf2ba 100644 (file)
@@ -59,7 +59,7 @@ fn fn_usage_expr(expr: @ast::expr,
 
         let args_ctx = {unsafe_fn_legal: false,
                         generic_bare_fn_legal: false with ctx};
-        for arg in args {
+        for args.each {|arg|
             visit::visit_expr_opt(arg, args_ctx, v);
         }
       }
index 035da0d477b666469540107524febf8d53e358da..aac422dbca7ebe074f8ce0e594ac1a69e417ad5f 100644 (file)
@@ -9,6 +9,7 @@
 import result::{result, extensions, ok, err, map, map2, iter2};
 import ty::type_is_bot;
 import driver::session::session;
+import util::common::{indent, indenter};
 
 export infer_ctxt;
 export new_infer_ctxt;
@@ -66,27 +67,18 @@ fn new_infer_ctxt(tcx: ty::ctxt) -> infer_ctxt {
 }
 
 fn mk_subty(cx: infer_ctxt, a: ty::t, b: ty::t) -> ures {
-    #debug[">> mk_subty(%s <: %s)", a.to_str(cx), b.to_str(cx)];
-    cx.commit {||
-        cx.tys(a, b)
-    }
+    #debug["mk_subty(%s <: %s)", a.to_str(cx), b.to_str(cx)];
+    indent {|| cx.commit {|| sub(cx).tys(a, b) } }.to_ures()
 }
 
 fn mk_eqty(cx: infer_ctxt, a: ty::t, b: ty::t) -> ures {
-    #debug[">> mk_eqty(%s <: %s)", a.to_str(cx), b.to_str(cx)];
-    cx.commit {||
-        cx.eq_tys(a, b)
-    }
+    #debug["mk_eqty(%s <: %s)", a.to_str(cx), b.to_str(cx)];
+    indent {|| cx.commit {|| cx.eq_tys(a, b) } }.to_ures()
 }
 
 fn compare_tys(tcx: ty::ctxt, a: ty::t, b: ty::t) -> ures {
     let infcx = new_infer_ctxt(tcx);
-    #debug[">> compare_tys(%s == %s)", a.to_str(infcx), b.to_str(infcx)];
-    infcx.commit {||
-        mk_subty(infcx, a, b).then {||
-            mk_subty(infcx, b, a)
-        }
-    }
+    mk_eqty(infcx, a, b)
 }
 
 fn resolve_type_structure(cx: infer_ctxt, a: ty::t) -> fres<ty::t> {
@@ -108,6 +100,25 @@ fn then<T:copy>(f: fn() -> result<T,ty::type_err>)
     }
 }
 
+impl methods<T:copy> for cres<T> {
+    fn to_ures() -> ures {
+        alt self {
+          ok(_v) { ok(()) }
+          err(e) { err(e) }
+        }
+    }
+
+    fn compare(t: T, f: fn() -> ty::type_err) -> cres<T> {
+        self.chain {|s|
+            if s == t {
+                self
+            } else {
+                err(f())
+            }
+        }
+    }
+}
+
 iface to_str {
     fn to_str(cx: infer_ctxt) -> str;
 }
@@ -157,36 +168,36 @@ fn to_str(cx: infer_ctxt) -> str {
 }
 
 iface st {
-    fn st(infcx: infer_ctxt, b: self) -> ures;
+    fn sub(infcx: infer_ctxt, b: self) -> ures;
     fn lub(infcx: infer_ctxt, b: self) -> cres<self>;
     fn glb(infcx: infer_ctxt, b: self) -> cres<self>;
 }
 
 impl of st for ty::t {
-    fn st(infcx: infer_ctxt, b: ty::t) -> ures {
-        infcx.tys(self, b)
+    fn sub(infcx: infer_ctxt, b: ty::t) -> ures {
+        sub(infcx).tys(self, b).to_ures()
     }
 
     fn lub(infcx: infer_ctxt, b: ty::t) -> cres<ty::t> {
-        lub(infcx).c_tys(self, b)
+        lub(infcx).tys(self, b)
     }
 
     fn glb(infcx: infer_ctxt, b: ty::t) -> cres<ty::t> {
-        glb(infcx).c_tys(self, b)
+        glb(infcx).tys(self, b)
     }
 }
 
 impl of st for ty::region {
-    fn st(infcx: infer_ctxt, b: ty::region) -> ures {
-        infcx.regions(self, b)
+    fn sub(infcx: infer_ctxt, b: ty::region) -> ures {
+        sub(infcx).regions(self, b).chain {|_r| ok(()) }
     }
 
     fn lub(infcx: infer_ctxt, b: ty::region) -> cres<ty::region> {
-        lub(infcx).c_regions(self, b)
+        lub(infcx).regions(self, b)
     }
 
     fn glb(infcx: infer_ctxt, b: ty::region) -> cres<ty::region> {
-        glb(infcx).c_regions(self, b)
+        glb(infcx).regions(self, b)
     }
 }
 
@@ -201,7 +212,6 @@ fn glb(infcx: infer_ctxt, b: ty::region) -> cres<ty::region> {
 // the old range).  They therefore return a result.
 impl unify_methods for infer_ctxt {
     fn uok() -> ures {
-        #debug["Unification OK"];
         ok(())
     }
 
@@ -226,24 +236,22 @@ fn set_ty(vid: ty_vid, +new_v: var_value<ty_vid, ty::t>) {
         self.set(self.vb, vid, new_v);
     }
 
-    fn commit<T:copy,E:copy>(f: fn() -> result<T,E>) -> result<T,E> {
+    fn commit<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
 
         assert self.vb.bindings.len() == 0u;
         assert self.rb.bindings.len() == 0u;
 
-        let r = self.try(f);
+        let r <- self.try(f);
 
         // TODO---could use a vec::clear() that ran destructors but kept
         // the vec at its currently allocated length
         self.vb.bindings = [];
         self.rb.bindings = [];
 
-        #debug[">> Commit result: %?", r];
-
         ret r;
     }
 
-    fn try<T:copy,E:copy>(f: fn() -> result<T,E>) -> result<T,E> {
+    fn try<T,E>(f: fn() -> result<T,E>) -> result<T,E> {
 
         fn rollback_to<V:copy vid, T:copy>(
             vb: vals_and_bindings<V, T>, len: uint) {
@@ -257,7 +265,7 @@ fn rollback_to<V:copy vid, T:copy>(
         let vbl = self.vb.bindings.len();
         let rbl = self.rb.bindings.len();
         #debug["try(vbl=%u, rbl=%u)", vbl, rbl];
-        let r = f();
+        let r <- f();
         alt r {
           result::ok(_) { #debug["try--ok"]; }
           result::err(_) {
@@ -292,23 +300,14 @@ fn get<V:copy vid, T:copy>(
         }
     }
 
-    fn get_var(vid: ty_vid)
-        -> {root: ty_vid, bounds:bounds<ty::t>} {
-
-        ret self.get(self.vb, vid);
-    }
-
-    fn get_region(rid: region_vid)
-        -> {root: region_vid, bounds:bounds<ty::region>} {
-
-        ret self.get(self.rb, rid);
-    }
-
     // Combines the two bounds into a more general bound.
     fn merge_bnd<V:copy to_str>(
         a: bound<V>, b: bound<V>,
         merge_op: fn(V,V) -> cres<V>) -> cres<bound<V>> {
 
+        #debug["merge_bnd(%s,%s)", a.to_str(self), b.to_str(self)];
+        let _r = indenter();
+
         alt (a, b) {
           (none, none) {
             ok(none)
@@ -332,6 +331,7 @@ fn merge_bnds<V:copy to_str>(
         lub: fn(V,V) -> cres<V>,
         glb: fn(V,V) -> cres<V>) -> cres<bounds<V>> {
 
+        let _r = indenter();
         self.merge_bnd(a.ub, b.ub, glb).chain {|ub|
             #debug["glb of ubs %s and %s is %s",
                    a.ub.to_str(self), b.ub.to_str(self),
@@ -383,6 +383,7 @@ fn set_var_to_merged_bounds<V:copy vid, T:copy to_str st>(
         // them explicitly gives the type inferencer more
         // information and helps to produce tighter bounds
         // when necessary.
+        indent {||
         self.bnds(a.lb, b.ub).then {||
         self.bnds(b.lb, a.ub).then {||
         self.merge_bnd(a.ub, b.ub, {|x, y| x.glb(self, y)}).chain {|ub|
@@ -395,10 +396,10 @@ fn set_var_to_merged_bounds<V:copy vid, T:copy to_str st>(
             // the new bounds must themselves
             // be relatable:
             self.bnds(bnds.lb, bnds.ub).then {||
-            self.set(vb, v_id, bounded(bnds));
-            self.uok()
+                self.set(vb, v_id, bounded(bnds));
+                self.uok()
             }
-        }}}}
+        }}}}}
     }
 
     fn vars<V:copy vid, T:copy to_str st>(
@@ -419,7 +420,7 @@ fn vars<V:copy vid, T:copy to_str st>(
         // see if we can make those types subtypes.
         alt (a_bounds.ub, b_bounds.lb) {
           (some(a_ub), some(b_lb)) {
-            let r = self.try {|| a_ub.st(self, b_lb) };
+            let r = self.try {|| a_ub.sub(self, b_lb) };
             alt r {
               ok(()) { ret result::ok(()); }
               err(_) { /*fallthrough */ }
@@ -464,149 +465,6 @@ fn tvar<V: copy vid, T: copy to_str st>(
         self.set_var_to_merged_bounds(vb, b_id, a_bounds, b_bounds)
     }
 
-    fn regions(a: ty::region, b: ty::region) -> ures {
-        alt (a, b) { // XXX
-          (ty::re_var(a_id), ty::re_var(b_id)) {
-            self.vars(self.rb, a_id, b_id)
-          }
-          (ty::re_var(a_id), _) {
-            self.vart(self.rb, a_id, b)
-          }
-          (_, ty::re_var(b_id)) {
-            self.tvar(self.rb, a, b_id)
-          }
-
-          (ty::re_free(a_id, _), ty::re_scope(b_id)) |
-          (ty::re_scope(a_id), ty::re_free(b_id, _)) |
-          (ty::re_scope(a_id), ty::re_scope(b_id)) {
-            let rm = self.tcx.region_map;
-            alt region::nearest_common_ancestor(rm, a_id, b_id) {
-              some(r_id) if r_id == a_id { self.uok() }
-              _ { err(ty::terr_regions_differ(false, b, a)) }
-            }
-          }
-
-          // For these types, we cannot define any additional relationship:
-          (ty::re_free(_, _), ty::re_free(_, _)) |
-          (ty::re_bound(_), ty::re_bound(_)) |
-          (ty::re_bound(_), ty::re_free(_, _)) |
-          (ty::re_bound(_), ty::re_scope(_)) |
-          (ty::re_free(_, _), ty::re_bound(_)) |
-          (ty::re_scope(_), ty::re_bound(_)) {
-            if a == b {
-                self.uok()
-            } else {
-                err(ty::terr_regions_differ(false, b, a))
-            }
-          }
-
-          (ty::re_default, _) |
-          (_, ty::re_default) {
-            // actually a compiler bug, I think.
-            err(ty::terr_regions_differ(false, b, a))
-          }
-        }
-    }
-
-    fn mts(a: ty::mt, b: ty::mt) -> ures {
-        #debug("mts(%s <: %s)", a.to_str(self), b.to_str(self));
-
-        if a.mutbl != b.mutbl && b.mutbl != ast::m_const {
-            ret self.uerr(ty::terr_mutability);
-        }
-
-        alt b.mutbl {
-          ast::m_mutbl {
-            // If supertype is mut, subtype must match exactly
-            // (i.e., invariant if mut):
-            self.eq_tys(a.ty, b.ty)
-          }
-          ast::m_imm | ast::m_const {
-            // Otherwise we can be covariant:
-            self.tys(a.ty, b.ty)
-          }
-        }
-    }
-
-    fn flds(a: ty::field, b: ty::field) -> ures {
-        if a.ident != b.ident {
-            ret self.uerr(ty::terr_record_fields(a.ident, b.ident));
-        }
-        self.mts(a.mt, b.mt)
-    }
-
-    fn tps(as: [ty::t], bs: [ty::t]) -> ures {
-        if check vec::same_length(as, bs) {
-            iter2(as, bs) {|a, b| self.tys(a, b) }
-        } else {
-            self.uerr(ty::terr_ty_param_size(as.len(), bs.len()))
-        }
-    }
-
-    fn protos(a: ast::proto, b: ast::proto) -> ures {
-        alt (a, b) {
-          (_, ast::proto_any) { self.uok() }
-          (ast::proto_bare, _) { self.uok() }
-          (_, _) if a == b { self.uok() }
-          _ { self.uerr(ty::terr_proto_mismatch(a, b)) }
-        }
-    }
-
-    fn ret_styles(
-        a_ret_style: ret_style,
-        b_ret_style: ret_style) -> ures {
-
-        if b_ret_style != ast::noreturn && b_ret_style != a_ret_style {
-            /* even though typestate checking is mostly
-               responsible for checking control flow annotations,
-               this check is necessary to ensure that the
-               annotation in an object method matches the
-               declared object type */
-            self.uerr(ty::terr_ret_style_mismatch(a_ret_style, b_ret_style))
-        } else {
-            self.uok()
-        }
-    }
-
-    fn modes(a: ast::mode, b: ast::mode) -> ures {
-        alt ty::unify_mode(self.tcx, a, b) {
-          ok(_) { self.uok() }
-          err(e) { self.uerr(e) }
-        }
-    }
-
-    fn args(a: ty::arg, b: ty::arg) -> ures {
-        self.modes(a.mode, b.mode).then {||
-            self.tys(b.ty, a.ty) // Note: contravariant
-        }
-    }
-
-    fn argvecs(
-        a_args: [ty::arg],
-        b_args: [ty::arg]) -> ures {
-
-        if check vec::same_length(a_args, b_args) {
-            iter2(a_args, b_args) {|a, b| self.args(a, b) }
-        } else {
-            ret self.uerr(ty::terr_arg_count);
-        }
-    }
-
-    fn fns(a_f: ty::fn_ty, b_f: ty::fn_ty) -> ures {
-        self.protos(a_f.proto, b_f.proto).then {||
-            self.ret_styles(a_f.ret_style, b_f.ret_style).then {||
-                self.argvecs(a_f.inputs, b_f.inputs).then {||
-                    self.tys(a_f.output, b_f.output).then {||
-                        //TODO self.constrvecs(a_f.constraints,
-                        //TODO                 b_f.constraints).then {||
-                            self.uok()
-                        //TODO }
-                    }
-                }
-            }
-        }
-    }
-
     fn constrs(
         expected: @ty::type_constr,
         actual_constr: @ty::type_constr) -> ures {
@@ -619,7 +477,7 @@ fn constrs(
         let actual_arg_len = vec::len(actual_constr.node.args);
         if expected_arg_len != actual_arg_len { ret err_res; }
         let mut i = 0u;
-        for a in expected.node.args {
+        for expected.node.args.each {|a|
             let actual = actual_constr.node.args[i];
             alt a.node {
               ast::carg_base {
@@ -654,16 +512,17 @@ fn bnds<T:copy to_str st>(
         a: bound<T>, b: bound<T>) -> ures {
 
         #debug("bnds(%s <: %s)", a.to_str(self), b.to_str(self));
-
-        alt (a, b) {
-          (none, none) |
-          (some(_), none) |
-          (none, some(_)) {
-            self.uok()
-          }
-          (some(t_a), some(t_b)) {
-            t_a.st(self, t_b)
-          }
+        indent {||
+            alt (a, b) {
+              (none, none) |
+              (some(_), none) |
+              (none, some(_)) {
+                self.uok()
+              }
+              (some(t_a), some(t_b)) {
+                t_a.sub(self, t_b)
+              }
+            }
         }
     }
 
@@ -675,113 +534,17 @@ fn constrvecs(
                 self.constrs(a, b)
             }
         } else {
-            self.uerr(ty::terr_constr_len(as.len(), bs.len()))
+            self.uerr(ty::terr_constr_len(bs.len(), as.len()))
         }
     }
 
-    fn eq_tys(a: ty::t, b: ty::t) -> ures {
-        self.tys(a, b).then {||
-            self.tys(b, a)
-        }
+    fn sub_tys(a: ty::t, b: ty::t) -> ures {
+        sub(self).tys(a, b).chain {|_t| ok(()) }
     }
 
-    fn tys(a: ty::t, b: ty::t) -> ures {
-        #debug("tys(%s <: %s)",
-               ty_to_str(self.tcx, a),
-               ty_to_str(self.tcx, b));
-
-        // Fast path.
-        if a == b { ret self.uok(); }
-
-        alt (ty::get(a).struct, ty::get(b).struct) {
-          (ty::ty_bot, _) { self.uok() }
-
-          (ty::ty_var(a_id), ty::ty_var(b_id)) {
-            self.vars(self.vb, a_id, b_id)
-          }
-          (ty::ty_var(a_id), _) {
-            self.vart(self.vb, a_id, b)
-          }
-          (_, ty::ty_var(b_id)) {
-            self.tvar(self.vb, a, b_id)
-          }
-
-          (ty::ty_nil, _) |
-          (ty::ty_bool, _) |
-          (ty::ty_int(_), _) |
-          (ty::ty_uint(_), _) |
-          (ty::ty_float(_), _) |
-          (ty::ty_str, _) {
-            let cfg = self.tcx.sess.targ_cfg;
-            if ty::mach_sty(cfg, a) == ty::mach_sty(cfg, b) {
-                self.uok()
-            } else {
-                self.uerr(ty::terr_mismatch)
-            }
-          }
-
-          (ty::ty_param(a_n, _), ty::ty_param(b_n, _))
-          if a_n == b_n {
-            self.uok()
-          }
-
-          (ty::ty_enum(a_id, a_tps), ty::ty_enum(b_id, b_tps)) |
-          (ty::ty_iface(a_id, a_tps), ty::ty_iface(b_id, b_tps)) |
-          (ty::ty_class(a_id, a_tps), ty::ty_class(b_id, b_tps))
-          if a_id == b_id {
-            self.tps(a_tps, b_tps)
-          }
-
-          (ty::ty_box(a_mt), ty::ty_box(b_mt)) |
-          (ty::ty_uniq(a_mt), ty::ty_uniq(b_mt)) |
-          (ty::ty_vec(a_mt), ty::ty_vec(b_mt)) |
-          (ty::ty_ptr(a_mt), ty::ty_ptr(b_mt)) {
-            self.mts(a_mt, b_mt)
-          }
-
-          (ty::ty_rptr(a_r, a_mt), ty::ty_rptr(b_r, b_mt)) {
-            self.mts(a_mt, b_mt).then {||
-                self.regions(a_r, b_r)
-            }
-          }
-
-          (ty::ty_res(a_id, a_t, a_tps), ty::ty_res(b_id, b_t, b_tps))
-          if a_id == b_id {
-            self.tys(a_t, b_t).then {||
-                self.tps(a_tps, b_tps)
-            }
-          }
-
-          (ty::ty_rec(a_fields), ty::ty_rec(b_fields)) {
-            if check vec::same_length(a_fields, b_fields) {
-                iter2(a_fields, b_fields) {|a,b|
-                    self.flds(a, b)
-                }
-            } else {
-                ret self.uerr(ty::terr_record_size(a_fields.len(),
-                                             b_fields.len()));
-            }
-          }
-
-          (ty::ty_tup(a_tys), ty::ty_tup(b_tys)) {
-            if check vec::same_length(a_tys, b_tys) {
-                iter2(a_tys, b_tys) {|a,b| self.tys(a,b) }
-            } else {
-                self.uerr(ty::terr_tuple_size(a_tys.len(), b_tys.len()))
-            }
-          }
-
-          (ty::ty_fn(a_fty), ty::ty_fn(b_fty)) {
-            self.fns(a_fty, b_fty)
-          }
-
-          (ty::ty_constr(a_t, a_constrs), ty::ty_constr(b_t, b_constrs)) {
-            self.tys(a_t, b_t).then {||
-                self.constrvecs(a_constrs, b_constrs)
-            }
-          }
-
-          _ { self.uerr(ty::terr_mismatch) }
+    fn eq_tys(a: ty::t, b: ty::t) -> ures {
+        self.sub_tys(a, b).then {||
+            self.sub_tys(b, a)
         }
     }
 }
@@ -943,7 +706,7 @@ fn fixup_ty(typ: ty::t) -> fres<ty::t> {
 //
 // The `c_X()` top-level items work for *both LUB and GLB*: any
 // operation which varies between LUB and GLB will be dynamically
-// dispatched using a `self.c_Y()` operation.
+// dispatched using a `self.Y()` operation.
 //
 // In principle, the subtyping relation computed above could be built
 // on the combine framework---this would result in less code but would
@@ -958,180 +721,91 @@ fn fixup_ty(typ: ty::t) -> fres<ty::t> {
 iface combine {
     fn infcx() -> infer_ctxt;
     fn tag() -> str;
-    fn bnd<V:copy>(b: bounds<V>) -> option<V>;
-    fn with_bnd<V:copy>(b: bounds<V>, v: V) -> bounds<V>;
-    fn c_bot(b: ty::t) -> cres<ty::t>;
-    fn c_mts(a: ty::mt, b: ty::mt) -> cres<ty::mt>;
-    fn c_contratys(t1: ty::t, t2: ty::t) -> cres<ty::t>;
-    fn c_tys(t1: ty::t, t2: ty::t) -> cres<ty::t>;
-    fn c_protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto>;
-    fn c_ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style>;
-
-    // Combining regions (along with some specific cases that are
-    // different for LUB/GLB):
-    fn c_regions(
-        a: ty::region, b: ty::region) -> cres<ty::region>;
-    fn c_regions_scope_scope(
-        a: ty::region, a_id: ast::node_id,
-        b: ty::region, b_id: ast::node_id) -> cres<ty::region>;
-    fn c_regions_free_scope(
-        a: ty::region, a_id: ast::node_id, a_br: ty::bound_region,
-        b: ty::region, b_id: ast::node_id) -> cres<ty::region>;
-}
-
-enum lub = infer_ctxt;
-enum glb = infer_ctxt;
-
-fn c_vars<V:copy vid, C:combine, T:copy to_str st>(
-    self: C, vb: vals_and_bindings<V, T>,
-    a_t: T, a_vid: V, b_vid: V,
-    c_ts: fn(T, T) -> cres<T>) -> cres<T> {
-
-    // The comments in this function are written for LUB and types,
-    // but they apply equally well to GLB and regions if you inverse
-    // upper/lower/sub/super/etc.
-
-    // Need to find a type that is a supertype of both a and b:
-    let {root: a_vid, bounds: a_bounds} = self.infcx().get(vb, a_vid);
-    let {root: b_vid, bounds: b_bounds} = self.infcx().get(vb, b_vid);
-
-    #debug["%s.c_vars(%s=%s <: %s=%s)",
-           self.tag(),
-           a_vid.to_str(), a_bounds.to_str(self.infcx()),
-           b_vid.to_str(), b_bounds.to_str(self.infcx())];
-
-    if a_vid == b_vid {
-        ret ok(a_t);
-    }
 
-    // If both A and B have an UB type, then we can just compute the
-    // LUB of those types:
-    let a_bnd = self.bnd(a_bounds), b_bnd = self.bnd(b_bounds);
-    alt (a_bnd, b_bnd) {
-      (some(a_ty), some(b_ty)) {
-        alt self.infcx().try {|| c_ts(a_ty, b_ty) } {
-            ok(t) { ret ok(t); }
-            err(_) { /*fallthrough */ }
-        }
-      }
-      _ {/*fallthrough*/}
-    }
-
-    // Otherwise, we need to merge A and B into one variable.  We can
-    // then use either variable as an upper bound:
-    self.infcx().vars(vb, a_vid, b_vid).then {||
-        ok(a_t)
-    }
+    fn mts(a: ty::mt, b: ty::mt) -> cres<ty::mt>;
+    fn contratys(a: ty::t, b: ty::t) -> cres<ty::t>;
+    fn tys(a: ty::t, b: ty::t) -> cres<ty::t>;
+    fn tps(as: [ty::t], bs: [ty::t]) -> cres<[ty::t]>;
+    fn fns(a: ty::fn_ty, b: ty::fn_ty) -> cres<ty::fn_ty>;
+    fn flds(a: ty::field, b: ty::field) -> cres<ty::field>;
+    fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode>;
+    fn args(a: ty::arg, b: ty::arg) -> cres<ty::arg>;
+    fn protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto>;
+    fn ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style>;
+    fn contraregions(a: ty::region, b: ty::region) -> cres<ty::region>;
+    fn regions(a: ty::region, b: ty::region) -> cres<ty::region>;
 }
 
-fn c_var_t<V:copy vid, C:combine, T:copy to_str st>(
-    self: C, vb: vals_and_bindings<V, T>,
-    a_vid: V, b: T,
-    c_ts: fn(T, T) -> cres<T>) -> cres<T> {
+enum sub = infer_ctxt;  // "less than" == "subtype" or "subregion"
+enum lub = infer_ctxt;  // "least upper bound" (common supertype)
+enum glb = infer_ctxt;  // "greatest lower bound" (common subtype)
 
-    let {root: a_id, bounds: a_bounds} = self.infcx().get(vb, a_vid);
-
-    // The comments in this function are written for LUB, but they
-    // apply equally well to GLB if you inverse upper/lower/sub/super/etc.
-
-    #debug["%s.c_var_ty(%s=%s <: %s)",
-           self.tag(),
-           a_id.to_str(), a_bounds.to_str(self.infcx()),
-           b.to_str(self.infcx())];
-
-    alt self.bnd(a_bounds) {
-      some(a_bnd) {
-        // If a has an upper bound, return it.
-        ret c_ts(a_bnd, b);
-      }
-      none {
-        // If a does not have an upper bound, make b the upper bound of a
-        // and then return b.
-        let a_bounds = self.with_bnd(a_bounds, b);
-        self.infcx().bnds(a_bounds.lb, a_bounds.ub).then {||
-            self.infcx().set(vb, a_id, bounded(a_bounds));
-            ok(b)
-        }
-      }
-    }
-}
-
-fn c_tuptys<C:combine>(self: C, as: [ty::t], bs: [ty::t])
-    -> cres<[ty::t]> {
+fn super_tps<C:combine>(
+    self: C, as: [ty::t], bs: [ty::t]) -> cres<[ty::t]> {
 
+    // Note: type parameters are always treated as *invariant*
+    // (otherwise the type system would be unsound).  In the
+    // future we could allow type parameters to declare a
+    // variance.
     if check vec::same_length(as, bs) {
-        map2(as, bs) {|a, b| self.c_tys(a, b) }
-    } else {
-        err(ty::terr_tuple_size(as.len(), bs.len()))
-    }
-}
-
-fn c_tps<C:combine>(self: C, _did: ast::def_id, as: [ty::t], bs: [ty::t])
-    -> cres<[ty::t]> {
-    // FIXME #1973 lookup the declared variance of the type parameters
-    // based on did
-    if check vec::same_length(as, bs) {
-        map2(as, bs) {|a,b| self.c_tys(a, b) }
+        iter2(as, bs) {|a, b| self.infcx().eq_tys(a, b) }.then {||
+            ok(as)
+        }
     } else {
-        err(ty::terr_ty_param_size(as.len(), bs.len()))
+        err(ty::terr_ty_param_size(bs.len(), as.len()))
     }
 }
 
-fn c_fieldvecs<C:combine>(self: C, as: [ty::field], bs: [ty::field])
-    -> cres<[ty::field]> {
-
-    if check vec::same_length(as, bs) {
-        map2(as, bs) {|a,b| c_flds(self, a, b) }
-    } else {
-        err(ty::terr_record_size(as.len(), bs.len()))
-    }
-}
+fn super_flds<C:combine>(
+    self: C, a: ty::field, b: ty::field) -> cres<ty::field> {
 
-fn c_flds<C:combine>(self: C, a: ty::field, b: ty::field) -> cres<ty::field> {
     if a.ident == b.ident {
-        self.c_mts(a.mt, b.mt).chain {|mt|
+        self.mts(a.mt, b.mt).chain {|mt|
             ok({ident: a.ident, mt: mt})
+        }.chain_err {|e|
+            err(ty::terr_in_field(@e, a.ident))
         }
     } else {
-        err(ty::terr_record_fields(a.ident, b.ident))
+        err(ty::terr_record_fields(b.ident, a.ident))
     }
 }
 
-fn c_modes<C:combine>(self: C, a: ast::mode, b: ast::mode)
+fn super_modes<C:combine>(
+    self: C, a: ast::mode, b: ast::mode)
     -> cres<ast::mode> {
 
     let tcx = self.infcx().tcx;
     ty::unify_mode(tcx, a, b)
 }
 
-fn c_args<C:combine>(self: C, a: ty::arg, b: ty::arg)
+fn super_args<C:combine>(
+    self: C, a: ty::arg, b: ty::arg)
     -> cres<ty::arg> {
 
-    c_modes(self, a.mode, b.mode).chain {|m|
-        // Note: contravariant
-        self.c_contratys(b.ty, a.ty).chain {|t|
+    self.modes(a.mode, b.mode).chain {|m|
+        self.contratys(a.ty, b.ty).chain {|t|
             ok({mode: m, ty: t})
         }
     }
 }
 
-fn c_argvecs<C:combine>(
-    self: C, a_args: [ty::arg], b_args: [ty::arg]) -> cres<[ty::arg]> {
+fn super_fns<C:combine>(
+    self: C, a_f: ty::fn_ty, b_f: ty::fn_ty) -> cres<ty::fn_ty> {
 
-    if check vec::same_length(a_args, b_args) {
-        map2(a_args, b_args) {|a, b| c_args(self, a, b) }
-    } else {
-        err(ty::terr_arg_count)
-    }
-}
+    fn argvecs<C:combine>(
+        self: C, a_args: [ty::arg], b_args: [ty::arg]) -> cres<[ty::arg]> {
 
-fn c_fns<C:combine>(
-    self: C, a_f: ty::fn_ty, b_f: ty::fn_ty) -> cres<ty::fn_ty> {
+        if check vec::same_length(a_args, b_args) {
+            map2(a_args, b_args) {|a, b| self.args(a, b) }
+        } else {
+            err(ty::terr_arg_count)
+        }
+    }
 
-    self.c_protos(a_f.proto, b_f.proto).chain {|p|
-        self.c_ret_styles(a_f.ret_style, b_f.ret_style).chain {|rs|
-            c_argvecs(self, a_f.inputs, b_f.inputs).chain {|inputs|
-                self.c_tys(a_f.output, b_f.output).chain {|output|
+    self.protos(a_f.proto, b_f.proto).chain {|p|
+        self.ret_styles(a_f.ret_style, b_f.ret_style).chain {|rs|
+            argvecs(self, a_f.inputs, b_f.inputs).chain {|inputs|
+                self.tys(a_f.output, b_f.output).chain {|output|
                     //FIXME self.infcx().constrvecs(a_f.constraints,
                     //FIXME                         b_f.constraints).then {||
                         ok({proto: p,
@@ -1146,39 +820,21 @@ fn c_fns<C:combine>(
     }
 }
 
-fn c_tys<C:combine>(
+fn super_tys<C:combine>(
     self: C, a: ty::t, b: ty::t) -> cres<ty::t> {
 
     let tcx = self.infcx().tcx;
-
-    #debug("%s.c_tys(%s, %s)",
-           self.tag(),
-           ty_to_str(tcx, a),
-           ty_to_str(tcx, b));
-
-    // Fast path.
-    if a == b { ret ok(a); }
-
     alt (ty::get(a).struct, ty::get(b).struct) {
-      (ty::ty_bot, _) { self.c_bot(b) }
-      (_, ty::ty_bot) { self.c_bot(b) }
-
-      (ty::ty_var(a_id), ty::ty_var(b_id)) {
-        c_vars(self, self.infcx().vb,
-               a, a_id, b_id,
-               {|x, y| self.c_tys(x, y) })
-      }
-
-      // Note that the LUB/GLB operations are commutative:
-      (ty::ty_var(v_id), _) {
-        c_var_t(self, self.infcx().vb,
-                v_id, b,
-                {|x, y| self.c_tys(x, y) })
-      }
-      (_, ty::ty_var(v_id)) {
-        c_var_t(self, self.infcx().vb,
-                v_id, a,
-                {|x, y| self.c_tys(x, y) })
+      // The "subtype" ought to be handling cases involving bot or var:
+      (ty::ty_bot, _) |
+      (_, ty::ty_bot) |
+      (ty::ty_var(_), _) |
+      (_, ty::ty_var(_)) {
+        tcx.sess.bug(
+            #fmt["%s: bot and var types should have been handled (%s,%s)",
+                 self.tag(),
+                 a.to_str(self.infcx()),
+                 b.to_str(self.infcx())]);
       }
 
       (ty::ty_nil, _) |
@@ -1191,7 +847,7 @@ fn c_tys<C:combine>(
         if ty::mach_sty(cfg, a) == ty::mach_sty(cfg, b) {
             ok(a)
         } else {
-            err(ty::terr_mismatch)
+            err(ty::terr_sorts(b, a))
         }
       }
 
@@ -1201,53 +857,52 @@ fn c_tys<C:combine>(
 
       (ty::ty_enum(a_id, a_tps), ty::ty_enum(b_id, b_tps))
       if a_id == b_id {
-        c_tps(self, a_id, a_tps, b_tps).chain {|tps|
+        self.tps(a_tps, b_tps).chain {|tps|
             ok(ty::mk_enum(tcx, a_id, tps))
         }
       }
 
       (ty::ty_iface(a_id, a_tps), ty::ty_iface(b_id, b_tps))
       if a_id == b_id {
-        c_tps(self, a_id, a_tps, b_tps).chain {|tps|
+        self.tps(a_tps, b_tps).chain {|tps|
             ok(ty::mk_iface(tcx, a_id, tps))
         }
       }
 
       (ty::ty_class(a_id, a_tps), ty::ty_class(b_id, b_tps))
       if a_id == b_id {
-        // FIXME variance
-        c_tps(self, a_id, a_tps, b_tps).chain {|tps|
+        self.tps(a_tps, b_tps).chain {|tps|
             ok(ty::mk_class(tcx, a_id, tps))
         }
       }
 
       (ty::ty_box(a_mt), ty::ty_box(b_mt)) {
-        self.c_mts(a_mt, b_mt).chain {|mt|
+        self.mts(a_mt, b_mt).chain {|mt|
             ok(ty::mk_box(tcx, mt))
         }
       }
 
       (ty::ty_uniq(a_mt), ty::ty_uniq(b_mt)) {
-        self.c_mts(a_mt, b_mt).chain {|mt|
+        self.mts(a_mt, b_mt).chain {|mt|
             ok(ty::mk_uniq(tcx, mt))
         }
       }
 
       (ty::ty_vec(a_mt), ty::ty_vec(b_mt)) {
-        self.c_mts(a_mt, b_mt).chain {|mt|
+        self.mts(a_mt, b_mt).chain {|mt|
             ok(ty::mk_vec(tcx, mt))
         }
       }
 
       (ty::ty_ptr(a_mt), ty::ty_ptr(b_mt)) {
-        self.c_mts(a_mt, b_mt).chain {|mt|
+        self.mts(a_mt, b_mt).chain {|mt|
             ok(ty::mk_ptr(tcx, mt))
         }
       }
 
       (ty::ty_rptr(a_r, a_mt), ty::ty_rptr(b_r, b_mt)) {
-        self.c_regions(a_r, b_r).chain {|r|
-            self.c_mts(a_mt, b_mt).chain {|mt|
+        self.contraregions(a_r, b_r).chain {|r|
+            self.mts(a_mt, b_mt).chain {|mt|
                 ok(ty::mk_rptr(tcx, r, mt))
             }
         }
@@ -1255,124 +910,187 @@ fn c_tys<C:combine>(
 
       (ty::ty_res(a_id, a_t, a_tps), ty::ty_res(b_id, b_t, b_tps))
       if a_id == b_id {
-        self.c_tys(a_t, b_t).chain {|t|
-            c_tps(self, a_id, a_tps, b_tps).chain {|tps|
+        self.tys(a_t, b_t).chain {|t|
+            self.tps(a_tps, b_tps).chain {|tps|
                 ok(ty::mk_res(tcx, a_id, t, tps))
             }
         }
       }
 
-      (ty::ty_rec(a_fields), ty::ty_rec(b_fields)) {
-        c_fieldvecs(self, a_fields, b_fields).chain {|fs|
-            ok(ty::mk_rec(tcx, fs))
+      (ty::ty_rec(as), ty::ty_rec(bs)) {
+        if check vec::same_length(as, bs) {
+            map2(as, bs) {|a,b| self.flds(a, b) }.chain {|flds|
+                ok(ty::mk_rec(tcx, flds))
+            }
+        } else {
+            err(ty::terr_record_size(bs.len(), as.len()))
         }
       }
 
-      (ty::ty_tup(a_tys), ty::ty_tup(b_tys)) {
-        c_tuptys(self, a_tys, b_tys).chain {|ts|
-            ok(ty::mk_tup(tcx, ts))
+      (ty::ty_tup(as), ty::ty_tup(bs)) {
+        if check vec::same_length(as, bs) {
+            map2(as, bs) {|a, b| self.tys(a, b) }.chain {|ts|
+                ok(ty::mk_tup(tcx, ts))
+            }
+        } else {
+            err(ty::terr_tuple_size(bs.len(), as.len()))
         }
       }
 
       (ty::ty_fn(a_fty), ty::ty_fn(b_fty)) {
-        c_fns(self, a_fty, b_fty).chain {|fty|
+        self.fns(a_fty, b_fty).chain {|fty|
             ok(ty::mk_fn(tcx, fty))
         }
       }
 
       (ty::ty_constr(a_t, a_constrs), ty::ty_constr(b_t, b_constrs)) {
-        self.c_tys(a_t, b_t).chain {|t|
+        self.tys(a_t, b_t).chain {|t|
             self.infcx().constrvecs(a_constrs, b_constrs).then {||
                 ok(ty::mk_constr(tcx, t, a_constrs))
             }
         }
       }
 
-      _ { err(ty::terr_mismatch) }
+      _ { err(ty::terr_sorts(b, a)) }
     }
 }
 
-fn c_regions<C:combine>(
-    self: C, a: ty::region, b: ty::region) -> cres<ty::region> {
+impl of combine for sub {
+    fn infcx() -> infer_ctxt { *self }
+    fn tag() -> str { "sub" }
 
-    #debug["%s.c_regions(%?, %?)",
-           self.tag(),
-           a.to_str(self.infcx()),
-           b.to_str(self.infcx())];
+    fn lub() -> lub { lub(*self) }
 
-    alt (a, b) {
-      (ty::re_var(a_id), ty::re_var(b_id)) {
-        c_vars(self, self.infcx().rb,
-               a, a_id, b_id,
-               {|x, y| self.c_regions(x, y) })
-      }
+    fn contratys(a: ty::t, b: ty::t) -> cres<ty::t> {
+        self.tys(b, a)
+    }
 
-      (ty::re_var(v_id), r) |
-      (r, ty::re_var(v_id)) {
-        c_var_t(self, self.infcx().rb,
-                v_id, r,
-                {|x, y| self.c_regions(x, y) })
-      }
+    fn contraregions(a: ty::region, b: ty::region) -> cres<ty::region> {
+        self.regions(b, a)
+    }
 
-      (f @ ty::re_free(f_id, f_br), s @ ty::re_scope(s_id)) |
-      (s @ ty::re_scope(s_id), f @ ty::re_free(f_id, f_br)) {
-        self.c_regions_free_scope(f, f_id, f_br, s, s_id)
-      }
+    fn regions(a: ty::region, b: ty::region) -> cres<ty::region> {
+        #debug["regions(%s <= %s)", a.to_str(*self), b.to_str(*self)];
+        indent {||
+            alt (a, b) {
+              (ty::re_var(a_id), ty::re_var(b_id)) {
+                self.infcx().vars(self.rb, a_id, b_id).then {||
+                    ok(a)
+                }
+              }
+              (ty::re_var(a_id), _) {
+                  self.infcx().vart(self.rb, a_id, b).then {||
+                      ok(a)
+                  }
+              }
+              (_, ty::re_var(b_id)) {
+                  self.infcx().tvar(self.rb, a, b_id).then {||
+                      ok(a)
+                  }
+              }
+              _ {
+                self.lub().regions(a, b).compare(b) {||
+                    ty::terr_regions_differ(b, a)
+                }
+              }
+            }
+        }
+    }
 
-      (ty::re_scope(a_id), ty::re_scope(b_id)) {
-        self.c_regions_scope_scope(a, a_id, b, b_id)
-      }
+    fn mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
+        #debug("mts(%s <: %s)", a.to_str(*self), b.to_str(*self));
 
-      // For these types, we cannot define any additional relationship:
-      (ty::re_free(_, _), ty::re_free(_, _)) |
-      (ty::re_bound(_), ty::re_bound(_)) |
-      (ty::re_bound(_), ty::re_free(_, _)) |
-      (ty::re_bound(_), ty::re_scope(_)) |
-      (ty::re_free(_, _), ty::re_bound(_)) |
-      (ty::re_scope(_), ty::re_bound(_)) {
-        if a == b {
-            #debug["... yes, %s == %s.",
-                   a.to_str(self.infcx()),
-                   b.to_str(self.infcx())];
-            ok(a)
-        } else {
-            #debug["... no, %s != %s.",
-                   a.to_str(self.infcx()),
-                   b.to_str(self.infcx())];
-            err(ty::terr_regions_differ(false, b, a))
+        if a.mutbl != b.mutbl && b.mutbl != ast::m_const {
+            ret err(ty::terr_mutability);
         }
-      }
 
-      (ty::re_default, _) |
-      (_, ty::re_default) {
-        // actually a compiler bug, I think.
-        err(ty::terr_regions_differ(false, b, a))
-      }
+        alt b.mutbl {
+          ast::m_mutbl {
+            // If supertype is mut, subtype must match exactly
+            // (i.e., invariant if mut):
+            self.infcx().eq_tys(a.ty, b.ty).then {|| ok(a) }
+          }
+          ast::m_imm | ast::m_const {
+            // Otherwise we can be covariant:
+            self.tys(a.ty, b.ty).chain {|_t| ok(a) }
+          }
+        }
     }
-}
 
-impl of combine for lub {
-    fn infcx() -> infer_ctxt { *self }
+    fn protos(a: ast::proto, b: ast::proto) -> cres<ast::proto> {
+        self.lub().protos(a, b).compare(b) {||
+            ty::terr_proto_mismatch(b, a)
+        }
+    }
 
-    fn tag() -> str { "lub" }
+    fn ret_styles(a: ret_style, b: ret_style) -> cres<ret_style> {
+        self.lub().ret_styles(a, b).compare(b) {||
+            ty::terr_ret_style_mismatch(b, a)
+        }
+    }
 
-    fn bnd<V:copy>(b: bounds<V>) -> option<V> {
-        b.ub
+    fn tys(a: ty::t, b: ty::t) -> cres<ty::t> {
+        #debug("%s.tys(%s, %s)", self.tag(),
+               a.to_str(*self), b.to_str(*self));
+        if a == b { ret ok(a); }
+        indent {||
+            alt (ty::get(a).struct, ty::get(b).struct) {
+              (ty::ty_bot, _) {
+                ok(a)
+              }
+              (ty::ty_var(a_id), ty::ty_var(b_id)) {
+                self.infcx().vars(self.vb, a_id, b_id).then {|| ok(a) }
+              }
+              (ty::ty_var(a_id), _) {
+                self.infcx().vart(self.vb, a_id, b).then {|| ok(a) }
+              }
+              (_, ty::ty_var(b_id)) {
+                self.infcx().tvar(self.vb, a, b_id).then {|| ok(a) }
+              }
+              (_, ty::ty_bot) {
+                err(ty::terr_sorts(b, a))
+              }
+              _ {
+                super_tys(self, a, b)
+              }
+            }
+        }
+    }
+
+    // Traits please:
+
+    fn flds(a: ty::field, b: ty::field) -> cres<ty::field> {
+        super_flds(self, a, b)
     }
 
-    fn with_bnd<V:copy>(b: bounds<V>, v: V) -> bounds<V> {
-        assert b.ub == none;
-        {ub: some(v) with b}
+    fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode> {
+        super_modes(self, a, b)
     }
 
-    fn c_bot(b: ty::t) -> cres<ty::t> {
-        ok(b)
+    fn args(a: ty::arg, b: ty::arg) -> cres<ty::arg> {
+        super_args(self, a, b)
     }
 
-    fn c_mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
+    fn fns(a: ty::fn_ty, b: ty::fn_ty) -> cres<ty::fn_ty> {
+        super_fns(self, a, b)
+    }
+
+    fn tps(as: [ty::t], bs: [ty::t]) -> cres<[ty::t]> {
+        super_tps(self, as, bs)
+    }
+}
+
+impl of combine for lub {
+    fn infcx() -> infer_ctxt { *self }
+    fn tag() -> str { "lub" }
+
+    fn bot_ty(b: ty::t) -> cres<ty::t> { ok(b) }
+    fn ty_bot(b: ty::t) -> cres<ty::t> { self.bot_ty(b) } // commutative
+
+    fn mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
         let tcx = self.infcx().tcx;
 
-        #debug("%s.c_mts(%s, %s)",
+        #debug("%s.mts(%s, %s)",
                self.tag(),
                mt_to_str(tcx, a),
                mt_to_str(tcx, b));
@@ -1385,7 +1103,7 @@ fn c_mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
 
         alt m {
           ast::m_imm | ast::m_const {
-            self.c_tys(a.ty, b.ty).chain {|t|
+            self.tys(a.ty, b.ty).chain {|t|
                 ok({ty: t, mutbl: m})
             }
           }
@@ -1396,7 +1114,7 @@ fn c_mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
                     ok({ty: a.ty, mutbl: m})
                 }
             }.chain_err {|_e|
-                self.c_tys(a.ty, b.ty).chain {|t|
+                self.tys(a.ty, b.ty).chain {|t|
                     ok({ty: t, mutbl: ast::m_const})
                 }
             }
@@ -1404,15 +1122,11 @@ fn c_mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
         }
     }
 
-    fn c_contratys(a: ty::t, b: ty::t) -> cres<ty::t> {
-        glb(self.infcx()).c_tys(a, b)
-    }
-
-    fn c_tys(a: ty::t, b: ty::t) -> cres<ty::t> {
-        c_tys(self, a, b)
+    fn contratys(a: ty::t, b: ty::t) -> cres<ty::t> {
+        glb(self.infcx()).tys(a, b)
     }
 
-    fn c_protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto> {
+    fn protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto> {
         if p1 == ast::proto_bare {
             ok(p2)
         } else if p2 == ast::proto_bare {
@@ -1424,7 +1138,7 @@ fn c_protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto> {
         }
     }
 
-    fn c_ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style> {
+    fn ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style> {
         alt (r1, r2) {
           (ast::return_val, _) |
           (_, ast::return_val) {
@@ -1436,55 +1150,112 @@ fn c_ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style> {
         }
     }
 
-    fn c_regions(a: ty::region, b: ty::region) -> cres<ty::region> {
-        ret c_regions(self, a, b);
+    fn contraregions(a: ty::region, b: ty::region) -> cres<ty::region> {
+        ret glb(self.infcx()).regions(a, b);
     }
 
-    fn c_regions_free_scope(
-        a: ty::region, _a_id: ast::node_id, _a_br: ty::bound_region,
-        _b: ty::region, _b_id: ast::node_id) -> cres<ty::region> {
+    fn regions(a: ty::region, b: ty::region) -> cres<ty::region> {
+        #debug["%s.regions(%?, %?)",
+               self.tag(),
+               a.to_str(self.infcx()),
+               b.to_str(self.infcx())];
 
-        // for LUB, the scope is within the function and the free
-        // region is always a parameter to the method.
-        ret ok(a); // NDM--not so for nested functions
-    }
+        indent {||
+            alt (a, b) {
+              (ty::re_static, _) | (_, ty::re_static) {
+                ok(ty::re_static) // nothing lives longer than static
+              }
+
+              (ty::re_var(a_id), ty::re_var(b_id)) {
+                lattice_vars(self, self.infcx().rb,
+                           a, a_id, b_id,
+                           {|x, y| self.regions(x, y) })
+              }
+
+              (ty::re_var(v_id), r) |
+              (r, ty::re_var(v_id)) {
+                lattice_var_t(self, self.infcx().rb,
+                              v_id, r,
+                              {|x, y| self.regions(x, y) })
+              }
 
-    fn c_regions_scope_scope(a: ty::region, a_id: ast::node_id,
-                             b: ty::region, b_id: ast::node_id)
-        -> cres<ty::region> {
+              (f @ ty::re_free(f_id, f_br), ty::re_scope(s_id)) |
+              (ty::re_scope(s_id), f @ ty::re_free(f_id, f_br)) {
+                // for LUB, the scope is within the function and the free
+                // region is always a parameter to the method.
+                ok(f) // NDM--not so for nested functions
+              }
+
+              (ty::re_scope(a_id), ty::re_scope(b_id)) {
+                // The region corresponding to an outer block is a
+                // subtype of the region corresponding to an inner
+                // block.
+                let rm = self.infcx().tcx.region_map;
+                alt region::nearest_common_ancestor(rm, a_id, b_id) {
+                  some(r_id) { ok(ty::re_scope(r_id)) }
+                  _ { err(ty::terr_regions_differ(b, a)) }
+                }
+              }
+
+              // For these types, we cannot define any additional
+              // relationship:
+              (ty::re_free(_, _), ty::re_free(_, _)) |
+              (ty::re_bound(_), ty::re_bound(_)) |
+              (ty::re_bound(_), ty::re_free(_, _)) |
+              (ty::re_bound(_), ty::re_scope(_)) |
+              (ty::re_free(_, _), ty::re_bound(_)) |
+              (ty::re_scope(_), ty::re_bound(_)) {
+                if a == b {
+                    ok(a)
+                } else {
+                    err(ty::terr_regions_differ(b, a))
+                }
+              }
 
-        // The region corresponding to an outer block is a subtype of the
-        // region corresponding to an inner block.
-        let rm = self.infcx().tcx.region_map;
-        alt region::nearest_common_ancestor(rm, a_id, b_id) {
-          some(r_id) { ok(ty::re_scope(r_id)) }
-          _ { err(ty::terr_regions_differ(false, b, a)) }
+              (ty::re_default, _) |
+              (_, ty::re_default) {
+                // actually a compiler bug, I think.
+                err(ty::terr_regions_differ(b, a))
+              }
+            }
         }
     }
-}
 
-impl of combine for glb {
-    fn infcx() -> infer_ctxt { *self }
+    // Traits please:
 
-    fn tag() -> str { "glb" }
+    fn tys(a: ty::t, b: ty::t) -> cres<ty::t> {
+        lattice_tys(self, a, b)
+    }
 
-    fn bnd<V:copy>(b: bounds<V>) -> option<V> {
-        b.lb
+    fn flds(a: ty::field, b: ty::field) -> cres<ty::field> {
+        super_flds(self, a, b)
     }
 
-    fn with_bnd<V:copy>(b: bounds<V>, v: V) -> bounds<V> {
-        assert b.lb == none;
-        {lb: some(v) with b}
+    fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode> {
+        super_modes(self, a, b)
     }
 
-    fn c_bot(_b: ty::t) -> cres<ty::t> {
-        ok(ty::mk_bot(self.infcx().tcx))
+    fn args(a: ty::arg, b: ty::arg) -> cres<ty::arg> {
+        super_args(self, a, b)
     }
 
-    fn c_mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
+    fn fns(a: ty::fn_ty, b: ty::fn_ty) -> cres<ty::fn_ty> {
+        super_fns(self, a, b)
+    }
+
+    fn tps(as: [ty::t], bs: [ty::t]) -> cres<[ty::t]> {
+        super_tps(self, as, bs)
+    }
+}
+
+impl of combine for glb {
+    fn infcx() -> infer_ctxt { *self }
+    fn tag() -> str { "glb" }
+
+    fn mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
         let tcx = self.infcx().tcx;
 
-        #debug("%s.c_mts(%s, %s)",
+        #debug("%s.mts(%s, %s)",
                self.tag(),
                mt_to_str(tcx, a),
                mt_to_str(tcx, b));
@@ -1493,12 +1264,12 @@ fn c_mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
           // If one side or both is mut, then the GLB must use
           // the precise type from the mut side.
           (ast::m_mutbl, ast::m_const) {
-            self.infcx().tys(a.ty, b.ty).then {||
+            sub(*self).tys(a.ty, b.ty).chain {|_t|
                 ok({ty: a.ty, mutbl: ast::m_mutbl})
             }
           }
           (ast::m_const, ast::m_mutbl) {
-            self.infcx().tys(b.ty, a.ty).then {||
+            sub(*self).tys(b.ty, a.ty).chain {|_t|
                 ok({ty: b.ty, mutbl: ast::m_mutbl})
             }
           }
@@ -1513,7 +1284,7 @@ fn c_mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
           (ast::m_imm, ast::m_const) |
           (ast::m_const, ast::m_imm) |
           (ast::m_imm, ast::m_imm) {
-            self.c_tys(a.ty, b.ty).chain {|t|
+            self.tys(a.ty, b.ty).chain {|t|
                 ok({ty: t, mutbl: ast::m_imm})
             }
           }
@@ -1521,7 +1292,7 @@ fn c_mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
           // If both sides are const, then we can use GLB of both
           // sides and mutbl of only `m_const`.
           (ast::m_const, ast::m_const) {
-            self.c_tys(a.ty, b.ty).chain {|t|
+            self.tys(a.ty, b.ty).chain {|t|
                 ok({ty: t, mutbl: ast::m_const})
             }
           }
@@ -1534,15 +1305,11 @@ fn c_mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
         }
     }
 
-    fn c_contratys(a: ty::t, b: ty::t) -> cres<ty::t> {
-        lub(self.infcx()).c_tys(a, b)
-    }
-
-    fn c_tys(a: ty::t, b: ty::t) -> cres<ty::t> {
-        c_tys(self, a, b)
+    fn contratys(a: ty::t, b: ty::t) -> cres<ty::t> {
+        lub(self.infcx()).tys(a, b)
     }
 
-    fn c_protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto> {
+    fn protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto> {
         if p1 == ast::proto_any {
             ok(p2)
         } else if p2 == ast::proto_any {
@@ -1554,7 +1321,7 @@ fn c_protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto> {
         }
     }
 
-    fn c_ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style> {
+    fn ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style> {
         alt (r1, r2) {
           (ast::return_val, ast::return_val) {
             ok(ast::return_val)
@@ -1566,32 +1333,244 @@ fn c_ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style> {
         }
     }
 
-    fn c_regions(a: ty::region, b: ty::region) -> cres<ty::region> {
-        ret c_regions(self, a, b);
+    fn regions(a: ty::region, b: ty::region) -> cres<ty::region> {
+        #debug["%s.regions(%?, %?)",
+               self.tag(),
+               a.to_str(self.infcx()),
+               b.to_str(self.infcx())];
+
+        indent {||
+            alt (a, b) {
+              (ty::re_static, r) | (r, ty::re_static) {
+                // static lives longer than everything else
+                ok(r)
+              }
+
+              (ty::re_var(a_id), ty::re_var(b_id)) {
+                lattice_vars(self, self.infcx().rb,
+                             a, a_id, b_id,
+                             {|x, y| self.regions(x, y) })
+              }
+
+              (ty::re_var(v_id), _) | (_, ty::re_var(v_id)) {
+               lattice_var_t(self, self.infcx().rb,
+                             v_id, b,
+                             {|x, y| self.regions(x, y) })
+              }
+
+              (f @ ty::re_free(f_id, f_br), ty::re_scope(s_id)) |
+              (ty::re_scope(s_id), f @ ty::re_free(f_id, f_br)) {
+                // for GLB, the scope is within the function and the free
+                // region is always a parameter to the method.  So the GLB
+                // must be the scope.
+                ok(b) // NDM--not so for nested functions
+              }
+
+              (ty::re_scope(a_id), ty::re_scope(b_id)) {
+                // We want to generate a region that is contained by both of
+                // these: so, if one of these scopes is a subscope of the
+                // other, return it.  Otherwise fail.
+                let rm = self.infcx().tcx.region_map;
+                alt region::nearest_common_ancestor(rm, a_id, b_id) {
+                  some(r_id) if a_id == r_id { ok(b) }
+                  some(r_id) if b_id == r_id { ok(a) }
+                  _ { err(ty::terr_regions_differ(b, a)) }
+                }
+              }
+
+              // For these types, we cannot define any additional
+              // relationship:
+              (ty::re_free(_, _), ty::re_free(_, _)) |
+              (ty::re_bound(_), ty::re_bound(_)) |
+              (ty::re_bound(_), ty::re_free(_, _)) |
+              (ty::re_bound(_), ty::re_scope(_)) |
+              (ty::re_free(_, _), ty::re_bound(_)) |
+              (ty::re_scope(_), ty::re_bound(_)) {
+                if a == b {
+                    ok(a)
+                } else {
+                    err(ty::terr_regions_differ(b, a))
+                }
+              }
+
+              (ty::re_default, _) |
+              (_, ty::re_default) {
+                // actually a compiler bug, I think.
+                err(ty::terr_regions_differ(b, a))
+              }
+            }
+        }
+    }
+
+    fn contraregions(a: ty::region, b: ty::region) -> cres<ty::region> {
+        lub(self.infcx()).regions(a, b)
+    }
+
+    fn tys(a: ty::t, b: ty::t) -> cres<ty::t> {
+        lattice_tys(self, a, b)
+    }
+
+    // Traits please:
+
+    fn flds(a: ty::field, b: ty::field) -> cres<ty::field> {
+        super_flds(self, a, b)
+    }
+
+    fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode> {
+        super_modes(self, a, b)
+    }
+
+    fn args(a: ty::arg, b: ty::arg) -> cres<ty::arg> {
+        super_args(self, a, b)
+    }
+
+    fn fns(a: ty::fn_ty, b: ty::fn_ty) -> cres<ty::fn_ty> {
+        super_fns(self, a, b)
+    }
+
+    fn tps(as: [ty::t], bs: [ty::t]) -> cres<[ty::t]> {
+        super_tps(self, as, bs)
+    }
+}
+
+// ______________________________________________________________________
+// Lattice operations on variables
+//
+// this is common code used by both LUB and GLB
+
+iface lattice_ops {
+    fn bnd<T:copy>(b: bounds<T>) -> option<T>;
+    fn with_bnd<T:copy>(b: bounds<T>, t: T) -> bounds<T>;
+    fn ty_bot(t: ty::t) -> cres<ty::t>;
+}
+
+impl of lattice_ops for lub {
+    fn bnd<T:copy>(b: bounds<T>) -> option<T> { b.ub }
+    fn with_bnd<T:copy>(b: bounds<T>, t: T) -> bounds<T> {
+        {ub: some(t) with b}
+    }
+    fn ty_bot(t: ty::t) -> cres<ty::t> {
+        ok(t)
+    }
+}
+
+impl of lattice_ops for glb {
+    fn bnd<T:copy>(b: bounds<T>) -> option<T> { b.lb }
+    fn with_bnd<T:copy>(b: bounds<T>, t: T) -> bounds<T> {
+        {lb: some(t) with b}
+    }
+    fn ty_bot(_t: ty::t) -> cres<ty::t> {
+        ok(ty::mk_bot(self.infcx().tcx))
+    }
+}
+
+fn lattice_tys<L:lattice_ops combine>(
+    self: L, a: ty::t, b: ty::t) -> cres<ty::t> {
+
+    #debug("%s.tys(%s, %s)", self.tag(),
+           a.to_str(self.infcx()),
+           b.to_str(self.infcx()));
+    if a == b { ret ok(a); }
+    indent {||
+        alt (ty::get(a).struct, ty::get(b).struct) {
+          (ty::ty_bot, _) { self.ty_bot(b) }
+          (_, ty::ty_bot) { self.ty_bot(a) }
+
+          (ty::ty_var(a_id), ty::ty_var(b_id)) {
+            lattice_vars(self, self.infcx().vb,
+                         a, a_id, b_id,
+                         {|x, y| self.tys(x, y) })
+          }
+
+          (ty::ty_var(a_id), _) {
+            lattice_var_t(self, self.infcx().vb, a_id, b,
+                          {|x, y| self.tys(x, y) })
+          }
+
+          (_, ty::ty_var(b_id)) {
+            lattice_var_t(self, self.infcx().vb, b_id, a,
+                          {|x, y| self.tys(x, y) })
+          }
+
+          _ {
+            super_tys(self, a, b)
+          }
+        }
+    }
+}
+
+fn lattice_vars<V:copy vid, T:copy to_str st, L:lattice_ops combine>(
+    self: L, vb: vals_and_bindings<V, T>,
+    a_t: T, a_vid: V, b_vid: V,
+    c_ts: fn(T, T) -> cres<T>) -> cres<T> {
+
+    // The comments in this function are written for LUB and types,
+    // but they apply equally well to GLB and regions if you inverse
+    // upper/lower/sub/super/etc.
+
+    // Need to find a type that is a supertype of both a and b:
+    let {root: a_vid, bounds: a_bounds} = self.infcx().get(vb, a_vid);
+    let {root: b_vid, bounds: b_bounds} = self.infcx().get(vb, b_vid);
+
+    #debug["%s.vars(%s=%s <: %s=%s)",
+           self.tag(),
+           a_vid.to_str(), a_bounds.to_str(self.infcx()),
+           b_vid.to_str(), b_bounds.to_str(self.infcx())];
+
+    if a_vid == b_vid {
+        ret ok(a_t);
     }
 
-    fn c_regions_free_scope(
-        _a: ty::region, _a_id: ast::node_id, _a_br: ty::bound_region,
-        b: ty::region, _b_id: ast::node_id) -> cres<ty::region> {
+    // If both A and B have an UB type, then we can just compute the
+    // LUB of those types:
+    let a_bnd = self.bnd(a_bounds), b_bnd = self.bnd(b_bounds);
+    alt (a_bnd, b_bnd) {
+      (some(a_ty), some(b_ty)) {
+        alt self.infcx().try {|| c_ts(a_ty, b_ty) } {
+            ok(t) { ret ok(t); }
+            err(_) { /*fallthrough */ }
+        }
+      }
+      _ {/*fallthrough*/}
+    }
 
-        // for GLB, the scope is within the function and the free
-        // region is always a parameter to the method.  So the GLB
-        // must be the scope.
-        ret ok(b); // NDM--not so for nested functions
+    // Otherwise, we need to merge A and B into one variable.  We can
+    // then use either variable as an upper bound:
+    self.infcx().vars(vb, a_vid, b_vid).then {||
+        ok(a_t)
     }
+}
 
-    fn c_regions_scope_scope(a: ty::region, a_id: ast::node_id,
-                             b: ty::region, b_id: ast::node_id)
-        -> cres<ty::region> {
+fn lattice_var_t<V:copy vid, T:copy to_str st, L:lattice_ops combine>(
+    self: L, vb: vals_and_bindings<V, T>,
+    a_vid: V, b: T,
+    c_ts: fn(T, T) -> cres<T>) -> cres<T> {
 
-        // We want to generate a region that is contained by both of
-        // these: so, if one of these scopes is a subscope of the
-        // other, return it.  Otherwise fail.
-        let rm = self.infcx().tcx.region_map;
-        alt region::nearest_common_ancestor(rm, a_id, b_id) {
-          some(r_id) if a_id == r_id { ok(b) }
-          some(r_id) if b_id == r_id { ok(a) }
-          _ { err(ty::terr_regions_differ(false, b, a)) }
+    let {root: a_id, bounds: a_bounds} = self.infcx().get(vb, a_vid);
+
+    // The comments in this function are written for LUB, but they
+    // apply equally well to GLB if you inverse upper/lower/sub/super/etc.
+
+    #debug["%s.var_ty(%s=%s <: %s)",
+           self.tag(),
+           a_id.to_str(), a_bounds.to_str(self.infcx()),
+           b.to_str(self.infcx())];
+
+    alt self.bnd(a_bounds) {
+      some(a_bnd) {
+        // If a has an upper bound, return it.
+        #debug["bnd=some(%s)", a_bnd.to_str(self.infcx())];
+        ret c_ts(a_bnd, b);
+      }
+      none {
+        // If a does not have an upper bound, make b the upper bound of a
+        // and then return b.
+        #debug["bnd=none"];
+        let a_bounds = self.with_bnd(a_bounds, b);
+        self.infcx().bnds(a_bounds.lb, a_bounds.ub).then {||
+            self.infcx().set(vb, a_id, bounded(a_bounds));
+            ok(b)
         }
+      }
     }
 }
index c02ec4a23775ce8d6b7737afe3831604aa79c311..df274ea06f2868c1d7874b0350accb9a5209671b 100644 (file)
@@ -85,8 +85,8 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span,
     // the common flow point for all functions that appear in the AST.
 
     with_appropriate_checker(cx, fn_id) { |checker|
-        for @{def, span} in *freevars::get_freevars(cx.tcx, fn_id) {
-            let id = ast_util::def_id_of_def(def).node;
+        for vec::each(*freevars::get_freevars(cx.tcx, fn_id)) {|fv|
+            let id = ast_util::def_id_of_def(fv.def).node;
             if checker == check_copy {
                 let last_uses = alt check cx.last_uses.find(fn_id) {
                   some(last_use::closes_over(vars)) { vars }
@@ -96,7 +96,7 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span,
                     vec::position_elem(last_uses, id)) { cont; }
             }
             let ty = ty::node_id_to_type(cx.tcx, id);
-            checker(cx, ty, span);
+            checker(cx, ty, fv.span);
         }
     }
 
@@ -146,7 +146,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
       // Vector add copies.
       expr_binary(add, ls, rs) { maybe_copy(cx, ls); maybe_copy(cx, rs); }
       expr_rec(fields, def) {
-        for field in fields { maybe_copy(cx, field.node.expr); }
+        for fields.each {|field| maybe_copy(cx, field.node.expr); }
         alt def {
           some(ex) {
             // All noncopyable fields must be overridden
@@ -155,7 +155,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
               ty::ty_rec(f) { f }
               _ { cx.tcx.sess.span_bug(ex.span, "bad expr type in record"); }
             };
-            for tf in ty_fields {
+            for ty_fields.each {|tf|
                 if !vec::any(fields, {|f| f.node.ident == tf.ident}) &&
                     !ty::kind_can_be_copied(ty::type_kind(cx.tcx, tf.mt.ty)) {
                     cx.tcx.sess.span_err(ex.span,
@@ -167,14 +167,14 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
         }
       }
       expr_tup(exprs) | expr_vec(exprs, _) {
-        for expr in exprs { maybe_copy(cx, expr); }
+        for exprs.each {|expr| maybe_copy(cx, expr); }
       }
       expr_bind(_, args) {
-        for a in args { alt a { some(ex) { maybe_copy(cx, ex); } _ {} } }
+        for args.each {|a| alt a { some(ex) { maybe_copy(cx, ex); } _ {} } }
       }
       expr_call(f, args, _) {
         let mut i = 0u;
-        for arg_t in ty::ty_fn_args(ty::expr_ty(cx.tcx, f)) {
+        for ty::ty_fn_args(ty::expr_ty(cx.tcx, f)).each {|arg_t|
             alt ty::arg_mode(cx.tcx, arg_t) {
               by_copy { maybe_copy(cx, args[i]); }
               by_ref | by_val | by_mutbl_ref | by_move { }
@@ -183,7 +183,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
         }
       }
       expr_path(_) | expr_field(_, _, _) {
-        option::with_option_do(cx.tcx.node_type_substs.find(e.id)) {|ts|
+        option::iter(cx.tcx.node_type_substs.find(e.id)) {|ts|
             let bounds = alt check e.node {
               expr_path(_) {
                 let did = ast_util::def_id_of_def(cx.tcx.def_map.get(e.id));
@@ -236,7 +236,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
 fn check_stmt(stmt: @stmt, cx: ctx, v: visit::vt<ctx>) {
     alt stmt.node {
       stmt_decl(@{node: decl_local(locals), _}, _) {
-        for local in locals {
+        for locals.each {|local|
             alt local.node.init {
               some({op: init_assign, expr}) { maybe_copy(cx, expr); }
               _ {}
@@ -251,7 +251,7 @@ fn check_stmt(stmt: @stmt, cx: ctx, v: visit::vt<ctx>) {
 fn check_ty(aty: @ty, cx: ctx, v: visit::vt<ctx>) {
     alt aty.node {
       ty_path(_, id) {
-        option::with_option_do(cx.tcx.node_type_substs.find(id)) {|ts|
+        option::iter(cx.tcx.node_type_substs.find(id)) {|ts|
             let did = ast_util::def_id_of_def(cx.tcx.def_map.get(id));
             let bounds = ty::lookup_item_type(cx.tcx, did).bounds;
             vec::iter2(ts, *bounds) {|ty, bound|
index 08b6add9ccd22d1d9587b8f163219ff7c52d2a47..b737ba1b02c808ce121988d9e38484624b980d3a 100644 (file)
@@ -106,15 +106,11 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
       expr_while(_, _) | expr_do_while(_, _) | expr_loop(_) {
         visit_block(lp, cx) {|| visit::visit_expr(ex, cx, v);}
       }
-      expr_for(_, coll, blk) {
-        v.visit_expr(coll, cx, v);
-        visit_block(lp, cx) {|| visit::visit_block(blk, cx, v);}
-      }
       expr_alt(input, arms, _) {
         v.visit_expr(input, cx, v);
         let before = cx.current;
         let mut sets = [];
-        for arm in arms {
+        for arms.each {|arm|
             cx.current = before;
             v.visit_arm(arm, cx, v);
             sets += [cx.current];
@@ -137,7 +133,7 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
             clear_in_current(cx, root_id, false);
           }
           _ {
-            option::with_option_do(def_is_owned_local(cx, my_def)) {|nid|
+            option::iter(def_is_owned_local(cx, my_def)) {|nid|
                 clear_in_current(cx, nid, false);
                 cx.current += [{def: nid,
                                 uses: cons(var_use(ex.id), @nil)}];
@@ -185,14 +181,14 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
               }
             }
         }
-        for f in fns { v.visit_expr(f, cx, v); }
+        for fns.each {|f| v.visit_expr(f, cx, v); }
         vec::iter2(args, arg_ts) {|arg, arg_t|
             alt arg.node {
               expr_path(_) {
                 alt ty::arg_mode(cx.tcx, arg_t) {
                   by_ref | by_val | by_mutbl_ref {
                     let def = cx.def_map.get(arg.id);
-                    option::with_option_do(def_is_owned_local(cx, def)) {|id|
+                    option::iter(def_is_owned_local(cx, def)) {|id|
                         clear_in_current(cx, id, false);
                         cx.spill_map.insert(id, ());
                     }
@@ -213,7 +209,7 @@ fn visit_stmt(s: @stmt, cx: ctx, v: visit::vt<ctx>) {
       stmt_decl(@{node: decl_local(ls), _}, _) {
         shadow_in_current(cx, {|id|
             let mut rslt = false;
-            for local in ls {
+            for ls.each {|local|
                 let mut found = false;
                 pat_util::pat_bindings(cx.tcx.def_map, local.node.pat,
                                        {|pid, _a, _b|
@@ -246,8 +242,8 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
       proto_box | proto_uniq | proto_bare {
         alt cx.tcx.freevars.find(id) {
           some(vars) {
-            for v in *vars {
-                option::with_option_do(def_is_owned_local(cx, v.def)) {|nid|
+            for vec::each(*vars) {|v|
+                option::iter(def_is_owned_local(cx, v.def)) {|nid|
                     clear_in_current(cx, nid, false);
                     cx.current += [{def: nid,
                                     uses: cons(close_over(id), @nil)}];
@@ -304,22 +300,22 @@ fn add_block_exit(cx: ctx, tp: block_type) -> bool {
 fn join_branches(branches: [set]) -> set {
     let mut found: set = [], i = 0u;
     let l = vec::len(branches);
-    for set in branches {
+    for branches.each {|set|
         i += 1u;
-        for {def, uses} in set {
-            if !vec::any(found, {|v| v.def == def}) {
-                let mut j = i, nne = uses;
+        for set.each {|elt|
+            if !vec::any(found, {|v| v.def == elt.def}) {
+                let mut j = i, nne = elt.uses;
                 while j < l {
-                    for {def: d2, uses} in branches[j] {
-                        if d2 == def {
-                            list::iter(uses) {|e|
+                    for vec::each(branches[j]) {|elt2|
+                        if elt2.def == elt.def {
+                            list::iter(elt2.uses) {|e|
                                 if !list::has(nne, e) { nne = cons(e, @nne); }
                             }
                         }
                     }
                     j += 1u;
                 }
-                found += [{def: def, uses: nne}];
+                found += [{def: elt.def, uses: nne}];
             }
         }
     }
@@ -327,11 +323,11 @@ fn join_branches(branches: [set]) -> set {
 }
 
 fn leave_fn(cx: ctx) {
-    for {def, uses} in cx.current {
-        list::iter(uses) {|use|
+    for cx.current.each {|elt|
+        list::iter(elt.uses) {|use|
             let key = alt use {
               var_use(pth_id) { path(pth_id) }
-              close_over(fn_id) { close(fn_id, def) }
+              close_over(fn_id) { close(fn_id, elt.def) }
             };
             if !cx.last_uses.contains_key(key) {
                 cx.last_uses.insert(key, true);
@@ -343,16 +339,16 @@ fn leave_fn(cx: ctx) {
 fn shadow_in_current(cx: ctx, p: fn(node_id) -> bool) {
     let mut out = [];
     cx.current <-> out;
-    for e in out { if !p(e.def) { cx.current += [e]; } }
+    for out.each {|e| if !p(e.def) { cx.current += [e]; } }
 }
 
 fn clear_in_current(cx: ctx, my_def: node_id, to: bool) {
-    for {def, uses} in cx.current {
-        if def == my_def {
-            list::iter(uses) {|use|
+    for cx.current.each {|elt|
+        if elt.def == my_def {
+            list::iter(elt.uses) {|use|
                 let key = alt use {
                   var_use(pth_id) { path(pth_id) }
-                  close_over(fn_id) { close(fn_id, def) }
+                  close_over(fn_id) { close(fn_id, elt.def) }
                 };
                 if !to || !cx.last_uses.contains_key(key) {
                     cx.last_uses.insert(key, to);
index 47e1de3122947d57b9505501e03b3ddcc1a89d61..ea244ef77569912463aaf99d56c92bf629fadcc6 100644 (file)
@@ -60,7 +60,8 @@ fn default() -> [(option, bool)] {
     }
 
     fn contains(xs: [(option, bool)], x: option) -> bool {
-        for (o, _) in xs {
+        for xs.each {|c|
+            let (o, _) = c;
             if o == x { ret true; }
         }
         ret false;
@@ -85,7 +86,8 @@ fn contains(xs: [(option, bool)], x: option) -> bool {
         }
     };
 
-    for (o, v) in default() {
+    for default().each {|c|
+        let (o, v) = c;
         if !contains(result, o) {
             result += [(o, v)];
         }
@@ -97,7 +99,7 @@ fn contains(xs: [(option, bool)], x: option) -> bool {
 fn check_ctypes(tcx: ty::ctxt, crate: @ast::crate) {
     fn check_native_fn(tcx: ty::ctxt, decl: ast::fn_decl) {
         let tys = vec::map(decl.inputs) {|a| a.ty };
-        for ty in (tys + [decl.output]) {
+        for vec::each(tys + [decl.output]) {|ty|
             alt ty.node {
               ast::ty_path(_, id) {
                 alt tcx.def_map.get(id) {
@@ -125,7 +127,7 @@ fn check_item(tcx: ty::ctxt, it: @ast::item) {
         alt it.node {
           ast::item_native_mod(nmod) if attr::native_abi(it.attrs) !=
               either::right(ast::native_abi_rust_intrinsic) {
-            for ni in nmod.items {
+            for nmod.items.each {|ni|
                 alt ni.node {
                   ast::native_item_fn(decl, tps) {
                     check_native_fn(tcx, decl);
@@ -148,7 +150,8 @@ fn check_item(tcx: ty::ctxt, it: @ast::item) {
 fn check_crate(tcx: ty::ctxt, crate: @ast::crate,
                opts: [(option, bool)], time: bool) {
     let lint_opts = lint::merge_opts(crate.node.attrs, opts);
-    for (lopt, switch) in lint_opts {
+    for lint_opts.each {|opt|
+        let (lopt, switch) = opt;
         if switch == true {
             lopt.run(tcx, crate, time);
         }
index 268d63b84f52f30a8d3d504de41fc5ec7a194caf..633960f935156f03372550183f070712fc4e7243 100644 (file)
@@ -56,7 +56,7 @@ fn maybe_auto_unbox(tcx: ty::ctxt, t: ty::t) -> {t: ty::t, ds: [deref]} {
             let mut is_mutbl = false;
             alt ty::get(auto_unbox.t).struct {
               ty::ty_rec(fields) {
-                for fld: ty::field in fields {
+                for fields.each {|fld|
                     if str::eq(ident, fld.ident) {
                         is_mutbl = fld.mt.mutbl == m_mutbl;
                         break;
@@ -74,7 +74,7 @@ fn maybe_auto_unbox(tcx: ty::ctxt, t: ty::t) -> {t: ty::t, ds: [deref]} {
                           }
                           none { false }
                   };
-                  for fld: ty::field_ty in ty::lookup_class_fields(tcx, did) {
+                  for ty::lookup_class_fields(tcx, did).each {|fld|
                     if str::eq(ident, fld.ident) {
                         is_mutbl = fld.mutability == class_mutable
                             || in_self; // all fields can be mutated
@@ -169,7 +169,7 @@ fn visit_decl(d: @decl, &&cx: @ctx, v: visit::vt<@ctx>) {
     visit::visit_decl(d, cx, v);
     alt d.node {
       decl_local(locs) {
-        for loc in locs {
+        for locs.each {|loc|
             alt loc.node.init {
               some(init) {
                 if init.op == init_move { check_move_rhs(cx, init.expr); }
@@ -198,7 +198,7 @@ fn visit_expr(ex: @expr, &&cx: @ctx, v: visit::vt<@ctx>) {
         check_lval(cx, dest, msg_assign);
       }
       expr_fn(_, _, _, cap) {
-        for moved in cap.moves {
+        for cap.moves.each {|moved|
             let def = cx.tcx.def_map.get(moved.id);
             alt is_illegal_to_modify_def(cx, def, msg_move_out) {
               some(name) { mk_err(cx, moved.span, msg_move_out, moved.name); }
@@ -281,7 +281,7 @@ fn check_move_rhs(cx: @ctx, src: @expr) {
 fn check_call(cx: @ctx, f: @expr, args: [@expr]) {
     let arg_ts = ty::ty_fn_args(ty::expr_ty(cx.tcx, f));
     let mut i = 0u;
-    for arg_t: ty::arg in arg_ts {
+    for arg_ts.each {|arg_t|
         alt ty::resolved_mode(cx.tcx, arg_t.mode) {
           by_mutbl_ref { check_lval(cx, args[i], msg_mutbl_ref); }
           by_move { check_lval(cx, args[i], msg_move_out); }
@@ -294,7 +294,7 @@ fn check_call(cx: @ctx, f: @expr, args: [@expr]) {
 fn check_bind(cx: @ctx, f: @expr, args: [option<@expr>]) {
     let arg_ts = ty::ty_fn_args(ty::expr_ty(cx.tcx, f));
     let mut i = 0u;
-    for arg in args {
+    for args.each {|arg|
         alt arg {
           some(expr) {
             let o_msg = alt ty::resolved_mode(cx.tcx, arg_ts[i].mode) {
diff --git a/src/rustc/middle/pairwise.rs b/src/rustc/middle/pairwise.rs
new file mode 100644 (file)
index 0000000..802671e
--- /dev/null
@@ -0,0 +1,407 @@
+iface lattice<T> {
+    fn lub(T, T) -> cres<T>;
+    fn glb(T, T) -> cres<T>;
+}
+
+iface lattice_op<T> {
+    fn bnd<V:copy>(b: bounds<V>) -> option<V>;
+    fn with_bnd<V:copy>(b: bounds<V>, v: V) -> bounds<V>;
+}
+
+iface pairwise {
+    fn infcx() -> infer_ctxt;
+    fn tag() -> str;
+
+    fn c_tys(t1: ty::t, t2: ty::t) -> cres<ty::t>;
+    fn c_flds(a: ty::field, b: ty::field) -> cres<ty::field>;
+    fn c_bot(b: ty::t) -> cres<ty::t>;
+    fn c_mts(a: ty::mt, b: ty::mt) -> cres<ty::mt>;
+    fn c_contratys(t1: ty::t, t2: ty::t) -> cres<ty::t>;
+    fn c_protos(p1: ast::proto, p2: ast::proto) -> cres<ast::proto>;
+    fn c_ret_styles(r1: ret_style, r2: ret_style) -> cres<ret_style>;
+
+    // Combining regions (along with some specific cases that are
+    // different for LUB/GLB):
+    fn c_regions(
+        a: ty::region, b: ty::region) -> cres<ty::region>;
+    fn c_regions_scope_scope(
+        a: ty::region, a_id: ast::node_id,
+        b: ty::region, b_id: ast::node_id) -> cres<ty::region>;
+    fn c_regions_free_scope(
+        a: ty::region, a_id: ast::node_id, a_br: ty::bound_region,
+        b: ty::region, b_id: ast::node_id) -> cres<ty::region>;
+}
+
+fn c_vars<V:copy vid, PW:pairwise, T:copy to_str st>(
+    self: PW, vb: vals_and_bindings<V, T>,
+    a_t: T, a_vid: V, b_vid: V,
+    c_ts: fn(T, T) -> cres<T>) -> cres<T> {
+
+    // The comments in this function are written for LUB and types,
+    // but they apply equally well to GLB and regions if you inverse
+    // upper/lower/sub/super/etc.
+
+    // Need to find a type that is a supertype of both a and b:
+    let {root: a_vid, bounds: a_bounds} = self.infcx().get(vb, a_vid);
+    let {root: b_vid, bounds: b_bounds} = self.infcx().get(vb, b_vid);
+
+    #debug["%s.c_vars(%s=%s <: %s=%s)",
+           self.tag(),
+           a_vid.to_str(), a_bounds.to_str(self.infcx()),
+           b_vid.to_str(), b_bounds.to_str(self.infcx())];
+
+    if a_vid == b_vid {
+        ret ok(a_t);
+    }
+
+    // If both A and B have an UB type, then we can just compute the
+    // LUB of those types:
+    let a_bnd = self.bnd(a_bounds), b_bnd = self.bnd(b_bounds);
+    alt (a_bnd, b_bnd) {
+      (some(a_ty), some(b_ty)) {
+        alt self.infcx().try {|| c_ts(a_ty, b_ty) } {
+            ok(t) { ret ok(t); }
+            err(_) { /*fallthrough */ }
+        }
+      }
+      _ {/*fallthrough*/}
+    }
+
+    // Otherwise, we need to merge A and B into one variable.  We can
+    // then use either variable as an upper bound:
+    self.infcx().vars(vb, a_vid, b_vid).then {||
+        ok(a_t)
+    }
+}
+
+fn c_var_t<V:copy vid, PW:pairwise, T:copy to_str st>(
+    self: PW, vb: vals_and_bindings<V, T>,
+    a_vid: V, b: T,
+    c_ts: fn(T, T) -> cres<T>) -> cres<T> {
+
+    let {root: a_id, bounds: a_bounds} = self.infcx().get(vb, a_vid);
+
+    // The comments in this function are written for LUB, but they
+    // apply equally well to GLB if you inverse upper/lower/sub/super/etc.
+
+    #debug["%s.c_var_ty(%s=%s <: %s)",
+           self.tag(),
+           a_id.to_str(), a_bounds.to_str(self.infcx()),
+           b.to_str(self.infcx())];
+
+    alt self.bnd(a_bounds) {
+      some(a_bnd) {
+        // If a has an upper bound, return it.
+        ret c_ts(a_bnd, b);
+      }
+      none {
+        // If a does not have an upper bound, make b the upper bound of a
+        // and then return b.
+        let a_bounds = self.with_bnd(a_bounds, b);
+        self.infcx().bnds(a_bounds.lb, a_bounds.ub).then {||
+            self.infcx().set(vb, a_id, bounded(a_bounds));
+            ok(b)
+        }
+      }
+    }
+}
+
+fn c_tuptys<PW:pairwise>(self: PW, as: [ty::t], bs: [ty::t])
+    -> cres<[ty::t]> {
+
+    if check vec::same_length(as, bs) {
+        map2(as, bs) {|a, b| self.c_tys(a, b) }
+    } else {
+        err(ty::terr_tuple_size(as.len(), bs.len()))
+    }
+}
+
+fn c_tps<PW:pairwise>(self: PW, _did: ast::def_id, as: [ty::t], bs: [ty::t])
+    -> cres<[ty::t]> {
+    // FIXME #1973 lookup the declared variance of the type parameters
+    // based on did
+    if check vec::same_length(as, bs) {
+        map2(as, bs) {|a,b| self.c_tys(a, b) }
+    } else {
+        err(ty::terr_ty_param_size(as.len(), bs.len()))
+    }
+}
+
+fn c_fieldvecs<PW:pairwise>(
+    self: PW, as: [ty::field], bs: [ty::field])
+    -> cres<[ty::field]> {
+
+    if check vec::same_length(as, bs) {
+        map2(as, bs) {|a,b| self.c_flds(a, b) }
+    } else {
+        err(ty::terr_record_size(as.len(), bs.len()))
+    }
+}
+
+fn c_flds<PW:pairwise>(
+    self: PW, a: ty::field, b: ty::field) -> cres<ty::field> {
+
+    if a.ident == b.ident {
+        self.c_mts(a.mt, b.mt).chain {|mt|
+            ok({ident: a.ident, mt: mt})
+        }
+    } else {
+        err(ty::terr_record_fields(a.ident, b.ident))
+    }
+}
+
+fn c_modes<PW:pairwise>(
+    self: PW, a: ast::mode, b: ast::mode)
+    -> cres<ast::mode> {
+
+    let tcx = self.infcx().tcx;
+    ty::unify_mode(tcx, a, b)
+}
+
+fn c_args<PW:pairwise>(
+    self: PW, a: ty::arg, b: ty::arg)
+    -> cres<ty::arg> {
+
+    self.c_modes(a.mode, b.mode).chain {|m|
+        // Note: contravariant
+        self.c_contratys(b.ty, a.ty).chain {|t|
+            ok({mode: m, ty: t})
+        }
+    }
+}
+
+fn c_argvecs<PW:pairwise>(
+    self: PW, a_args: [ty::arg], b_args: [ty::arg]) -> cres<[ty::arg]> {
+
+    if check vec::same_length(a_args, b_args) {
+        map2(a_args, b_args) {|a, b| self.c_args(a, b) }
+    } else {
+        err(ty::terr_arg_count)
+    }
+}
+
+fn c_fns<PW:pairwise>(
+    self: PW, a_f: ty::fn_ty, b_f: ty::fn_ty) -> cres<ty::fn_ty> {
+
+    self.c_protos(a_f.proto, b_f.proto).chain {|p|
+        self.c_ret_styles(a_f.ret_style, b_f.ret_style).chain {|rs|
+            self.c_argvecs(a_f.inputs, b_f.inputs).chain {|inputs|
+                self.c_tys(a_f.output, b_f.output).chain {|output|
+                    //FIXME self.infcx().constrvecs(a_f.constraints,
+                    //FIXME                         b_f.constraints).then {||
+                        ok({proto: p,
+                            inputs: inputs,
+                            output: output,
+                            ret_style: rs,
+                            constraints: a_f.constraints})
+                    //FIXME }
+                }
+            }
+        }
+    }
+}
+
+fn c_tys<PW:pairwise>(
+    self: PW, a: ty::t, b: ty::t) -> cres<ty::t> {
+
+    let tcx = self.infcx().tcx;
+
+    #debug("%s.c_tys(%s, %s)",
+           self.tag(),
+           ty_to_str(tcx, a),
+           ty_to_str(tcx, b));
+
+    // Fast path.
+    if a == b { ret ok(a); }
+
+    alt (ty::get(a).struct, ty::get(b).struct) {
+      (ty::ty_bot, _) { self.c_bot(b) }
+      (_, ty::ty_bot) { self.c_bot(b) }
+
+      (ty::ty_var(a_id), ty::ty_var(b_id)) {
+        self.c_vars(self.infcx().vb,
+               a, a_id, b_id,
+               {|x, y| self.c_tys(x, y) })
+      }
+
+      // Note that the LUB/GLB operations are commutative:
+      (ty::ty_var(v_id), _) {
+        self.c_var_t(self.infcx().vb,
+                v_id, b,
+                {|x, y| self.c_tys(x, y) })
+      }
+      (_, ty::ty_var(v_id)) {
+        self.c_var_t(self.infcx().vb,
+                v_id, a,
+                {|x, y| self.c_tys(x, y) })
+      }
+
+      (ty::ty_nil, _) |
+      (ty::ty_bool, _) |
+      (ty::ty_int(_), _) |
+      (ty::ty_uint(_), _) |
+      (ty::ty_float(_), _) |
+      (ty::ty_str, _) {
+        let cfg = tcx.sess.targ_cfg;
+        if ty::mach_sty(cfg, a) == ty::mach_sty(cfg, b) {
+            ok(a)
+        } else {
+            err(ty::terr_mismatch)
+        }
+      }
+
+      (ty::ty_param(a_n, _), ty::ty_param(b_n, _)) if a_n == b_n {
+        ok(a)
+      }
+
+      (ty::ty_enum(a_id, a_tps), ty::ty_enum(b_id, b_tps))
+      if a_id == b_id {
+        self.c_tps(a_id, a_tps, b_tps).chain {|tps|
+            ok(ty::mk_enum(tcx, a_id, tps))
+        }
+      }
+
+      (ty::ty_iface(a_id, a_tps), ty::ty_iface(b_id, b_tps))
+      if a_id == b_id {
+        self.c_tps(a_id, a_tps, b_tps).chain {|tps|
+            ok(ty::mk_iface(tcx, a_id, tps))
+        }
+      }
+
+      (ty::ty_class(a_id, a_tps), ty::ty_class(b_id, b_tps))
+      if a_id == b_id {
+        // FIXME variance
+        self.c_tps(a_id, a_tps, b_tps).chain {|tps|
+            ok(ty::mk_class(tcx, a_id, tps))
+        }
+      }
+
+      (ty::ty_box(a_mt), ty::ty_box(b_mt)) {
+        self.c_mts(a_mt, b_mt).chain {|mt|
+            ok(ty::mk_box(tcx, mt))
+        }
+      }
+
+      (ty::ty_uniq(a_mt), ty::ty_uniq(b_mt)) {
+        self.c_mts(a_mt, b_mt).chain {|mt|
+            ok(ty::mk_uniq(tcx, mt))
+        }
+      }
+
+      (ty::ty_vec(a_mt), ty::ty_vec(b_mt)) {
+        self.c_mts(a_mt, b_mt).chain {|mt|
+            ok(ty::mk_vec(tcx, mt))
+        }
+      }
+
+      (ty::ty_ptr(a_mt), ty::ty_ptr(b_mt)) {
+        self.c_mts(a_mt, b_mt).chain {|mt|
+            ok(ty::mk_ptr(tcx, mt))
+        }
+      }
+
+      (ty::ty_rptr(a_r, a_mt), ty::ty_rptr(b_r, b_mt)) {
+        self.c_regions(a_r, b_r).chain {|r|
+            self.c_mts(a_mt, b_mt).chain {|mt|
+                ok(ty::mk_rptr(tcx, r, mt))
+            }
+        }
+      }
+
+      (ty::ty_res(a_id, a_t, a_tps), ty::ty_res(b_id, b_t, b_tps))
+      if a_id == b_id {
+        self.c_tys(a_t, b_t).chain {|t|
+            self.c_tps(a_id, a_tps, b_tps).chain {|tps|
+                ok(ty::mk_res(tcx, a_id, t, tps))
+            }
+        }
+      }
+
+      (ty::ty_rec(a_fields), ty::ty_rec(b_fields)) {
+        self.c_fieldvecs(a_fields, b_fields).chain {|fs|
+            ok(ty::mk_rec(tcx, fs))
+        }
+      }
+
+      (ty::ty_tup(a_tys), ty::ty_tup(b_tys)) {
+        self.c_tuptys(a_tys, b_tys).chain {|ts|
+            ok(ty::mk_tup(tcx, ts))
+        }
+      }
+
+      (ty::ty_fn(a_fty), ty::ty_fn(b_fty)) {
+        self.c_fns(a_fty, b_fty).chain {|fty|
+            ok(ty::mk_fn(tcx, fty))
+        }
+      }
+
+      (ty::ty_constr(a_t, a_constrs), ty::ty_constr(b_t, b_constrs)) {
+        self.c_tys(a_t, b_t).chain {|t|
+            self.infcx().constrvecs(a_constrs, b_constrs).then {||
+                ok(ty::mk_constr(tcx, t, a_constrs))
+            }
+        }
+      }
+
+      _ { err(ty::terr_mismatch) }
+    }
+}
+
+fn c_regions<PW:pairwise>(
+    self: PW, a: ty::region, b: ty::region) -> cres<ty::region> {
+
+    #debug["%s.c_regions(%?, %?)",
+           self.tag(),
+           a.to_str(self.infcx()),
+           b.to_str(self.infcx())];
+
+    alt (a, b) {
+      (ty::re_var(a_id), ty::re_var(b_id)) {
+        self.c_vars(self.infcx().rb,
+               a, a_id, b_id,
+               {|x, y| self.c_regions(x, y) })
+      }
+
+      (ty::re_var(v_id), r) |
+      (r, ty::re_var(v_id)) {
+        self.c_var_t(self.infcx().rb,
+                v_id, r,
+                {|x, y| self.c_regions(x, y) })
+      }
+
+      (f @ ty::re_free(f_id, f_br), s @ ty::re_scope(s_id)) |
+      (s @ ty::re_scope(s_id), f @ ty::re_free(f_id, f_br)) {
+        self.c_regions_free_scope(f, f_id, f_br, s, s_id)
+      }
+
+      (ty::re_scope(a_id), ty::re_scope(b_id)) {
+        self.c_regions_scope_scope(a, a_id, b, b_id)
+      }
+
+      // For these types, we cannot define any additional relationship:
+      (ty::re_free(_, _), ty::re_free(_, _)) |
+      (ty::re_bound(_), ty::re_bound(_)) |
+      (ty::re_bound(_), ty::re_free(_, _)) |
+      (ty::re_bound(_), ty::re_scope(_)) |
+      (ty::re_free(_, _), ty::re_bound(_)) |
+      (ty::re_scope(_), ty::re_bound(_)) {
+        if a == b {
+            #debug["... yes, %s == %s.",
+                   a.to_str(self.infcx()),
+                   b.to_str(self.infcx())];
+            ok(a)
+        } else {
+            #debug["... no, %s != %s.",
+                   a.to_str(self.infcx()),
+                   b.to_str(self.infcx())];
+            err(ty::terr_regions_differ(false, b, a))
+        }
+      }
+
+      (ty::re_default, _) |
+      (_, ty::re_default) {
+        // actually a compiler bug, I think.
+        err(ty::terr_regions_differ(false, b, a))
+      }
+    }
+}
index 037b00d95f5abf5b26a17cb4efa8b326558f0352..ebcbbb2359b66c370cb66b66de74ec0de053174c 100644 (file)
@@ -55,8 +55,8 @@ fn walk_pat(pat: @pat, it: fn(@pat)) {
     it(pat);
     alt pat.node {
       pat_ident(pth, some(p)) { walk_pat(p, it); }
-      pat_rec(fields, _) { for f in fields { walk_pat(f.pat, it); } }
-      pat_enum(_, s) | pat_tup(s) { for p in s { walk_pat(p, it); } }
+      pat_rec(fields, _) { for fields.each {|f| walk_pat(f.pat, it); } }
+      pat_enum(_, s) | pat_tup(s) { for s.each {|p| walk_pat(p, it); } }
       pat_box(s) | pat_uniq(s) { walk_pat(s, it); }
       pat_wild | pat_lit(_) | pat_range(_, _) | pat_ident(_, none) {}
     }
index 1e002e9c1d07a0cca5a59b94f80ffa7eae9b14c9..c66f09f8836065b1dae1859bd5bd8216a93bbd5c 100644 (file)
@@ -377,6 +377,8 @@ fn resolve_region_binding(cx: ctxt, span: span, region: ast::region) {
         // }
       }
 
+      ast::re_static { /* fallthrough */ }
+
       ast::re_named(ident) {
         alt cx.scope.resolve_ident(ident) {
           some(r) {
@@ -438,7 +440,7 @@ fn resolve_block(blk: ast::blk, cx: ctxt, visitor: visit::vt<ctxt>) {
     record_parent(cx, blk.node.id);
 
     // Resolve queued locals to this block.
-    for local_id in cx.queued_locals {
+    for cx.queued_locals.each {|local_id|
         cx.region_map.local_blocks.insert(local_id, blk.node.id);
     }
 
index 611f010ae1060e5d61bfbf9e28a6a872e7e9c160..c16b164d153201da4f223585338a1303e9b78c43 100644 (file)
@@ -28,7 +28,7 @@ fn check_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt<ctxt>) {
             alt ty::get(t).struct {
               ty::ty_rptr(region, _) {
                 alt region {
-                  ty::re_bound(_) | ty::re_free(_, _) {
+                  ty::re_bound(_) | ty::re_free(_, _) | ty::re_static {
                     /* ok */
                   }
                   ty::re_scope(rbi) {
index 601e2ac47682694db73c917c9b4485351a64dd56..fc4ea88581eb65a5ad6ec5deca8c8289b869015e 100644 (file)
@@ -187,7 +187,7 @@ fn create_env(sess: session, amap: ast_map::map) -> @env {
 fn iter_export_paths(vi: ast::view_item, f: fn(vp: @ast::view_path)) {
     alt vi.node {
       ast::view_item_export(vps) {
-        for vp in vps {
+        for vps.each {|vp|
             f(vp);
         }
       }
@@ -198,9 +198,7 @@ fn iter_export_paths(vi: ast::view_item, f: fn(vp: @ast::view_path)) {
 fn iter_import_paths(vi: ast::view_item, f: fn(vp: @ast::view_path)) {
     alt vi.node {
       ast::view_item_import(vps) {
-        for vp in vps {
-            f(vp);
-        }
+        for vps.each {|vp| f(vp);}
       }
       _ {}
     }
@@ -237,7 +235,7 @@ fn index_vi(e: @env, i: @ast::view_item, sc: scopes, _v: vt<scopes>) {
                 e.imports.insert(id, is_glob(path, sc, vp.span));
               }
               ast::view_path_list(mod_path, idents, _) {
-                for ident in idents {
+                for idents.each {|ident|
                     let t = todo(ident.node.name,
                                  @(*mod_path + [ident.node.name]),
                                  ident.span, sc);
@@ -410,7 +408,7 @@ fn resolve_names(e: @env, c: @ast::crate) {
     e.sess.abort_if_errors();
 
     fn walk_expr(e: @env, exp: @ast::expr, sc: scopes, v: vt<scopes>) {
-        visit_expr_with_scope(exp, sc, v);
+        visit::visit_expr(exp, sc, v);
         alt exp.node {
           ast::expr_path(p) {
             maybe_insert(e, exp.id,
@@ -438,9 +436,9 @@ fn walk_ty(e: @env, t: @ast::ty, sc: scopes, v: vt<scopes>) {
     fn walk_tps(e: @env, tps: [ast::ty_param], sc: scopes, v: vt<scopes>) {
         let outer_current_tp = e.current_tp;
         let mut current = 0u;
-        for tp in tps {
+        for tps.each {|tp|
             e.current_tp = some(current);
-            for bound in *tp.bounds {
+            for vec::each(*tp.bounds) {|bound|
                 alt bound {
                   bound_iface(t) { v.visit_ty(t, sc, v); }
                   _ {}
@@ -504,7 +502,7 @@ fn visit_item_with_scope(e: @env, i: @ast::item, sc: scopes, v: vt<scopes>) {
         visit::visit_ty_params(tps, sc, v);
         alt ifce { some(ty) { v.visit_ty(ty, sc, v); } _ {} }
         v.visit_ty(sty, sc, v);
-        for m in methods {
+        for methods.each {|m|
             v.visit_ty_params(m.tps, sc, v);
             let msc = cons(scope_method(m.self_id, tps + m.tps), @sc);
             v.visit_fn(visit::fk_method(m.ident, [], m),
@@ -513,9 +511,9 @@ fn visit_item_with_scope(e: @env, i: @ast::item, sc: scopes, v: vt<scopes>) {
       }
       ast::item_iface(tps, methods) {
         visit::visit_ty_params(tps, sc, v);
-        for m in methods {
+        for methods.each {|m|
             let msc = cons(scope_method(i.id, tps + m.tps), @sc);
-            for a in m.decl.inputs { v.visit_ty(a.ty, msc, v); }
+            for m.decl.inputs.each {|a| v.visit_ty(a.ty, msc, v); }
             v.visit_ty(m.decl.output, msc, v);
         }
       }
@@ -530,7 +528,7 @@ fn visit_item_with_scope(e: @env, i: @ast::item, sc: scopes, v: vt<scopes>) {
                             ctor.node.body, ctor.span, ctor.node.id,
                             ctor_scope, v);
         /* visit the items */
-        for cm in members {
+        for members.each {|cm|
             alt cm.node {
               class_method(m) {
                   let msc = cons(scope_method(m.self_id, tps + m.tps),
@@ -571,7 +569,7 @@ fn visit_fn_with_scope(e: @env, fk: visit::fn_kind, decl: ast::fn_decl,
 
     // here's where we need to set up the mapping
     // for f's constrs in the table.
-    for c: @ast::constr in decl.constraints { resolve_constr(e, c, sc, v); }
+    for decl.constraints.each {|c| resolve_constr(e, c, sc, v); }
     let scope = alt fk {
       visit::fk_item_fn(_, tps) | visit::fk_res(_, tps) |
       visit::fk_method(_, tps, _) | visit::fk_ctor(_, tps)
@@ -586,8 +584,8 @@ fn visit_fn_with_scope(e: @env, fk: visit::fn_kind, decl: ast::fn_decl,
 fn visit_block_with_scope(b: ast::blk, sc: scopes, v: vt<scopes>) {
     let pos = @mut 0u, loc = @mut 0u;
     let block_sc = cons(scope_block(b, pos, loc), @sc);
-    for vi in b.node.view_items { v.visit_view_item(vi, block_sc, v); }
-    for stmt in b.node.stmts {
+    for b.node.view_items.each {|vi| v.visit_view_item(vi, block_sc, v); }
+    for b.node.stmts.each {|stmt|
         v.visit_stmt(stmt, block_sc, v);;
         *pos += 1u;;
         *loc = 0u;
@@ -602,31 +600,19 @@ fn visit_decl_with_scope(d: @decl, sc: scopes, v: vt<scopes>) {
     };
     alt d.node {
       decl_local(locs) {
-        for loc in locs { v.visit_local(loc, sc, v);; *loc_pos += 1u; }
+        for locs.each {|loc| v.visit_local(loc, sc, v);; *loc_pos += 1u; }
       }
       decl_item(it) { v.visit_item(it, sc, v); }
     }
 }
 
 fn visit_arm_with_scope(a: ast::arm, sc: scopes, v: vt<scopes>) {
-    for p: @pat in a.pats { v.visit_pat(p, sc, v); }
+    for a.pats.each {|p| v.visit_pat(p, sc, v); }
     let sc_inner = cons(scope_arm(a), @sc);
     visit::visit_expr_opt(a.guard, sc_inner, v);
     v.visit_block(a.body, sc_inner, v);
 }
 
-fn visit_expr_with_scope(x: @ast::expr, sc: scopes, v: vt<scopes>) {
-    alt x.node {
-      ast::expr_for(decl, coll, blk) {
-        let new_sc = cons(scope_loop(decl), @sc);
-        v.visit_expr(coll, sc, v);
-        v.visit_local(decl, new_sc, v);
-        v.visit_block(blk, new_sc, v);
-      }
-      _ { visit::visit_expr(x, sc, v); }
-    }
-}
-
 // This is only for irrefutable patterns (e.g. ones that appear in a let)
 // So if x occurs, and x is already known to be a enum, that's always an error
 fn visit_local_with_scope(e: @env, loc: @local, sc:scopes, v:vt<scopes>) {
@@ -717,7 +703,7 @@ fn register(e: env, id: node_id, cx: ctxt, sp: codemap::span,
     fn find_imports_after(e: env, id: node_id, sc: scopes) -> [node_id] {
         fn lst(my_id: node_id, vis: [@view_item]) -> [node_id] {
             let mut imports = [], found = false;
-            for vi in vis {
+            for vis.each {|vi|
                 iter_effective_import_paths(*vi) {|vp|
                     alt vp.node {
                       view_path_simple(_, _, id)
@@ -726,7 +712,7 @@ fn lst(my_id: node_id, vis: [@view_item]) -> [node_id] {
                         if found { imports += [id]; }
                       }
                       view_path_list(_, ids, _) {
-                        for id in ids {
+                        for ids.each {|id|
                             if id.node.id == my_id { found = true; }
                             if found { imports += [id.node.id]; }
                         }
@@ -844,7 +830,7 @@ fn find_fn_or_mod_scope(sc: scopes) -> option<scope> {
       in_scope(sc) {
         alt find_fn_or_mod_scope(sc) {
           some(err_scope) {
-            for rs: {ident: str, sc: scope} in e.reported {
+            for e.reported.each {|rs|
                 if str::eq(rs.ident, name) && err_scope == rs.sc { ret; }
             }
             e.reported += [{ident: name, sc: err_scope}];
@@ -1115,7 +1101,7 @@ fn in_scope(e: env, sp: span, name: ident, s: scope, ns: namespace) ->
 fn lookup_in_ty_params(e: env, name: ident, ty_params: [ast::ty_param])
     -> option<def> {
     let mut n = 0u;
-    for tp: ast::ty_param in ty_params {
+    for ty_params.each {|tp|
         if str::eq(tp.ident, name) && alt e.current_tp {
             some(cur) { n < cur } none { true }
         } { ret some(ast::def_ty_param(local_def(tp.id), n)); }
@@ -1139,7 +1125,7 @@ fn lookup_in_fn(e: env, name: ident, decl: ast::fn_decl,
                 ns: namespace) -> option<def> {
     alt ns {
       ns_val {
-        for a: ast::arg in decl.inputs {
+        for decl.inputs.each {|a|
             if str::eq(a.ident, name) {
                 ret some(ast::def_arg(a.id, a.mode));
             }
@@ -1189,7 +1175,7 @@ fn lookup_in_block(e: env, name: ident, sp: span, b: ast::blk_, pos: uint,
                     } else {
                         alt ns {
                            ns_val {
-                               for v: ast::variant in variants {
+                               for variants.each {|v|
                                   if str::eq(v.node.name, name) {
                                      let i = v.node.id;
                                      ret some(ast::def_variant
@@ -1216,8 +1202,7 @@ fn lookup_in_block(e: env, name: ident, sp: span, b: ast::blk_, pos: uint,
           _ { }
         }
     }
-    for vi in b.view_items {
-
+    for b.view_items.each {|vi|
         let mut is_import = false;
         alt vi.node {
           ast::view_item_import(_) { is_import = true; }
@@ -1227,7 +1212,7 @@ fn lookup_in_block(e: env, name: ident, sp: span, b: ast::blk_, pos: uint,
         alt vi.node {
 
           ast::view_item_import(vps) | ast::view_item_export(vps) {
-            for vp in vps {
+            for vps.each {|vp|
                 alt vp.node {
                   ast::view_path_simple(ident, _, id) {
                     if is_import && name == ident {
@@ -1236,7 +1221,7 @@ fn lookup_in_block(e: env, name: ident, sp: span, b: ast::blk_, pos: uint,
                   }
 
                   ast::view_path_list(path, idents, _) {
-                    for ident in idents {
+                    for idents.each {|ident|
                         if name == ident.node.name {
                             ret lookup_import(e, ident.node.id, ns);
                         }
@@ -1467,7 +1452,7 @@ fn lookup_in_mod_(e: env, def: glob_imp_def, sp: span, name: ident,
     else if vec::len(matches) == 1u {
         ret some(matches[0].def);
     } else {
-        for match: glob_imp_def in matches {
+        for matches.each {|match|
             let sp = match.path.span;
             e.sess.span_note(sp, #fmt["'%s' is imported here", id]);
         }
@@ -1546,7 +1531,7 @@ fn add_to_index(index: hashmap<ident, list<mod_index_entry>>, id: ident,
 
 fn index_view_items(view_items: [@ast::view_item],
                     index: hashmap<ident, list<mod_index_entry>>) {
-    for vi in view_items {
+    for view_items.each {|vi|
         alt vi.node {
           ast::view_item_use(ident, _, id) {
            add_to_index(index, ident, mie_view_item(ident, id, vi.span));
@@ -1560,7 +1545,7 @@ fn index_view_items(view_items: [@ast::view_item],
                 add_to_index(index, ident, mie_import_ident(id, vp.span));
               }
               ast::view_path_list(_, idents, _) {
-                for ident in idents {
+                for idents.each {|ident|
                     add_to_index(index, ident.node.name,
                                  mie_import_ident(ident.node.id,
                                                   ident.span));
@@ -1579,7 +1564,7 @@ fn index_mod(md: ast::_mod) -> mod_index {
 
     index_view_items(md.view_items, index);
 
-    for it: @ast::item in md.items {
+    for md.items.each {|it|
         alt it.node {
           ast::item_const(_, _) | ast::item_fn(_, _, _) | ast::item_mod(_) |
           ast::item_native_mod(_) | ast::item_ty(_, _) |
@@ -1590,7 +1575,7 @@ fn index_mod(md: ast::_mod) -> mod_index {
           ast::item_enum(variants, _) {
             add_to_index(index, it.ident, mie_item(it));
             let mut variant_idx: uint = 0u;
-            for v: ast::variant in variants {
+            for variants.each {|v|
                 add_to_index(index, v.node.name,
                              mie_enum_variant(variant_idx, variants,
                                              it.id, it.span));
@@ -1619,7 +1604,7 @@ fn index_nmod(md: ast::native_mod) -> mod_index {
 
     index_view_items(md.view_items, index);
 
-    for it: @ast::native_item in md.items {
+    for md.items.each {|it|
         add_to_index(index, it.ident, mie_native_item(it));
     }
     ret index;
@@ -1649,11 +1634,12 @@ fn ns_ok(wanted:namespace, actual:namespace) -> bool {
 
 fn lookup_external(e: env, cnum: int, ids: [ident], ns: namespace) ->
    option<def> {
-    for d: def in csearch::lookup_defs(e.sess.cstore, cnum, ids) {
+    let mut result = none;
+    for csearch::lookup_defs(e.sess.cstore, cnum, ids).each {|d|
         e.ext_map.insert(def_id_of_def(d), ids);
-        if ns_ok(ns, ns_for_def(d)) { ret some(d); }
+        if ns_ok(ns, ns_for_def(d)) { result = some(d); }
     }
-    ret none;
+    ret result;
 }
 
 
@@ -1720,7 +1706,7 @@ fn mie_span(mie: mod_index_entry) -> span {
 fn check_item(e: @env, i: @ast::item, &&x: (), v: vt<()>) {
     fn typaram_names(tps: [ast::ty_param]) -> [ident] {
         let mut x: [ast::ident] = [];
-        for tp: ast::ty_param in tps { x += [tp.ident]; }
+        for tps.each {|tp| x += [tp.ident]; }
         ret x;
     }
     visit::visit_item(i, x, v);
@@ -1769,7 +1755,7 @@ fn check_arm(e: @env, a: ast::arm, &&x: (), v: vt<()>) {
             e.sess.span_err(a.pats[i].span,
                             "inconsistent number of bindings");
         } else {
-            for name: ident in ch.seen {
+            for ch.seen.each {|name|
                 if is_none(vec::find(seen0, bind str::eq(name, _))) {
                     // Fight the alias checker
                     let name_ = name;
@@ -1787,13 +1773,13 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
     let values = checker(*e, "value");
     let types = checker(*e, "type");
     let mods = checker(*e, "module");
-    for st: @ast::stmt in b.node.stmts {
+    for b.node.stmts.each {|st|
         alt st.node {
           ast::stmt_decl(d, _) {
             alt d.node {
               ast::decl_local(locs) {
                 let local_values = checker(*e, "value");
-                for loc in locs {
+                for locs.each {|loc|
                      pat_util::pat_bindings(e.def_map, loc.node.pat)
                          {|_i, p_sp, n|
                          let ident = path_to_ident(n);
@@ -1806,7 +1792,7 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
                 alt it.node {
                   ast::item_enum(variants, _) {
                     add_name(types, it.span, it.ident);
-                    for v: ast::variant in variants {
+                    for variants.each {|v|
                         add_name(values, v.span, v.node.name);
                     }
                   }
@@ -1868,7 +1854,7 @@ fn checker(e: env, kind: str) -> checker {
 }
 
 fn check_name(ch: checker, sp: span, name: ident) {
-    for s: ident in ch.seen {
+    for ch.seen.each {|s|
         if str::eq(s, name) {
             ch.sess.span_fatal(sp, "duplicate " + ch.kind + " name: " + name);
         }
@@ -1882,7 +1868,7 @@ fn add_name(ch: checker, sp: span, name: ident) {
 fn ensure_unique<T>(e: env, sp: span, elts: [T], id: fn(T) -> ident,
                     kind: str) {
     let ch = checker(e, kind);
-    for elt: T in elts { add_name(ch, sp, id(elt)); }
+    for elts.each {|elt| add_name(ch, sp, id(elt)); }
 }
 
 fn check_exports(e: @env) {
@@ -1908,7 +1894,7 @@ fn iter_mod(e: env, m: def, sp: span, _dr: dir,
                             [ found_def_item(item, ns_val),
                              found_def_item(item, ns_type),
                              found_def_item(item, ns_module) ];
-                        for d in defs {
+                        for defs.each {|d|
                             alt d {
                               some(def) {
                                 f(ident, def);
@@ -1942,7 +1928,7 @@ fn lookup_glob_any(e: @env, info: @indexed_mod, sp: span,
 
 
     fn maybe_add_reexport(e: @env, export_id: node_id, def: option<def>) {
-        option::with_option_do(def) {|def|
+        option::iter(def) {|def|
             add_export(e, export_id, def_id_of_def(def), true);
         }
     }
@@ -2015,7 +2001,7 @@ fn check_export_enum_list(e: @env, export_id: node_id, _mod: @indexed_mod,
                               ids: [ast::path_list_ident]) {
         let parent_id = check_enum_ok(e, span, id, _mod);
         add_export(e, export_id, local_def(parent_id), false);
-        for variant_id in ids {
+        for ids.each {|variant_id|
             let mut found = false;
             alt _mod.index.find(variant_id.node.name) {
               some(ms) {
@@ -2048,7 +2034,7 @@ enum %s",
           some(m) {
             let glob_is_re_exported = int_hash();
 
-            for vi in m.view_items {
+            for m.view_items.each {|vi|
                 iter_export_paths(*vi) { |vp|
                     alt vp.node {
                       ast::view_path_simple(ident, _, id) {
@@ -2071,7 +2057,7 @@ enum %s",
             }
             // Now follow the export-glob links and fill in the
             // globbed_exports and exp_map lists.
-            for glob in _mod.glob_imports {
+            for _mod.glob_imports.each {|glob|
                 let id = alt check glob.path.node {
                   ast::view_path_glob(_, node_id) { node_id }
                 };
@@ -2124,10 +2110,10 @@ fn lookup_imported_impls(e: env, id: node_id,
           ast::view_path_simple(name, pt, id) {
             let mut found = [];
             if vec::len(*pt) == 1u {
-                option::with_option_do(sc) {|sc|
+                option::iter(sc) {|sc|
                     list::iter(sc) {|level|
                         if vec::len(found) == 0u {
-                            for imp in *level {
+                            for vec::each(*level) {|imp|
                                 if imp.ident == pt[0] {
                                     found += [@{ident: name with *imp}];
                                 }
@@ -2138,13 +2124,15 @@ fn lookup_imported_impls(e: env, id: node_id,
                 }
             } else {
                 lookup_imported_impls(e, id) {|is|
-                    for i in *is { impls += [@{ident: name with *i}]; }
+                    for vec::each(*is) {|i|
+                        impls += [@{ident: name with *i}];
+                    }
                 }
             }
           }
 
           ast::view_path_list(base, names, _) {
-            for nm in names {
+            for names.each {|nm|
                 lookup_imported_impls(e, nm.node.id) {|is| impls += *is; }
             }
           }
@@ -2198,10 +2186,10 @@ fn find_impls_in_mod_by_id(e: env, defid: def_id, &impls: [@_impl],
             let mut tmp = [];
             let mi = e.mod_map.get(defid.node);
             let md = option::get(mi.m);
-            for vi in md.view_items {
+            for md.view_items.each {|vi|
                 find_impls_in_view_item(e, vi, tmp, none);
             }
-            for i in md.items {
+            for md.items.each {|i|
                 find_impls_in_item(e, i, tmp, none, none);
             }
             @vec::filter(tmp) {|i| is_exported(e, i.ident, mi)}
@@ -2213,7 +2201,7 @@ fn find_impls_in_mod_by_id(e: env, defid: def_id, &impls: [@_impl],
     }
     alt name {
       some(n) {
-        for im in *cached {
+        for vec::each(*cached) {|im|
             if n == im.ident { impls += [im]; }
         }
       }
@@ -2234,10 +2222,10 @@ fn find_impls_in_mod(e: env, m: def, &impls: [@_impl],
 fn visit_block_with_impl_scope(e: @env, b: ast::blk, sc: iscopes,
                                v: vt<iscopes>) {
     let mut impls = [];
-    for vi in b.node.view_items {
+    for b.node.view_items.each {|vi|
         find_impls_in_view_item(*e, vi, impls, some(sc));
     }
-    for st in b.node.stmts {
+    for b.node.stmts.each {|st|
         alt st.node {
           ast::stmt_decl(@{node: ast::decl_item(i), _}, _) {
             find_impls_in_item(*e, i, impls, none, none);
@@ -2252,10 +2240,10 @@ fn visit_block_with_impl_scope(e: @env, b: ast::blk, sc: iscopes,
 fn visit_mod_with_impl_scope(e: @env, m: ast::_mod, s: span, id: node_id,
                              sc: iscopes, v: vt<iscopes>) {
     let mut impls = [];
-    for vi in m.view_items {
+    for m.view_items.each {|vi|
         find_impls_in_view_item(*e, vi, impls, some(sc));
     }
-    for i in m.items { find_impls_in_item(*e, i, impls, none, none); }
+    for m.items.each {|i| find_impls_in_item(*e, i, impls, none, none); }
     let impls = @impls;
     visit::visit_mod(m, s, id, if vec::len(*impls) > 0u {
                                    cons(impls, @sc)
index 7cd14b7af3948405aa85560bb809fd71525bd149..ed1c95dcd4a753cda0a1eaf4bc2365532c2e1820 100644 (file)
@@ -1657,7 +1657,7 @@ fn trans_if(cx: block, cond: @ast::expr, thn: ast::blk,
     let then_cx = scope_block(bcx, "then");
     then_cx.block_span = some(thn.span);
     let else_cx = scope_block(bcx, "else");
-    option::with_option_do(els) {|e| else_cx.block_span = some(e.span); }
+    option::iter(els) {|e| else_cx.block_span = some(e.span); }
     CondBr(bcx, cond_val, then_cx.llbb, else_cx.llbb);
     let then_bcx = trans_block(then_cx, thn, then_dest);
     let then_bcx = trans_block_cleanups(then_bcx, then_cx);
@@ -1685,39 +1685,6 @@ fn trans_if(cx: block, cond: @ast::expr, thn: ast::blk,
     ret join_returns(cx, [then_bcx, else_bcx], [then_dest, else_dest], dest);
 }
 
-fn trans_for(cx: block, local: @ast::local, seq: @ast::expr,
-             body: ast::blk) -> block {
-    let _icx = cx.insn_ctxt("trans_for");
-    fn inner(bcx: block, local: @ast::local, curr: ValueRef, t: ty::t,
-             body: ast::blk, outer_next_cx: block) -> block {
-        let next_cx = sub_block(bcx, "next");
-        let scope_cx = loop_scope_block(bcx, cont_other(next_cx),
-                                        outer_next_cx, "for loop scope",
-                                        body.span);
-        Br(bcx, scope_cx.llbb);
-        let curr = PointerCast(bcx, curr,
-                               T_ptr(type_of(bcx.ccx(), t)));
-        let bcx = alt::bind_irrefutable_pat(scope_cx, local.node.pat,
-                                                  curr, false);
-        let bcx = trans_block(bcx, body, ignore);
-        cleanup_and_Br(bcx, scope_cx, next_cx.llbb);
-        ret next_cx;
-    }
-    let ccx = cx.ccx();
-    let next_cx = sub_block(cx, "next");
-    let seq_ty = expr_ty(cx, seq);
-    let {bcx: bcx, val: seq} = trans_temp_expr(cx, seq);
-    let seq = PointerCast(bcx, seq, T_ptr(ccx.opaque_vec_type));
-    let mut fill = tvec::get_fill(bcx, seq);
-    if ty::type_is_str(seq_ty) {
-        fill = Sub(bcx, fill, C_int(ccx, 1));
-    }
-    let bcx = tvec::iter_vec_raw(bcx, seq, seq_ty, fill,
-                                 bind inner(_, local, _, _, body, next_cx));
-    Br(bcx, next_cx.llbb);
-    ret next_cx;
-}
-
 fn trans_while(cx: block, cond: @ast::expr, body: ast::blk)
     -> block {
     let _icx = cx.insn_ctxt("trans_while");
@@ -2750,7 +2717,7 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t, ret_ty: ty::t,
             Unreachable(bcx);
         } else if ret_in_loop {
             bcx = with_cond(bcx, Load(bcx, option::get(ret_flag))) {|bcx|
-                option::with_option_do(bcx.fcx.loop_ret) {|lret|
+                option::iter(bcx.fcx.loop_ret) {|lret|
                     Store(bcx, C_bool(true), lret.flagptr);
                     Store(bcx, C_bool(false), bcx.fcx.llretptr);
                 }
@@ -2788,7 +2755,7 @@ fn need_invoke(bcx: block) -> bool {
     loop {
         alt cur.kind {
           block_scope(info) {
-            for cleanup in info.cleanups {
+            for info.cleanups.each {|cleanup|
                 alt cleanup {
                   clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) {
                     if cleanup_type == normal_exit_and_unwind {
@@ -2925,7 +2892,7 @@ fn trans_rec(bcx: block, fields: [ast::field],
     let ty_fields = alt check ty::get(t).struct { ty::ty_rec(f) { f } };
 
     let mut temp_cleanups = [];
-    for fld in fields {
+    for fields.each {|fld|
         let ix = option::get(vec::position(ty_fields, {|ft|
             str::eq(fld.node.ident, ft.ident)
         }));
@@ -2940,7 +2907,7 @@ fn trans_rec(bcx: block, fields: [ast::field],
         let mut i = 0;
         bcx = cx;
         // Copy over inherited fields
-        for tf in ty_fields {
+        for ty_fields.each {|tf|
             if !vec::any(fields, {|f| str::eq(f.node.ident, tf.ident)}) {
                 let dst = GEPi(bcx, addr, [0, i]);
                 let base = GEPi(bcx, base_val, [0, i]);
@@ -2955,7 +2922,7 @@ fn trans_rec(bcx: block, fields: [ast::field],
 
     // Now revoke the cleanups as we pass responsibility for the data
     // structure on to the caller
-    for cleanup in temp_cleanups { revoke_clean(bcx, cleanup); }
+    for temp_cleanups.each {|cleanup| revoke_clean(bcx, cleanup); }
     ret bcx;
 }
 
@@ -3148,10 +3115,6 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
             trans_check_expr(bcx, a, "Claim")
         };
       }
-      ast::expr_for(decl, seq, body) {
-        assert dest == ignore;
-        ret trans_for(bcx, decl, seq, body);
-      }
       ast::expr_while(cond, body) {
         assert dest == ignore;
         ret trans_while(bcx, cond, body);
@@ -3707,15 +3670,16 @@ fn cleanup_and_leave(bcx: block, upto: option<BasicBlockRef>,
     let _icx = bcx.insn_ctxt("cleanup_and_leave");
     let mut cur = bcx, bcx = bcx;
     let is_lpad = leave == none;
+    let mut done = false;
     loop {
         alt cur.kind {
           block_scope(info) if info.cleanups.len() > 0u {
-            for cp in info.cleanup_paths {
-                if cp.target == leave {
-                    Br(bcx, cp.dest);
-                    ret;
-                }
+            option::iter(vec::find(info.cleanup_paths,
+                                             {|cp| cp.target == leave})) {|cp|
+                Br(bcx, cp.dest);
+                done = true;
             }
+            if done { ret; }
             let sub_cx = sub_block(bcx, "cleanup");
             Br(bcx, sub_cx.llbb);
             info.cleanup_paths += [{target: leave, dest: sub_cx.llbb}];
@@ -3822,7 +3786,7 @@ fn alloc_local(cx: block, local: @ast::local) -> block {
     }
     let val = alloc_ty(cx, t);
     if cx.sess().opts.debuginfo {
-        option::with_option_do(simple_name) {|name|
+        option::iter(simple_name) {|name|
             str::as_c_str(name, {|buf|
                 llvm::LLVMSetValueName(val, buf)
             });
@@ -4318,7 +4282,7 @@ fn trans_class_ctor(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
   let mut bcx = bcx_top;
   // Initialize fields to zero so init assignments can validly
   // drop their LHS
-  for field in fields {
+  for fields.each {|field|
      let ix = field_idx_strict(bcx.tcx(), sp, field.ident, fields);
      bcx = zero_alloca(bcx, GEPi(bcx, selfptr, [0, ix]),
                        field.mt.ty);
@@ -4784,14 +4748,16 @@ fn create_module_map(ccx: @crate_ctxt) -> ValueRef {
 }
 
 
-fn decl_crate_map(sess: session::session, mapname: str,
+fn decl_crate_map(sess: session::session, mapmeta: link::link_meta,
                   llmod: ModuleRef) -> ValueRef {
     let targ_cfg = sess.targ_cfg;
     let int_type = T_int(targ_cfg);
     let mut n_subcrates = 1;
     let cstore = sess.cstore;
     while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; }
-    let mapname = if sess.building_library { mapname } else { "toplevel" };
+    let mapname = if sess.building_library {
+        mapmeta.name + "_" + mapmeta.vers + "_" + mapmeta.extras_hash
+    } else { "toplevel" };
     let sym_name = "_rust_crate_map_" + mapname;
     let arrtype = T_array(int_type, n_subcrates as uint);
     let maptype = T_struct([int_type, arrtype]);
@@ -4802,13 +4768,15 @@ fn decl_crate_map(sess: session::session, mapname: str,
     ret map;
 }
 
-// FIXME use hashed metadata instead of crate names once we have that
 fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
     let mut subcrates: [ValueRef] = [];
     let mut i = 1;
     let cstore = ccx.sess.cstore;
     while cstore::have_crate_data(cstore, i) {
-        let nm = "_rust_crate_map_" + cstore::get_crate_data(cstore, i).name;
+        let cdata = cstore::get_crate_data(cstore, i);
+        let nm = "_rust_crate_map_" + cdata.name +
+            "_" + cstore::get_crate_vers(cstore, i) +
+            "_" + cstore::get_crate_hash(cstore, i);
         let cr = str::as_c_str(nm, {|buf|
             llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf)
         });
@@ -4893,7 +4861,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt,
     lib::llvm::associate_type(tn, "taskptr", taskptr_type);
     let tydesc_type = T_tydesc(targ_cfg);
     lib::llvm::associate_type(tn, "tydesc", tydesc_type);
-    let crate_map = decl_crate_map(sess, link_meta.name, llmod);
+    let crate_map = decl_crate_map(sess, link_meta, llmod);
     let dbg_cx = if sess.opts.debuginfo {
         option::some(debuginfo::mk_ctxt(llmod_id))
     } else {
index 8bcb022799c3a9547d31d34cf5ea7f5f9abeb577..36dfc3eb19c5310c29eff59e6c6f6cfbb07f8d7d 100644 (file)
@@ -325,7 +325,7 @@ fn build_closure(bcx0: block,
           }
         }
     }
-    option::with_option_do(include_ret_handle) {|flagptr|
+    option::iter(include_ret_handle) {|flagptr|
         let our_ret = alt bcx.fcx.loop_ret {
           some({retptr, _}) { retptr }
           none { bcx.fcx.llretptr }
index 2878180f96059c3bfb51aa3081876ba322156921..c089361bda0421e741adc95685e388d50f225fd9 100644 (file)
@@ -280,19 +280,13 @@ fn add_clean_free(cx: block, ptr: ValueRef, shared: bool) {
 // drop glue checks whether it is zero.
 fn revoke_clean(cx: block, val: ValueRef) {
     in_scope_cx(cx) {|info|
-        let mut i = 0u;
-        for cu in info.cleanups {
-            alt cu {
-              clean_temp(v, _, _) if v == val {
-                info.cleanups =
-                    vec::slice(info.cleanups, 0u, i) +
-                    vec::slice(info.cleanups, i + 1u, info.cleanups.len());
-                scope_clean_changed(info);
-                break;
-              }
-              _ {}
-            }
-            i += 1u;
+        option::iter(vec::position(info.cleanups, {|cu|
+            alt cu { clean_temp(v, _, _) if v == val { true } _ { false } }
+        })) {|i|
+            info.cleanups =
+                vec::slice(info.cleanups, 0u, i) +
+                vec::slice(info.cleanups, i + 1u, info.cleanups.len());
+            scope_clean_changed(info);
         }
     }
 }
@@ -842,7 +836,7 @@ fn hash_mono_id(&&mi: mono_id) -> uint {
         h = h * alt param {
           mono_precise(ty, vts) {
             let mut h = ty::type_id(ty);
-            option::with_option_do(vts) {|vts|
+            option::iter(vts) {|vts|
                 for vec::each(vts) {|vt| h += hash_mono_id(vt); }
             }
             h
index cbca8f63a52c4450cfbe0b6753022eeb354d9eea..42f762ac1b535469fac830efeb4ecca8e9b0e133 100644 (file)
@@ -152,7 +152,7 @@ fn cached_metadata<T: copy>(cache: metadata_cache, mdtag: int,
                            eq: fn(md: T) -> bool) -> option<T> unsafe {
     if cache.contains_key(mdtag) {
         let items = cache.get(mdtag);
-        for item in items {
+        for items.each {|item|
             let md: T = md_from_metadata::<T>(item);
             if eq(md) {
                 ret option::some(md);
@@ -421,7 +421,7 @@ fn create_record(cx: @crate_ctxt, t: ty::t, fields: [ast::ty_field],
                                option::get(cx.dbg_cx).names("rec"),
                                line_from_span(cx.sess.codemap,
                                               span) as int);
-    for field in fields {
+    for fields.each {|field|
         let field_t = ty::get_field(t, field.node.ident).mt.ty;
         let ty_md = create_ty(cx, field_t, field.node.mt.ty);
         let (size, align) = size_and_align_of(cx, field_t);
index 00745b77f5765abbaebd86f95c851ec323f6e8bb..6e522196343d5b01e11dc7e29f756536d31e401c 100644 (file)
@@ -51,7 +51,7 @@ fn traverse_exports(cx: ctx, vis: [@view_item]) -> bool {
 }
 
 fn traverse_export(cx: ctx, exp_id: node_id) {
-    option::with_option_do(cx.exp_map.find(exp_id)) {|defs|
+    option::iter(cx.exp_map.find(exp_id)) {|defs|
         for vec::each(defs) {|def| traverse_def_id(cx, def.id); }
     }
 }
index 49efb8a00cc29f861ad8fab92475bc502829dff7..5460b4c8f28744fd3603ef0cb498ff7d8aa99e11 100644 (file)
@@ -372,7 +372,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
       ty::ty_class(did, ts) {
         // same as records
         let mut s = [shape_struct], sub = [];
-        for f:field in ty::class_items_as_fields(ccx.tcx, did, ts) {
+        for ty::class_items_as_fields(ccx.tcx, did, ts).each {|f|
             sub += shape_of(ccx, f.mt.ty, ty_param_map);
         }
         add_substr(s, sub);
@@ -465,7 +465,7 @@ fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef {
     let data_sz = vec::len(data) as u16;
 
     let mut info_sz = 0u16;
-    for did_ in ccx.shape_cx.tag_order {
+    for ccx.shape_cx.tag_order.each {|did_|
         let did = did_; // Satisfy alias checker.
         let num_variants = vec::len(*ty::enum_variants(ccx.tcx, did)) as u16;
         add_u16(header, header_sz + info_sz);
@@ -478,7 +478,7 @@ fn gen_enum_shapes(ccx: @crate_ctxt) -> ValueRef {
 
     let mut lv_table = [];
     i = 0u;
-    for did_ in ccx.shape_cx.tag_order {
+    for ccx.shape_cx.tag_order.each {|did_|
         let did = did_; // Satisfy alias checker.
         let variants = ty::enum_variants(ccx.tcx, did);
         add_u16(info, vec::len(*variants) as u16);
index 3705831e36feb26bbf0ca7dae3954ffc4bdb6222..b220f30a5ac3c125dedf73f47f28ee1f7a1cf560 100644 (file)
@@ -146,7 +146,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
         }
       }
       expr_path(_) {
-        option::with_option_do(cx.ccx.tcx.node_type_substs.find(e.id)) {|ts|
+        option::iter(cx.ccx.tcx.node_type_substs.find(e.id)) {|ts|
             let id = ast_util::def_id_of_def(cx.ccx.tcx.def_map.get(e.id));
             vec::iter2(type_uses_for(cx.ccx, id, ts.len()), ts) {|uses, subst|
                 type_needs(cx, uses, subst)
@@ -190,7 +190,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
             }
         }
       }
-      expr_for(_, _, _) | expr_do_while(_, _) | expr_alt(_, _, _) |
+      expr_do_while(_, _) | expr_alt(_, _, _) |
       expr_block(_) | expr_if(_, _, _) | expr_while(_, _) |
       expr_fail(_) | expr_break | expr_cont | expr_unary(_, _) |
       expr_lit(_) | expr_assert(_) | expr_check(_, _) |
@@ -215,7 +215,7 @@ fn handle_body(cx: ctx, body: blk) {
         },
         visit_block: {|b, cx, v|
             visit::visit_block(b, cx, v);
-            option::with_option_do(b.node.expr) {|e|
+            option::iter(b.node.expr) {|e|
                 node_type_needs(cx, use_repr, e.id);
             }
         },
index 3693f22d6e28244e51fd8b224a58fe9c3834e727..c2677e184c46def2efbbb3c4611136d172f2a751 100644 (file)
@@ -38,7 +38,7 @@ fn node_ids_in_fn(tcx: ty::ctxt, body: blk, rs: @mut [node_id]) {
 }
 
 fn init_vecs(ccx: crate_ctxt, node_ids: [node_id], len: uint) {
-    for i: node_id in node_ids {
+    for node_ids.each {|i|
         log(debug, int::str(i) + " |-> " + uint::str(len));
         add_node(ccx, i, empty_ann(len));
     }
index 1cd78f890fc00d9f66eb0fad99c57249410c2710..7f97aed65bcda33ce570aaeac7ab0c81bc4e5baa 100644 (file)
@@ -37,7 +37,7 @@ fn def_id_to_str(d: def_id) -> str {
 fn comma_str(args: [@constr_arg_use]) -> str {
     let mut rslt = "";
     let mut comma = false;
-    for a: @constr_arg_use in args {
+    for args.each {|a|
         if comma { rslt += ", "; } else { comma = true; }
         alt a.node {
           carg_base { rslt += "*"; }
@@ -66,7 +66,7 @@ fn constraint_to_str(tcx: ty::ctxt, c: sp_constr) -> str {
 fn tritv_to_str(fcx: fn_ctxt, v: tritv::t) -> str {
     let mut s = "";
     let mut comma = false;
-    for p: norm_constraint in constraints(fcx) {
+    for constraints(fcx).each {|p|
         alt tritv_get(v, p.bit_num) {
           dont_care { }
           tt {
@@ -86,11 +86,12 @@ fn log_tritv(fcx: fn_ctxt, v: tritv::t) {
 
 fn first_difference_string(fcx: fn_ctxt, expected: tritv::t, actual: tritv::t)
    -> str {
-    let s: str = "";
-    for c: norm_constraint in constraints(fcx) {
+    let mut s = "";
+    for constraints(fcx).each {|c|
         if tritv_get(expected, c.bit_num) == ttrue &&
                tritv_get(actual, c.bit_num) != ttrue {
-            ret constraint_to_str(fcx.ccx.tcx, c.c);
+            s = constraint_to_str(fcx.ccx.tcx, c.c);
+            break;
         }
     }
     ret s;
@@ -102,7 +103,7 @@ fn log_tritv_err(fcx: fn_ctxt, v: tritv::t) {
 
 fn tos(v: [uint]) -> str {
     let mut rslt = "";
-    for i: uint in v {
+    for v.each {|i|
         if i == 0u {
             rslt += "0";
         } else if i == 1u { rslt += "1"; } else { rslt += "?"; }
@@ -539,7 +540,7 @@ fn norm_a_constraint(id: def_id, c: constraint) -> [norm_constraint] {
       }
       cpred(p, descs) {
         let mut rslt: [norm_constraint] = [];
-        for pd: pred_args in *descs {
+        for vec::each(*descs) {|pd|
             rslt +=
                 [{bit_num: pd.node.bit_num,
                   c: respan(pd.span, npred(p, id, pd.node.args))}];
@@ -567,7 +568,7 @@ fn match_args(fcx: fn_ctxt, occs: @mut [pred_args],
               occ: [@constr_arg_use]) -> uint {
     #debug("match_args: looking at %s",
            constr_args_to_str(fn@(i: inst) -> str { ret i.ident; }, occ));
-    for pd: pred_args in *occs {
+    for vec::each(*occs) {|pd|
         log(debug,
                  "match_args: candidate " + pred_args_to_str(pd));
         fn eq(p: inst, q: inst) -> bool { ret p.node == q.node; }
@@ -619,7 +620,7 @@ fn expr_to_constr_arg(tcx: ty::ctxt, e: @expr) -> @constr_arg_use {
 fn exprs_to_constr_args(tcx: ty::ctxt, args: [@expr]) -> [@constr_arg_use] {
     let f = bind expr_to_constr_arg(tcx, _);
     let mut rslt: [@constr_arg_use] = [];
-    for e: @expr in args { rslt += [f(e)]; }
+    for args.each {|e| rslt += [f(e)]; }
     rslt
 }
 
@@ -653,7 +654,7 @@ fn pred_args_to_str(p: pred_args) -> str {
 fn substitute_constr_args(cx: ty::ctxt, actuals: [@expr], c: @ty::constr) ->
    tsconstr {
     let mut rslt: [@constr_arg_use] = [];
-    for a: @constr_arg in c.node.args {
+    for c.node.args.each {|a|
         rslt += [substitute_arg(cx, actuals, a)];
     }
     ret npred(c.node.path, c.node.id, rslt);
@@ -678,7 +679,7 @@ fn substitute_arg(cx: ty::ctxt, actuals: [@expr], a: @constr_arg) ->
 fn pred_args_matches(pattern: [constr_arg_general_<inst>], desc: pred_args) ->
    bool {
     let mut i = 0u;
-    for c: @constr_arg_use in desc.node.args {
+    for desc.node.args.each {|c|
         let n = pattern[i];
         alt c.node {
           carg_ident(p) {
@@ -702,7 +703,7 @@ fn pred_args_matches(pattern: [constr_arg_general_<inst>], desc: pred_args) ->
 
 fn find_instance_(pattern: [constr_arg_general_<inst>], descs: [pred_args]) ->
    option<uint> {
-    for d: pred_args in descs {
+    for descs.each {|d|
         if pred_args_matches(pattern, d) { ret some(d.node.bit_num); }
     }
     ret none;
@@ -720,7 +721,7 @@ fn find_instances(_fcx: fn_ctxt, subst: subst, c: constraint) ->
     alt c {
       cinit(_, _, _) {/* this is dealt with separately */ }
       cpred(p, descs) {
-        for d: pred_args in *descs {
+        for vec::each(copy *descs) {|d|
             if args_mention(d.node.args, find_in_subst_bool, subst) {
                 let old_bit_num = d.node.bit_num;
                 let newv = replace(subst, d);
@@ -736,7 +737,7 @@ fn find_instances(_fcx: fn_ctxt, subst: subst, c: constraint) ->
 }
 
 fn find_in_subst(id: node_id, s: subst) -> option<inst> {
-    for p: {from: inst, to: inst} in s {
+    for s.each {|p|
         if id == p.from.node { ret some(p.to); }
     }
     ret none;
@@ -748,7 +749,7 @@ fn find_in_subst_bool(s: subst, id: node_id) -> bool {
 
 fn insts_to_str(stuff: [constr_arg_general_<inst>]) -> str {
     let mut rslt = "<";
-    for i: constr_arg_general_<inst> in stuff {
+    for stuff.each {|i|
         rslt +=
             " " +
                 alt i {
@@ -763,7 +764,7 @@ fn insts_to_str(stuff: [constr_arg_general_<inst>]) -> str {
 
 fn replace(subst: subst, d: pred_args) -> [constr_arg_general_<inst>] {
     let mut rslt: [constr_arg_general_<inst>] = [];
-    for c: @constr_arg_use in d.node.args {
+    for d.node.args.each {|c|
         alt c.node {
           carg_ident(p) {
             alt find_in_subst(p.node, subst) {
@@ -872,7 +873,7 @@ fn copy_in_poststate_two(fcx: fn_ctxt, src_post: poststate,
         // replace any occurrences of the src def_id with the
         // dest def_id
         let insts = find_instances(fcx, subst, val);
-        for p: {from: uint, to: uint} in insts {
+        for insts.each {|p|
             if promises_(p.from, src_post) {
                 set_in_poststate_(p.to, target_post);
             }
@@ -887,7 +888,7 @@ fn forget_in_postcond(fcx: fn_ctxt, parent_exp: node_id, dead_v: node_id) {
     let d = local_node_id_to_local_def_id(fcx, dead_v);
     alt d {
       some(d_id) {
-        for c: norm_constraint in constraints(fcx) {
+        for constraints(fcx).each {|c|
             if constraint_mentions(fcx, c, d_id) {
                 #debug("clearing constraint %u %s",
                        c.bit_num,
@@ -909,7 +910,7 @@ fn forget_in_postcond_still_init(fcx: fn_ctxt, parent_exp: node_id,
     let d = local_node_id_to_local_def_id(fcx, dead_v);
     alt d {
       some(d_id) {
-        for c: norm_constraint in constraints(fcx) {
+        for constraints(fcx).each {|c|
             if non_init_constraint_mentions(fcx, c, d_id) {
                 clear_in_postcond(c.bit_num,
                                   node_id_to_ts_ann(fcx.ccx,
@@ -928,7 +929,7 @@ fn forget_in_poststate(fcx: fn_ctxt, p: poststate, dead_v: node_id) -> bool {
     let mut changed = false;
     alt d {
       some(d_id) {
-        for c: norm_constraint in constraints(fcx) {
+        for constraints(fcx).each {|c|
             if constraint_mentions(fcx, c, d_id) {
                 changed |= clear_in_poststate_(c.bit_num, p);
             }
@@ -947,7 +948,7 @@ fn forget_in_poststate_still_init(fcx: fn_ctxt, p: poststate, dead_v: node_id)
     let mut changed = false;
     alt d {
       some(d_id) {
-        for c: norm_constraint in constraints(fcx) {
+        for constraints(fcx).each {|c|
             if non_init_constraint_mentions(fcx, c, d_id) {
                 changed |= clear_in_poststate_(c.bit_num, p);
             }
@@ -959,7 +960,7 @@ fn forget_in_poststate_still_init(fcx: fn_ctxt, p: poststate, dead_v: node_id)
 }
 
 fn any_eq(v: [node_id], d: node_id) -> bool {
-    for i: node_id in v { if i == d { ret true; } }
+    for v.each {|i| if i == d { ret true; } }
     false
 }
 
@@ -1000,7 +1001,7 @@ fn mentions<T>(&[T] s, &fn(&[T], def_id) -> bool q,
     ret vec::any(bind mentions(s,q,_), args);
     */
 
-    for a: @constr_arg_use in args {
+    for args.each {|a|
         alt a.node { carg_ident(p1) { if q(s, p1.node) { ret true; } } _ { } }
     }
     ret false;
@@ -1010,7 +1011,7 @@ fn mentions<T>(&[T] s, &fn(&[T], def_id) -> bool q,
 
 // FIXME: This should be a function in vec::.
 fn vec_contains(v: @mut [node_id], i: node_id) -> bool {
-    for d: node_id in *v { if d == i { ret true; } }
+    for vec::each(*v) {|d| if d == i { ret true; } }
     ret false;
 }
 
@@ -1029,7 +1030,7 @@ fn args_to_constr_args(tcx: ty::ctxt, args: [arg],
                        indices: [@sp_constr_arg<uint>]) -> [@constr_arg_use] {
     let mut actuals: [@constr_arg_use] = [];
     let num_args = vec::len(args);
-    for a: @sp_constr_arg<uint> in indices {
+    for indices.each {|a|
         actuals +=
             [@respan(a.span,
                      alt a.node {
@@ -1075,7 +1076,7 @@ fn local_to_bindings(tcx: ty::ctxt, loc: @local) -> binding {
 
 fn locals_to_bindings(tcx: ty::ctxt, locals: [@local]) -> [binding] {
     let mut rslt = [];
-    for loc in locals { rslt += [local_to_bindings(tcx, loc)]; }
+    for locals.each {|loc| rslt += [local_to_bindings(tcx, loc)]; }
     ret rslt;
 }
 
@@ -1085,7 +1086,7 @@ fn callee_modes(fcx: fn_ctxt, callee: node_id) -> [mode] {
     alt ty::get(ty).struct {
       ty::ty_fn({inputs: args, _}) {
         let mut modes = [];
-        for arg: ty::arg in args { modes += [arg.mode]; }
+        for args.each {|arg| modes += [arg.mode]; }
         ret modes;
       }
       _ {
@@ -1108,7 +1109,7 @@ fn callee_arg_init_ops(fcx: fn_ctxt, callee: node_id) -> [init_op] {
 fn anon_bindings(ops: [init_op], es: [@expr]) -> [binding] {
     let mut bindings: [binding] = [];
     let mut i = 0;
-    for op: init_op in ops {
+    for ops.each {|op|
         bindings += [{lhs: [], rhs: some({op: op, expr: es[i]})}];
         i += 1;
     }
index 1c1235ae4ed17235fed33b3de82c6c361984048c..ee2a159371ec754a7d22ef407051bb3a607b5d36 100644 (file)
@@ -67,7 +67,7 @@ fn seq_postconds(fcx: fn_ctxt, ps: [postcond]) -> postcond {
     let sz = vec::len(ps);
     if sz >= 1u {
         let prev = tritv_clone(ps[0]);
-        for p: postcond in vec::slice(ps, 1u, sz) { seq_tritv(prev, p); }
+        vec::iter_between(ps, 1u, sz) {|p| seq_tritv(prev, p); }
         ret prev;
     } else { ret ann::empty_poststate(num_constraints(fcx.enclosing)); }
 }
index 843a8f24896481a0835b50f3fe126299780fb780..decf1af6401cbc3da562ee9324b6690ff3d2608a 100644 (file)
@@ -19,7 +19,7 @@
 fn check_unused_vars(fcx: fn_ctxt) {
 
     // FIXME: could be more efficient
-    for c: norm_constraint in constraints(fcx) {
+    for constraints(fcx).each {|c|
         alt c.c.node {
           ninit(id, v) {
             if !vec_contains(fcx.enclosing.used_vars, id) && v[0] != '_' as u8
index 90099df649272035715319311170fbc4a733fb59..b6f1de95984b6582d7b44b2a75d2021fb3d331b4 100644 (file)
@@ -27,7 +27,7 @@ fn collect_pred(e: @expr, cx: ctxt, v: visit::vt<ctxt>) {
       // If it's a call, generate appropriate instances of the
       // call's constraints.
       expr_call(operator, operands, _) {
-        for c: @ty::constr in constraints_expr(cx.tcx, operator) {
+        for constraints_expr(cx.tcx, operator).each {|c|
             let ct: sp_constr =
                 respan(c.span,
                        aux::substitute_constr_args(cx.tcx, operands, c));
@@ -105,20 +105,21 @@ fn mk_fn_info(ccx: crate_ctxt,
     /* now we have to add bit nums for both the constraints
        and the variables... */
 
-    for c: sp_constr in { *cx.cs } {
-        next = add_constraint(cx.tcx, c, next, res_map);
+    let mut i = 0u, l = vec::len(*cx.cs);
+    while i < l {
+        next = add_constraint(cx.tcx, cx.cs[i], next, res_map);
+        i += 1u;
     }
     /* if this function has any constraints, instantiate them to the
        argument names and add them */
-    let mut sc;
-    for c: @constr in f_decl.constraints {
-        sc = ast_constr_to_sp_constr(cx.tcx, f_decl.inputs, c);
+    for f_decl.constraints.each {|c|
+        let sc = ast_constr_to_sp_constr(cx.tcx, f_decl.inputs, c);
         next = add_constraint(cx.tcx, sc, next, res_map);
     }
 
     /* Need to add constraints for args too, b/c they
     can be deinitialized */
-    for a: arg in f_decl.inputs {
+    for f_decl.inputs.each {|a|
         next = add_constraint(
             cx.tcx,
             respan(f_sp, ninit(a.id, a.ident)),
index 43ebc69ba3ff689fc6634eafa404fe59ce27966a..ec7c8354d8c717bf2b881aab27389a2b67ebd7f4 100644 (file)
@@ -60,7 +60,9 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) {
       item_class(_,_,_) {
           fail "find_pre_post_item: implement item_class";
       }
-      item_impl(_, _, _, ms) { for m in ms { find_pre_post_method(ccx, m); } }
+      item_impl(_, _, _, ms) {
+        for ms.each {|m| find_pre_post_method(ccx, m); }
+      }
     }
 }
 
@@ -75,7 +77,7 @@ fn find_pre_post_exprs(fcx: fn_ctxt, args: [@expr], id: node_id) {
         log_expr(*args[0]);
     }
     fn do_one(fcx: fn_ctxt, e: @expr) { find_pre_post_expr(fcx, e); }
-    for e: @expr in args { do_one(fcx, e); }
+    for args.each {|e| do_one(fcx, e); }
 
     fn get_pp(ccx: crate_ctxt, &&e: @expr) -> pre_and_post {
         ret expr_pp(ccx, e);
@@ -282,7 +284,7 @@ fn forget_args_moved_in(fcx: fn_ctxt, parent: @expr, modes: [mode],
 fn find_pre_post_expr_fn_upvars(fcx: fn_ctxt, e: @expr) {
     let rslt = expr_pp(fcx.ccx, e);
     clear_pp(rslt);
-    for def in *freevars::get_freevars(fcx.ccx.tcx, e.id) {
+    for vec::each(*freevars::get_freevars(fcx.ccx.tcx, e.id)) {|def|
         log(debug, ("handle_var_def: def=", def));
         handle_var_def(fcx, rslt, def.def, "upvar");
     }
@@ -304,7 +306,7 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
 
         find_pre_post_exprs(fcx, args, e.id);
         /* see if the call has any constraints on its type */
-        for c: @ty::constr in constraints_expr(fcx.ccx.tcx, operator) {
+        for constraints_expr(fcx.ccx.tcx, operator).each {|c|
             let i =
                 bit_num(fcx, substitute_constr_args(fcx.ccx.tcx, args, c));
             require(i, expr_pp(fcx.ccx, e));
@@ -336,7 +338,7 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
 
         let use_cap_item = fn@(&&cap_item: @capture_item) {
             let d = local_node_id_to_local_def_id(fcx, cap_item.id);
-            option::with_option_do(d, { |id| use_var(fcx, id) });
+            option::iter(d, { |id| use_var(fcx, id) });
         };
         vec::iter(cap_clause.copies, use_cap_item);
         vec::iter(cap_clause.moves, use_cap_item);
@@ -451,9 +453,6 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
         set_pre_and_post(fcx.ccx, e.id, block_precond(fcx.ccx, body),
                          loop_postcond);
       }
-      expr_for(d, index, body) {
-        find_pre_post_loop(fcx, d, index, body, e.id);
-      }
       expr_index(val, sub) { find_pre_post_exprs(fcx, [val, sub], e.id); }
       expr_alt(ex, alts, _) {
         find_pre_post_expr(fcx, ex);
@@ -466,7 +465,7 @@ fn do_an_alt(fcx: fn_ctxt, an_alt: arm) -> pre_and_post {
             ret block_pp(fcx.ccx, an_alt.body);
         }
         let mut alt_pps = [];
-        for a: arm in alts { alt_pps += [do_an_alt(fcx, a)]; }
+        for alts.each {|a| alt_pps += [do_an_alt(fcx, a)]; }
         fn combine_pp(antec: pre_and_post, fcx: fn_ctxt, &&pp: pre_and_post,
                       &&next: pre_and_post) -> pre_and_post {
             union(pp.precondition, seq_preconds(fcx, [antec, next]));
@@ -517,7 +516,7 @@ fn combine_pp(antec: pre_and_post, fcx: fn_ctxt, &&pp: pre_and_post,
         let mut cmodes = callee_modes(fcx, operator.id);
         let mut modes = [];
         let mut i = 0;
-        for expr_opt: option<@expr> in maybe_args {
+        for maybe_args.each {|expr_opt|
             alt expr_opt {
               none {/* no-op */ }
               some(expr) { modes += [cmodes[i]]; args += [expr]; }
@@ -541,9 +540,8 @@ fn find_pre_post_stmt(fcx: fn_ctxt, s: stmt) {
       stmt_decl(adecl, id) {
         alt adecl.node {
           decl_local(alocals) {
-            let mut e_pp;
             let prev_pp = empty_pre_post(num_constraints(fcx.enclosing));
-            for alocal in alocals {
+            for alocals.each {|alocal|
                 alt alocal.node.init {
                   some(an_init) {
                     /* LHS always becomes initialized,
@@ -586,7 +584,7 @@ fn find_pre_post_stmt(fcx: fn_ctxt, s: stmt) {
 
                     /* Clear out anything that the previous initializer
                     guaranteed */
-                    e_pp = expr_pp(fcx.ccx, an_init.expr);
+                    let e_pp = expr_pp(fcx.ccx, an_init.expr);
                     tritv_copy(prev_pp.precondition,
                                seq_preconds(fcx, [prev_pp, e_pp]));
                     /* Include the LHSs too, since those aren't in the
@@ -650,13 +648,13 @@ fn do_one_(fcx: fn_ctxt, s: @stmt) {
                 log_pp_err(stmt_pp(fcx.ccx, *s));
         */
     }
-    for s: @stmt in b.node.stmts { do_one_(fcx, s); }
+    for b.node.stmts.each {|s| do_one_(fcx, s); }
     fn do_inner_(fcx: fn_ctxt, &&e: @expr) { find_pre_post_expr(fcx, e); }
     let do_inner = bind do_inner_(fcx, _);
     option::map::<@expr, ()>(b.node.expr, do_inner);
 
     let mut pps: [pre_and_post] = [];
-    for s: @stmt in b.node.stmts { pps += [stmt_pp(fcx.ccx, *s)]; }
+    for b.node.stmts.each {|s| pps += [stmt_pp(fcx.ccx, *s)]; }
     alt b.node.expr {
       none {/* no-op */ }
       some(e) { pps += [expr_pp(fcx.ccx, e)]; }
@@ -665,7 +663,7 @@ fn do_one_(fcx: fn_ctxt, s: @stmt) {
     let block_precond = seq_preconds(fcx, pps);
 
     let mut postconds = [];
-    for pp: pre_and_post in pps { postconds += [get_post(pp)]; }
+    for pps.each {|pp| postconds += [get_post(pp)]; }
 
     /* A block may be empty, so this next line ensures that the postconds
        vector is non-empty. */
index 8f1b11fd576545d1ef67a91f61c19f2589a7b534..8ec37b9c0cb673174b3c5351a8bd1fe6f71d248f 100644 (file)
@@ -67,14 +67,14 @@ fn seq_states(fcx: fn_ctxt, pres: prestate, bindings: [binding]) ->
    {changed: bool, post: poststate} {
     let mut changed = false;
     let mut post = tritv_clone(pres);
-    for b: binding in bindings {
+    for bindings.each {|b|
         alt b.rhs {
           some(an_init) {
             // an expression, with or without a destination
             changed |=
                 find_pre_post_state_expr(fcx, post, an_init.expr) || changed;
             post = tritv_clone(expr_poststate(fcx.ccx, an_init.expr));
-            for i: inst in b.lhs {
+            for b.lhs.each {|i|
                 alt an_init.expr.node {
                   expr_path(p) {
                     handle_move_or_copy(fcx, post, p, an_init.expr.id, i,
@@ -91,7 +91,7 @@ fn seq_states(fcx: fn_ctxt, pres: prestate, bindings: [binding]) ->
             }
           }
           none {
-            for i: inst in b.lhs {
+            for b.lhs.each {|i|
                 // variables w/o an initializer
                 clear_in_poststate_ident_(fcx, i.node, i.ident, post);
             }
@@ -375,7 +375,7 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
         let callee_ops = callee_arg_init_ops(fcx, operator.id);
         let mut ops = [];
         let mut i = 0;
-        for a_opt: option<@expr> in maybe_args {
+        for maybe_args.each {|a_opt|
             alt a_opt {
               none {/* no-op */ }
               some(a) { ops += [callee_ops[i]]; args += [a]; }
@@ -410,7 +410,7 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
 
         let base_pres = alt vec::last_opt(exs) { none { pres }
                           some(f) { expr_poststate(fcx.ccx, f) }};
-        option::with_option_do(maybe_base, {|base|
+        option::iter(maybe_base, {|base|
             changed |= find_pre_post_state_expr(fcx, base_pres, base) |
               set_poststate_ann(fcx.ccx, e.id,
                                 expr_poststate(fcx.ccx, base))});
@@ -561,9 +561,6 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
                                             false_postcond(num_constrs));
         }
       }
-      expr_for(d, index, body) {
-        ret find_pre_post_state_loop(fcx, pres, d, index, body, e.id);
-      }
       expr_index(val, sub) {
         ret find_pre_post_state_two(fcx, pres, val, sub, e.id, oper_pure);
       }
@@ -575,7 +572,7 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
         let mut a_post;
         if vec::len(alts) > 0u {
             a_post = false_postcond(num_constrs);
-            for an_alt: arm in alts {
+            for alts.each {|an_alt|
                 alt an_alt.guard {
                   some(e) {
                     changed |= find_pre_post_state_expr(fcx, e_post, e);
@@ -611,7 +608,7 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
         handle_fail(fcx, pres, post);
         ret set_prestate_ann(fcx.ccx, e.id, pres) |
                 set_poststate_ann(fcx.ccx, e.id, post) |
-                option::with_option(maybe_fail_val, false, {|fail_val|
+                option::map_default(maybe_fail_val, false, {|fail_val|
                         find_pre_post_state_expr(fcx, pres, fail_val)});
       }
       expr_check(_, p) {
@@ -702,7 +699,7 @@ fn find_pre_post_state_block(fcx: fn_ctxt, pres0: prestate, b: blk) -> bool {
      initializes.  Then <pres> becomes the new poststate. */
 
     let mut changed = false;
-    for s: @stmt in b.node.stmts {
+    for b.node.stmts.each {|s|
         changed |= find_pre_post_state_stmt(fcx, pres, s);
         pres = stmt_poststate(fcx.ccx, *s);
     }
@@ -745,12 +742,12 @@ fn find_pre_post_state_fn(fcx: fn_ctxt,
 
     // Arguments start out initialized
     let block_pre = block_prestate(fcx.ccx, f_body);
-    for a: arg in f_decl.inputs {
+    for f_decl.inputs.each {|a|
         set_in_prestate_constr(fcx, ninit(a.id, a.ident), block_pre);
     }
 
     // Instantiate any constraints on the arguments so we can use them
-    for c: @constr in f_decl.constraints {
+    for f_decl.constraints.each {|c|
         let tsc = ast_constr_to_ts_constr(fcx.ccx.tcx, f_decl.inputs, c);
         set_in_prestate_constr(fcx, tsc, block_pre);
     }
index 89c34064f6d19c508851315348e022fcc50d0b35..094d2f90d5d9a2ff019d673bf43528aad97fbe81 100644 (file)
@@ -267,6 +267,7 @@ enum region {
     re_free(node_id, bound_region),
     re_scope(node_id),
     re_var(region_vid),
+    re_static, // effectively `top` in the region lattice
     re_default
 }
 
@@ -340,7 +341,9 @@ enum type_err {
     terr_mode_mismatch(mode, mode),
     terr_constr_len(uint, uint),
     terr_constr_mismatch(@type_constr, @type_constr),
-    terr_regions_differ(bool /* variance */, region, region),
+    terr_regions_differ(region, region),
+    terr_in_field(@type_err, str),
+    terr_sorts(t, t)
 }
 
 enum param_bound {
@@ -369,7 +372,7 @@ fn to_str() -> str { #fmt["<R%u>", self.to_uint()] }
 
 fn param_bounds_to_kind(bounds: param_bounds) -> kind {
     let mut kind = kind_noncopyable;
-    for bound in *bounds {
+    for vec::each(*bounds) {|bound|
         alt bound {
           bound_copy {
             if kind != kind_sendable { kind = kind_copyable; }
@@ -408,7 +411,7 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
            region_map: @middle::region::region_map) -> ctxt {
     let interner = map::hashmap({|&&k: intern_key|
         hash_type_structure(k.struct) +
-            option::with_option(k.o_def_id, 0u, ast_util::hash_def_id)
+            option::map_default(k.o_def_id, 0u, ast_util::hash_def_id)
     }, {|&&a, &&b| a == b});
     @{interner: interner,
       mut next_id: 0u,
@@ -461,7 +464,9 @@ fn derive_flags(&has_params: bool, &has_vars: bool, &has_rptrs: bool,
       ty_param(_, _) { has_params = true; }
       ty_var(_) | ty_self(_) { has_vars = true; }
       ty_enum(_, tys) | ty_iface(_, tys) | ty_class(_, tys) {
-        for tt in tys { derive_flags(has_params, has_vars, has_rptrs, tt); }
+        for tys.each {|tt|
+            derive_flags(has_params, has_vars, has_rptrs, tt);
+        }
       }
       ty_box(m) | ty_uniq(m) | ty_vec(m) | ty_ptr(m) {
         derive_flags(has_params, has_vars, has_rptrs, m.ty);
@@ -475,22 +480,24 @@ fn derive_flags(&has_params: bool, &has_vars: bool, &has_rptrs: bool,
         derive_flags(has_params, has_vars, has_rptrs, m.ty);
       }
       ty_rec(flds) {
-        for f in flds {
+        for flds.each {|f|
           derive_flags(has_params, has_vars, has_rptrs, f.mt.ty);
         }
       }
       ty_tup(ts) {
-        for tt in ts { derive_flags(has_params, has_vars, has_rptrs, tt); }
+        for ts.each {|tt| derive_flags(has_params, has_vars, has_rptrs, tt); }
       }
       ty_fn(f) {
-        for a in f.inputs {
+        for f.inputs.each {|a|
           derive_flags(has_params, has_vars, has_rptrs, a.ty);
         }
         derive_flags(has_params, has_vars, has_rptrs, f.output);
       }
       ty_res(_, tt, tps) {
         derive_flags(has_params, has_vars, has_rptrs, tt);
-        for tt in tps { derive_flags(has_params, has_vars, has_rptrs, tt); }
+        for tps.each {|tt|
+            derive_flags(has_params, has_vars, has_rptrs, tt);
+        }
       }
       ty_constr(tt, _) {
         derive_flags(has_params, has_vars, has_rptrs, tt);
@@ -630,19 +637,19 @@ fn maybe_walk_ty(ty: t, f: fn(t) -> bool) {
       }
       ty_enum(_, subtys) | ty_iface(_, subtys) | ty_class(_, subtys)
        | ty_self(subtys) {
-        for subty: t in subtys { maybe_walk_ty(subty, f); }
+        for subtys.each {|subty| maybe_walk_ty(subty, f); }
       }
       ty_rec(fields) {
-        for fl: field in fields { maybe_walk_ty(fl.mt.ty, f); }
+        for fields.each {|fl| maybe_walk_ty(fl.mt.ty, f); }
       }
-      ty_tup(ts) { for tt in ts { maybe_walk_ty(tt, f); } }
+      ty_tup(ts) { for ts.each {|tt| maybe_walk_ty(tt, f); } }
       ty_fn(ft) {
-        for a: arg in ft.inputs { maybe_walk_ty(a.ty, f); }
+        for ft.inputs.each {|a| maybe_walk_ty(a.ty, f); }
         maybe_walk_ty(ft.output, f);
       }
       ty_res(_, sub, tps) {
         maybe_walk_ty(sub, f);
-        for tp: t in tps { maybe_walk_ty(tp, f); }
+        for tps.each {|tp| maybe_walk_ty(tp, f); }
       }
       ty_constr(sub, _) { maybe_walk_ty(sub, f); }
       ty_uniq(tm) { maybe_walk_ty(tm.ty, f); }
@@ -892,23 +899,24 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
       ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
       ty_type | ty_ptr(_) | ty_rptr(_, _) { false }
       ty_rec(flds) {
-        for f in flds { if type_needs_drop(cx, f.mt.ty) { accum = true; } }
+        for flds.each {|f| if type_needs_drop(cx, f.mt.ty) { accum = true; } }
         accum
       }
       ty_class(did, ts) {
-          for f in ty::class_items_as_fields(cx, did, ts)
-          { if type_needs_drop(cx, f.mt.ty) { accum = true; } }
+        for vec::each(ty::class_items_as_fields(cx, did, ts)) {|f|
+            if type_needs_drop(cx, f.mt.ty) { accum = true; }
+        }
         accum
       }
 
       ty_tup(elts) {
-        for m in elts { if type_needs_drop(cx, m) { accum = true; } }
+        for elts.each {|m| if type_needs_drop(cx, m) { accum = true; } }
         accum
       }
       ty_enum(did, tps) {
         let variants = enum_variants(cx, did);
-        for variant in *variants {
-            for aty in variant.args {
+        for vec::each(*variants) {|variant|
+            for variant.args.each {|aty|
                 // Perform any type parameter substitutions.
                 let arg_ty = substitute_type_params(cx, tps, aty);
                 if type_needs_drop(cx, arg_ty) { accum = true; }
@@ -965,8 +973,8 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t,
             true
           }
           ty_enum(did, tps) {
-            for v in *enum_variants(cx, did) {
-                for aty in v.args {
+            for vec::each(*enum_variants(cx, did)) {|v|
+                for v.args.each {|aty|
                     let t = substitute_type_params(cx, tps, aty);
                     needs_unwind_cleanup |=
                         type_needs_unwind_cleanup_(cx, t, tycache,
@@ -1065,13 +1073,15 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
       // Records lower to the lowest of their members.
       ty_rec(flds) {
         let mut lowest = kind_sendable;
-        for f in flds { lowest = lower_kind(lowest, type_kind(cx, f.mt.ty)); }
+        for flds.each {|f|
+            lowest = lower_kind(lowest, type_kind(cx, f.mt.ty));
+        }
         lowest
       }
       // Tuples lower to the lowest of their members.
       ty_tup(tys) {
         let mut lowest = kind_sendable;
-        for ty in tys { lowest = lower_kind(lowest, type_kind(cx, ty)); }
+        for tys.each {|ty| lowest = lower_kind(lowest, type_kind(cx, ty)); }
         lowest
       }
       // Enums lower to the lowest of their variants.
@@ -1081,8 +1091,8 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
         if vec::len(*variants) == 0u {
             lowest = kind_noncopyable;
         } else {
-            for variant in *variants {
-                for aty in variant.args {
+            for vec::each(*variants) {|variant|
+                for variant.args.each {|aty|
                     // Perform any type parameter substitutions.
                     let arg_ty = substitute_type_params(cx, tps, aty);
                     lowest = lower_kind(lowest, type_kind(cx, arg_ty));
@@ -1243,8 +1253,8 @@ fn type_structurally_contains(cx: ctxt, ty: t, test: fn(sty) -> bool) ->
     if test(sty) { ret true; }
     alt sty {
       ty_enum(did, tps) {
-        for variant in *enum_variants(cx, did) {
-            for aty in variant.args {
+        for vec::each(*enum_variants(cx, did)) {|variant|
+            for variant.args.each {|aty|
                 let sty = substitute_type_params(cx, tps, aty);
                 if type_structurally_contains(cx, sty, test) { ret true; }
             }
@@ -1252,13 +1262,13 @@ fn type_structurally_contains(cx: ctxt, ty: t, test: fn(sty) -> bool) ->
         ret false;
       }
       ty_rec(fields) {
-        for field in fields {
+        for fields.each {|field|
             if type_structurally_contains(cx, field.mt.ty, test) { ret true; }
         }
         ret false;
       }
       ty_tup(ts) {
-        for tt in ts {
+        for ts.each {|tt|
             if type_structurally_contains(cx, tt, test) { ret true; }
         }
         ret false;
@@ -1339,7 +1349,7 @@ fn type_is_pod(cx: ctxt, ty: t) -> bool {
       // Structural types
       ty_enum(did, tps) {
         let variants = enum_variants(cx, did);
-        for variant: variant_info in *variants {
+        for vec::each(*variants) {|variant|
             let tup_ty = mk_tup(cx, variant.args);
 
             // Perform any type parameter substitutions.
@@ -1348,12 +1358,12 @@ fn type_is_pod(cx: ctxt, ty: t) -> bool {
         }
       }
       ty_rec(flds) {
-        for f: field in flds {
+        for flds.each {|f|
             if !type_is_pod(cx, f.mt.ty) { result = false; }
         }
       }
       ty_tup(elts) {
-        for elt in elts { if !type_is_pod(cx, elt) { result = false; } }
+        for elts.each {|elt| if !type_is_pod(cx, elt) { result = false; } }
       }
       ty_res(_, inner, tps) {
         result = type_is_pod(cx, substitute_type_params(cx, tps, inner));
@@ -1449,14 +1459,14 @@ fn hash_def(id: uint, did: ast::def_id) -> uint {
     fn hash_subty(id: uint, subty: t) -> uint { (id << 2u) + type_id(subty) }
     fn hash_subtys(id: uint, subtys: [t]) -> uint {
         let mut h = id;
-        for s in subtys { h = (h << 2u) + type_id(s) }
+        for subtys.each {|s| h = (h << 2u) + type_id(s) }
         h
     }
     fn hash_type_constr(id: uint, c: @type_constr) -> uint {
         let mut h = id;
         h = (h << 2u) + hash_def(h, c.node.id);
         // FIXME this makes little sense
-        for a in c.node.args {
+        for c.node.args.each {|a|
             alt a.node {
               carg_base { h += h << 2u; }
               carg_lit(_) { fail "lit args not implemented yet"; }
@@ -1473,6 +1483,7 @@ fn hash_region(r: region) -> uint {
           re_scope(id)  { ((id as uint) << 2u) | 2u }
           re_var(id)    { (id.to_uint() << 2u) | 3u }
           re_default    { 4u }
+          re_bot        { 5u }
         }
     }
     alt st {
@@ -1495,27 +1506,27 @@ fn hash_region(r: region) -> uint {
       ty_str { 17u }
       ty_enum(did, tys) {
         let mut h = hash_def(18u, did);
-        for typ: t in tys { h = hash_subty(h, typ); }
+        for tys.each {|typ| h = hash_subty(h, typ); }
         h
       }
       ty_box(mt) { hash_subty(19u, mt.ty) }
       ty_vec(mt) { hash_subty(21u, mt.ty) }
       ty_rec(fields) {
         let mut h = 26u;
-        for f in fields { h = hash_subty(h, f.mt.ty); }
+        for fields.each {|f| h = hash_subty(h, f.mt.ty); }
         h
       }
       ty_tup(ts) { hash_subtys(25u, ts) }
       ty_fn(f) {
         let mut h = 27u;
-        for a in f.inputs { h = hash_subty(h, a.ty); }
+        for f.inputs.each {|a| h = hash_subty(h, a.ty); }
         hash_subty(h, f.output)
       }
       ty_var(v) { hash_uint(30u, v.to_uint()) }
       ty_param(pid, did) { hash_def(hash_uint(31u, pid), did) }
       ty_self(ts) {
         let mut h = 28u;
-        for t in ts { h = hash_subty(h, t); }
+        for ts.each {|t| h = hash_subty(h, t); }
         h
       }
       ty_type { 32u }
@@ -1531,13 +1542,13 @@ fn hash_region(r: region) -> uint {
       }
       ty_constr(t, cs) {
         let mut h = hash_subty(36u, t);
-        for c in cs { h = (h << 2u) + hash_type_constr(h, c); }
+        for cs.each {|c| h = (h << 2u) + hash_type_constr(h, c); }
         h
       }
       ty_uniq(mt) { hash_subty(37u, mt.ty) }
       ty_iface(did, tys) {
         let mut h = hash_def(40u, did);
-        for typ: t in tys { h = hash_subty(h, typ); }
+        for tys.each {|typ| h = hash_subty(h, typ); }
         h
       }
       ty_opaque_closure_ptr(ck_block) { 41u }
@@ -1546,7 +1557,7 @@ fn hash_region(r: region) -> uint {
       ty_opaque_box { 44u }
       ty_class(did, tys) {
           let mut h = hash_def(45u, did);
-          for typ: t in tys { h = hash_subty(h, typ); }
+          for tys.each {|typ| h = hash_subty(h, typ); }
           h
       }
     }
@@ -1575,7 +1586,7 @@ fn args_eq<T>(eq: fn(T, T) -> bool,
               a: [@sp_constr_arg<T>],
               b: [@sp_constr_arg<T>]) -> bool {
     let mut i: uint = 0u;
-    for arg: @sp_constr_arg<T> in a {
+    for a.each {|arg|
         if !arg_eq(eq, arg, b[i]) { ret false; }
         i += 1u;
     }
@@ -1592,7 +1603,7 @@ fn constr_eq(c: @constr, d: @constr) -> bool {
 fn constrs_eq(cs: [@constr], ds: [@constr]) -> bool {
     if vec::len(cs) != vec::len(ds) { ret false; }
     let mut i = 0u;
-    for c: @constr in cs { if !constr_eq(c, ds[i]) { ret false; } i += 1u; }
+    for cs.each {|c| if !constr_eq(c, ds[i]) { ret false; } i += 1u; }
     ret true;
 }
 
@@ -1717,7 +1728,7 @@ fn stmt_node_id(s: @ast::stmt) -> ast::node_id {
 
 fn field_idx(id: ast::ident, fields: [field]) -> option<uint> {
     let mut i = 0u;
-    for f in fields { if f.ident == id { ret some(i); } i += 1u; }
+    for fields.each {|f| if f.ident == id { ret some(i); } i += 1u; }
     ret none;
 }
 
@@ -1735,7 +1746,7 @@ fn get_fields(rec_ty:t) -> [field] {
 
 fn method_idx(id: ast::ident, meths: [method]) -> option<uint> {
     let mut i = 0u;
-    for m in meths { if m.ident == id { ret some(i); } i += 1u; }
+    for meths.each {|m| if m.ident == id { ret some(i); } i += 1u; }
     ret none;
 }
 
@@ -1835,6 +1846,33 @@ fn set_default_mode(cx: ctxt, m: ast::mode, m_def: ast::rmode) {
     }
 }
 
+fn ty_sort_str(cx: ctxt, t: t) -> str {
+    alt get(t).struct {
+      ty_nil | ty_bot | ty_bool | ty_int(_) |
+      ty_uint(_) | ty_float(_) | ty_str | ty_type | ty_opaque_box |
+      ty_opaque_closure_ptr(_) {
+        ty_to_str(cx, t)
+      }
+
+      ty_enum(_, _) { "enum" }
+      ty_box(_) { "@-ptr" }
+      ty_uniq(_) { "~-ptr" }
+      ty_vec(_) { "vector" }
+      ty_ptr(_) { "*-ptr" }
+      ty_rptr(_, _) { "&-ptr" }
+      ty_rec(_) { "record" }
+      ty_fn(_) { "fn" }
+      ty_iface(_, _) { "iface" }
+      ty_class(_, _) { "class" }
+      ty_res(_, _, _) { "resource" }
+      ty_tup(_) { "tuple" }
+      ty_var(_) { "variable" }
+      ty_param(_, _) { "type parameter" }
+      ty_self(_) { "self" }
+      ty_constr(t, _) { ty_sort_str(cx, t) }
+    }
+}
+
 fn type_err_to_str(cx: ctxt, err: type_err) -> str {
     alt err {
       terr_mismatch { ret "types differ"; }
@@ -1874,8 +1912,8 @@ fn to_str(s: ast::ret_style) -> str {
       }
       terr_record_mutability { ret "record elements differ in mutability"; }
       terr_record_fields(e_fld, a_fld) {
-        ret "expected a record with field '" + e_fld +
-                "' but found one with field '" + a_fld + "'";
+        ret "expected a record with field `" + e_fld +
+                "` but found one with field `" + a_fld + "`";
       }
       terr_arg_count { ret "incorrect number of function parameters"; }
       terr_mode_mismatch(e_mode, a_mode) {
@@ -1892,16 +1930,18 @@ fn to_str(s: ast::ret_style) -> str {
                 " but found one with constraint " +
                 ty_constr_to_str(a_constr);
       }
-      terr_regions_differ(true, region_a, region_b) {
-        ret #fmt("reference lifetime %s does not match reference lifetime %s",
-                 region_to_str(cx, region_a), region_to_str(cx, region_b));
-      }
-      terr_regions_differ(false, subregion, superregion) {
+      terr_regions_differ(subregion, superregion) {
         ret #fmt("references with lifetime %s do not outlive references with \
                   lifetime %s",
                  region_to_str(cx, subregion),
                  region_to_str(cx, superregion));
       }
+      terr_in_field(err, fname) {
+        ret #fmt("in field `%s`, %s", fname, type_err_to_str(cx, *err));
+      }
+      terr_sorts(exp, act) {
+        ret #fmt("%s vs %s", ty_sort_str(cx, exp), ty_sort_str(cx, act));
+      }
     }
 }
 
@@ -2181,7 +2221,7 @@ fn lookup_class_method_by_name(cx:ctxt, did: ast::def_id, name: ident,
                                sp: span) -> def_id {
     if check is_local(did) {
        let ms = lookup_class_method_ids(cx, did);
-       for m in ms {
+       for ms.each {|m|
          if m.name == name {
              ret ast_util::local_def(m.id);
          }
@@ -2196,7 +2236,7 @@ fn lookup_class_method_by_name(cx:ctxt, did: ast::def_id, name: ident,
 
 fn class_field_tys(items: [@class_member]) -> [field_ty] {
     let mut rslt = [];
-    for it in items {
+    for items.each {|it|
        alt it.node {
           instance_var(nm, _, cm, id, privacy) {
               rslt += [{ident: nm, id: ast_util::local_def(id),
@@ -2214,7 +2254,7 @@ fn class_field_tys(items: [@class_member]) -> [field_ty] {
 fn class_items_as_fields(cx:ctxt, did: ast::def_id, substs: [ty::t])
     -> [field] {
     let mut rslt = [];
-    for f in lookup_class_fields(cx, did) {
+    for lookup_class_fields(cx, did).each {|f|
        // consider all instance vars mut, because the
        // constructor may mutate all vars
        rslt += [{ident: f.ident, mt:
index 9fcef5055867e61f0174abdb5a63b6b689d217e1..83b07b9e86c691d602e715b1fd656c6718d8132a 100644 (file)
@@ -20,6 +20,7 @@
 import std::serialization::{serialize_uint, deserialize_uint};
 import std::ufind;
 import syntax::print::pprust::*;
+import util::common::indent;
 
 export check_crate;
 export method_map;
@@ -231,8 +232,10 @@ fn instantiate_path(fcx: @fn_ctxt, pth: @ast::path,
 // Type tests
 fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t {
     alt infer::resolve_type_structure(fcx.infcx, tp) {
-      result::ok(typ_s) { ret typ_s; }
-      result::err(_) {
+      // note: the bot type doesn't count as resolved; it's what we use when
+      // there is no information about a variable.
+      result::ok(t_s) if !ty::type_is_bot(t_s) { ret t_s; }
+      _ {
         fcx.ccx.tcx.sess.span_fatal
             (sp, "the type of this value must be known in this context");
       }
@@ -316,7 +319,7 @@ fn instantiate(tcx: ty::ctxt, sp: span, mode: mode, id: ast::def_id,
             tcx.sess.span_fatal(sp, "wrong number of type arguments for a \
                                      polymorphic type");
         }
-        for ast_ty: @ast::ty in args {
+        for args.each {|ast_ty|
             param_bindings += [do_ast_ty_to_ty(tcx, mode, ast_ty)];
         }
         #debug("substituting(%s into %s)",
@@ -366,6 +369,9 @@ fn do_ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty)
               ast::re_self | ast::re_named(_) {
                 tcx.region_map.ast_type_to_region.get(region.id)
               }
+              ast::re_static {
+                ty::re_static
+              }
             };
             ty::mk_rptr(tcx, r, ast_mt_to_mt(tcx, mode, mt))
           }
@@ -375,7 +381,7 @@ fn do_ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty)
           }
           ast::ty_rec(fields) {
             let mut flds: [field] = [];
-            for f: ast::ty_field in fields {
+            for fields.each {|f|
                 let tm = ast_mt_to_mt(tcx, mode, f.node.mt);
                 flds += [{ident: f.node.ident, mt: tm}];
             }
@@ -432,7 +438,7 @@ fn do_ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty)
           }
           ast::ty_constr(t, cs) {
             let mut out_cs = [];
-            for constr: @ast::ty_constr in cs {
+            for cs.each {|constr|
                 out_cs += [ty::ast_constr_to_constr(tcx, constr)];
             }
             ty::mk_constr(tcx, do_ast_ty_to_ty(tcx, mode, t), out_cs)
@@ -695,12 +701,12 @@ fn ty_of_native_fn_decl(tcx: ty::ctxt, mode: mode, decl: ast::fn_decl,
 fn ty_param_bounds(tcx: ty::ctxt, mode: mode, params: [ast::ty_param])
     -> @[ty::param_bounds] {
     let mut result = [];
-    for param in params {
+    for params.each {|param|
         result += [alt tcx.ty_param_bounds.find(param.id) {
           some(bs) { bs }
           none {
             let mut bounds = [];
-            for b in *param.bounds {
+            for vec::each(*param.bounds) {|b|
                 bounds += [alt b {
                   ast::bound_send { ty::bound_send }
                   ast::bound_copy { ty::bound_copy }
@@ -990,7 +996,7 @@ fn get_enum_variant_types(tcx: ty::ctxt, enum_ty: ty::t,
                               variants: [ast::variant],
                               ty_params: [ast::ty_param]) {
         // Create a set of parameter types shared among all the variants.
-        for variant in variants {
+        for variants.each {|variant|
             // Nullary enum constructors get turned into constants; n-ary enum
             // constructors get turned into functions.
             let result_ty = if vec::len(variant.node.args) == 0u {
@@ -999,7 +1005,7 @@ fn get_enum_variant_types(tcx: ty::ctxt, enum_ty: ty::t,
                 // As above, tell ast_ty_to_ty() that trans_ty_item_to_ty()
                 // should be called to resolve named types.
                 let mut args: [arg] = [];
-                for va: ast::variant_arg in variant.node.args {
+                for variant.node.args.each {|va|
                     let arg_ty = {
                         // NDM We need BOUNDS here.  It should be that this
                         // yields a type like "foo &anon".  Basically every
@@ -1057,7 +1063,7 @@ fn convert_methods(tcx: ty::ctxt, ms: [@ast::method],
         i_bounds: @[ty::param_bounds], maybe_self: option<ty::t>)
         -> [{mty: ty::method, id: ast::node_id, span: span}] {
         let mut my_methods = [];
-        for m in ms {
+        for ms.each {|m|
            alt maybe_self {
               some(selfty) {
                 write_ty_to_tcx(tcx, m.self_id, selfty);
@@ -1082,7 +1088,7 @@ fn convert(tcx: ty::ctxt, it: @ast::item) {
           ast::item_native_mod(m) {
             if syntax::attr::native_abi(it.attrs) ==
                either::right(ast::native_abi_rust_intrinsic) {
-                for item in m.items { check_intrinsic_type(tcx, item); }
+                for m.items.each {|item| check_intrinsic_type(tcx, item); }
             }
           }
           ast::item_enum(variants, ty_params) {
@@ -1111,7 +1117,7 @@ fn convert(tcx: ty::ctxt, it: @ast::item) {
                     if did.crate == ast::local_crate {
                         ensure_iface_methods(tcx, did.node);
                     }
-                    for if_m in *ty::iface_methods(tcx, did) {
+                    for vec::each(*ty::iface_methods(tcx, did)) {|if_m|
                         alt vec::find(my_methods,
                                       {|m| if_m.ident == m.mty.ident}) {
                           some({mty: m, id, span}) {
@@ -1191,7 +1197,7 @@ fn convert(tcx: ty::ctxt, it: @ast::item) {
               /* FIXME: check for proper public/privateness */
               // Write the type of each of the members
               let (fields, methods) = split_class_items(members);
-              for f in fields {
+              for fields.each {|f|
                  convert_class_item(tcx, f);
               }
               // The selfty is just the class type
@@ -1342,7 +1348,7 @@ fn full(fcx: @fn_ctxt,
 
         let mut ty_param_substs: [mut ty::t] = [mut];
         let mut ty_param_subst_var_ids: [ty_vid] = [];
-        for ty_param_subst: ty::t in ty_param_substs_0 {
+        for ty_param_substs_0.each {|ty_param_subst|
             // Generate a type variable and unify it with the type parameter
             // substitution. We will then pull out these type variables.
             let t_0 = next_ty_var(fcx);
@@ -1355,7 +1361,7 @@ fn mk_result(fcx: @fn_ctxt, result_ty: ty::t,
                      ty_param_subst_var_ids: [ty_vid]) ->
            ty_param_substs_and_ty {
             let mut result_ty_param_substs: [ty::t] = [];
-            for var_id in ty_param_subst_var_ids {
+            for ty_param_subst_var_ids.each {|var_id|
                 let tp_subst = ty::mk_var(fcx.ccx.tcx, var_id);
                 result_ty_param_substs += [tp_subst];
             }
@@ -1401,7 +1407,7 @@ fn variant_arg_types(ccx: @crate_ctxt, _sp: span, vid: ast::def_id,
     alt ty::get(tpt.ty).struct {
       ty::ty_fn(f) {
         // N-ary variant.
-        for arg: ty::arg in f.inputs {
+        for f.inputs.each {|arg|
             let arg_ty =
                 ty::substitute_type_params(ccx.tcx, enum_ty_params, arg.ty);
             result += [arg_ty];
@@ -1459,7 +1465,7 @@ fn resolve_type_vars_for_node(wbcx: wb_ctxt, sp: span, id: ast::node_id)
             alt fcx.opt_node_ty_substs(id) {
               some(substs) {
                 let mut new_substs = [];
-                for subst: ty::t in substs {
+                for substs.each {|subst|
                     alt resolve_type_vars_in_type(fcx, sp, subst) {
                       some(t) { new_substs += [t]; }
                       none { wbcx.success = false; ret none; }
@@ -1598,7 +1604,7 @@ fn resolve_type_vars_in_fn(fcx: @fn_ctxt,
                            visit_local: visit_local
                               with *visit::default_visitor()});
         visit.visit_block(blk, wbcx, visit);
-        for arg in decl.inputs {
+        for decl.inputs.each {|arg|
             resolve_type_vars_for_node(wbcx, arg.ty.span, arg.id);
         }
         ret wbcx.success;
@@ -1982,7 +1988,7 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
         fn matches(name: str, f: ty::field) -> bool {
             ret str::eq(name, f.ident);
         }
-        for f: ast::field_pat in fields {
+        for fields.each {|f|
             alt vec::find(ex_fields, bind matches(f.ident, _)) {
               some(field) {
                 check_pat(pcx, f.pat, field.mt.ty);
@@ -2015,7 +2021,7 @@ fn matches(name: str, f: ty::field) -> bool {
                       fields", vec::len(ex_elts), e_count]);
         }
         let mut i = 0u;
-        for elt in elts {
+        for elts.each {|elt|
             check_pat(pcx, elt, ex_elts[i]);
             i += 1u;
         }
@@ -2205,7 +2211,7 @@ fn lookup_method_inner_(tcx: ty::ctxt, ms: [ty::method],
         origin: method_origin, self_sub: option<self_subst>}> {
     #debug("lookup_method_inner_: %? %? %s", ms, parent, name);
     let mut i = 0u;
-    for m in ms  {
+    for ms.each {|m|
        if m.ident == name {
           let fty = ty::mk_fn(tcx, {proto: ast::proto_box with m.fty});
           if ty::type_has_vars(fty) {
@@ -2257,7 +2263,7 @@ fn lookup_method_inner(fcx: @fn_ctxt, expr: @ast::expr,
     alt ty::get(ty).struct {
       ty::ty_param(n, did) {
         let mut bound_n = 0u;
-        for bound in *tcx.ty_param_bounds.get(did.node) {
+        for vec::each(*tcx.ty_param_bounds.get(did.node)) {|bound|
             alt bound {
               ty::bound_iface(t) {
                 let (iid, tps) = alt check ty::get(t).struct {
@@ -2322,10 +2328,10 @@ fn ty_from_did(tcx: ty::ctxt, did: ast::def_id) -> ty::t {
     let mut result = none, complained = false;
     std::list::iter(fcx.ccx.impl_map.get(expr.id)) {|impls|
         if option::is_none(result) {
-            for @{did, methods, _} in *impls {
-                alt vec::find(methods, {|m| m.ident == name}) {
+            for vec::each(*impls) {|im|
+                alt vec::find(im.methods, {|m| m.ident == name}) {
                   some(m) {
-                    let mut {n_tps, ty: self_ty} = impl_self_ty(tcx, did);
+                    let mut {n_tps, ty: self_ty} = impl_self_ty(tcx, im.did);
                     let mut {vars, ty: self_ty} = if n_tps > 0u {
                         bind_params(fcx, self_ty, n_tps)
                     } else {
@@ -2472,7 +2478,7 @@ fn check_expr_fn_with_unifier(fcx: @fn_ctxt,
 fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
                            expected: ty::t) -> bool {
 
-    #debug("typechecking expr %d (%s)",
+    #debug(">> typechecking expr %d (%s)",
            expr.id, syntax::print::pprust::expr_to_str(expr));
 
     // A generic function to factor out common logic from call and bind
@@ -2532,7 +2538,7 @@ fn check_call_or_bind(
         let check_args = fn@(check_blocks: bool) -> bool {
             let mut i = 0u;
             let mut bot = false;
-            for a_opt in args {
+            for args.each {|a_opt|
                 alt a_opt {
                   some(a) {
                     let is_block = alt a.node {
@@ -2570,7 +2576,7 @@ fn check_assignment(fcx: @fn_ctxt, _sp: span, lhs: @ast::expr,
     fn check_call(fcx: @fn_ctxt, sp: span, f: @ast::expr, args: [@ast::expr])
         -> {fty: ty::t, bot: bool} {
         let mut args_opt_0: [option<@ast::expr>] = [];
-        for arg: @ast::expr in args {
+        for args.each {|arg|
             args_opt_0 += [some::<@ast::expr>(arg)];
         }
 
@@ -2676,21 +2682,18 @@ fn check_binop(fcx: @fn_ctxt, expr: @ast::expr,
         let lhs_t = structurally_resolved_type(fcx, lhs.span, lhs_t);
         ret alt (op, ty::get(lhs_t).struct) {
           (ast::add, ty::ty_vec(lhs_mt)) {
-            // For adding vectors with type L=[M TL] and R=[M TR], the result
-            // is somewhat subtle.  Let L_c=[const TL] and R_c=[const TR] be
-            // const versions of the vectors in L and R.  Next, let T be a
-            // fresh type variable where TL <: T and TR <: T.  Then the result
-            // type is a fresh type variable T1 where T1 <: [const T].  This
-            // allows the result to be either a mut or immutable vector,
-            // depending on external demands.
-            let const_vec_t =
-                ty::mk_vec(tcx, {ty: next_ty_var(fcx),
-                                 mutbl: ast::m_const});
+            // For adding vectors with type L=[ML TL] and R=[MR TR], the the
+            // result [ML T] where TL <: T and TR <: T.  In other words, the
+            // result type is (generally) the LUB of (TL, TR) and takes the
+            // mutability from the LHS.
+            let t_var = next_ty_var(fcx);
+            let const_vec_t = ty::mk_vec(tcx, {ty: t_var,
+                                               mutbl: ast::m_const});
             demand::simple(fcx, lhs.span, const_vec_t, lhs_t);
             let rhs_bot = check_expr_with(fcx, rhs, const_vec_t);
-            let result_var = next_ty_var(fcx);
-            demand::simple(fcx, lhs.span, const_vec_t, result_var);
-            fcx.write_ty(expr.id, result_var);
+            let result_vec_t = ty::mk_vec(tcx, {ty: t_var,
+                                                mutbl: lhs_mt.mutbl});
+            fcx.write_ty(expr.id, result_vec_t);
             lhs_bot | rhs_bot
           }
 
@@ -2954,21 +2957,6 @@ fn check_user_unop(fcx: @fn_ctxt, op_str: str, mname: str,
             check_expr_with(fcx, cond, ty::mk_bool(tcx)) |
                 check_then_else(fcx, thn, elsopt, id, expr.span);
       }
-      ast::expr_for(decl, seq, body) {
-        bot = check_expr(fcx, seq);
-        let mut elt_ty;
-        let ety = fcx.expr_ty(seq);
-        alt structure_of(fcx, expr.span, ety) {
-          ty::ty_vec(vec_elt_ty) { elt_ty = vec_elt_ty.ty; }
-          ty::ty_str { elt_ty = ty::mk_mach_uint(tcx, ast::ty_u8); }
-          _ {
-            tcx.sess.span_fatal(expr.span,
-                                "mismatched types: expected vector or string "
-                                + "but found `" + ty_to_str(tcx, ety) + "`");
-          }
-        }
-        bot |= check_for(fcx, decl, elt_ty, body, id);
-      }
       ast::expr_while(cond, body) {
         bot = check_expr_with(fcx, cond, ty::mk_bool(tcx));
         check_block_no_value(fcx, body);
@@ -2993,7 +2981,7 @@ fn check_user_unop(fcx: @fn_ctxt, op_str: str, mname: str,
         // Typecheck the patterns first, so that we get types for all the
         // bindings.
         //let pattern_ty = fcx.expr_ty(discrim);
-        for arm: ast::arm in arms {
+        for arms.each {|arm|
             let pcx = {
                 fcx: fcx,
                 map: pat_util::pat_id_map(tcx.def_map, arm.pats[0]),
@@ -3002,14 +2990,12 @@ fn check_user_unop(fcx: @fn_ctxt, op_str: str, mname: str,
                 pat_region: ty::re_scope(parent_block)
             };
 
-            for p: @ast::pat in arm.pats {
-                check_pat(pcx, p, pattern_ty);
-            }
+            for arm.pats.each {|p| check_pat(pcx, p, pattern_ty);}
         }
         // Now typecheck the blocks.
         let mut result_ty = next_ty_var(fcx);
         let mut arm_non_bot = false;
-        for arm: ast::arm in arms {
+        for arms.each {|arm|
             alt arm.guard {
               some(e) { check_expr_with(fcx, e, ty::mk_bool(tcx)); }
               none { }
@@ -3168,14 +3154,14 @@ fn check_user_unop(fcx: @fn_ctxt, op_str: str, mname: str,
       }
       ast::expr_vec(args, mutbl) {
         let t: ty::t = next_ty_var(fcx);
-        for e: @ast::expr in args { bot |= check_expr_with(fcx, e, t); }
+        for args.each {|e| bot |= check_expr_with(fcx, e, t); }
         let typ = ty::mk_vec(tcx, {ty: t, mutbl: mutbl});
         fcx.write_ty(id, typ);
       }
       ast::expr_tup(elts) {
         let mut elt_ts = [];
         vec::reserve(elt_ts, vec::len(elts));
-        for e in elts {
+        for elts.each {|e|
             check_expr(fcx, e);
             let ety = fcx.expr_ty(e);
             elt_ts += [ety];
@@ -3184,7 +3170,7 @@ fn check_user_unop(fcx: @fn_ctxt, op_str: str, mname: str,
         fcx.write_ty(id, typ);
       }
       ast::expr_rec(fields, base) {
-        option::with_option_do(base) {|b| check_expr(fcx, b); }
+        option::iter(base) {|b| check_expr(fcx, b); }
         let fields_t = vec::map(fields, {|f|
             bot |= check_expr(fcx, f.node.expr);
             let expr_t = fcx.expr_ty(f.node.expr);
@@ -3211,9 +3197,9 @@ fn get_node(f: spanned<field>) -> field { f.node }
               }
             }
             fcx.write_ty(id, bexpr_t);
-            for f: spanned<ty::field> in fields_t {
+            for fields_t.each {|f|
                 let mut found = false;
-                for bf: ty::field in base_fields {
+                for base_fields.each {|bf|
                     if str::eq(f.node.ident, bf.ident) {
                         demand::simple(fcx, f.span, bf.mt.ty, f.node.mt.ty);
                         found = true;
@@ -3385,6 +3371,8 @@ fn get_node(f: spanned<field>) -> field { f.node }
            ty_to_str(tcx, expected));
 
     unify(fcx, expr.span, expected, fcx.expr_ty(expr));
+
+    #debug("<< bot=%b", bot);
     ret bot;
 }
 
@@ -3462,7 +3450,7 @@ fn check_stmt(fcx: @fn_ctxt, stmt: @ast::stmt) -> bool {
         node_id = id;
         alt decl.node {
           ast::decl_local(ls) {
-            for l in ls { bot |= check_decl_local(fcx, l); }
+            for ls.each {|l| bot |= check_decl_local(fcx, l); }
           }
           ast::decl_item(_) {/* ignore for now */ }
         }
@@ -3498,7 +3486,7 @@ fn check_block(fcx0: @fn_ctxt, blk: ast::blk) -> bool {
     };
     let mut bot = false;
     let mut warned = false;
-    for s: @ast::stmt in blk.node.stmts {
+    for blk.node.stmts.each {|s|
         if bot && !warned &&
                alt s.node {
                  ast::stmt_decl(@{node: ast::decl_local(_), _}, _) |
@@ -3585,7 +3573,7 @@ fn check_enum_variants(ccx: @crate_ctxt, sp: span, vs: [ast::variant],
           ccx: ccx};
     let mut disr_vals: [int] = [];
     let mut disr_val = 0;
-    for v in vs {
+    for vs.each {|v|
         alt v.node.disr_expr {
           some(e) {
             check_expr(fcx, e);
@@ -3663,7 +3651,7 @@ fn check_pred_expr(fcx: @fn_ctxt, e: @ast::expr) -> bool {
                                              in constraint");
               }
             }
-            for operand: @ast::expr in operands {
+            for operands.each {|operand|
                 if !ast_util::is_constraint_arg(operand) {
                     let s =
                         "constraint args must be slot variables or literals";
@@ -3684,11 +3672,10 @@ fn check_pred_expr(fcx: @fn_ctxt, e: @ast::expr) -> bool {
 }
 
 fn check_constraints(fcx: @fn_ctxt, cs: [@ast::constr], args: [ast::arg]) {
-    let mut c_args;
     let num_args = vec::len(args);
-    for c: @ast::constr in cs {
-        c_args = [];
-        for a: @spanned<ast::fn_constr_arg> in c.node.args {
+    for cs.each {|c|
+        let mut c_args = [];
+        for c.node.args.each {|a|
             c_args += [
                  // "base" should not occur in a fn type thing, as of
                  // yet, b/c we don't allow constraints on the return type
@@ -3855,7 +3842,7 @@ fn check_method(ccx: @crate_ctxt, method: @ast::method, self_ty: ty::t) {
 
 fn class_types(ccx: @crate_ctxt, members: [@ast::class_member]) -> class_map {
     let rslt = int_hash::<ty::t>();
-    for m in members {
+    for members.each {|m|
       alt m.node {
          ast::instance_var(_,t,_,id,_) {
            rslt.insert(id, ast_ty_to_ty(ccx.tcx, m_collect, t));
@@ -3894,9 +3881,7 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
         let self_ty = ast_ty_to_ty(ccx.tcx, m_check, ty);
         let self_region = ty::re_free(it.id, ty::br_self);
         let self_ty = replace_self_region(ccx.tcx, self_region, self_ty);
-        for m in ms {
-            check_method(ccx, m, self_ty);
-        }
+        for ms.each {|m| check_method(ccx, m, self_ty);}
       }
       ast::item_class(tps, members, ctor) {
           let cid = some(it.id);
@@ -3912,7 +3897,7 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
                         some(class_t));
 
           // typecheck the members
-          for m in members { check_class_member(class_ccx, class_t, m); }
+          for members.each {|m| check_class_member(class_ccx, class_t, m); }
       }
       _ {/* nothing to do */ }
     }
@@ -3992,8 +3977,8 @@ fn lookup_vtables(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
                       allow_unsafe: bool) -> vtable_res {
         let tcx = fcx.ccx.tcx;
         let mut result = [], i = 0u;
-        for ty in tys {
-            for bound in *bounds[i] {
+        for tys.each {|ty|
+            for vec::each(*bounds[i]) {|bound|
                 alt bound {
                   ty::bound_iface(i_ty) {
                     let i_ty = ty::substitute_type_params(tcx, tys, i_ty);
@@ -4019,7 +4004,7 @@ fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
         alt ty::get(ty).struct {
           ty::ty_param(n, did) {
             let mut n_bound = 0u;
-            for bound in *tcx.ty_param_bounds.get(did.node) {
+            for vec::each(*tcx.ty_param_bounds.get(did.node)) {|bound|
                 alt bound {
                   ty::bound_iface(ity) {
                     alt check ty::get(ity).struct {
@@ -4035,7 +4020,7 @@ fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
           }
           ty::ty_iface(did, tps) if iface_id == did {
             if !allow_unsafe {
-                for m in *ty::iface_methods(tcx, did) {
+                for vec::each(*ty::iface_methods(tcx, did)) {|m|
                     if ty::type_has_vars(ty::mk_fn(tcx, m.fty)) {
                         tcx.sess.span_err(
                             sp, "a boxed iface with self types may not be \
@@ -4054,7 +4039,7 @@ fn lookup_vtable(fcx: @fn_ctxt, isc: resolve::iscopes, sp: span,
             let mut found = none;
             std::list::iter(isc) {|impls|
                 if option::is_none(found) {
-                    for im in *impls {
+                    for vec::each(*impls) {|im|
                         let match = alt ty::impl_iface(tcx, im.did) {
                           some(ity) {
                             alt check ty::get(ity).struct {
index 5a19efb005b3b11ee800b6c2c3fdfd73ffea3673..a76133b4c829b05bcbaa433f95268106340ff346 100644 (file)
@@ -9,11 +9,13 @@
 #[license = "MIT"];
 #[crate_type = "lib"];
 
-use std (name = "std",
-         vers = "0.2",
-         url = "https://github.com/mozilla/rust/tree/master/src/libstd");
+#[no_core];
 
-use rustsyntax;
+use core(vers = "0.2");
+use std(vers = "0.2");
+use rustsyntax(vers = "0.2");
+
+import core::*;
 
 mod middle {
     mod trans {
index 1a6b7b0ccf956a1a1b02cf5d06cf4b875d727237..537517491904cf0fb5970a27d6bfa8d551d285c6 100644 (file)
@@ -5,6 +5,24 @@
 import syntax::visit;
 import syntax::print;
 
+fn indent<R>(op: fn() -> R) -> R {
+    // Use in conjunction with the log post-processor like `src/etc/indenter`
+    // to make debug output more readable.
+    #debug[">>"];
+    let r <- op();
+    #debug["<< (Result = %?)", r];
+    ret r;
+}
+
+resource _indenter(_i: ()) {
+    #debug["<<"];
+}
+
+fn indenter() -> _indenter {
+    #debug[">>"];
+    _indenter(())
+}
+
 type flag = hashmap<str, ()>;
 
 fn def_eq(a: ast::def_id, b: ast::def_id) -> bool {
@@ -28,7 +46,7 @@ fn new_def_hash<V: copy>() -> std::map::hashmap<ast::def_id, V> {
 
 fn field_exprs(fields: [ast::field]) -> [@ast::expr] {
     let mut es = [];
-    for f: ast::field in fields { es += [f.node.expr]; }
+    for fields.each {|f| es += [f.node.expr]; }
     ret es;
 }
 
index 75327597ce92959a4d684f828aacae7b2df7a46d..a5cc6c28d53c08214a9c02fc5d5a6d2b33981c07 100644 (file)
@@ -65,22 +65,24 @@ fn get_target_lib_file_path(file: path) -> path {
      target_triple: target_triple} as filesearch
 }
 
-// FIXME #1001: This can't be an obj method
 fn search<T: copy>(filesearch: filesearch, pick: pick<T>) -> option<T> {
-    for lib_search_path in filesearch.lib_search_paths() {
+    let mut rslt = none;
+    for filesearch.lib_search_paths().each {|lib_search_path|
         #debug("searching %s", lib_search_path);
-        for path in os::list_dir_path(lib_search_path) {
+        for os::list_dir_path(lib_search_path).each {|path|
             #debug("testing %s", path);
             let maybe_picked = pick(path);
             if option::is_some(maybe_picked) {
                 #debug("picked %s", path);
-                ret maybe_picked;
+                rslt = maybe_picked;
+                break;
             } else {
                 #debug("rejected %s", path);
             }
         }
+        if option::is_some(rslt) { break; }
     }
-    ret option::none;
+    ret rslt;
 }
 
 fn relative_target_lib_path(target_triple: str) -> [path] {
index 2cb0fef1a90476aab47cf201952d529b10c0b29a..6be2f415c2ce822b7664e6625a891403430d5cd5 100644 (file)
@@ -36,6 +36,7 @@ fn region_to_str(cx: ctxt, region: region) -> str {
       // These two should not be seen by end-users (very often, anyhow):
       re_var(id)    { #fmt("&%s.", id.to_str()) }
       re_default    { "&(default)." }
+      re_static     { "&static." }
     }
 }
 
@@ -72,7 +73,7 @@ fn fn_to_str(cx: ctxt, proto: ast::proto, ident: option<ast::ident>,
         alt ident { some(i) { s += " "; s += i; } _ { } }
         s += "(";
         let mut strs = [];
-        for a: arg in inputs { strs += [fn_input_to_str(cx, a)]; }
+        for inputs.each {|a| strs += [fn_input_to_str(cx, a)]; }
         s += str::connect(strs, ", ");
         s += ")";
         if ty::get(output).struct != ty_nil {
@@ -138,12 +139,12 @@ fn parameterized(cx: ctxt, base: str, tps: [ty::t]) -> str {
       ty_type { "type" }
       ty_rec(elems) {
         let mut strs: [str] = [];
-        for fld: field in elems { strs += [field_to_str(cx, fld)]; }
+        for elems.each {|fld| strs += [field_to_str(cx, fld)]; }
         "{" + str::connect(strs, ",") + "}"
       }
       ty_tup(elems) {
         let mut strs = [];
-        for elem in elems { strs += [ty_to_str(cx, elem)]; }
+        for elems.each {|elem| strs += [ty_to_str(cx, elem)]; }
         "(" + str::connect(strs, ",") + ")"
       }
       ty_fn(f) {
@@ -178,7 +179,7 @@ fn constr_to_str(c: @constr) -> str {
 fn constrs_str(constrs: [@constr]) -> str {
     let mut s = "";
     let mut colon = true;
-    for c: @constr in constrs {
+    for constrs.each {|c|
         if colon { s += " : "; colon = false; } else { s += ", "; }
         s += constr_to_str(c);
     }
index eda5acb18117e6056bfc9cea5d8b75eab69b872b..3c2a11b051643dc8698ecfc313fc4a252076ec15 100644 (file)
@@ -59,7 +59,7 @@ fn usage() {
 
     println("Usage: rustdoc [options] <cratefile>\n");
     println("Options:\n");
-    for opt in opts() {
+    for opts().each {|opt|
         println(#fmt("    %s", tuple::second(opt)));
     }
     println("");
@@ -132,7 +132,7 @@ fn config_from_opts(
     let result = result::chain(result) {|config|
         let output_format = getopts::opt_maybe_str(
             match, opt_output_format());
-        option::with_option(output_format, result::ok(config))
+        option::map_default(output_format, result::ok(config))
            {|output_format|
             result::chain(parse_output_format(output_format)) {|output_format|
                 result::ok({
@@ -144,7 +144,7 @@ fn config_from_opts(
     };
     let result = result::chain(result) {|config|
         let output_style = getopts::opt_maybe_str(match, opt_output_style());
-        option::with_option(output_style, result::ok(config))
+        option::map_default(output_style, result::ok(config))
           {|output_style|
             result::chain(parse_output_style(output_style)) {|output_style|
                 result::ok({
index ad72e55ba105469295d24c89e125893c33896fb1..7057dc67e65c46e53ed5d34f172da9b97b0beb66 100644 (file)
@@ -328,7 +328,7 @@ fn write_mod_contents(
         write_index(ctxt, option::get(doc.index));
     }
 
-    for itemtag in doc.items {
+    for doc.items.each {|itemtag|
         write_item(ctxt, itemtag);
     }
 }
@@ -381,7 +381,7 @@ fn write_index(ctxt: ctxt, index: doc::index) {
         ret;
     }
 
-    for entry in index.entries {
+    for index.entries.each {|entry|
         let header = header_text_(entry.kind, entry.name);
         let id = entry.link;
         if option::is_some(entry.brief) {
@@ -431,7 +431,7 @@ fn write_nmod(ctxt: ctxt, doc: doc::nmoddoc) {
         write_index(ctxt, option::get(doc.index));
     }
 
-    for fndoc in doc.fns {
+    for doc.fns.each {|fndoc|
         write_item_header(ctxt, doc::fntag(fndoc));
         write_fn(ctxt, fndoc);
     }
index d15caffd46fd4008ba1b12e1232dccaae73e7440..136d3bfe034fa6b3b8b31ac8ff5311609eec8813 100644 (file)
@@ -1,7 +1,7 @@
 export anymap, seqmap, parmap;
 
 fn anymap<T:send, U:send>(v: [T], f: fn~(T) -> U) -> [U] {
-    seqmap(v, f)
+    parmap(v, f)
 }
 
 fn seqmap<T, U>(v: [T], f: fn(T) -> U) -> [U] {
index f50e93e1464ff3f53005ce0628b59be42806ed2e..d4ed8c336efe11e21ddc02cd9df5a0dec0394b5e 100644 (file)
@@ -82,13 +82,13 @@ fn build_reexport_def_set(srv: astsrv::srv) -> def_set {
     let assoc_list = astsrv::exec(srv) {|ctxt|
         let def_set = common::new_def_hash();
         ctxt.exp_map.items {|_id, defs|
-            for def in defs {
+            for defs.each {|def|
                 if def.reexp {
                     def_set.insert(def.id, ());
                 }
             }
         }
-        for def in find_reexport_impls(ctxt) {
+        for find_reexport_impls(ctxt).each {|def|
             def_set.insert(def, ());
         }
         to_assoc_list(def_set)
@@ -137,7 +137,7 @@ fn build_reexport_def_map(
     fn fold_mod(fold: fold::fold<ctxt>, doc: doc::moddoc) -> doc::moddoc {
         let doc = fold::default_seq_fold_mod(fold, doc);
 
-        for item in doc.items {
+        for doc.items.each {|item|
             let def_id = ast_util::local_def(item.id());
             if fold.ctxt.def_set.contains_key(def_id) {
                 fold.ctxt.def_map.insert(def_id, item);
@@ -150,7 +150,7 @@ fn fold_mod(fold: fold::fold<ctxt>, doc: doc::moddoc) -> doc::moddoc {
     fn fold_nmod(fold: fold::fold<ctxt>, doc: doc::nmoddoc) -> doc::nmoddoc {
         let doc = fold::default_seq_fold_nmod(fold, doc);
 
-        for fndoc in doc.fns {
+        for doc.fns.each {|fndoc|
             let def_id = ast_util::local_def(fndoc.id());
             if fold.ctxt.def_set.contains_key(def_id) {
                 fold.ctxt.def_map.insert(def_id, doc::fntag(fndoc));
@@ -184,7 +184,7 @@ fn build_reexport_path_map(srv: astsrv::srv, -def_map: def_map) -> path_map {
             let modpath = ast_map::path_to_str(vec::init(*path));
 
             let mut reexportdocs = [];
-            for def in defs {
+            for defs.each {|def|
                 if !def.reexp { cont; }
                 alt def_map.find(def.id) {
                   some(itemtag) {
@@ -195,7 +195,7 @@ fn build_reexport_path_map(srv: astsrv::srv, -def_map: def_map) -> path_map {
             }
 
             if reexportdocs.len() > 0u {
-                option::with_option_do(path_map.find(modpath)) {|docs|
+                option::iter(path_map.find(modpath)) {|docs|
                     reexportdocs = docs + vec::filter(reexportdocs, {|x|
                         !vec::contains(docs, x)
                     });
@@ -206,7 +206,8 @@ fn build_reexport_path_map(srv: astsrv::srv, -def_map: def_map) -> path_map {
             }
         }
 
-        for (path, doc) in find_reexport_impl_docs(ctxt, def_map) {
+        for find_reexport_impl_docs(ctxt, def_map).each {|elt|
+            let (path, doc) = elt;
             let docs = alt path_map.find(path) {
               some(docs) { docs + [(doc)] }
               none { [doc] }
@@ -272,7 +273,7 @@ fn visit_mod(
         let all_impls = all_impls(m);
         alt check ctxt.impl_map.get(mod_id) {
           list::cons(impls, @list::nil) {
-            for i in *impls {
+            for vec::each(*impls) {|i|
                 // This impl is not an item in the current mod
                 if !all_impls.contains_key(i.did) {
                     // Ignore external impls because I don't
@@ -289,7 +290,7 @@ fn visit_mod(
 
 fn all_impls(m: ast::_mod) -> map::set<ast::def_id> {
     let all_impls = common::new_def_hash();
-    for item in m.items {
+    for m.items.each {|item|
         alt item.node {
           ast::item_impl(_, _, _, _) {
             all_impls.insert(ast_util::local_def(item.id), ());
index f7aed2df287a42de2ef76e5699a4b61c86b866b9..e910d33f3a824a7c469c8c7a63316c90d4458610 100644 (file)
@@ -9,8 +9,13 @@
 #[license = "MIT"];
 #[crate_type = "bin"];
 
-use std;
-use rustc;
+#[no_core];
+
+use core(vers = "0.2");
+use std(vers = "0.2");
+use rustc(vers = "0.2");
+
+import core::*;
 
 mod config;
 mod parse;
index 4e055be8a1a27655f6358e68759fcf0d01faada9..f7929062c6d06a9e9b68c5b345465679837dd6ca 100644 (file)
@@ -94,7 +94,7 @@ fn sectionalize(desc: option<str>) -> (option<str>, [doc::section]) {
     let mut current_section = none;
     let mut sections = [];
 
-    for line in lines {
+    for lines.each {|line|
         alt parse_header(line) {
           some(header) {
             if option::is_some(current_section) {
index 9e3169119bcd12760b749fc31be99c537ef7586a..9c26221960ca1a4f764cb9948ea25a4b54a008e6 100644 (file)
@@ -6,7 +6,7 @@ fn alist_add<A: copy, B: copy>(lst: alist<A,B>, k: A, v: B) {
 
 fn alist_get<A: copy, B: copy>(lst: alist<A,B>, k: A) -> B {
     let eq_fn = lst.eq_fn;
-    for pair in lst.data {
+    for lst.data.each {|pair|
         let (ki, vi) = pair; // copy req'd for alias analysis
         if eq_fn(k, ki) { ret vi; }
     }
diff --git a/src/test/auxiliary/crateresolve1-1.rs b/src/test/auxiliary/crateresolve1-1.rs
new file mode 100644 (file)
index 0000000..a91eda1
--- /dev/null
@@ -0,0 +1,6 @@
+#[link(name = "crateresolve1",
+       vers = "0.1")];
+
+#[crate_type = "lib"];
+
+fn f() -> int { 10 }
diff --git a/src/test/auxiliary/crateresolve1-2.rs b/src/test/auxiliary/crateresolve1-2.rs
new file mode 100644 (file)
index 0000000..053745d
--- /dev/null
@@ -0,0 +1,6 @@
+#[link(name = "crateresolve1",
+       vers = "0.2")];
+
+#[crate_type = "lib"];
+
+fn f() -> int { 20 }
diff --git a/src/test/auxiliary/crateresolve1-3.rs b/src/test/auxiliary/crateresolve1-3.rs
new file mode 100644 (file)
index 0000000..78d2a64
--- /dev/null
@@ -0,0 +1,6 @@
+#[link(name = "crateresolve1",
+       vers = "0.3")];
+
+#[crate_type = "lib"];
+
+fn f() -> int { 30 }
diff --git a/src/test/auxiliary/crateresolve2-1.rs b/src/test/auxiliary/crateresolve2-1.rs
new file mode 100644 (file)
index 0000000..2dabc24
--- /dev/null
@@ -0,0 +1,6 @@
+#[link(name = "crateresolve2",
+       vers = "0.1")];
+
+#[crate_type = "lib"];
+
+fn f() -> int { 10 }
diff --git a/src/test/auxiliary/crateresolve2-2.rs b/src/test/auxiliary/crateresolve2-2.rs
new file mode 100644 (file)
index 0000000..83abb61
--- /dev/null
@@ -0,0 +1,6 @@
+#[link(name = "crateresolve2",
+       vers = "0.2")];
+
+#[crate_type = "lib"];
+
+fn f() -> int { 20 }
diff --git a/src/test/auxiliary/crateresolve2-3.rs b/src/test/auxiliary/crateresolve2-3.rs
new file mode 100644 (file)
index 0000000..52c746f
--- /dev/null
@@ -0,0 +1,6 @@
+#[link(name = "crateresolve2",
+       vers = "0.3")];
+
+#[crate_type = "lib"];
+
+fn f() -> int { 30 }
diff --git a/src/test/auxiliary/crateresolve3-1.rs b/src/test/auxiliary/crateresolve3-1.rs
new file mode 100644 (file)
index 0000000..a2315e4
--- /dev/null
@@ -0,0 +1,6 @@
+#[link(name = "crateresolve3",
+       vers = "0.1")];
+
+#[crate_type = "lib"];
+
+fn f() -> int { 10 }
diff --git a/src/test/auxiliary/crateresolve3-2.rs b/src/test/auxiliary/crateresolve3-2.rs
new file mode 100644 (file)
index 0000000..2e3684c
--- /dev/null
@@ -0,0 +1,6 @@
+#[link(name = "crateresolve3",
+       vers = "0.2")];
+
+#[crate_type = "lib"];
+
+fn g() -> int { 20 }
diff --git a/src/test/auxiliary/crateresolve4a-1.rs b/src/test/auxiliary/crateresolve4a-1.rs
new file mode 100644 (file)
index 0000000..3c41daa
--- /dev/null
@@ -0,0 +1,4 @@
+#[link(name = "crateresolve4a", vers = "0.1")];
+#[crate_type = "lib"];
+
+fn f() -> int { 10 }
diff --git a/src/test/auxiliary/crateresolve4a-2.rs b/src/test/auxiliary/crateresolve4a-2.rs
new file mode 100644 (file)
index 0000000..cba82fd
--- /dev/null
@@ -0,0 +1,4 @@
+#[link(name = "crateresolve4a", vers= "0.2")];
+#[crate_type = "lib"];
+
+fn g() -> int { 20 }
diff --git a/src/test/auxiliary/crateresolve4b-1.rs b/src/test/auxiliary/crateresolve4b-1.rs
new file mode 100644 (file)
index 0000000..b5cda2a
--- /dev/null
@@ -0,0 +1,8 @@
+// aux-build:crateresolve4a-1.rs
+// aux-build:crateresolve4a-2.rs
+#[link(name = "crateresolve4b", vers = "0.1")];
+#[crate_type = "lib"];
+
+use crateresolve4a(vers="0.2");
+
+fn f() -> int { crateresolve4a::g() }
diff --git a/src/test/auxiliary/crateresolve4b-2.rs b/src/test/auxiliary/crateresolve4b-2.rs
new file mode 100644 (file)
index 0000000..1129b98
--- /dev/null
@@ -0,0 +1,8 @@
+// aux-build:crateresolve4a-1.rs
+// aux-build:crateresolve4a-2.rs
+#[link(name = "crateresolve4b", vers = "0.2")];
+#[crate_type = "lib"];
+
+use crateresolve4a(vers="0.1");
+
+fn g() -> int { crateresolve4a::f() }
diff --git a/src/test/auxiliary/crateresolve5-1.rs b/src/test/auxiliary/crateresolve5-1.rs
new file mode 100644 (file)
index 0000000..9de656e
--- /dev/null
@@ -0,0 +1,16 @@
+#[link(name = "crateresolve5",
+       vers = "0.1")];
+
+#[crate_type = "lib"];
+
+fn structural() -> { name: str, val: int } {
+    { name: "crateresolve5", val: 10 }
+}
+
+enum e {
+    e_val
+}
+
+fn nominal() -> e { e_val }
+
+fn f() -> int { 10 }
diff --git a/src/test/auxiliary/crateresolve5-2.rs b/src/test/auxiliary/crateresolve5-2.rs
new file mode 100644 (file)
index 0000000..ff884a5
--- /dev/null
@@ -0,0 +1,16 @@
+#[link(name = "crateresolve5",
+       vers = "0.2")];
+
+#[crate_type = "lib"];
+
+fn structural() -> { name: str, val: int } {
+    { name: "crateresolve5", val: 10 }
+}
+
+enum e {
+    e_val
+}
+
+fn nominal() -> e { e_val }
+
+fn f() -> int { 20 }
diff --git a/src/test/auxiliary/crateresolve6-1.rs b/src/test/auxiliary/crateresolve6-1.rs
new file mode 100644 (file)
index 0000000..fff8c18
--- /dev/null
@@ -0,0 +1,7 @@
+#[link(name = "crateresolve6",
+       vers = "0.1",
+       calories = "100")];
+
+#[crate_type = "lib"];
+
+fn f() -> int { 100 }
diff --git a/src/test/auxiliary/crateresolve6-2.rs b/src/test/auxiliary/crateresolve6-2.rs
new file mode 100644 (file)
index 0000000..3623e2e
--- /dev/null
@@ -0,0 +1,7 @@
+#[link(name = "crateresolve6",
+       vers = "0.1",
+       calories = "200")];
+
+#[crate_type = "lib"];
+
+fn f() -> int { 200 }
diff --git a/src/test/auxiliary/crateresolve7-1.rs b/src/test/auxiliary/crateresolve7-1.rs
new file mode 100644 (file)
index 0000000..4357505
--- /dev/null
@@ -0,0 +1,7 @@
+#[link(name = "crateresolve7",
+       vers = "0.1",
+       calories = "100")];
+
+#[crate_type = "lib"];
+
+fn f() -> int { 100 }
diff --git a/src/test/auxiliary/crateresolve7-2.rs b/src/test/auxiliary/crateresolve7-2.rs
new file mode 100644 (file)
index 0000000..eeb9684
--- /dev/null
@@ -0,0 +1,7 @@
+#[link(name = "crateresolve7",
+       vers = "0.1",
+       calories = "200")];
+
+#[crate_type = "lib"];
+
+fn f() -> int { 200 }
diff --git a/src/test/auxiliary/crateresolve7x.rs b/src/test/auxiliary/crateresolve7x.rs
new file mode 100644 (file)
index 0000000..456f40b
--- /dev/null
@@ -0,0 +1,14 @@
+// xfail-fast
+// aux-build:crateresolve7-1.rs
+// aux-build:crateresolve7-2.rs
+
+// These both have the same version but differ in other metadata
+mod a {
+    use cr7_1 (name = "crateresolve7", vers = "0.1", calories="100");
+    fn f() -> int { cr7_1::f() }
+}
+
+mod b {
+    use cr7_2 (name = "crateresolve7", vers = "0.1", calories="200");
+    fn f() -> int { cr7_2::f() }
+}
index 39c0f8791409761004a466ff2daf9e8e23b0b2b0..dad3e6d836a7ea5d35a7c964b1b2efc41838549b 100644 (file)
@@ -39,7 +39,7 @@ fn run(args: [str]) {
     let to_child = to_child;
     let mut worker_results = [];
     uint::range(0u, workers) {|_i|
-        let builder = task::task_builder();
+        let builder = task::builder();
         worker_results += [task::future_result(builder)];
         task::run(builder) {||
             uint::range(0u, size / workers) {|_i|
index 9ce1561d4d0fb2645f026bd17f9c79f3f57b2923..9b2fcadd2c5d7515093c935535170b16c38db52f 100644 (file)
@@ -25,7 +25,7 @@ fn myrandom_next(r: myrandom, mx: u32) -> u32 {
 fn make_cumulative(aa: [aminoacids]) -> [aminoacids] {
     let mut cp: u32 = 0u32;
     let mut ans: [aminoacids] = [];
-    for a: aminoacids in aa { cp += a.prob; ans += [{ch: a.ch, prob: cp}]; }
+    for aa.each {|a| cp += a.prob; ans += [{ch: a.ch, prob: cp}]; }
     ret ans;
 }
 
index 72d85bfba6581ab90d4d7e5f123f150601aba994..12f9ab94cf37304f2989346ae5282cf7649e9327 100644 (file)
@@ -71,11 +71,11 @@ fn stress_task(&&id: int) {
 fn stress(num_tasks: int) {
     let mut results = [];
     range(0, num_tasks) {|i|
-        let builder = task::task_builder();
+        let builder = task::builder();
         results += [task::future_result(builder)];
         task::run(builder) {|| stress_task(i); }
     }
-    for r in results { future::get(r); }
+    for results.each {|r| future::get(r); }
 }
 
 fn main(argv: [str]) {
index 938e0013dd5e5135b9ffeb75f2943b49b82ee12f..d2820f32ff9b653986f3414d276c67c955edba83 100644 (file)
@@ -77,7 +77,7 @@ fn start_mappers<K1: send, K2: send,
                          ctrl: chan<ctrl_proto<K2, V>>, inputs: [K1]) ->
        [joinable_task] {
         let tasks = [];
-        for i in inputs {
+        for inputs.each {|i|
             let m = map, c = ctrl, ii = i;
             tasks += [task::spawn_joinable {|| map_task(m, c, ii)}];
         }
@@ -201,7 +201,7 @@ fn finish<K: send, V: send>(_k: K, v: chan<reduce_proto<V>>) {
         }
         treemap::traverse(reducers, finish);
 
-        for t in tasks { task::join(t); }
+        for tasks.each {|t| task::join(t); }
     }
 }
 
@@ -218,7 +218,7 @@ fn main(argv: [str]) {
     }
 
     let iargs = [];
-    for a in vec::slice(argv, 1u, vec::len(argv)) {
+    vec::iter_between(argv, 1u, vec::len(argv)) {|a|
         iargs += [str::bytes(a)];
     }
 
index 20ffd613240ec366da606d5d6c45796fad4b2fe1..75afbe33569c256f72796df6f6127456840f4775 100644 (file)
@@ -61,8 +61,8 @@ enum reduce_proto { emit_val(int), done, ref, release, }
     fn start_mappers(ctrl: chan<ctrl_proto>, -inputs: [str]) ->
        [future::future<task::task_result>] {
         let mut results = [];
-        for i: str in inputs {
-            let builder = task::task_builder();
+        for inputs.each {|i|
+            let builder = task::builder();
             results += [task::future_result(builder)];
             task::run(builder) {|| map_task(ctrl, i)}
         }
@@ -160,7 +160,7 @@ fn map_reduce(-inputs: [str]) {
                     // log(error, "creating new reducer for " + k);
                     let p = port();
                     let ch = chan(p);
-                    let builder = task::task_builder();
+                    let builder = task::builder();
                     results += [task::future_result(builder)];
                     task::run(builder) {||reduce_task(k, ch)}
                     c = recv(p);
@@ -174,7 +174,7 @@ fn map_reduce(-inputs: [str]) {
 
         reducers.values {|v| send(v, done); }
 
-        for r in results { future::get(r); }
+        for results.each {|r| future::get(r); }
     }
 }
 
index ded6f62a6dd85d861dba2fb97fc5b5c1c8bc36d0..bab121bd6d348b1b5a5498e275c67e9432264b3e 100644 (file)
@@ -3,7 +3,7 @@
 
 fn bad_bang(i: uint) -> ! {
     ret 7u;
-    //!^ ERROR expected `_|_` but found `uint` (types differ)
+    //!^ ERROR expected `_|_` but found `uint`
 }
 
 fn main() { bad_bang(5u); }
index f5ec75c59fa9bb6f80eb0f985315d62b9b7799ff..b6e2dea4e5ae73d883894e1602dfcb4059222983 100644 (file)
@@ -3,7 +3,7 @@
 
 fn bad_bang(i: uint) -> ! {
     if i < 0u { } else { fail; }
-    //!^ ERROR expected `_|_` but found `()` (types differ)
+    //!^ ERROR expected `_|_` but found `()`
 }
 
 fn main() { bad_bang(5u); }
index 20b147cb5e331edefebd5d01ca22f4226f532b78..bdb543ed19bc8ffaceb2674e6f367f5cfbb6ecfb 100644 (file)
@@ -1,4 +1,4 @@
 fn f() -> ! {
-    3 //! ERROR expected `_|_` but found `int` (types differ)
+    3 //! ERROR expected `_|_` but found `int`
 }
 fn main() { }
index d2e7edbfc0f19fb98e991f3819cd823475f85aa3..c9f933012780d3afa5d08e83cda855368e74ece1 100644 (file)
@@ -1,7 +1,7 @@
 // error-pattern:mismatched types: expected `()` but found `bool`
 
 fn main() {
-    for i in [0] {
+    for vec::iter([0]) {|_i|
         true
     }
 }
\ No newline at end of file
diff --git a/src/test/compile-fail/crateresolve1.rs b/src/test/compile-fail/crateresolve1.rs
new file mode 100644 (file)
index 0000000..278d86c
--- /dev/null
@@ -0,0 +1,9 @@
+// aux-build:crateresolve1-1.rs
+// aux-build:crateresolve1-2.rs
+// aux-build:crateresolve1-3.rs
+// error-pattern:multiple matching crates for `crateresolve1`
+
+use crateresolve1;
+
+fn main() {
+}
diff --git a/src/test/compile-fail/crateresolve2.rs b/src/test/compile-fail/crateresolve2.rs
new file mode 100644 (file)
index 0000000..e2d49b5
--- /dev/null
@@ -0,0 +1,14 @@
+// aux-build:crateresolve2-1.rs
+// aux-build:crateresolve2-2.rs
+// aux-build:crateresolve2-3.rs
+// error-pattern:using multiple versions of crate `crateresolve2`
+
+use crateresolve2(vers = "0.1");
+
+mod m {
+    use crateresolve2(vers = "0.2");
+}
+
+fn main() {
+    let x: int = false;
+}
diff --git a/src/test/compile-fail/crateresolve5.rs b/src/test/compile-fail/crateresolve5.rs
new file mode 100644 (file)
index 0000000..a6b0f64
--- /dev/null
@@ -0,0 +1,12 @@
+// xfail-fast
+// aux-build:crateresolve5-1.rs
+// aux-build:crateresolve5-2.rs
+// error-pattern:mismatched types
+
+use cr5_1 (name = "crateresolve5", vers = "0.1");
+use cr5_2 (name = "crateresolve5", vers = "0.2");
+
+fn main() {
+    // Nominal types from two multiple versions of a crate are different types
+    assert cr5_1::nominal() == cr5_2::nominal();
+}
diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs
new file mode 100644 (file)
index 0000000..8559d78
--- /dev/null
@@ -0,0 +1,14 @@
+iface monad<A> {
+    fn bind<B>(fn(A) -> self<B>);
+}
+impl monad<A> of monad<A> for [A] {
+    fn bind<B>(f: fn(A) -> [B]) {
+        let mut r = fail;
+        for self.each {|elt| r += f(elt); }
+        //!^ WARNING unreachable expression
+        //!^^ ERROR the type of this value must be known
+   }
+}
+fn main() {
+    ["hi"].bind {|x| [x] };
+}
\ No newline at end of file
diff --git a/src/test/compile-fail/issue-2150.rs b/src/test/compile-fail/issue-2150.rs
new file mode 100644 (file)
index 0000000..6fc8bf7
--- /dev/null
@@ -0,0 +1,8 @@
+fn fail_len(v: [const int]) -> uint {
+    let mut i = fail;
+    for v.each {|x| i += 1u; }
+    //!^ WARNING unreachable statement
+    //!^^ ERROR the type of this value must be known
+    ret i;
+}
+fn main() {}
\ No newline at end of file
diff --git a/src/test/compile-fail/issue-2151.rs b/src/test/compile-fail/issue-2151.rs
new file mode 100644 (file)
index 0000000..a69b6df
--- /dev/null
@@ -0,0 +1,6 @@
+fn main() {
+    vec::iter(fail) {|i|
+        log (debug, i * 2);
+        //!^ ERROR the type of this value must be known
+   };
+}
\ No newline at end of file
index 9b8f85fc6686661da43fa8bfcc14fff470578a65..75d8c4a37df4f5c9b3909f169707fc95391f2b4b 100644 (file)
@@ -1,6 +1,6 @@
 fn g() -> ! { fail; }
 fn f() -> ! {
-    ret 42; //! ERROR expected `_|_` but found `int` (types differ)
+    ret 42; //! ERROR expected `_|_` but found `int`
     g(); //! WARNING unreachable statement
 }
 fn main() { }
index 6521f5159a92d70a93b2f978bf93f2d37bbf4f9c..58e8ef4fe53fb054f3898ed7e9d35ef548123126 100644 (file)
@@ -1,5 +1,5 @@
 fn f() -> ! {
-    ret 42; //! ERROR expected `_|_` but found `int` (types differ)
+    ret 42; //! ERROR expected `_|_` but found `int`
     fail; //! WARNING unreachable statement
 }
 fn main() { }
index eaaa4ecc9fb68778fb6b5f49ddd54e5ea4b121d9..d2015e10698f677bed77fa8dda53df60b3ac1d44 100644 (file)
@@ -4,7 +4,7 @@ fn forever() -> ! {
   loop {
     break;
   }
-  ret 42; //! ERROR expected `_|_` but found `int` (types differ)
+  ret 42; //! ERROR expected `_|_` but found `int`
 }
 
 fn main() {
diff --git a/src/test/compile-fail/rec-expected.rs b/src/test/compile-fail/rec-expected.rs
new file mode 100644 (file)
index 0000000..acbb7f0
--- /dev/null
@@ -0,0 +1,9 @@
+type foo = {a: int};
+type bar = {b: int};
+
+fn want_foo(f: foo) {}
+fn have_bar(b: bar) {
+    want_foo(b); //! ERROR expected a record with field `a`
+}
+
+fn main() {}
\ No newline at end of file
diff --git a/src/test/compile-fail/regions-leaking-ptr.rs b/src/test/compile-fail/regions-leaking-ptr.rs
new file mode 100644 (file)
index 0000000..ffc9f6c
--- /dev/null
@@ -0,0 +1,19 @@
+// The type of `y` ends up getting inferred to the type of the block.
+// This generates a ton of error msgs at the moment.
+fn broken() -> int {
+    let mut x = 3;
+    let mut y = [&x]; //! ERROR reference escapes its block
+    while x < 10 {
+        let z = x;
+        y += [&z];
+        x += 1;
+    }
+    vec::foldl(0, y) {|v, p| v + *p }
+    //!^ ERROR reference escapes its block
+    //!^^ ERROR reference escapes its block
+    //!^^^ ERROR reference escapes its block
+    //!^^^^ ERROR reference escapes its block
+    //!^^^^^ ERROR reference escapes its block
+}
+
+fn main() { }
\ No newline at end of file
diff --git a/src/test/compile-fail/regions-nested-fns.rs b/src/test/compile-fail/regions-nested-fns.rs
new file mode 100644 (file)
index 0000000..5953fe9
--- /dev/null
@@ -0,0 +1,23 @@
+// xfail-test
+
+fn ignore<T>(t: T) {}
+
+fn nested(x: &x.int) {
+    let y = 3;
+    let mut ay = &y;
+
+    ignore(fn&(z: &z.int) {
+        ay = x;
+        ay = &y;
+        ay = z; //! ERROR foo
+    });
+
+    ignore(fn&(z: &z.int) -> &z.int {
+        if false { ret x; }  //! ERROR bar
+        if false { ret &y; } //! ERROR bar
+        if false { ret ay; } //! ERROR bar
+        ret z;
+    });
+}
+
+fn main() {}
\ No newline at end of file
diff --git a/src/test/compile-fail/terr-in-field.rs b/src/test/compile-fail/terr-in-field.rs
new file mode 100644 (file)
index 0000000..0b676e3
--- /dev/null
@@ -0,0 +1,9 @@
+type foo = {a: int, b: int};
+type bar = {a: int, b: uint};
+
+fn want_foo(f: foo) {}
+fn have_bar(b: bar) {
+    want_foo(b); //! ERROR (in field `b`, int vs uint)
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/terr-sorts.rs b/src/test/compile-fail/terr-sorts.rs
new file mode 100644 (file)
index 0000000..6ab3846
--- /dev/null
@@ -0,0 +1,9 @@
+type foo = {a: int, b: int};
+type bar = @foo;
+
+fn want_foo(f: foo) {}
+fn have_bar(b: bar) {
+    want_foo(b); //! ERROR (record vs @-ptr)
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/tps-invariant-class.rs b/src/test/compile-fail/tps-invariant-class.rs
new file mode 100644 (file)
index 0000000..0c4b3b5
--- /dev/null
@@ -0,0 +1,21 @@
+class box_impl<T> {
+    let mut f: T;
+
+    new(f: T) {
+        self.f = f;
+    }
+}
+
+fn set_box_impl<T>(b: box_impl<@const T>, v: @const T) {
+    b.f = v;
+}
+
+fn main() {
+    let b = box_impl::<@int>(@3);
+    set_box_impl(b, @mut 5);
+    //!^ ERROR values differ in mutability
+
+    // No error when type of parameter actually IS @const int
+    let b = box_impl::<@const int>(@3);
+    set_box_impl(b, @mut 5);
+}
\ No newline at end of file
diff --git a/src/test/compile-fail/tps-invariant-enum.rs b/src/test/compile-fail/tps-invariant-enum.rs
new file mode 100644 (file)
index 0000000..16375bd
--- /dev/null
@@ -0,0 +1,18 @@
+enum box_impl<T> = {
+    mut f: T
+};
+
+fn set_box_impl<T>(b: box_impl<@const T>, v: @const T) {
+    b.f = v;
+}
+
+fn main() {
+    let b = box_impl::<@int>({mut f: @3});
+    set_box_impl(b, @mut 5);
+    //!^ ERROR values differ in mutability
+
+    // No error when type of parameter actually IS @const int
+    let x: @const int = @3; // only way I could find to upcast
+    let b = box_impl::<@const int>({mut f: x});
+    set_box_impl(b, @mut 5);
+}
\ No newline at end of file
diff --git a/src/test/compile-fail/tps-invariant-iface.rs b/src/test/compile-fail/tps-invariant-iface.rs
new file mode 100644 (file)
index 0000000..49ab080
--- /dev/null
@@ -0,0 +1,29 @@
+iface box_iface<T> {
+    fn get() -> T;
+    fn set(t: T);
+}
+
+enum box_impl<T> = {
+    mut f: T
+};
+
+impl<T:copy> of box_iface<T> for box_impl<T> {
+    fn get() -> T { ret self.f; }
+    fn set(t: T) { self.f = t; }
+}
+
+fn set_box_iface<T>(b: box_iface<@const T>, v: @const T) {
+    b.set(v);
+}
+
+fn set_box_impl<T>(b: box_impl<@const T>, v: @const T) {
+    b.set(v);
+}
+
+fn main() {
+    let b = box_impl::<@int>({mut f: @3});
+    set_box_iface(b as box_iface::<@int>, @mut 5);
+    //!^ ERROR values differ in mutability
+    set_box_impl(b, @mut 5);
+    //!^ ERROR values differ in mutability
+}
\ No newline at end of file
diff --git a/src/test/compile-fail/unreachable-code-1.rs b/src/test/compile-fail/unreachable-code-1.rs
new file mode 100644 (file)
index 0000000..1dba6f9
--- /dev/null
@@ -0,0 +1,14 @@
+// xfail-pretty
+
+fn id(x: bool) -> bool { x }
+
+fn call_id() {
+    let c <- fail;
+    id(c); //! WARNING unreachable statement
+}
+
+fn call_id_3() { id(ret) && id(ret); }
+    //!^ ERROR the type of this value must be known
+
+fn main() {
+}
diff --git a/src/test/compile-fail/unsafe-for.rs b/src/test/compile-fail/unsafe-for.rs
deleted file mode 100644 (file)
index a4e54d3..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-// error-pattern:invalidate reference x
-
-fn main() {
-    let v: [mut {mut x: int}] = [mut {mut x: 1}];
-    for x in v { v[0] = {mut x: 2}; log(debug, x); }
-}
diff --git a/src/test/compile-fail/vec-add.rs b/src/test/compile-fail/vec-add.rs
new file mode 100644 (file)
index 0000000..2d96f0c
--- /dev/null
@@ -0,0 +1,89 @@
+fn add(i: [int], m: [mut int], c: [const int]) {
+
+    // Check that:
+    //  (1) vectors of any two mutabilities can be added
+    //  (2) result has mutability of lhs
+
+   add(i + [3],
+       m + [3],
+       c + [3]);
+
+   add(i + [mut 3],
+       m + [mut 3],
+       c + [mut 3]);
+
+   add(i + i,
+       m + i,
+       c + i);
+
+   add(i + m,
+       m + m,
+       c + m);
+
+   add(i + c,
+       m + c,
+       c + c);
+
+   add(m + [3], //! ERROR mismatched types
+       m + [3],
+       m + [3]);
+
+   add(i + [3],
+       i + [3], //! ERROR mismatched types
+       i + [3]);
+
+   add(c + [3], //! ERROR mismatched types
+       c + [3], //! ERROR mismatched types
+       c + [3]);
+
+   add(m + [mut 3], //! ERROR mismatched types
+       m + [mut 3],
+       m + [mut 3]);
+
+   add(i + [mut 3],
+       i + [mut 3], //! ERROR mismatched types
+       i + [mut 3]);
+
+   add(c + [mut 3], //! ERROR mismatched types
+       c + [mut 3], //! ERROR mismatched types
+       c + [mut 3]);
+
+   add(m + i, //! ERROR mismatched types
+       m + i,
+       m + i);
+
+   add(i + i,
+       i + i, //! ERROR mismatched types
+       i + i);
+
+   add(c + i, //! ERROR mismatched types
+       c + i, //! ERROR mismatched types
+       c + i);
+
+   add(m + m, //! ERROR mismatched types
+       m + m,
+       m + m);
+
+   add(i + m,
+       i + m, //! ERROR mismatched types
+       i + m);
+
+   add(c + m, //! ERROR mismatched types
+       c + m, //! ERROR mismatched types
+       c + m);
+
+   add(m + c, //! ERROR mismatched types
+       m + c,
+       m + c);
+
+   add(i + c,
+       i + c, //! ERROR mismatched types
+       i + c);
+
+   add(c + c, //! ERROR mismatched types
+       c + c, //! ERROR mismatched types
+       c + c);
+}
+
+fn main() {
+}
index 02e37aac6b882aeff6235cefce9a6588b522cbd8..464203ed6cfe4defc33a49f70caaed0254ca1d01 100644 (file)
@@ -1,8 +1,10 @@
+// xfail-test
+
 fn concat<T: copy>(v: [const [const T]]) -> [T] {
     let mut r = [];
 
     // Earlier versions of our type checker accepted this:
-    for inner: [T] in v {
+    for v.each {|inner|
         //!^ ERROR found `[const 'a]` (values differ in mutability)
         r += inner;
     }
index 4f4bf6ff51267b6b43e7d77b959decc62d9a4afe..b525d0a2da517436a343e6f2f30590ae90d68de5 100644 (file)
@@ -4,5 +4,7 @@
 // preserved.  They are needed to disambiguate `{ret n+1}; - 0` from
 // `({ret n+1}-0)`.
 
-fn wsucc(n: int) -> int { ({ ret n + 1 }) - 0; }
+fn id(f: fn() -> int) -> int { f() }
+
+fn wsucc(n: int) -> int { (id {|| 1 }) - 0 }
 fn main() { }
index 7ed3bc4505d888a316e57b6bce5c2dba6c4e5dab..f0a7681acfe8470a2306b1d540becb7c9be8869e 100644 (file)
@@ -1,5 +1,5 @@
 fn main(args: [str]) {
     let vs: [str] = ["hi", "there", "this", "is", "a", "vec"];
     let vvs: [[str]] = [args, vs];
-    for vs: [str] in vvs { for s: str in vs { log(debug, s); } }
+    for vvs.each {|vs| for vs.each {|s| log(debug, s); } }
 }
index f5f0332dc431c2ad57c0ee29254b6df823d52d18..223aca32bcbe278b321c78ed034e8d29ceb6b338 100644 (file)
@@ -1,5 +1,5 @@
 fn main() {
     let mut sum = 0;
-    for x in [1, 2, 3, 4, 5] { sum += x; }
+    for vec::each([1, 2, 3, 4, 5]) {|x| sum += x; }
     assert (sum == 15);
 }
index ed9fb1c99a1833341878e6ecdf6170e1ec85619b..4d8f7ede6801c1a08c4bde44581a2559a8d2fb43 100644 (file)
@@ -1,5 +1,5 @@
 // From #1174:
-// xfail-test bots are crashing on this on x86_64
+// xfail-fast
 
 use std;
 import str;
@@ -7,7 +7,7 @@
 
 #[nolink]
 native mod libc {
-    fn write(fd: c_int, buf: *u8, nbyte: size_t);
+    fn write(fd: core::libc::c_int, buf: *u8, nbyte: core::libc::size_t);
 }
 
 fn main() {
index e91c5fe5d23ce13da54ca4f4caf6444806b36c9a..8e868a186122881cbc5681f0ec41ce5d1c27122d 100644 (file)
@@ -1,4 +1,4 @@
-fn iter_vec<T>(v: [T], f: fn(T)) { for x: T in v { f(x); } }
+fn iter_vec<T>(v: [T], f: fn(T)) { for v.each {|x| f(x); } }
 
 fn main() {
     let v = [1, 2, 3, 4, 5, 6, 7];
index bc984241aae6a16250b0116ae93883675e2c1fe6..bcb1ea761516f114fb735295ae1aaead449416ee 100644 (file)
@@ -1,4 +1,4 @@
-fn iter_vec<T>(v: [T], f: fn(T)) { for x: T in v { f(x); } }
+fn iter_vec<T>(v: [T], f: fn(T)) { for v.each {|x| f(x); } }
 
 fn main() {
     let v = [1, 2, 3, 4, 5];
index a13843d37cf4f35343a7a9c83d9040c6a82a5722..9f0d1028e6a8e864b0bff11c2554be172e03b7c3 100644 (file)
@@ -6,12 +6,14 @@ fn main() {
     assert (i == 10);
     do  { i += 1; if i == 20 { break; } } while i < 30
     assert (i == 20);
-    for x: int in [1, 2, 3, 4, 5, 6] { if x == 3 { break; } assert (x <= 3); }
+    for vec::each([1, 2, 3, 4, 5, 6]) {|x|
+        if x == 3 { break; } assert (x <= 3);
+    }
     i = 0;
     while i < 10 { i += 1; if i % 2 == 0 { cont; } assert (i % 2 != 0); }
     i = 0;
     do  { i += 1; if i % 2 == 0 { cont; } assert (i % 2 != 0); } while i < 10
-    for x: int in [1, 2, 3, 4, 5, 6] {
+    for vec::each([1, 2, 3, 4, 5, 6]) {|x|
         if x % 2 == 0 { cont; }
         assert (x % 2 != 0);
     }
diff --git a/src/test/run-pass/crateresolve1.rs b/src/test/run-pass/crateresolve1.rs
new file mode 100644 (file)
index 0000000..3dd0206
--- /dev/null
@@ -0,0 +1,10 @@
+// xfail-fast
+// aux-build:crateresolve1-1.rs
+// aux-build:crateresolve1-2.rs
+// aux-build:crateresolve1-3.rs
+
+use crateresolve1(vers = "0.2");
+
+fn main() {
+    assert crateresolve1::f() == 20;
+}
diff --git a/src/test/run-pass/crateresolve2.rs b/src/test/run-pass/crateresolve2.rs
new file mode 100644 (file)
index 0000000..5198ca9
--- /dev/null
@@ -0,0 +1,25 @@
+// xfail-fast
+// aux-build:crateresolve2-1.rs
+// aux-build:crateresolve2-2.rs
+// aux-build:crateresolve2-3.rs
+
+mod a {
+    use crateresolve2(vers = "0.1");
+    fn f() { assert crateresolve2::f() == 10; }
+}
+
+mod b {
+    use crateresolve2(vers = "0.2");
+    fn f() { assert crateresolve2::f() == 20; }
+}
+
+mod c {
+    use crateresolve2(vers = "0.3");
+    fn f() { assert crateresolve2::f() == 30; }
+}
+
+fn main() {
+    a::f();
+    b::f();
+    c::f();
+}
diff --git a/src/test/run-pass/crateresolve3.rs b/src/test/run-pass/crateresolve3.rs
new file mode 100644 (file)
index 0000000..29d4c0c
--- /dev/null
@@ -0,0 +1,21 @@
+// xfail-fast
+// aux-build:crateresolve3-1.rs
+// aux-build:crateresolve3-2.rs
+
+// verify able to link with crates with same name but different versions
+// as long as no name collision on invoked functions.
+
+mod a {
+    use crateresolve3(vers = "0.1");
+    fn f() { assert crateresolve3::f() == 10; }
+}
+
+mod b {
+    use crateresolve3(vers = "0.2");
+    fn f() { assert crateresolve3::g() == 20; }
+}
+
+fn main() {
+    a::f();
+    b::f();
+}
diff --git a/src/test/run-pass/crateresolve4.rs b/src/test/run-pass/crateresolve4.rs
new file mode 100644 (file)
index 0000000..1fe8393
--- /dev/null
@@ -0,0 +1,20 @@
+// xfail-fast
+// aux-build:crateresolve4a-1.rs
+// aux-build:crateresolve4a-2.rs
+// aux-build:crateresolve4b-1.rs
+// aux-build:crateresolve4b-2.rs
+
+mod a {
+    use crateresolve4b(vers = "0.1");
+    fn f() { assert crateresolve4b::f() == 20; }
+}
+
+mod b {
+    use crateresolve4b(vers = "0.2");
+    fn f() { assert crateresolve4b::g() == 10; }
+}
+
+fn main() {
+    a::f();
+    b::f();
+}
diff --git a/src/test/run-pass/crateresolve5.rs b/src/test/run-pass/crateresolve5.rs
new file mode 100644 (file)
index 0000000..99269c3
--- /dev/null
@@ -0,0 +1,13 @@
+// xfail-fast
+// aux-build:crateresolve5-1.rs
+// aux-build:crateresolve5-2.rs
+
+use cr5_1 (name = "crateresolve5", vers = "0.1");
+use cr5_2 (name = "crateresolve5", vers = "0.2");
+
+fn main() {
+    // Structural types can be used between two versions of the same crate
+    assert cr5_1::structural() == cr5_2::structural();
+    // Make sure these are actually two different crates
+    assert cr5_1::f() == 10 && cr5_2::f() == 20;
+}
diff --git a/src/test/run-pass/crateresolve6.rs b/src/test/run-pass/crateresolve6.rs
new file mode 100644 (file)
index 0000000..8c459c1
--- /dev/null
@@ -0,0 +1,13 @@
+// xfail-fast
+// aux-build:crateresolve6-1.rs
+// aux-build:crateresolve6-2.rs
+// error-pattern:mismatched types
+
+// These both have the same version but differ in other metadata
+use cr6_1 (name = "crateresolve6", vers = "0.1", calories="100");
+use cr6_2 (name = "crateresolve6", vers = "0.1", calories="200");
+
+fn main() {
+    assert cr6_1::f() == 100;
+    assert cr6_2::f() == 200;
+}
diff --git a/src/test/run-pass/crateresolve7.rs b/src/test/run-pass/crateresolve7.rs
new file mode 100644 (file)
index 0000000..009e0d7
--- /dev/null
@@ -0,0 +1,11 @@
+// xfail-fast
+// aux-build:crateresolve7-1.rs
+// aux-build:crateresolve7-2.rs
+// aux-build:crateresolve7x.rs
+
+use crateresolve7x;
+
+fn main() {
+    assert crateresolve7x::a::f() == 100;
+    assert crateresolve7x::b::f() == 200;
+}
index 21eca8fefacf284ced5ebf4e8898934baa191375..977536cd57c8b6e0f5c5f65841a9cec4d6390d72 100644 (file)
@@ -1,2 +1,2 @@
-fn wsucc(n: int) -> int { ({ ret n + 1 } + 0); }
+fn wsucc(n: int) -> int { 0 + { ret n + 1 } }
 fn main() { }
index 569d596e7b7ac9a8c4876e9a3fe93fc66525b1be..71480c47a7551d3cd43c9127a97fafd337b0854f 100644 (file)
@@ -1,5 +1,5 @@
 fn main() {
-    for {x: x, y: y}: {x: int, y: int} in [{x: 10, y: 20}, {x: 30, y: 0}] {
-        assert (x + y == 30);
+    for vec::each([{x: 10, y: 20}, {x: 30, y: 0}]) {|elt|
+        assert (elt.x + elt.y == 30);
     }
 }
diff --git a/src/test/run-pass/for-implicit-copy.rs b/src/test/run-pass/for-implicit-copy.rs
deleted file mode 100644 (file)
index 5725563..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-fn main() {
-    let x = [@{mut a: @10, b: @20}];
-    for @{a, b} in x {
-        assert *a == 10;
-        (*x[0]).a = @30;
-        assert *a == 10;
-    }
-}
index d605e1797e1661d951023e936faea190c38e7d1c..177fd1f5c541aae107900feba80dc55d958c70e8 100644 (file)
@@ -1 +1 @@
-fn main() { let x: [int] = []; for i: int in x { fail "moop"; } }
+fn main() { let x: [int] = []; for x.each {|_i| fail "moop"; } }
index e3392da13d730ed128d36f7ff11482d1b2282eec..197fda5c2f4dab622141b08b50908a3cba306ebe 100644 (file)
@@ -34,7 +34,7 @@ mod map_reduce {
     enum ctrl_proto { find_reducer([u8], chan<int>), mapper_done, }
 
     fn start_mappers(ctrl: chan<ctrl_proto>, inputs: [str]) {
-        for i: str in inputs {
+        for inputs.each {|i|
             task::spawn {|| map_task(ctrl, i); };
         }
     }
index 21c195377c980a0aad70fc62521a74756465717d..5ad911d553e3a65cb7f2231b294364e95da82110 100644 (file)
@@ -17,7 +17,7 @@ fn to_str() -> str { "()" }
 impl <T> of map<T> for [T] {
     fn map<U>(f: fn(T) -> U) -> [U] {
         let mut r = [];
-        for x in self { r += [f(x)]; }
+        for self.each {|x| r += [f(x)]; }
         r
     }
 }
index f7025949c2c97681e127e14b9ffa0e87019e4810..f106e8c8a45b4be21f9b7a6bd9b2b8359cecc872 100644 (file)
@@ -3,12 +3,12 @@
 fn main() {
     let x = [1, 2, 3];
     let mut y = 0;
-    for i: int in x { log(debug, i); y += i; }
+    for x.each {|i| log(debug, i); y += i; }
     log(debug, y);
     assert (y == 6);
     let s = "hello there";
     let mut i: int = 0;
-    for c: u8 in s {
+    for str::each(s) {|c|
         if i == 0 { assert (c == 'h' as u8); }
         if i == 1 { assert (c == 'e' as u8); }
         if i == 2 { assert (c == 'l' as u8); }
index 546679fc3915741980e9d087d31ad547afc39985..3fe01a229ee18fbaf740cfa056e16e8e2aabbf76 100644 (file)
@@ -1,6 +1,6 @@
 fn main() {
     let x = [10, 20, 30];
     let mut sum = 0;
-    for x in x { sum += x; }
+    for x.each {|x| sum += x; }
     assert (sum == 60);
 }
index fa17a369f5c2a349ebc7399852536770e8846a5c..99e18ef87dd915f09fcd31273534c3098fdd16c8 100644 (file)
@@ -14,7 +14,7 @@ fn iloop() {
 
 fn main() {
     uint::range(0u, 100u) {|_i|
-        let builder = task::task_builder();
+        let builder = task::builder();
         task::unsupervise(builder);
         task::run(builder) {|| iloop(); };
     }
index 856682dca07c5395d398a44a495abf942febc4f4..8db233508551a4378441c66b336db90301453f12 100644 (file)
@@ -1 +1 @@
-fn main(args: [str]) { for s in args { log(debug, s); } }
+fn main(args: [str]) { for args.each {|s| log(debug, s); } }
index c66de1b33676c8b1da3e778b49bb6abce6b3b4ed..8c9d63922a6f011a6f8923a1053a6d3a6b67ba28 100644 (file)
@@ -4,7 +4,7 @@
 // -*- rust -*-
 fn len(v: [const int]) -> uint {
     let mut i = 0u;
-    for x: int in v { i += 1u; }
+    for v.each {|x| i += 1u; }
     ret i;
 }
 
index d5a05d47cf066188f1e4525530414da221b59928..8779cef04704b7a23750abd409360ac099f1f9d4 100644 (file)
@@ -5,7 +5,7 @@
 impl <A> of monad<A> for [A] {
     fn bind<B>(f: fn(A) -> [B]) -> [B] {
         let mut r = [];
-        for elt in self { r += f(elt); }
+        for self.each {|elt| r += f(elt); }
         r
     }
 }
index ec0edf4eade00248ecca91929e35339413679d10..461be434b0a01597edecca2d2fde34d5d8dd87f1 100644 (file)
@@ -58,7 +58,7 @@ fn main() {
         calllink10
     ];
     let rng = rand::rng();
-    for f in fns {
+    for fns.each {|f|
         let sz = rng.next() % 256u32 + 256u32;
         let frame_backoff = rng.next() % 10u32 + 1u32;
         task::try {|| runtest(f, frame_backoff) };
diff --git a/src/test/run-pass/option-ext.rs b/src/test/run-pass/option-ext.rs
new file mode 100644 (file)
index 0000000..cb6b630
--- /dev/null
@@ -0,0 +1,8 @@
+fn main(args: [str]) {
+    let thing = "{{ f }}";
+    let f = str::find_str(thing, "{{");
+
+    if f.is_none() {
+        io::println("None!");
+    }
+}
\ No newline at end of file
index 70f59ee2e1b66557bfc921a091e339bc11f67046..04b58f908bc20915865fc2c10debf9e4816992b9 100644 (file)
@@ -14,7 +14,7 @@ fn run(i: int) {
         ret;
     }
 
-    let builder = task::task_builder();
+    let builder = task::builder();
     let opts = {
         sched: some({
             mode: task::osmain,
@@ -26,7 +26,7 @@ fn run(i: int) {
     task::unsupervise(builder);
     task::run(builder) {||
         task::yield();
-        let builder = task::task_builder();
+        let builder = task::builder();
         let opts = {
             sched: some({
                 mode: task::single_threaded,
diff --git a/src/test/run-pass/region-param.rs b/src/test/run-pass/region-param.rs
deleted file mode 100644 (file)
index 9e483f0..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-fn region_identity(x: &r.uint) -> &r.uint { x }
-
-fn apply<T>(t: T, f: fn(T) -> T) -> T { f(t) }
-
-fn parameterized(x: &uint) -> uint {
-    let z = apply(x) {|y|
-        region_identity(y)
-    };
-    *z
-}
-
-fn main() {
-    let x = 3u;
-    assert parameterized(&x) == 3u;
-}
\ No newline at end of file
diff --git a/src/test/run-pass/regions-bot.rs b/src/test/run-pass/regions-bot.rs
new file mode 100644 (file)
index 0000000..b25d7ce
--- /dev/null
@@ -0,0 +1,8 @@
+// A very limited test of the "bottom" region
+
+fn produce_static<T>() -> &static.T { fail; }
+
+fn foo<T>(x: &T) -> &uint { produce_static() }
+
+fn main() {
+}
\ No newline at end of file
diff --git a/src/test/run-pass/regions-params.rs b/src/test/run-pass/regions-params.rs
new file mode 100644 (file)
index 0000000..9e483f0
--- /dev/null
@@ -0,0 +1,15 @@
+fn region_identity(x: &r.uint) -> &r.uint { x }
+
+fn apply<T>(t: T, f: fn(T) -> T) -> T { f(t) }
+
+fn parameterized(x: &uint) -> uint {
+    let z = apply(x) {|y|
+        region_identity(y)
+    };
+    *z
+}
+
+fn main() {
+    let x = 3u;
+    assert parameterized(&x) == 3u;
+}
\ No newline at end of file
index 42c96fbd036323603c3ba1ebf292097eaac97bfd..bfd9b477d8e0ac0ef1630dce9f6dc04d3c40ed1d 100644 (file)
@@ -22,7 +22,7 @@ fn iloop() {
 
 fn main() {
     uint::range(0u, 16u) {|_i|
-        let builder = task::task_builder();
+        let builder = task::builder();
         task::unsupervise(builder);
         task::run(builder) {|| iloop(); }
     }
index 7362feaef63afc6254d92ee1d1e0cf50f33cdc2e..5ec60b38c109e6abe259fc93b1a6dce906c16c02 100644 (file)
@@ -6,7 +6,7 @@ fn foo(c: [int]) {
 
     alt none::<int> {
       some::<int>(_) {
-        for i: int in c {
+        for c.each {|i|
             log(debug, a);
             let a = 17;
             b += [a];
index fe184b874df1c163ab63f0d703f9ab97801d003a..10a67b9217ce272fb49273cd35953480d9850c96 100644 (file)
@@ -19,10 +19,10 @@ fn times(f: fn(uint)) {
 
 impl util<T> for [T] {
     fn length_() -> uint { vec::len(self) }
-    fn iter_(f: fn(T)) { for x in self { f(x); } }
+    fn iter_(f: fn(T)) { for self.each {|x| f(x); } }
     fn map_<U>(f: fn(T) -> U) -> [U] {
         let mut r = [];
-        for elt in self { r += [f(elt)]; }
+        for self.each {|elt| r += [f(elt)]; }
         r
     }
 }
index ba5184570f2da88f5d7806b6ad1f1d3c6f32c091..51e61298290dc8eb0ad5bc5ca4a525f8412337fa 100644 (file)
@@ -7,7 +7,7 @@
 
 fn test00() {
     let i: int = 0;
-    let builder = task::task_builder();
+    let builder = task::builder();
     let r = task::future_result(builder);
     task::run(builder) {|| start(i); };
 
index 648b6ba7fa3ead4e2154122e0dadf482dd4676fe..0d8fbc735d4aa9ce75db3296a7fab9f7a18f4eaf 100644 (file)
@@ -32,7 +32,7 @@ fn test00() {
     // Create and spawn tasks...
     let mut results = [];
     while i < number_of_tasks {
-        let builder = task::task_builder();
+        let builder = task::builder();
         results += [task::future_result(builder)];
         task::run(builder) {||
             test00_start(ch, i, number_of_messages)
@@ -42,7 +42,7 @@ fn test00() {
 
     // Read from spawned tasks...
     let mut sum = 0;
-    for r in results {
+    for results.each {|r|
         i = 0;
         while i < number_of_messages {
             let value = recv(po);
@@ -52,7 +52,7 @@ fn test00() {
     }
 
     // Join spawned tasks...
-    for r in results { future::get(r); }
+    for results.each {|r| future::get(r); }
 
     #debug("Completed: Final number is: ");
     log(error, sum);
index 4cab65639b17bed98c03f8f4deee8b6667f01f18..e5c2433473441a047ffc95510126b90b0487224e 100644 (file)
@@ -16,7 +16,7 @@ fn test00() {
     let number_of_messages: int = 10;
     let ch = comm::chan(p);
 
-    let builder = task::task_builder();
+    let builder = task::builder();
     let r = task::future_result(builder);
     task::run(builder) {||
         test00_start(ch, number_of_messages);
index a39d1b6b7fa5d3d3dafc3cf402aebc7d343a7c3d..0d282fb69676a899f30dce8d00d029efa55ea74e 100644 (file)
@@ -41,17 +41,17 @@ fn test00() {
     let mut results = [];
     while i < number_of_tasks {
         i = i + 1;
-        let builder = task::task_builder();
+        let builder = task::builder();
         results += [task::future_result(builder)];
         task::run(builder) {|| test00_start(ch, i, number_of_messages);}
     }
     let mut sum: int = 0;
-    for r in results {
+    for results.each {|r|
         i = 0;
         while i < number_of_messages { sum += recv(po); i = i + 1; }
     }
 
-    for r in results { future::get(r); }
+    for results.each {|r| future::get(r); }
 
     #debug("Completed: Final number is: ");
     assert (sum ==
@@ -126,13 +126,13 @@ fn test06() {
     let mut results = [];
     while i < number_of_tasks {
         i = i + 1;
-        let builder = task::task_builder();
+        let builder = task::builder();
         results += [task::future_result(builder)];
         task::run(builder) {|| test06_start(i);};
     }
 
 
-    for r in results { future::get(r); }
+    for results.each {|r| future::get(r); }
 }
 
 
index a4efa4011e32176fe79f39c3b62f61caa6c5d6ec..77d6bc9e5657427f75618199b8747933f38eba4d 100644 (file)
@@ -24,7 +24,7 @@ fn supervisor() {
 }
 
 fn main() {
-    let builder = task::task_builder();
+    let builder = task::builder();
     task::unsupervise(builder);
     task::run(builder) {|| supervisor(); }
 }
index 0f005658d71ff6f0968616e32c8dc41b8f9d6754..3dd2ebb38592ef7246cb97ad6807cc9fa2663069 100644 (file)
@@ -5,7 +5,7 @@
 // that it doesn't bring down the whole proc
 
 fn main() {
-    let builder = task::task_builder();
+    let builder = task::builder();
     task::unsupervise(builder);
     task::run(builder) {||
         fn f() { f() };
index e7b5ea7070f7e7d8876131b07b57c26bda36f180..c97224144e25f885e503a50fd7448f21b3d91737 100644 (file)
@@ -9,8 +9,6 @@ fn call_id() {
 
 fn call_id_2() { id(true) && id(ret); }
 
-fn call_id_3() { id(ret) && id(ret); }
-
 fn call_id_4() { while id(ret) { } }
 
 fn bind_id_1() { bind id(fail); }
@@ -27,7 +25,7 @@ fn call_id_4() { while id(ret) { } }
 
 fn log_cont() { do { log(error, cont); } while false }
 
-fn ret_ret() -> int { ret (ret 2) + 3; }
+fn ret_ret() -> int { ret 3 + (ret 2); }
 
 fn ret_guard() {
     alt check 2 {
@@ -53,7 +51,6 @@ fn main() {
   ret_ret();
   log_ret();
   call_id_2();
-  call_id_3();
   call_id_4();
   bind_id_2();
   ret_guard();
index f32d269925b090c8d3dce68a76c0e2d259ce3b9e..5634b818794b8a6b9c39c69d7eaafeabd67dc837 100644 (file)
@@ -8,7 +8,7 @@ fn f() {
 }
 
 fn main() {
-    let builder = task::task_builder();
+    let builder = task::builder();
     task::unsupervise(builder);
     task::run(builder) {|| f(); }
 }
\ No newline at end of file
index 63250d8f7c0b1c9edfc86eb03df674a08ea6d72b..f8e3d93f431ddde714268751a215a7770f0188b5 100644 (file)
@@ -15,7 +15,7 @@ fn f(c: comm::chan<bool>) {
 fn main() {
     let p = comm::port();
     let c = comm::chan(p);
-    let builder = task::task_builder();
+    let builder = task::builder();
     task::unsupervise(builder);
     task::run(builder) {|| f(c); }
     assert comm::recv(p);
index 4dd7313c7f3d7ab3a8de46187a95fb9fadd8978a..6b0e82928f4e7fadf8a2eeaad8fb1d0ad40a2397 100644 (file)
@@ -12,7 +12,7 @@ fn f() {
 }
 
 fn main() {
-    let builder = task::task_builder();
+    let builder = task::builder();
     task::unsupervise(builder);
     task::run(builder) {|| f(); }
 }
\ No newline at end of file
index df26dfb688d2cea2169a6f105409e0cfc84a9f53..2b733dcf9c1a4e431ab5d8a892587d1a231666fc 100644 (file)
@@ -8,7 +8,7 @@ fn f() {
 }
 
 fn main() {
-    let builder = task::task_builder();
+    let builder = task::builder();
     task::unsupervise(builder);
     task::run(builder) {|| f(); }
 }
\ No newline at end of file
diff --git a/src/test/run-pass/use-crate-name-alias.rs b/src/test/run-pass/use-crate-name-alias.rs
new file mode 100644 (file)
index 0000000..fe75111
--- /dev/null
@@ -0,0 +1,4 @@
+// Issue #1706
+use stdlib(name="std");
+
+fn main() {}
index b9f3f5688b66f193c344b1011d20825dacfdfff8..2ba0f47eee4b4e98ed48c689871c85db596ba50a 100644 (file)
@@ -31,7 +31,7 @@ fn main() {
 
     fn check_str_eq(a: str, b: str) {
         let mut i: int = 0;
-        for ab: u8 in a {
+        for str::each(a) {|ab|
             log(debug, i);
             log(debug, ab);
             let bb: u8 = b[i];
index 953f453bdc21c6a3ba4203c45433cde803ee18e2..041d8470a6f6ca383eab32c758f6ccca541f6048 100644 (file)
@@ -4,7 +4,7 @@
 import task::*;
 
 fn main() {
-    let builder = task::task_builder();
+    let builder = task::builder();
     let result = task::future_result(builder);
     task::run(builder) {|| child(); }
     #error("1");
index 3133aceb8058172eb0cd5856d756c4ac3149c6b6..6218baa29bc5e8e219efd3b21dafd594c6af91c0 100644 (file)
@@ -4,7 +4,7 @@
 import task::*;
 
 fn main() {
-    let builder = task::task_builder();
+    let builder = task::builder();
     let result = task::future_result(builder);
     task::run(builder) {|| child(); }
     #error("1");