about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorErick Tryzelaar <erick.tryzelaar@gmail.com>2013-08-08 19:27:03 -0700
committerErick Tryzelaar <erick.tryzelaar@gmail.com>2013-08-08 19:27:03 -0700
commit56730c094cf95be58fb05b0e423673aca2a98b88 (patch)
tree096a652b16d38a6f4ff65dd39657ccf308249909 /src/libstd
parent03cc757fe90b88895fcf911d9cce5c04a008b127 (diff)
parent936f70bd878327d867b6f8f82061d738355a47c9 (diff)
downloadrust-56730c094cf95be58fb05b0e423673aca2a98b88.tar.gz
rust-56730c094cf95be58fb05b0e423673aca2a98b88.zip
Merge remote-tracking branch 'remotes/origin/master' into remove-str-trailing-nulls
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/at_vec.rs6
-rw-r--r--src/libstd/comm.rs8
-rw-r--r--src/libstd/either.rs2
-rw-r--r--src/libstd/fmt/mod.rs368
-rw-r--r--src/libstd/fmt/parse.rs896
-rw-r--r--src/libstd/fmt/rt.rs62
-rw-r--r--src/libstd/hashmap.rs10
-rw-r--r--src/libstd/iterator.rs43
-rw-r--r--src/libstd/local_data.rs12
-rw-r--r--src/libstd/num/f64.rs4
-rw-r--r--src/libstd/num/int_macros.rs18
-rw-r--r--src/libstd/num/strconv.rs6
-rw-r--r--src/libstd/num/uint_macros.rs17
-rw-r--r--src/libstd/option.rs34
-rw-r--r--src/libstd/os.rs4
-rw-r--r--src/libstd/rand.rs24
-rw-r--r--src/libstd/result.rs56
-rw-r--r--src/libstd/rt/comm.rs40
-rw-r--r--src/libstd/rt/env.rs28
-rw-r--r--src/libstd/rt/io/mem.rs2
-rw-r--r--src/libstd/rt/kill.rs23
-rw-r--r--src/libstd/rt/local.rs11
-rw-r--r--src/libstd/rt/mod.rs40
-rw-r--r--src/libstd/rt/sched.rs177
-rw-r--r--src/libstd/rt/select.rs6
-rw-r--r--src/libstd/rt/task.rs45
-rw-r--r--src/libstd/rt/test.rs33
-rw-r--r--src/libstd/run.rs12
-rw-r--r--src/libstd/std.rs3
-rw-r--r--src/libstd/str.rs22
-rw-r--r--src/libstd/str/ascii.rs6
-rw-r--r--src/libstd/task/mod.rs31
-rw-r--r--src/libstd/task/spawn.rs29
-rw-r--r--src/libstd/trie.rs30
-rw-r--r--src/libstd/unstable/lang.rs2
-rw-r--r--src/libstd/vec.rs4
36 files changed, 1840 insertions, 274 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index a84f3137bbd..f2470bed732 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -12,7 +12,7 @@
 
 use clone::Clone;
 use container::Container;
-use iterator::{Iterator, range};
+use iterator::Iterator;
 use option::{Option, Some, None};
 use sys;
 use unstable::raw::Repr;
@@ -92,8 +92,8 @@ pub fn append<T:Clone>(lhs: @[T], rhs: &[T]) -> @[T] {
         for x in lhs.iter() {
             push((*x).clone());
         }
-        for i in range(0u, rhs.len()) {
-            push(rhs[i].clone());
+        for elt in rhs.iter() {
+            push(elt.clone());
         }
     }
 }
diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs
index 4356f1143da..a4de10f8c77 100644
--- a/src/libstd/comm.rs
+++ b/src/libstd/comm.rs
@@ -314,7 +314,7 @@ mod pipesy {
 
     #[allow(non_camel_case_types)]
     pub mod oneshot {
-        priv use std::kinds::Send;
+        use std::kinds::Send;
         use ptr::to_mut_unsafe_ptr;
 
         pub fn init<T: Send>() -> (server::Oneshot<T>, client::Oneshot<T>) {
@@ -341,7 +341,7 @@ mod pipesy {
         #[allow(non_camel_case_types)]
         pub mod client {
 
-            priv use std::kinds::Send;
+            use std::kinds::Send;
 
             #[allow(non_camel_case_types)]
             pub fn try_send<T: Send>(pipe: Oneshot<T>, x_0: T) ->
@@ -489,7 +489,7 @@ mod pipesy {
 
     #[allow(non_camel_case_types)]
     pub mod streamp {
-        priv use std::kinds::Send;
+        use std::kinds::Send;
 
         pub fn init<T: Send>() -> (server::Open<T>, client::Open<T>) {
             pub use std::pipes::HasBuffer;
@@ -501,7 +501,7 @@ mod pipesy {
 
         #[allow(non_camel_case_types)]
         pub mod client {
-            priv use std::kinds::Send;
+            use std::kinds::Send;
 
             #[allow(non_camel_case_types)]
             pub fn try_data<T: Send>(pipe: Open<T>, x_0: T) ->
diff --git a/src/libstd/either.rs b/src/libstd/either.rs
index cfaef550c6f..bb74d9b3ec4 100644
--- a/src/libstd/either.rs
+++ b/src/libstd/either.rs
@@ -24,7 +24,7 @@ use vec;
 use vec::{OwnedVector, ImmutableVector};
 
 /// `Either` is a type that represents one of two alternatives
-#[deriving(Clone, Eq)]
+#[deriving(Clone, Eq, IterBytes)]
 pub enum Either<L, R> {
     Left(L),
     Right(R)
diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs
new file mode 100644
index 00000000000..2b8807b2291
--- /dev/null
+++ b/src/libstd/fmt/mod.rs
@@ -0,0 +1,368 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use prelude::*;
+
+use cast;
+use int;
+use rt::io::Decorator;
+use rt::io::mem::MemWriter;
+use rt::io;
+use str;
+use sys;
+use uint;
+use util;
+use vec;
+
+pub mod parse;
+pub mod rt;
+
+/// A struct to represent both where to emit formatting strings to and how they
+/// should be formatted. A mutable version of this is passed to all formatting
+/// traits.
+pub struct Formatter<'self> {
+    /// Flags for formatting (packed version of rt::Flag)
+    flags: uint,
+    /// Character used as 'fill' whenever there is alignment
+    fill: char,
+    /// Boolean indication of whether the output should be left-aligned
+    alignleft: bool,
+    /// Optionally specified integer width that the output should be
+    width: Option<uint>,
+    /// Optionally specified precision for numeric types
+    precision: Option<uint>,
+
+    /// Output buffer.
+    buf: &'self mut io::Writer,
+
+    priv curarg: vec::VecIterator<'self, Argument<'self>>,
+    priv args: &'self [Argument<'self>],
+}
+
+/// This struct represents the generic "argument" which is taken by the Xprintf
+/// family of functions. It contains a function to format the given value. At
+/// compile time it is ensured that the function and the value have the correct
+/// types, and then this struct is used to canonicalize arguments to one type.
+pub struct Argument<'self> {
+    priv formatter: extern "Rust" fn(&util::Void, &mut Formatter),
+    priv value: &'self util::Void,
+}
+
+#[allow(missing_doc)]
+pub trait Bool { fn fmt(&Self, &mut Formatter); }
+#[allow(missing_doc)]
+pub trait Char { fn fmt(&Self, &mut Formatter); }
+#[allow(missing_doc)]
+pub trait Signed { fn fmt(&Self, &mut Formatter); }
+#[allow(missing_doc)]
+pub trait Unsigned { fn fmt(&Self, &mut Formatter); }
+#[allow(missing_doc)]
+pub trait Octal { fn fmt(&Self, &mut Formatter); }
+#[allow(missing_doc)]
+pub trait Binary { fn fmt(&Self, &mut Formatter); }
+#[allow(missing_doc)]
+pub trait LowerHex { fn fmt(&Self, &mut Formatter); }
+#[allow(missing_doc)]
+pub trait UpperHex { fn fmt(&Self, &mut Formatter); }
+#[allow(missing_doc)]
+pub trait String { fn fmt(&Self, &mut Formatter); }
+#[allow(missing_doc)]
+pub trait Poly { fn fmt(&Self, &mut Formatter); }
+#[allow(missing_doc)]
+pub trait Pointer { fn fmt(&Self, &mut Formatter); }
+
+/// The sprintf function takes a precompiled format string and a list of
+/// arguments, to return the resulting formatted string.
+///
+/// This is currently an unsafe function because the types of all arguments
+/// aren't verified by immediate callers of this function. This currently does
+/// not validate that the correct types of arguments are specified for each
+/// format specifier, nor that each argument itself contains the right function
+/// for formatting the right type value. Because of this, the function is marked
+/// as `unsafe` if this is being called manually.
+///
+/// Thankfully the rust compiler provides the macro `ifmt!` which will perform
+/// all of this validation at compile-time and provides a safe interface for
+/// invoking this function.
+///
+/// # Arguments
+///
+///   * fmts - the precompiled format string to emit.
+///   * args - the list of arguments to the format string. These are only the
+///            positional arguments (not named)
+///
+/// Note that this function assumes that there are enough arguments for the
+/// format string.
+pub unsafe fn sprintf(fmt: &[rt::Piece], args: &[Argument]) -> ~str {
+    let output = MemWriter::new();
+    {
+        let mut formatter = Formatter {
+            flags: 0,
+            width: None,
+            precision: None,
+            // FIXME(#8248): shouldn't need a transmute
+            buf: cast::transmute(&output as &io::Writer),
+            alignleft: false,
+            fill: ' ',
+            args: args,
+            curarg: args.iter(),
+        };
+        for piece in fmt.iter() {
+            formatter.run(piece, None);
+        }
+    }
+    return str::from_bytes_owned(output.inner());
+}
+
+impl<'self> Formatter<'self> {
+    fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) {
+        let setcount = |slot: &mut Option<uint>, cnt: &parse::Count| {
+            match *cnt {
+                parse::CountIs(n) => { *slot = Some(n); }
+                parse::CountImplied => { *slot = None; }
+                parse::CountIsParam(i) => {
+                    let v = self.args[i].value;
+                    unsafe { *slot = Some(*(v as *util::Void as *uint)); }
+                }
+                parse::CountIsNextParam => {
+                    let v = self.curarg.next().unwrap().value;
+                    unsafe { *slot = Some(*(v as *util::Void as *uint)); }
+                }
+            }
+        };
+
+        match *piece {
+            rt::String(s) => { self.buf.write(s.as_bytes()); }
+            rt::CurrentArgument(()) => { self.buf.write(cur.unwrap().as_bytes()); }
+            rt::Argument(ref arg) => {
+                // Fill in the format parameters into the formatter
+                self.fill = arg.format.fill;
+                self.alignleft = arg.format.alignleft;
+                self.flags = arg.format.flags;
+                setcount(&mut self.width, &arg.format.width);
+                setcount(&mut self.precision, &arg.format.precision);
+
+                // Extract the correct argument
+                let value = match arg.position {
+                    rt::ArgumentNext => { *self.curarg.next().unwrap() }
+                    rt::ArgumentIs(i) => self.args[i],
+                };
+
+                // Then actually do some printing
+                match arg.method {
+                    None => { (value.formatter)(value.value, self); }
+                    Some(ref method) => { self.execute(*method, value); }
+                }
+            }
+        }
+    }
+
+    fn execute(&mut self, method: &rt::Method, arg: Argument) {
+        match *method {
+            // Pluralization is selection upon a numeric value specified as the
+            // parameter.
+            rt::Plural(offset, ref selectors, ref default) => {
+                // This is validated at compile-time to be a pointer to a
+                // '&uint' value.
+                let value: &uint = unsafe { cast::transmute(arg.value) };
+                let value = *value;
+
+                // First, attempt to match against explicit values without the
+                // offsetted value
+                for s in selectors.iter() {
+                    match s.selector {
+                        Right(val) if value == val => {
+                            return self.runplural(value, s.result);
+                        }
+                        _ => {}
+                    }
+                }
+
+                // Next, offset the value and attempt to match against the
+                // keyword selectors.
+                let value = value - match offset { Some(i) => i, None => 0 };
+                for s in selectors.iter() {
+                    let run = match s.selector {
+                        Left(parse::Zero) => value == 0,
+                        Left(parse::One) => value == 1,
+                        Left(parse::Two) => value == 2,
+
+                        // XXX: Few/Many should have a user-specified boundary
+                        //      One possible option would be in the function
+                        //      pointer of the 'arg: Argument' struct.
+                        Left(parse::Few) => value < 8,
+                        Left(parse::Many) => value >= 8,
+
+                        Right(*) => false
+                    };
+                    if run {
+                        return self.runplural(value, s.result);
+                    }
+                }
+
+                self.runplural(value, *default);
+            }
+
+            // Select is just a matching against the string specified.
+            rt::Select(ref selectors, ref default) => {
+                // This is validated at compile-time to be a pointer to a
+                // string slice,
+                let value: & &str = unsafe { cast::transmute(arg.value) };
+                let value = *value;
+
+                for s in selectors.iter() {
+                    if s.selector == value {
+                        for piece in s.result.iter() {
+                            self.run(piece, Some(value));
+                        }
+                        return;
+                    }
+                }
+                for piece in default.iter() {
+                    self.run(piece, Some(value));
+                }
+            }
+        }
+    }
+
+    fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) {
+        do uint::to_str_bytes(value, 10) |buf| {
+            let valuestr = str::from_bytes_slice(buf);
+            for piece in pieces.iter() {
+                self.run(piece, Some(valuestr));
+            }
+        }
+    }
+}
+
+/// This is a function which calls are emitted to by the compiler itself to
+/// create the Argument structures that are passed into the `sprintf` function.
+#[doc(hidden)]
+pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter),
+                       t: &'a T) -> Argument<'a> {
+    unsafe {
+        Argument {
+            formatter: cast::transmute(f),
+            value: cast::transmute(t)
+        }
+    }
+}
+
+/// When the compiler determines that the type of an argument *must* be a string
+/// (such as for select), then it invokes this method.
+#[doc(hidden)]
+pub fn argumentstr<'a>(s: &'a &str) -> Argument<'a> {
+    argument(String::fmt, s)
+}
+
+/// When the compiler determines that the type of an argument *must* be a uint
+/// (such as for plural), then it invokes this method.
+#[doc(hidden)]
+pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
+    argument(Unsigned::fmt, s)
+}
+
+// Implementations of the core formatting traits
+
+impl Bool for bool {
+    fn fmt(b: &bool, f: &mut Formatter) {
+        String::fmt(&(if *b {"true"} else {"false"}), f);
+    }
+}
+
+impl<'self> String for &'self str {
+    fn fmt(s: & &'self str, f: &mut Formatter) {
+        // XXX: formatting args
+        f.buf.write(s.as_bytes())
+    }
+}
+
+impl Char for char {
+    fn fmt(c: &char, f: &mut Formatter) {
+        // XXX: formatting args
+        // XXX: shouldn't require an allocation
+        let mut s = ~"";
+        s.push_char(*c);
+        f.buf.write(s.as_bytes());
+    }
+}
+
+impl Signed for int {
+    fn fmt(c: &int, f: &mut Formatter) {
+        // XXX: formatting args
+        do int::to_str_bytes(*c, 10) |buf| {
+            f.buf.write(buf);
+        }
+    }
+}
+
+impl Unsigned for uint {
+    fn fmt(c: &uint, f: &mut Formatter) {
+        // XXX: formatting args
+        do uint::to_str_bytes(*c, 10) |buf| {
+            f.buf.write(buf);
+        }
+    }
+}
+
+impl Octal for uint {
+    fn fmt(c: &uint, f: &mut Formatter) {
+        // XXX: formatting args
+        do uint::to_str_bytes(*c, 8) |buf| {
+            f.buf.write(buf);
+        }
+    }
+}
+
+impl LowerHex for uint {
+    fn fmt(c: &uint, f: &mut Formatter) {
+        // XXX: formatting args
+        do uint::to_str_bytes(*c, 16) |buf| {
+            f.buf.write(buf);
+        }
+    }
+}
+
+impl UpperHex for uint {
+    fn fmt(c: &uint, f: &mut Formatter) {
+        // XXX: formatting args
+        do uint::to_str_bytes(*c, 16) |buf| {
+            let mut local = [0u8, ..16];
+            for (l, &b) in local.mut_iter().zip(buf.iter()) {
+                *l = match b as char {
+                    'a' .. 'f' => (b - 'a' as u8) + 'A' as u8,
+                    _ => b,
+                };
+            }
+            f.buf.write(local.slice_to(buf.len()));
+        }
+    }
+}
+
+impl<T> Poly for T {
+    fn fmt(t: &T, f: &mut Formatter) {
+        // XXX: formatting args
+        let s = sys::log_str(t);
+        f.buf.write(s.as_bytes());
+    }
+}
+
+// n.b. use 'const' to get an implementation for both '*mut' and '*' at the same
+//      time.
+impl<T> Pointer for *const T {
+    fn fmt(t: &*const T, f: &mut Formatter) {
+        // XXX: formatting args
+        f.buf.write("0x".as_bytes());
+        LowerHex::fmt(&(*t as uint), f);
+    }
+}
+
+// If you expected tests to be here, look instead at the run-pass/ifmt.rs test,
+// it's a lot easier than creating all of the rt::Piece structures here.
diff --git a/src/libstd/fmt/parse.rs b/src/libstd/fmt/parse.rs
new file mode 100644
index 00000000000..673ea1d3fa8
--- /dev/null
+++ b/src/libstd/fmt/parse.rs
@@ -0,0 +1,896 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use prelude::*;
+
+use char;
+use str;
+use iterator;
+
+condition! { pub parse_error: ~str -> (); }
+
+/// A piece is a portion of the format string which represents the next part to
+/// emit. These are emitted as a stream by the `Parser` class.
+#[deriving(Eq)]
+pub enum Piece<'self> {
+    /// A literal string which should directly be emitted
+    String(&'self str),
+    /// A back-reference to whatever the current argument is. This is used
+    /// inside of a method call to refer back to the original argument.
+    CurrentArgument,
+    /// This describes that formatting should process the next argument (as
+    /// specified inside) for emission.
+    Argument(Argument<'self>),
+}
+
+/// Representation of an argument specification.
+#[deriving(Eq)]
+pub struct Argument<'self> {
+    /// Where to find this argument
+    position: Position<'self>,
+    /// How to format the argument
+    format: FormatSpec<'self>,
+    /// If not `None`, what method to invoke on the argument
+    method: Option<~Method<'self>>
+}
+
+/// Specification for the formatting of an argument in the format string.
+#[deriving(Eq)]
+pub struct FormatSpec<'self> {
+    /// Optionally specified character to fill alignment with
+    fill: Option<char>,
+    /// Optionally specified alignment
+    align: Option<Alignment>,
+    /// Packed version of various flags provided
+    flags: uint,
+    /// The integer precision to use
+    precision: Count,
+    /// The string width requested for the resulting format
+    width: Count,
+    /// The descriptor string representing the name of the format desired for
+    /// this argument, this can be empty or any number of characters, although
+    /// it is required to be one word.
+    ty: &'self str
+}
+
+/// Enum describing where an argument for a format can be located.
+#[deriving(Eq)]
+pub enum Position<'self> {
+    ArgumentNext, ArgumentIs(uint), ArgumentNamed(&'self str)
+}
+
+/// Enum of alignments which are supoprted.
+#[deriving(Eq)]
+pub enum Alignment { AlignLeft, AlignRight }
+
+/// Various flags which can be applied to format strings, the meaning of these
+/// flags is defined by the formatters themselves.
+#[deriving(Eq)]
+pub enum Flag {
+    FlagSignPlus,
+    FlagSignMinus,
+    FlagAlternate,
+}
+
+/// A count is used for the precision and width parameters of an integer, and
+/// can reference either an argument or a literal integer.
+#[deriving(Eq)]
+pub enum Count {
+    CountIs(uint),
+    CountIsParam(uint),
+    CountIsNextParam,
+    CountImplied,
+}
+
+/// Enum describing all of the possible methods which the formatting language
+/// currently supports.
+#[deriving(Eq)]
+pub enum Method<'self> {
+    /// A plural method selects on an integer over a list of either integer or
+    /// keyword-defined clauses. The meaning of the keywords is defined by the
+    /// current locale.
+    ///
+    /// An offset is optionally present at the beginning which is used to match
+    /// against keywords, but it is not matched against the literal integers.
+    ///
+    /// The final element of this enum is the default "other" case which is
+    /// always required to be specified.
+    Plural(Option<uint>, ~[PluralArm<'self>], ~[Piece<'self>]),
+
+    /// A select method selects over a string. Each arm is a different string
+    /// which can be selected for.
+    ///
+    /// As with `Plural`, a default "other" case is required as well.
+    Select(~[SelectArm<'self>], ~[Piece<'self>]),
+}
+
+/// Structure representing one "arm" of the `plural` function.
+#[deriving(Eq)]
+pub struct PluralArm<'self> {
+    /// A selector can either be specified by a keyword or with an integer
+    /// literal.
+    selector: Either<PluralKeyword, uint>,
+    /// Array of pieces which are the format of this arm
+    result: ~[Piece<'self>],
+}
+
+/// Enum of the 5 CLDR plural keywords. There is one more, "other", but that is
+/// specially placed in the `Plural` variant of `Method`
+///
+/// http://www.icu-project.org/apiref/icu4c/classicu_1_1PluralRules.html
+#[deriving(Eq, IterBytes)]
+pub enum PluralKeyword {
+    Zero, One, Two, Few, Many
+}
+
+/// Structure representing one "arm" of the `select` function.
+#[deriving(Eq)]
+pub struct SelectArm<'self> {
+    /// String selector which guards this arm
+    selector: &'self str,
+    /// Array of pieces which are the format of this arm
+    result: ~[Piece<'self>],
+}
+
+/// The parser structure for interpreting the input format string. This is
+/// modelled as an iterator over `Piece` structures to form a stream of tokens
+/// being output.
+///
+/// This is a recursive-descent parser for the sake of simplicity, and if
+/// necessary there's probably lots of room for improvement performance-wise.
+pub struct Parser<'self> {
+    priv input: &'self str,
+    priv cur: str::CharOffsetIterator<'self>,
+}
+
+impl<'self> iterator::Iterator<Piece<'self>> for Parser<'self> {
+    fn next(&mut self) -> Option<Piece<'self>> {
+        match self.cur.clone().next() {
+            Some((_, '#')) => { self.cur.next(); Some(CurrentArgument) }
+            Some((_, '{')) => {
+                self.cur.next();
+                let ret = Some(Argument(self.argument()));
+                if !self.consume('}') {
+                    self.err(~"unterminated format string");
+                }
+                ret
+            }
+            Some((pos, '\\')) => {
+                self.cur.next();
+                self.escape(); // ensure it's a valid escape sequence
+                Some(String(self.string(pos + 1))) // skip the '\' character
+            }
+            Some((_, '}')) | None => { None }
+            Some((pos, _)) => {
+                Some(String(self.string(pos)))
+            }
+        }
+    }
+}
+
+impl<'self> Parser<'self> {
+    /// Creates a new parser for the given format string
+    pub fn new<'a>(s: &'a str) -> Parser<'a> {
+        Parser {
+            input: s,
+            cur: s.char_offset_iter(),
+        }
+    }
+
+    /// Notifies of an error. The message doesn't actually need to be of type
+    /// ~str, but I think it does when this eventually uses conditions so it
+    /// might as well start using it now.
+    fn err(&self, msg: ~str) {
+        parse_error::cond.raise(msg);
+    }
+
+    /// Optionally consumes the specified character. If the character is not at
+    /// the current position, then the current iterator isn't moved and false is
+    /// returned, otherwise the character is consumed and true is returned.
+    fn consume(&mut self, c: char) -> bool {
+        match self.cur.clone().next() {
+            Some((_, maybe)) if c == maybe => {
+                self.cur.next();
+                true
+            }
+            Some(*) | None => false,
+        }
+    }
+
+    /// Attempts to consume any amount of whitespace followed by a character
+    fn wsconsume(&mut self, c: char) -> bool {
+        self.ws(); self.consume(c)
+    }
+
+    /// Consumes all whitespace characters until the first non-whitespace
+    /// character
+    fn ws(&mut self) {
+        loop {
+            match self.cur.clone().next() {
+                Some((_, c)) if char::is_whitespace(c) => { self.cur.next(); }
+                Some(*) | None => { return }
+            }
+        }
+    }
+
+    /// Consumes an escape sequence, failing if there is not a valid character
+    /// to be escaped.
+    fn escape(&mut self) -> char {
+        match self.cur.next() {
+            Some((_, c @ '#')) | Some((_, c @ '{')) |
+            Some((_, c @ '\\')) | Some((_, c @ '}')) => { c }
+            Some((_, c)) => {
+                self.err(fmt!("invalid escape character `%c`", c));
+                c
+            }
+            None => {
+                self.err(~"expected an escape sequence, but format string was \
+                           terminated");
+                ' '
+            }
+        }
+    }
+
+    /// Parses all of a string which is to be considered a "raw literal" in a
+    /// format string. This is everything outside of the braces.
+    fn string(&mut self, start: uint) -> &'self str {
+        loop {
+            // we may not consume the character, so clone the iterator
+            match self.cur.clone().next() {
+                Some((pos, '\\')) | Some((pos, '#')) |
+                Some((pos, '}')) | Some((pos, '{')) => {
+                    return self.input.slice(start, pos);
+                }
+                Some(*) => { self.cur.next(); }
+                None => {
+                    self.cur.next();
+                    return self.input.slice(start, self.input.len());
+                }
+            }
+        }
+    }
+
+    /// Parses an Argument structure, or what's contained within braces inside
+    /// the format string
+    fn argument(&mut self) -> Argument<'self> {
+        Argument {
+            position: self.position(),
+            format: self.format(),
+            method: self.method(),
+        }
+    }
+
+    /// Parses a positional argument for a format. This could either be an
+    /// integer index of an argument, a named argument, or a blank string.
+    fn position(&mut self) -> Position<'self> {
+        match self.integer() {
+            Some(i) => { ArgumentIs(i) }
+            None => {
+                match self.cur.clone().next() {
+                    Some((_, c)) if char::is_alphabetic(c) => {
+                        ArgumentNamed(self.word())
+                    }
+                    _ => ArgumentNext
+                }
+            }
+        }
+    }
+
+    /// Parses a format specifier at the current position, returning all of the
+    /// relevant information in the FormatSpec struct.
+    fn format(&mut self) -> FormatSpec<'self> {
+        let mut spec = FormatSpec {
+            fill: None,
+            align: None,
+            flags: 0,
+            precision: CountImplied,
+            width: CountImplied,
+            ty: self.input.slice(0, 0),
+        };
+        if !self.consume(':') { return spec }
+
+        // fill character
+        match self.cur.clone().next() {
+            Some((_, c)) => {
+                match self.cur.clone().skip(1).next() {
+                    Some((_, '>')) | Some((_, '<')) => {
+                        spec.fill = Some(c);
+                        self.cur.next();
+                    }
+                    Some(*) | None => {}
+                }
+            }
+            None => {}
+        }
+        // Alignment
+        if self.consume('<') {
+            spec.align = Some(AlignLeft);
+        } else if self.consume('>') {
+            spec.align = Some(AlignRight);
+        }
+        // Sign flags
+        if self.consume('+') {
+            spec.flags |= 1 << (FlagSignPlus as uint);
+        } else if self.consume('-') {
+            spec.flags |= 1 << (FlagSignMinus as uint);
+        }
+        // Alternate marker
+        if self.consume('#') {
+            spec.flags |= 1 << (FlagAlternate as uint);
+        }
+        // Width and precision
+        spec.width = self.count();
+        if self.consume('.') {
+            if self.consume('*') {
+                spec.precision = CountIsNextParam;
+            } else {
+                spec.precision = self.count();
+            }
+        }
+        // Finally the actual format specifier
+        spec.ty = self.word();
+        return spec;
+    }
+
+    /// Parses a method to be applied to the previously specified argument and
+    /// its format. The two current supported methods are 'plural' and 'select'
+    fn method(&mut self) -> Option<~Method<'self>> {
+        if !self.wsconsume(',') {
+            return None;
+        }
+        self.ws();
+        match self.word() {
+            "select" => {
+                if !self.wsconsume(',') {
+                    self.err(~"`select` must be followed by `,`");
+                }
+                Some(self.select())
+            }
+            "plural" => {
+                if !self.wsconsume(',') {
+                    self.err(~"`plural` must be followed by `,`");
+                }
+                Some(self.plural())
+            }
+            "" => {
+                self.err(~"expected method after comma");
+                return None;
+            }
+            method => {
+                self.err(fmt!("unknown method: `%s`", method));
+                return None;
+            }
+        }
+    }
+
+    /// Parses a 'select' statement (after the initial 'select' word)
+    fn select(&mut self) -> ~Method<'self> {
+        let mut other = None;
+        let mut arms = ~[];
+        // Consume arms one at a time
+        loop {
+            self.ws();
+            let selector = self.word();
+            if selector == "" {
+                self.err(~"cannot have an empty selector");
+                break
+            }
+            if !self.wsconsume('{') {
+                self.err(~"selector must be followed by `{`");
+            }
+            let pieces = self.collect();
+            if !self.wsconsume('}') {
+                self.err(~"selector case must be terminated by `}`");
+            }
+            if selector == "other" {
+                if !other.is_none() {
+                    self.err(~"multiple `other` statements in `select");
+                }
+                other = Some(pieces);
+            } else {
+                arms.push(SelectArm { selector: selector, result: pieces });
+            }
+            self.ws();
+            match self.cur.clone().next() {
+                Some((_, '}')) => { break }
+                Some(*) | None => {}
+            }
+        }
+        // The "other" selector must be present
+        let other = match other {
+            Some(arm) => { arm }
+            None => {
+                self.err(~"`select` statement must provide an `other` case");
+                ~[]
+            }
+        };
+        ~Select(arms, other)
+    }
+
+    /// Parses a 'plural' statement (after the initial 'plural' word)
+    fn plural(&mut self) -> ~Method<'self> {
+        let mut offset = None;
+        let mut other = None;
+        let mut arms = ~[];
+
+        // First, attempt to parse the 'offset:' field. We know the set of
+        // selector words which can appear in plural arms, and the only ones
+        // which start with 'o' are "other" and "offset", hence look two
+        // characters deep to see if we can consume the word "offset"
+        self.ws();
+        let mut it = self.cur.clone();
+        match it.next() {
+            Some((_, 'o')) => {
+                match it.next() {
+                    Some((_, 'f')) => {
+                        let word = self.word();
+                        if word != "offset" {
+                            self.err(fmt!("expected `offset`, found `%s`",
+                                          word));
+                        } else {
+                            if !self.consume(':') {
+                                self.err(~"`offset` must be followed by `:`");
+                            }
+                            match self.integer() {
+                                Some(i) => { offset = Some(i); }
+                                None => {
+                                    self.err(~"offset must be an integer");
+                                }
+                            }
+                        }
+                    }
+                    Some(*) | None => {}
+                }
+            }
+            Some(*) | None => {}
+        }
+
+        // Next, generate all the arms
+        loop {
+            let mut isother = false;
+            let selector = if self.wsconsume('=') {
+                match self.integer() {
+                    Some(i) => Right(i),
+                    None => {
+                        self.err(~"plural `=` selectors must be followed by an \
+                                   integer");
+                        Right(0)
+                    }
+                }
+            } else {
+                let word = self.word();
+                match word {
+                    "other" => { isother = true; Left(Zero) }
+                    "zero"  => Left(Zero),
+                    "one"   => Left(One),
+                    "two"   => Left(Two),
+                    "few"   => Left(Few),
+                    "many"  => Left(Many),
+                    word    => {
+                        self.err(fmt!("unexpected plural selector `%s`", word));
+                        if word == "" {
+                            break
+                        } else {
+                            Left(Zero)
+                        }
+                    }
+                }
+            };
+            if !self.wsconsume('{') {
+                self.err(~"selector must be followed by `{`");
+            }
+            let pieces = self.collect();
+            if !self.wsconsume('}') {
+                self.err(~"selector case must be terminated by `}`");
+            }
+            if isother {
+                if !other.is_none() {
+                    self.err(~"multiple `other` statements in `select");
+                }
+                other = Some(pieces);
+            } else {
+                arms.push(PluralArm { selector: selector, result: pieces });
+            }
+            self.ws();
+            match self.cur.clone().next() {
+                Some((_, '}')) => { break }
+                Some(*) | None => {}
+            }
+        }
+
+        let other = match other {
+            Some(arm) => { arm }
+            None => {
+                self.err(~"`plural` statement must provide an `other` case");
+                ~[]
+            }
+        };
+        ~Plural(offset, arms, other)
+    }
+
+    /// Parses a Count parameter at the current position. This does not check
+    /// for 'CountIsNextParam' because that is only used in precision, not
+    /// width.
+    fn count(&mut self) -> Count {
+        match self.integer() {
+            Some(i) => {
+                if self.consume('$') {
+                    CountIsParam(i)
+                } else {
+                    CountIs(i)
+                }
+            }
+            None => { CountImplied }
+        }
+    }
+
+    /// Parses a word starting at the current position. A word is considered to
+    /// be an alphabetic character followed by any number of alphanumeric
+    /// characters.
+    fn word(&mut self) -> &'self str {
+        let start = match self.cur.clone().next() {
+            Some((pos, c)) if char::is_alphabetic(c) => {
+                self.cur.next();
+                pos
+            }
+            Some(*) | None => { return self.input.slice(0, 0); }
+        };
+        let mut end;
+        loop {
+            match self.cur.clone().next() {
+                Some((_, c)) if char::is_alphanumeric(c) => {
+                    self.cur.next();
+                }
+                Some((pos, _)) => { end = pos; break }
+                None => { end = self.input.len(); break }
+            }
+        }
+        self.input.slice(start, end)
+    }
+
+    /// Optionally parses an integer at the current position. This doesn't deal
+    /// with overflow at all, it's just accumulating digits.
+    fn integer(&mut self) -> Option<uint> {
+        let mut cur = 0;
+        let mut found = false;
+        loop {
+            match self.cur.clone().next() {
+                Some((_, c)) => {
+                    match char::to_digit(c, 10) {
+                        Some(i) => {
+                            cur = cur * 10 + i;
+                            found = true;
+                            self.cur.next();
+                        }
+                        None => { break }
+                    }
+                }
+                None => { break }
+            }
+        }
+        if found {
+            return Some(cur);
+        } else {
+            return None;
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use prelude::*;
+    use realstd::fmt::{String};
+
+    fn same(fmt: &'static str, p: ~[Piece<'static>]) {
+        let mut parser = Parser::new(fmt);
+        assert_eq!(p, parser.collect());
+    }
+
+    fn fmtdflt() -> FormatSpec<'static> {
+        return FormatSpec {
+            fill: None,
+            align: None,
+            flags: 0,
+            precision: CountImplied,
+            width: CountImplied,
+            ty: "",
+        }
+    }
+
+    fn musterr(s: &str) {
+        Parser::new(s).next();
+    }
+
+    #[test]
+    fn simple() {
+        same("asdf", ~[String("asdf")]);
+        same("a\\{b", ~[String("a"), String("{b")]);
+        same("a\\#b", ~[String("a"), String("#b")]);
+        same("a\\}b", ~[String("a"), String("}b")]);
+        same("a\\}", ~[String("a"), String("}")]);
+        same("\\}", ~[String("}")]);
+    }
+
+    #[test] #[should_fail] fn invalid01() { musterr("{") }
+    #[test] #[should_fail] fn invalid02() { musterr("\\") }
+    #[test] #[should_fail] fn invalid03() { musterr("\\a") }
+    #[test] #[should_fail] fn invalid04() { musterr("{3a}") }
+    #[test] #[should_fail] fn invalid05() { musterr("{:|}") }
+    #[test] #[should_fail] fn invalid06() { musterr("{:>>>}") }
+
+    #[test]
+    fn format_nothing() {
+        same("{}", ~[Argument(Argument {
+            position: ArgumentNext,
+            format: fmtdflt(),
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_position() {
+        same("{3}", ~[Argument(Argument {
+            position: ArgumentIs(3),
+            format: fmtdflt(),
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_position_nothing_else() {
+        same("{3:}", ~[Argument(Argument {
+            position: ArgumentIs(3),
+            format: fmtdflt(),
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_type() {
+        same("{3:a}", ~[Argument(Argument {
+            position: ArgumentIs(3),
+            format: FormatSpec {
+                fill: None,
+                align: None,
+                flags: 0,
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "a",
+            },
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_align_fill() {
+        same("{3:>}", ~[Argument(Argument {
+            position: ArgumentIs(3),
+            format: FormatSpec {
+                fill: None,
+                align: Some(AlignRight),
+                flags: 0,
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "",
+            },
+            method: None,
+        })]);
+        same("{3:0<}", ~[Argument(Argument {
+            position: ArgumentIs(3),
+            format: FormatSpec {
+                fill: Some('0'),
+                align: Some(AlignLeft),
+                flags: 0,
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "",
+            },
+            method: None,
+        })]);
+        same("{3:*<abcd}", ~[Argument(Argument {
+            position: ArgumentIs(3),
+            format: FormatSpec {
+                fill: Some('*'),
+                align: Some(AlignLeft),
+                flags: 0,
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "abcd",
+            },
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_counts() {
+        same("{:10s}", ~[Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: None,
+                flags: 0,
+                precision: CountImplied,
+                width: CountIs(10),
+                ty: "s",
+            },
+            method: None,
+        })]);
+        same("{:10$.10s}", ~[Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: None,
+                flags: 0,
+                precision: CountIs(10),
+                width: CountIsParam(10),
+                ty: "s",
+            },
+            method: None,
+        })]);
+        same("{:.*s}", ~[Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: None,
+                flags: 0,
+                precision: CountIsNextParam,
+                width: CountImplied,
+                ty: "s",
+            },
+            method: None,
+        })]);
+        same("{:.10$s}", ~[Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: None,
+                flags: 0,
+                precision: CountIsParam(10),
+                width: CountImplied,
+                ty: "s",
+            },
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_flags() {
+        same("{:-}", ~[Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: None,
+                flags: (1 << FlagSignMinus as uint),
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "",
+            },
+            method: None,
+        })]);
+        same("{:+#}", ~[Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: None,
+                flags: (1 << FlagSignPlus as uint) | (1 << FlagAlternate as uint),
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "",
+            },
+            method: None,
+        })]);
+    }
+    #[test]
+    fn format_mixture() {
+        same("abcd {3:a} efg", ~[String("abcd "), Argument(Argument {
+            position: ArgumentIs(3),
+            format: FormatSpec {
+                fill: None,
+                align: None,
+                flags: 0,
+                precision: CountImplied,
+                width: CountImplied,
+                ty: "a",
+            },
+            method: None,
+        }), String(" efg")]);
+    }
+
+    #[test]
+    fn select_simple() {
+        same("{, select, other { haha } }", ~[Argument(Argument{
+            position: ArgumentNext,
+            format: fmtdflt(),
+            method: Some(~Select(~[], ~[String(" haha ")]))
+        })]);
+        same("{1, select, other { haha } }", ~[Argument(Argument{
+            position: ArgumentIs(1),
+            format: fmtdflt(),
+            method: Some(~Select(~[], ~[String(" haha ")]))
+        })]);
+        same("{1, select, other {#} }", ~[Argument(Argument{
+            position: ArgumentIs(1),
+            format: fmtdflt(),
+            method: Some(~Select(~[], ~[CurrentArgument]))
+        })]);
+        same("{1, select, other {{2, select, other {lol}}} }", ~[Argument(Argument{
+            position: ArgumentIs(1),
+            format: fmtdflt(),
+            method: Some(~Select(~[], ~[Argument(Argument{
+                position: ArgumentIs(2),
+                format: fmtdflt(),
+                method: Some(~Select(~[], ~[String("lol")]))
+            })])) // wat
+        })]);
+    }
+
+    #[test]
+    fn select_cases() {
+        same("{1, select, a{1} b{2} c{3} other{4} }", ~[Argument(Argument{
+            position: ArgumentIs(1),
+            format: fmtdflt(),
+            method: Some(~Select(~[
+                SelectArm{ selector: "a", result: ~[String("1")] },
+                SelectArm{ selector: "b", result: ~[String("2")] },
+                SelectArm{ selector: "c", result: ~[String("3")] },
+            ], ~[String("4")]))
+        })]);
+    }
+
+    #[test] #[should_fail] fn badselect01() {
+        musterr("{select, }")
+    }
+    #[test] #[should_fail] fn badselect02() {
+        musterr("{1, select}")
+    }
+    #[test] #[should_fail] fn badselect03() {
+        musterr("{1, select, }")
+    }
+    #[test] #[should_fail] fn badselect04() {
+        musterr("{1, select, a {}}")
+    }
+    #[test] #[should_fail] fn badselect05() {
+        musterr("{1, select, other }}")
+    }
+    #[test] #[should_fail] fn badselect06() {
+        musterr("{1, select, other {}")
+    }
+    #[test] #[should_fail] fn badselect07() {
+        musterr("{select, other {}")
+    }
+    #[test] #[should_fail] fn badselect08() {
+        musterr("{1 select, other {}")
+    }
+    #[test] #[should_fail] fn badselect09() {
+        musterr("{:d select, other {}")
+    }
+    #[test] #[should_fail] fn badselect10() {
+        musterr("{1:d select, other {}")
+    }
+
+    #[test]
+    fn plural_simple() {
+        same("{, plural, other { haha } }", ~[Argument(Argument{
+            position: ArgumentNext,
+            format: fmtdflt(),
+            method: Some(~Plural(None, ~[], ~[String(" haha ")]))
+        })]);
+        same("{:, plural, other { haha } }", ~[Argument(Argument{
+            position: ArgumentNext,
+            format: fmtdflt(),
+            method: Some(~Plural(None, ~[], ~[String(" haha ")]))
+        })]);
+        same("{, plural, offset:1 =2{2} =3{3} many{yes} other{haha} }",
+        ~[Argument(Argument{
+            position: ArgumentNext,
+            format: fmtdflt(),
+            method: Some(~Plural(Some(1), ~[
+                PluralArm{ selector: Right(2), result: ~[String("2")] },
+                PluralArm{ selector: Right(3), result: ~[String("3")] },
+                PluralArm{ selector: Left(Many), result: ~[String("yes")] }
+            ], ~[String("haha")]))
+        })]);
+    }
+}
diff --git a/src/libstd/fmt/rt.rs b/src/libstd/fmt/rt.rs
new file mode 100644
index 00000000000..6feb1d7a848
--- /dev/null
+++ b/src/libstd/fmt/rt.rs
@@ -0,0 +1,62 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! This is an internal module used by the ifmt! runtime. These structures are
+//! emitted to static arrays to precompile format strings ahead of time.
+//!
+//! These definitions are similar to their `ct` equivalents, but differ in that
+//! these can be statically allocated and are slightly optimized for the runtime
+
+#[allow(missing_doc)];
+#[doc(hidden)];
+
+use either::Either;
+use fmt::parse;
+use option::Option;
+
+pub enum Piece<'self> {
+    String(&'self str),
+    // FIXME(#8259): this shouldn't require the unit-value here
+    CurrentArgument(()),
+    Argument(Argument<'self>),
+}
+
+pub struct Argument<'self> {
+    position: Position,
+    format: FormatSpec,
+    method: Option<&'self Method<'self>>
+}
+
+pub struct FormatSpec {
+    fill: char,
+    alignleft: bool,
+    flags: uint,
+    precision: parse::Count,
+    width: parse::Count,
+}
+
+pub enum Position {
+    ArgumentNext, ArgumentIs(uint)
+}
+
+pub enum Method<'self> {
+    Plural(Option<uint>, &'self [PluralArm<'self>], &'self [Piece<'self>]),
+    Select(&'self [SelectArm<'self>], &'self [Piece<'self>]),
+}
+
+pub struct PluralArm<'self> {
+    selector: Either<parse::PluralKeyword, uint>,
+    result: &'self [Piece<'self>],
+}
+
+pub struct SelectArm<'self> {
+    selector: &'self str,
+    result: &'self [Piece<'self>],
+}
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs
index fbc471c0ae0..84cba254dcf 100644
--- a/src/libstd/hashmap.rs
+++ b/src/libstd/hashmap.rs
@@ -19,7 +19,7 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
 use clone::Clone;
 use cmp::{Eq, Equiv};
 use hash::Hash;
-use iterator::{Iterator, IteratorUtil, FromIterator, Extendable, range};
+use iterator::{Iterator, IteratorUtil, FromIterator, Extendable};
 use iterator::{FilterMap, Chain, Repeat, Zip};
 use num;
 use option::{None, Option, Some};
@@ -238,7 +238,7 @@ impl<K:Hash + Eq,V> HashMap<K, V> {
         let len_buckets = self.buckets.len();
         let bucket = self.buckets[idx].take();
 
-        let value = do bucket.map_consume |bucket| {
+        let value = do bucket.map_move |bucket| {
             bucket.value
         };
 
@@ -265,8 +265,8 @@ impl<K:Hash + Eq,V> Container for HashMap<K, V> {
 impl<K:Hash + Eq,V> Mutable for HashMap<K, V> {
     /// Clear the map, removing all key-value pairs.
     fn clear(&mut self) {
-        for idx in range(0u, self.buckets.len()) {
-            self.buckets[idx] = None;
+        for bkt in self.buckets.mut_iter() {
+            *bkt = None;
         }
         self.size = 0;
     }
@@ -479,7 +479,7 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
 impl<K: Hash + Eq, V: Clone> HashMap<K, V> {
     /// Like `find`, but returns a copy of the value.
     pub fn find_copy(&self, k: &K) -> Option<V> {
-        self.find(k).map_consume(|v| (*v).clone())
+        self.find(k).map_move(|v| (*v).clone())
     }
 
     /// Like `get`, but returns a copy of the value.
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index 1be398966bb..d10a5541e41 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -18,9 +18,9 @@ implementing the `Iterator` trait.
 */
 
 use cmp;
-use num::{Zero, One, Saturating};
+use num::{Zero, One, Integer, Saturating};
 use option::{Option, Some, None};
-use ops::{Add, Mul};
+use ops::{Add, Mul, Sub};
 use cmp::Ord;
 use clone::Clone;
 use uint;
@@ -674,7 +674,7 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
                     Some((y, y_val))
                 }
             }
-        }).map_consume(|(x, _)| x)
+        }).map_move(|(x, _)| x)
     }
 
     #[inline]
@@ -689,7 +689,7 @@ impl<A, T: Iterator<A>> IteratorUtil<A> for T {
                     Some((y, y_val))
                 }
             }
-        }).map_consume(|(x, _)| x)
+        }).map_move(|(x, _)| x)
     }
 }
 
@@ -1382,7 +1382,7 @@ impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for
                     return Some(x)
                 }
             }
-            match self.iter.next().map_consume(|x| (self.f)(x)) {
+            match self.iter.next().map_move(|x| (self.f)(x)) {
                 None => return self.backiter.chain_mut_ref(|it| it.next()),
                 next => self.frontiter = next,
             }
@@ -1414,7 +1414,7 @@ impl<'self,
                     y => return y
                 }
             }
-            match self.iter.next_back().map_consume(|x| (self.f)(x)) {
+            match self.iter.next_back().map_move(|x| (self.f)(x)) {
                 None => return self.frontiter.chain_mut_ref(|it| it.next_back()),
                 next => self.backiter = next,
             }
@@ -1531,7 +1531,7 @@ pub fn range<A: Add<A, A> + Ord + Clone + One>(start: A, stop: A) -> Range<A> {
     Range{state: start, stop: stop, one: One::one()}
 }
 
-impl<A: Add<A, A> + Ord + Clone + One> Iterator<A> for Range<A> {
+impl<A: Add<A, A> + Ord + Clone> Iterator<A> for Range<A> {
     #[inline]
     fn next(&mut self) -> Option<A> {
         if self.state < self.stop {
@@ -1544,6 +1544,22 @@ impl<A: Add<A, A> + Ord + Clone + One> Iterator<A> for Range<A> {
     }
 }
 
+impl<A: Sub<A, A> + Integer + Ord + Clone> DoubleEndedIterator<A> for Range<A> {
+    #[inline]
+    fn next_back(&mut self) -> Option<A> {
+        if self.stop > self.state {
+            // Integer doesn't technically define this rule, but we're going to assume that every
+            // Integer is reachable from every other one by adding or subtracting enough Ones. This
+            // seems like a reasonable-enough rule that every Integer should conform to, even if it
+            // can't be statically checked.
+            self.stop = self.stop - self.one;
+            Some(self.stop.clone())
+        } else {
+            None
+        }
+    }
+}
+
 impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
     #[inline]
     fn next(&mut self) -> Option<A> {
@@ -2121,4 +2137,17 @@ mod tests {
         check_randacc_iter(xs.iter().cycle().take_(27), 27);
         check_randacc_iter(empty.iter().cycle(), 0);
     }
+
+    #[test]
+    fn test_double_ended_range() {
+        assert_eq!(range(11i, 14).invert().collect::<~[int]>(), ~[13i, 12, 11]);
+        for _ in range(10i, 0).invert() {
+            fail!("unreachable");
+        }
+
+        assert_eq!(range(11u, 14).invert().collect::<~[uint]>(), ~[13u, 12, 11]);
+        for _ in range(10u, 0).invert() {
+            fail!("unreachable");
+        }
+    }
 }
diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs
index c2a60e1c0e9..a73809d202c 100644
--- a/src/libstd/local_data.rs
+++ b/src/libstd/local_data.rs
@@ -110,16 +110,16 @@ fn test_tls_multitask() {
     set(my_key, @~"parent data");
     do task::spawn {
         // TLS shouldn't carry over.
-        assert!(get(my_key, |k| k.map(|&k| *k)).is_none());
+        assert!(get(my_key, |k| k.map_move(|k| *k)).is_none());
         set(my_key, @~"child data");
-        assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) ==
+        assert!(*(get(my_key, |k| k.map_move(|k| *k)).unwrap()) ==
                 ~"child data");
         // should be cleaned up for us
     }
     // Must work multiple times
-    assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
-    assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
-    assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"parent data");
+    assert!(*(get(my_key, |k| k.map_move(|k| *k)).unwrap()) == ~"parent data");
+    assert!(*(get(my_key, |k| k.map_move(|k| *k)).unwrap()) == ~"parent data");
+    assert!(*(get(my_key, |k| k.map_move(|k| *k)).unwrap()) == ~"parent data");
 }
 
 #[test]
@@ -127,7 +127,7 @@ fn test_tls_overwrite() {
     static my_key: Key<@~str> = &Key;
     set(my_key, @~"first data");
     set(my_key, @~"next data"); // Shouldn't leak.
-    assert!(*(get(my_key, |k| k.map(|&k| *k)).unwrap()) == ~"next data");
+    assert!(*(get(my_key, |k| k.map_move(|k| *k)).unwrap()) == ~"next data");
 }
 
 #[test]
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index c7db60e6fd2..60527905779 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -278,18 +278,22 @@ impl One for f64 {
 
 #[cfg(not(test))]
 impl Add<f64,f64> for f64 {
+    #[inline]
     fn add(&self, other: &f64) -> f64 { *self + *other }
 }
 #[cfg(not(test))]
 impl Sub<f64,f64> for f64 {
+    #[inline]
     fn sub(&self, other: &f64) -> f64 { *self - *other }
 }
 #[cfg(not(test))]
 impl Mul<f64,f64> for f64 {
+    #[inline]
     fn mul(&self, other: &f64) -> f64 { *self * *other }
 }
 #[cfg(not(test))]
 impl Div<f64,f64> for f64 {
+    #[inline]
     fn div(&self, other: &f64) -> f64 { *self / *other }
 }
 #[cfg(not(test))]
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index 9842a570d7e..b692bedebfd 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -124,14 +124,6 @@ pub fn range_step_inclusive(start: $T, last: $T, step: $T, it: &fn($T) -> bool)
     range_step_core(start, last, step, Closed, it)
 }
 
-
-#[inline]
-/// Iterate over the range (`hi`..`lo`]
-pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool {
-    if hi == min_value { return true; }
-    range_step_inclusive(hi-1, lo, -1 as $T, it)
-}
-
 impl Num for $T {}
 
 #[cfg(not(test))]
@@ -889,10 +881,6 @@ mod tests {
     fn test_ranges() {
         let mut l = ~[];
 
-        do range_rev(14,11) |i| {
-            l.push(i);
-            true
-        };
         do range_step(20,26,2) |i| {
             l.push(i);
             true
@@ -917,8 +905,7 @@ mod tests {
             l.push(i);
             true
         };
-        assert_eq!(l, ~[13,12,11,
-                        20,22,24,
+        assert_eq!(l, ~[20,22,24,
                         36,34,32,
                         max_value-2,
                         max_value-3,max_value-1,
@@ -926,9 +913,6 @@ mod tests {
                         min_value+3,min_value+1]);
 
         // None of the `fail`s should execute.
-        do range_rev(0,10) |_i| {
-            fail!(~"unreachable");
-        };
         do range_step(10,0,1) |_i| {
             fail!(~"unreachable");
         };
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index 7ab3c81b61f..1f22343ad9c 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -422,9 +422,9 @@ pub fn float_to_str_common<T:NumCast+Zero+One+Eq+Ord+NumStrConv+Float+Round+
 
 // Some constants for from_str_bytes_common's input validation,
 // they define minimum radix values for which the character is a valid digit.
-priv static DIGIT_P_RADIX: uint = ('p' as uint) - ('a' as uint) + 11u;
-priv static DIGIT_I_RADIX: uint = ('i' as uint) - ('a' as uint) + 11u;
-priv static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
+static DIGIT_P_RADIX: uint = ('p' as uint) - ('a' as uint) + 11u;
+static DIGIT_I_RADIX: uint = ('i' as uint) - ('a' as uint) + 11u;
+static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
 
 /**
  * Parses a byte slice as a number. This is meant to
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index a2874c96703..29b8f29d87d 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -125,13 +125,6 @@ pub fn range_step_inclusive(start: $T, last: $T, step: $T_SIGNED, it: &fn($T) ->
     range_step_core(start, last, step, Closed, it)
 }
 
-#[inline]
-/// Iterate over the range (`hi`..`lo`]
-pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool {
-    if hi == min_value { return true; }
-    range_step_inclusive(hi-1, lo, -1 as $T_SIGNED, it)
-}
-
 impl Num for $T {}
 
 #[cfg(not(test))]
@@ -654,10 +647,6 @@ mod tests {
     pub fn test_ranges() {
         let mut l = ~[];
 
-        do range_rev(14,11) |i| {
-            l.push(i);
-            true
-        };
         do range_step(20,26,2) |i| {
             l.push(i);
             true
@@ -683,8 +672,7 @@ mod tests {
             true
         };
 
-        assert_eq!(l, ~[13,12,11,
-                        20,22,24,
+        assert_eq!(l, ~[20,22,24,
                         36,34,32,
                         max_value-2,
                         max_value-3,max_value-1,
@@ -692,9 +680,6 @@ mod tests {
                         min_value+3,min_value+1]);
 
         // None of the `fail`s should execute.
-        do range_rev(0,0) |_i| {
-            fail!("unreachable");
-        };
         do range_step(10,0,1) |_i| {
             fail!("unreachable");
         };
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index ea1bddcdb4b..66b30d8dd03 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -208,6 +208,12 @@ impl<T> Option<T> {
         match *self { Some(ref mut x) => Some(f(x)), None => None }
     }
 
+    /// Applies a function to the contained value or returns a default
+    #[inline]
+    pub fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
+        match *self { None => def, Some(ref t) => f(t) }
+    }
+
     /// Maps a `Some` value from one type to another by a mutable reference,
     /// or returns a default value.
     #[inline]
@@ -218,21 +224,15 @@ impl<T> Option<T> {
     /// As `map`, but consumes the option and gives `f` ownership to avoid
     /// copying.
     #[inline]
-    pub fn map_consume<U>(self, f: &fn(v: T) -> U) -> Option<U> {
-        match self { None => None, Some(v) => Some(f(v)) }
-    }
-
-    /// Applies a function to the contained value or returns a default
-    #[inline]
-    pub fn map_default<'a, U>(&'a self, def: U, f: &fn(&'a T) -> U) -> U {
-        match *self { None => def, Some(ref t) => f(t) }
+    pub fn map_move<U>(self, f: &fn(T) -> U) -> Option<U> {
+        match self { Some(x) => Some(f(x)), None => None }
     }
 
     /// As `map_default`, but consumes the option and gives `f`
     /// ownership to avoid copying.
     #[inline]
-    pub fn map_consume_default<U>(self, def: U, f: &fn(v: T) -> U) -> U {
-        match self { None => def, Some(v) => f(v) }
+    pub fn map_move_default<U>(self, def: U, f: &fn(T) -> U) -> U {
+        match self { None => def, Some(t) => f(t) }
     }
 
     /// Take the value out of the option, leaving a `None` in its place.
@@ -241,20 +241,6 @@ impl<T> Option<T> {
         util::replace(self, None)
     }
 
-    /// As `map_consume`, but swaps a None into the original option rather
-    /// than consuming it by-value.
-    #[inline]
-    pub fn take_map<U>(&mut self, blk: &fn(T) -> U) -> Option<U> {
-        self.take().map_consume(blk)
-    }
-
-    /// As `map_consume_default`, but swaps a None into the original option
-    /// rather than consuming it by-value.
-    #[inline]
-    pub fn take_map_default<U> (&mut self, def: U, blk: &fn(T) -> U) -> U {
-        self.take().map_consume_default(def, blk)
-    }
-
     /// Apply a function to the contained value or do nothing.
     /// Returns true if the contained value was mutated.
     pub fn mutate(&mut self, f: &fn(T) -> T) -> bool {
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 26f6dbc2b37..57415e89cfb 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -501,9 +501,7 @@ pub fn self_exe_path() -> Option<Path> {
         }
     }
 
-    do load_self().map |pth| {
-        Path(*pth).dir_path()
-    }
+    load_self().map_move(|path| Path(path).dir_path())
 }
 
 
diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs
index 4ef524d7715..5f8fa9fddbc 100644
--- a/src/libstd/rand.rs
+++ b/src/libstd/rand.rs
@@ -610,15 +610,32 @@ impl<R: Rng> RngUtil for R {
 }
 
 /// Create a random number generator with a default algorithm and seed.
+///
+/// It returns the cryptographically-safest `Rng` algorithm currently
+/// available in Rust. If you require a specifically seeded `Rng` for
+/// consistency over time you should pick one algorithm and create the
+/// `Rng` yourself.
 pub fn rng() -> IsaacRng {
     IsaacRng::new()
 }
 
+/// Create a weak random number generator with a default algorithm and seed.
+///
+/// It returns the fatest `Rng` algorithm currently available in Rust without
+/// consideration for cryptography or security. If you require a specifically
+/// seeded `Rng` for consistency over time you should pick one algorithm and
+/// create the `Rng` yourself.
+pub fn weak_rng() -> XorShiftRng {
+    XorShiftRng::new()
+}
+
 static RAND_SIZE_LEN: u32 = 8;
 static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
 
 /// A random number generator that uses the [ISAAC
 /// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29).
+///
+/// The ISAAC algorithm is suitable for cryptographic purposes.
 pub struct IsaacRng {
     priv cnt: u32,
     priv rsl: [u32, .. RAND_SIZE],
@@ -794,8 +811,11 @@ impl Rng for IsaacRng {
 }
 
 /// An [Xorshift random number
-/// generator](http://en.wikipedia.org/wiki/Xorshift). Not suitable for
-/// cryptographic purposes.
+/// generator](http://en.wikipedia.org/wiki/Xorshift).
+///
+/// The Xorshift algorithm is not suitable for cryptographic purposes
+/// but is very fast. If you do not know for sure that it fits your
+/// requirements, use a more secure one such as `IsaacRng`.
 pub struct XorShiftRng {
     priv x: u32,
     priv y: u32,
diff --git a/src/libstd/result.rs b/src/libstd/result.rs
index 91f42edf0ae..3e429c6116d 100644
--- a/src/libstd/result.rs
+++ b/src/libstd/result.rs
@@ -152,6 +152,40 @@ impl<T, E: ToStr> Result<T, E> {
     /// Call a method based on a previous result
     ///
     /// If `self` is `Ok` then the value is extracted and passed to `op`
+    /// whereupon `op`s result is wrapped in `Ok` and returned. if `self` is
+    /// `Err` then it is immediately returned.  This function can be used to
+    /// compose the results of two functions.
+    ///
+    /// Example:
+    ///
+    ///     let res = do read_file(file).map_move |buf| {
+    ///         parse_bytes(buf)
+    ///     }
+    #[inline]
+    pub fn map_move<U>(self, op: &fn(T) -> U) -> Result<U,E> {
+        match self {
+          Ok(t) => Ok(op(t)),
+          Err(e) => Err(e)
+        }
+    }
+
+    /// Call a method based on a previous result
+    ///
+    /// If `self` is `Err` then the value is extracted and passed to `op`
+    /// whereupon `op`s result is wrapped in an `Err` and returned. if `self` is
+    /// `Ok` then it is immediately returned.  This function can be used to pass
+    /// through a successful result while handling an error.
+    #[inline]
+    pub fn map_err_move<F>(self, op: &fn(E) -> F) -> Result<T,F> {
+        match self {
+          Ok(t) => Ok(t),
+          Err(e) => Err(op(e))
+        }
+    }
+
+    /// Call a method based on a previous result
+    ///
+    /// If `self` is `Ok` then the value is extracted and passed to `op`
     /// whereupon `op`s result is returned. if `self` is `Err` then it is
     /// immediately returned. This function can be used to compose the results
     /// of two functions.
@@ -312,7 +346,9 @@ pub fn iter_vec2<S, T, U: ToStr>(ss: &[S], ts: &[T],
 #[cfg(test)]
 mod tests {
     use super::*;
+
     use either;
+    use str::OwnedStr;
 
     pub fn op1() -> Result<int, ~str> { Ok(666) }
 
@@ -359,14 +395,26 @@ mod tests {
 
     #[test]
     pub fn test_impl_map() {
-        assert_eq!(Ok::<~str, ~str>(~"a").map(|_x| ~"b"), Ok(~"b"));
-        assert_eq!(Err::<~str, ~str>(~"a").map(|_x| ~"b"), Err(~"a"));
+        assert_eq!(Ok::<~str, ~str>(~"a").map(|x| (~"b").append(*x)), Ok(~"ba"));
+        assert_eq!(Err::<~str, ~str>(~"a").map(|x| (~"b").append(*x)), Err(~"a"));
     }
 
     #[test]
     pub fn test_impl_map_err() {
-        assert_eq!(Ok::<~str, ~str>(~"a").map_err(|_x| ~"b"), Ok(~"a"));
-        assert_eq!(Err::<~str, ~str>(~"a").map_err(|_x| ~"b"), Err(~"b"));
+        assert_eq!(Ok::<~str, ~str>(~"a").map_err(|x| (~"b").append(*x)), Ok(~"a"));
+        assert_eq!(Err::<~str, ~str>(~"a").map_err(|x| (~"b").append(*x)), Err(~"ba"));
+    }
+
+    #[test]
+    pub fn test_impl_map_move() {
+        assert_eq!(Ok::<~str, ~str>(~"a").map_move(|x| x + "b"), Ok(~"ab"));
+        assert_eq!(Err::<~str, ~str>(~"a").map_move(|x| x + "b"), Err(~"a"));
+    }
+
+    #[test]
+    pub fn test_impl_map_err_move() {
+        assert_eq!(Ok::<~str, ~str>(~"a").map_err_move(|x| x + "b"), Ok(~"a"));
+        assert_eq!(Err::<~str, ~str>(~"a").map_err_move(|x| x + "b"), Err(~"ab"));
     }
 
     #[test]
diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs
index a060059f5fc..936a6526508 100644
--- a/src/libstd/rt/comm.rs
+++ b/src/libstd/rt/comm.rs
@@ -159,7 +159,7 @@ impl<T> ChanOne<T> {
                     // Port is blocked. Wake it up.
                     let recvr = BlockedTask::cast_from_uint(task_as_state);
                     if do_resched {
-                        do recvr.wake().map_consume |woken_task| {
+                        do recvr.wake().map_move |woken_task| {
                             Scheduler::run_task(woken_task);
                         };
                     } else {
@@ -225,9 +225,10 @@ impl<T> Select for PortOne<T> {
     fn optimistic_check(&mut self) -> bool {
         // The optimistic check is never necessary for correctness. For testing
         // purposes, making it randomly return false simulates a racing sender.
-        use rand::{Rand, rng};
-        let mut rng = rng();
-        let actually_check = Rand::rand(&mut rng);
+        use rand::{Rand};
+        let actually_check = do Local::borrow::<Scheduler, bool> |sched| {
+            Rand::rand(&mut sched.rng)
+        };
         if actually_check {
             unsafe { (*self.packet()).state.load(Acquire) == STATE_ONE }
         } else {
@@ -381,7 +382,7 @@ impl<T> Drop for ChanOne<T> {
                     // The port is blocked waiting for a message we will never send. Wake it.
                     assert!((*this.packet()).payload.is_none());
                     let recvr = BlockedTask::cast_from_uint(task_as_state);
-                    do recvr.wake().map_consume |woken_task| {
+                    do recvr.wake().map_move |woken_task| {
                         Scheduler::run_task(woken_task);
                     };
                 }
@@ -508,7 +509,11 @@ impl<T> Peekable<T> for Port<T> {
     }
 }
 
-impl<T> Select for Port<T> {
+// XXX: Kind of gross. A Port<T> should be selectable so you can make an array
+// of them, but a &Port<T> should also be selectable so you can select2 on it
+// alongside a PortOne<U> without passing the port by value in recv_ready.
+
+impl<'self, T> Select for &'self Port<T> {
     #[inline]
     fn optimistic_check(&mut self) -> bool {
         do self.next.with_mut_ref |pone| { pone.optimistic_check() }
@@ -526,12 +531,29 @@ impl<T> Select for Port<T> {
     }
 }
 
-impl<T> SelectPort<(T, Port<T>)> for Port<T> {
-    fn recv_ready(self) -> Option<(T, Port<T>)> {
+impl<T> Select for Port<T> {
+    #[inline]
+    fn optimistic_check(&mut self) -> bool {
+        (&*self).optimistic_check()
+    }
+
+    #[inline]
+    fn block_on(&mut self, sched: &mut Scheduler, task: BlockedTask) -> bool {
+        (&*self).block_on(sched, task)
+    }
+
+    #[inline]
+    fn unblock_from(&mut self) -> bool {
+        (&*self).unblock_from()
+    }
+}
+
+impl<'self, T> SelectPort<T> for &'self Port<T> {
+    fn recv_ready(self) -> Option<T> {
         match self.next.take().recv_ready() {
             Some(StreamPayload { val, next }) => {
                 self.next.put_back(next);
-                Some((val, self))
+                Some(val)
             }
             None => None
         }
diff --git a/src/libstd/rt/env.rs b/src/libstd/rt/env.rs
index 1d7ff173149..6e671742fb6 100644
--- a/src/libstd/rt/env.rs
+++ b/src/libstd/rt/env.rs
@@ -10,7 +10,12 @@
 
 //! Runtime environment settings
 
+use from_str::FromStr;
 use libc::{size_t, c_char, c_int};
+use option::{Some, None};
+use os;
+
+// OLD RT stuff
 
 pub struct Environment {
     /// The number of threads to use by default
@@ -47,3 +52,26 @@ pub fn get() -> &Environment {
 extern {
     fn rust_get_rt_env() -> &Environment;
 }
+
+// NEW RT stuff
+
+// Note that these are all accessed without any synchronization.
+// They are expected to be initialized once then left alone.
+
+static mut MIN_STACK: uint = 2000000;
+
+pub fn init() {
+    unsafe {
+        match os::getenv("RUST_MIN_STACK") {
+            Some(s) => match FromStr::from_str(s) {
+                Some(i) => MIN_STACK = i,
+                None => ()
+            },
+            None => ()
+        }
+    }
+}
+
+pub fn min_stack() -> uint {
+    unsafe { MIN_STACK }
+}
diff --git a/src/libstd/rt/io/mem.rs b/src/libstd/rt/io/mem.rs
index c93945a6a9a..277897e5d2e 100644
--- a/src/libstd/rt/io/mem.rs
+++ b/src/libstd/rt/io/mem.rs
@@ -26,7 +26,7 @@ pub struct MemWriter {
 }
 
 impl MemWriter {
-    pub fn new() -> MemWriter { MemWriter { buf: ~[] } }
+    pub fn new() -> MemWriter { MemWriter { buf: vec::with_capacity(128) } }
 }
 
 impl Writer for MemWriter {
diff --git a/src/libstd/rt/kill.rs b/src/libstd/rt/kill.rs
index 3372c13b877..e07cb1425bf 100644
--- a/src/libstd/rt/kill.rs
+++ b/src/libstd/rt/kill.rs
@@ -402,10 +402,10 @@ impl KillHandle {
                     || {
                         // Prefer to check tombstones that were there first,
                         // being "more fair" at the expense of tail-recursion.
-                        others.take().map_consume_default(true, |f| f()) && {
+                        others.take().map_move_default(true, |f| f()) && {
                             let mut inner = this.take().unwrap();
                             (!inner.any_child_failed) &&
-                                inner.child_tombstones.take_map_default(true, |f| f())
+                                inner.child_tombstones.take().map_move_default(true, |f| f())
                         }
                     }
                 }
@@ -424,7 +424,7 @@ impl KillHandle {
                     let others = Cell::new(other_tombstones); // :(
                     || {
                         // Prefer fairness to tail-recursion, as in above case.
-                        others.take().map_consume_default(true, |f| f()) &&
+                        others.take().map_move_default(true, |f| f()) &&
                             f.take()()
                     }
                 }
@@ -493,7 +493,7 @@ impl Death {
         { use util; util::ignore(group); }
 
         // Step 1. Decide if we need to collect child failures synchronously.
-        do self.on_exit.take_map |on_exit| {
+        do self.on_exit.take().map_move |on_exit| {
             if success {
                 // We succeeded, but our children might not. Need to wait for them.
                 let mut inner = self.kill_handle.take_unwrap().unwrap();
@@ -501,7 +501,7 @@ impl Death {
                     success = false;
                 } else {
                     // Lockless access to tombstones protected by unwrap barrier.
-                    success = inner.child_tombstones.take_map_default(true, |f| f());
+                    success = inner.child_tombstones.take().map_move_default(true, |f| f());
                 }
             }
             on_exit(success);
@@ -510,12 +510,12 @@ impl Death {
         // Step 2. Possibly alert possibly-watching parent to failure status.
         // Note that as soon as parent_handle goes out of scope, the parent
         // can successfully unwrap its handle and collect our reported status.
-        do self.watching_parent.take_map |mut parent_handle| {
+        do self.watching_parent.take().map_move |mut parent_handle| {
             if success {
                 // Our handle might be None if we had an exit callback, and
                 // already unwrapped it. But 'success' being true means no
                 // child failed, so there's nothing to do (see below case).
-                do self.kill_handle.take_map |own_handle| {
+                do self.kill_handle.take().map_move |own_handle| {
                     own_handle.reparent_children_to(&mut parent_handle);
                 };
             } else {
@@ -590,7 +590,8 @@ impl Death {
     #[inline]
     pub fn assert_may_sleep(&self) {
         if self.wont_sleep != 0 {
-            rtabort!("illegal atomic-sleep: can't deschedule inside atomically()");
+            rtabort!("illegal atomic-sleep: attempt to reschedule while \
+                      using an Exclusive or LittleLock");
         }
     }
 }
@@ -614,6 +615,7 @@ mod test {
     // Test cases don't care about the spare killed flag.
     fn make_kill_handle() -> KillHandle { let (h,_) = KillHandle::new(); h }
 
+    #[ignore(reason = "linked failure")]
     #[test]
     fn no_tombstone_success() {
         do run_in_newsched_task {
@@ -819,6 +821,7 @@ mod test {
         }
     }
 
+    #[ignore(reason = "linked failure")]
     #[test]
     fn block_and_get_killed() {
         do with_test_task |mut task| {
@@ -830,6 +833,7 @@ mod test {
         }
     }
 
+    #[ignore(reason = "linked failure")]
     #[test]
     fn block_already_killed() {
         do with_test_task |mut task| {
@@ -839,6 +843,7 @@ mod test {
         }
     }
 
+    #[ignore(reason = "linked failure")]
     #[test]
     fn block_unkillably_and_get_killed() {
         do with_test_task |mut task| {
@@ -856,6 +861,7 @@ mod test {
         }
     }
 
+    #[ignore(reason = "linked failure")]
     #[test]
     fn block_on_pipe() {
         // Tests the "killable" path of casting to/from uint.
@@ -869,6 +875,7 @@ mod test {
         }
     }
 
+    #[ignore(reason = "linked failure")]
     #[test]
     fn block_unkillably_on_pipe() {
         // Tests the "indestructible" path of casting to/from uint.
diff --git a/src/libstd/rt/local.rs b/src/libstd/rt/local.rs
index 131507196b1..7154066e7b7 100644
--- a/src/libstd/rt/local.rs
+++ b/src/libstd/rt/local.rs
@@ -126,6 +126,7 @@ impl Local for IoFactoryObject {
 
 #[cfg(test)]
 mod test {
+    use option::None;
     use unstable::run_in_bare_thread;
     use rt::test::*;
     use super::*;
@@ -137,7 +138,7 @@ mod test {
         do run_in_bare_thread {
             local_ptr::init_tls_key();
             let mut sched = ~new_test_uv_sched();
-            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
             Local::put(task);
             let task: ~Task = Local::take();
             cleanup_task(task);
@@ -149,11 +150,11 @@ mod test {
         do run_in_bare_thread {
             local_ptr::init_tls_key();
             let mut sched = ~new_test_uv_sched();
-            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
             Local::put(task);
             let task: ~Task = Local::take();
             cleanup_task(task);
-            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
             Local::put(task);
             let task: ~Task = Local::take();
             cleanup_task(task);
@@ -166,7 +167,7 @@ mod test {
         do run_in_bare_thread {
             local_ptr::init_tls_key();
             let mut sched = ~new_test_uv_sched();
-            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
             Local::put(task);
 
             unsafe {
@@ -182,7 +183,7 @@ mod test {
         do run_in_bare_thread {
             local_ptr::init_tls_key();
             let mut sched = ~new_test_uv_sched();
-            let task = ~Task::new_root(&mut sched.stack_pool, || {});
+            let task = ~Task::new_root(&mut sched.stack_pool, None, || {});
             Local::put(task);
 
             let res = do Local::borrow::<Task,bool> |_task| {
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 760ca8a9ada..01a52892f63 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -63,8 +63,7 @@ Several modules in `core` are clients of `rt`:
 use cell::Cell;
 use clone::Clone;
 use container::Container;
-use iter::Times;
-use iterator::{Iterator, IteratorUtil};
+use iterator::{Iterator, IteratorUtil, range};
 use option::{Some, None};
 use ptr::RawPtr;
 use rt::local::Local;
@@ -212,6 +211,7 @@ pub fn init(argc: int, argv: **u8, crate_map: *u8) {
     // Need to propagate the unsafety to `start`.
     unsafe {
         args::init(argc, argv);
+        env::init();
         logging::init(crate_map);
         rust_update_gc_metadata(crate_map);
     }
@@ -246,11 +246,16 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
 
     let main = Cell::new(main);
 
-    // The shared list of sleeping schedulers. Schedulers wake each other
-    // occassionally to do new work.
+    // The shared list of sleeping schedulers.
     let sleepers = SleeperList::new();
-    // The shared work queue. Temporary until work stealing is implemented.
-    let work_queue = WorkQueue::new();
+
+    // Create a work queue for each scheduler, ntimes. Create an extra
+    // for the main thread if that flag is set. We won't steal from it.
+    let mut work_queues = ~[];
+    for _ in range(0u, nscheds) {
+        let work_queue: WorkQueue<~Task> = WorkQueue::new();
+        work_queues.push(work_queue);
+    }
 
     // The schedulers.
     let mut scheds = ~[];
@@ -258,12 +263,15 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
     // sent the Shutdown message to terminate the schedulers.
     let mut handles = ~[];
 
-    do nscheds.times {
+    for i in range(0u, nscheds) {
         rtdebug!("inserting a regular scheduler");
 
         // Every scheduler is driven by an I/O event loop.
         let loop_ = ~UvEventLoop::new();
-        let mut sched = ~Scheduler::new(loop_, work_queue.clone(), sleepers.clone());
+        let mut sched = ~Scheduler::new(loop_,
+                                        work_queues[i].clone(),
+                                        work_queues.clone(),
+                                        sleepers.clone());
         let handle = sched.make_handle();
 
         scheds.push(sched);
@@ -279,9 +287,14 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
         let friend_handle = friend_sched.make_handle();
         scheds.push(friend_sched);
 
+        // This scheduler needs a queue that isn't part of the stealee
+        // set.
+        let work_queue = WorkQueue::new();
+
         let main_loop = ~UvEventLoop::new();
         let mut main_sched = ~Scheduler::new_special(main_loop,
-                                                     work_queue.clone(),
+                                                     work_queue,
+                                                     work_queues.clone(),
                                                      sleepers.clone(),
                                                      false,
                                                      Some(friend_handle));
@@ -330,8 +343,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
         // In the case where we do not use a main_thread scheduler we
         // run the main task in one of our threads.
 
-        let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool,
-                                            main.take());
+        let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool, None, main.take());
         main_task.death.on_exit = Some(on_exit.take());
         let main_task_cell = Cell::new(main_task);
 
@@ -351,7 +363,7 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
         let sched_cell = Cell::new(sched);
         let thread = do Thread::start {
             let mut sched = sched_cell.take();
-            let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool) || {
+            let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool, None) || {
                 rtdebug!("boostraping a non-primary scheduler");
             };
             sched.bootstrap(bootstrap_task);
@@ -368,10 +380,10 @@ fn run_(main: ~fn(), use_main_sched: bool) -> int {
         let mut main_sched = main_sched.unwrap();
 
         let home = Sched(main_sched.make_handle());
-        let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool,
+        let mut main_task = ~Task::new_root_homed(&mut main_sched.stack_pool, None,
                                                   home, main.take());
         main_task.death.on_exit = Some(on_exit.take());
-        rtdebug!("boostrapping main_task");
+        rtdebug!("bootstrapping main_task");
 
         main_sched.bootstrap(main_task);
     }
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index 1a75f2569b5..ce4e64c47d2 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -13,7 +13,6 @@ use option::{Option, Some, None};
 use cast::{transmute, transmute_mut_region, transmute_mut_unsafe};
 use clone::Clone;
 use unstable::raw;
-
 use super::sleeper_list::SleeperList;
 use super::work_queue::WorkQueue;
 use super::stack::{StackPool};
@@ -28,6 +27,9 @@ use rt::rtio::RemoteCallback;
 use rt::metrics::SchedMetrics;
 use borrow::{to_uint};
 use cell::Cell;
+use rand::{XorShiftRng, RngUtil};
+use iterator::{range};
+use vec::{OwnedVector};
 
 /// The Scheduler is responsible for coordinating execution of Coroutines
 /// on a single thread. When the scheduler is running it is owned by
@@ -37,9 +39,11 @@ use cell::Cell;
 /// XXX: This creates too many callbacks to run_sched_once, resulting
 /// in too much allocation and too many events.
 pub struct Scheduler {
-    /// A queue of available work. Under a work-stealing policy there
-    /// is one per Scheduler.
-    work_queue: WorkQueue<~Task>,
+    /// There are N work queues, one per scheduler.
+    priv work_queue: WorkQueue<~Task>,
+    /// Work queues for the other schedulers. These are created by
+    /// cloning the core work queues.
+    work_queues: ~[WorkQueue<~Task>],
     /// The queue of incoming messages from other schedulers.
     /// These are enqueued by SchedHandles after which a remote callback
     /// is triggered to handle the message.
@@ -70,7 +74,10 @@ pub struct Scheduler {
     run_anything: bool,
     /// If the scheduler shouldn't run some tasks, a friend to send
     /// them to.
-    friend_handle: Option<SchedHandle>
+    friend_handle: Option<SchedHandle>,
+    /// A fast XorShift rng for scheduler use
+    rng: XorShiftRng
+
 }
 
 pub struct SchedHandle {
@@ -97,10 +104,13 @@ impl Scheduler {
 
     pub fn new(event_loop: ~EventLoopObject,
                work_queue: WorkQueue<~Task>,
+               work_queues: ~[WorkQueue<~Task>],
                sleeper_list: SleeperList)
         -> Scheduler {
 
-        Scheduler::new_special(event_loop, work_queue, sleeper_list, true, None)
+        Scheduler::new_special(event_loop, work_queue,
+                               work_queues,
+                               sleeper_list, true, None)
 
     }
 
@@ -108,6 +118,7 @@ impl Scheduler {
     // task field is None.
     pub fn new_special(event_loop: ~EventLoopObject,
                        work_queue: WorkQueue<~Task>,
+                       work_queues: ~[WorkQueue<~Task>],
                        sleeper_list: SleeperList,
                        run_anything: bool,
                        friend: Option<SchedHandle>)
@@ -120,12 +131,14 @@ impl Scheduler {
             no_sleep: false,
             event_loop: event_loop,
             work_queue: work_queue,
+            work_queues: work_queues,
             stack_pool: StackPool::new(),
             sched_task: None,
             cleanup_job: None,
             metrics: SchedMetrics::new(),
             run_anything: run_anything,
-            friend_handle: friend
+            friend_handle: friend,
+            rng: XorShiftRng::new()
         }
     }
 
@@ -248,7 +261,7 @@ impl Scheduler {
 
         // Second activity is to try resuming a task from the queue.
 
-        let result = sched.resume_task_from_queue();
+        let result = sched.do_work();
         let mut sched = match result {
             Some(sched) => {
                 // Failed to dequeue a task, so we return.
@@ -325,7 +338,7 @@ impl Scheduler {
     /// As enqueue_task, but with the possibility for the blocked task to
     /// already have been killed.
     pub fn enqueue_blocked_task(&mut self, blocked_task: BlockedTask) {
-        do blocked_task.wake().map_consume |task| {
+        do blocked_task.wake().map_move |task| {
             self.enqueue_task(task);
         };
     }
@@ -415,47 +428,98 @@ impl Scheduler {
         }
     }
 
-    // Resume a task from the queue - but also take into account that
-    // it might not belong here.
+    // Workstealing: In this iteration of the runtime each scheduler
+    // thread has a distinct work queue. When no work is available
+    // locally, make a few attempts to steal work from the queues of
+    // other scheduler threads. If a few steals fail we end up in the
+    // old "no work" path which is fine.
+
+    // First step in the process is to find a task. This function does
+    // that by first checking the local queue, and if there is no work
+    // there, trying to steal from the remote work queues.
+    fn find_work(&mut self) -> Option<~Task> {
+        rtdebug!("scheduler looking for work");
+        match self.work_queue.pop() {
+            Some(task) => {
+                rtdebug!("found a task locally");
+                return Some(task)
+            }
+            None => {
+                // Our naive stealing, try kinda hard.
+                rtdebug!("scheduler trying to steal");
+                let _len = self.work_queues.len();
+                return self.try_steals(2);
+            }
+        }
+    }
+
+    // With no backoff try stealing n times from the queues the
+    // scheduler knows about. This naive implementation can steal from
+    // our own queue or from other special schedulers.
+    fn try_steals(&mut self, n: uint) -> Option<~Task> {
+        for _ in range(0, n) {
+            let index = self.rng.gen_uint_range(0, self.work_queues.len());
+            let work_queues = &mut self.work_queues;
+            match work_queues[index].steal() {
+                Some(task) => {
+                    rtdebug!("found task by stealing"); return Some(task)
+                }
+                None => ()
+            }
+        };
+        rtdebug!("giving up on stealing");
+        return None;
+    }
 
-    // If we perform a scheduler action we give away the scheduler ~
-    // pointer, if it is still available we return it.
+    // Given a task, execute it correctly.
+    fn process_task(~self, task: ~Task) -> Option<~Scheduler> {
+        let mut this = self;
+        let mut task = task;
 
-    fn resume_task_from_queue(~self) -> Option<~Scheduler> {
+        rtdebug!("processing a task");
 
+        let home = task.take_unwrap_home();
+        match home {
+            Sched(home_handle) => {
+                if home_handle.sched_id != this.sched_id() {
+                    rtdebug!("sending task home");
+                    task.give_home(Sched(home_handle));
+                    Scheduler::send_task_home(task);
+                    return Some(this);
+                } else {
+                    rtdebug!("running task here");
+                    task.give_home(Sched(home_handle));
+                    this.resume_task_immediately(task);
+                    return None;
+                }
+            }
+            AnySched if this.run_anything => {
+                rtdebug!("running anysched task here");
+                task.give_home(AnySched);
+                this.resume_task_immediately(task);
+                return None;
+            }
+            AnySched => {
+                rtdebug!("sending task to friend");
+                task.give_home(AnySched);
+                this.send_to_friend(task);
+                return Some(this);
+            }
+        }
+    }
+
+    // Bundle the helpers together.
+    fn do_work(~self) -> Option<~Scheduler> {
         let mut this = self;
 
-        match this.work_queue.pop() {
+        rtdebug!("scheduler calling do work");
+        match this.find_work() {
             Some(task) => {
-                let mut task = task;
-                let home = task.take_unwrap_home();
-                match home {
-                    Sched(home_handle) => {
-                        if home_handle.sched_id != this.sched_id() {
-                            task.give_home(Sched(home_handle));
-                            Scheduler::send_task_home(task);
-                            return Some(this);
-                        } else {
-                            this.event_loop.callback(Scheduler::run_sched_once);
-                            task.give_home(Sched(home_handle));
-                            this.resume_task_immediately(task);
-                            return None;
-                        }
-                    }
-                    AnySched if this.run_anything => {
-                        this.event_loop.callback(Scheduler::run_sched_once);
-                        task.give_home(AnySched);
-                        this.resume_task_immediately(task);
-                        return None;
-                    }
-                    AnySched => {
-                        task.give_home(AnySched);
-                        this.send_to_friend(task);
-                        return Some(this);
-                    }
-                }
+                rtdebug!("found some work! processing the task");
+                return this.process_task(task);
             }
             None => {
+                rtdebug!("no work was found, returning the scheduler struct");
                 return Some(this);
             }
         }
@@ -533,7 +597,7 @@ impl Scheduler {
                 sched.enqueue_blocked_task(last_task);
             }
         };
-        opt.map_consume(Local::put);
+        opt.map_move(Local::put);
     }
 
     // The primary function for changing contexts. In the current
@@ -711,7 +775,6 @@ impl Scheduler {
             GiveTask(task, f) => f.to_fn()(self, task)
         }
     }
-
 }
 
 // The cases for the below function.
@@ -745,6 +808,8 @@ impl ClosureConverter for UnsafeTaskReceiver {
 
 #[cfg(test)]
 mod test {
+    extern mod extra;
+
     use prelude::*;
     use rt::test::*;
     use unstable::run_in_bare_thread;
@@ -833,7 +898,7 @@ mod test {
             let mut sched = ~new_test_uv_sched();
             let sched_handle = sched.make_handle();
 
-            let mut task = ~do Task::new_root_homed(&mut sched.stack_pool,
+            let mut task = ~do Task::new_root_homed(&mut sched.stack_pool, None,
                                                 Sched(sched_handle)) {
                 unsafe { *task_ran_ptr = true };
                 assert!(Task::on_appropriate_sched());
@@ -862,12 +927,15 @@ mod test {
         do run_in_bare_thread {
 
             let sleepers = SleeperList::new();
-            let work_queue = WorkQueue::new();
+            let normal_queue = WorkQueue::new();
+            let special_queue = WorkQueue::new();
+            let queues = ~[normal_queue.clone(), special_queue.clone()];
 
             // Our normal scheduler
             let mut normal_sched = ~Scheduler::new(
                 ~UvEventLoop::new(),
-                work_queue.clone(),
+                normal_queue,
+                queues.clone(),
                 sleepers.clone());
 
             let normal_handle = Cell::new(normal_sched.make_handle());
@@ -877,7 +945,8 @@ mod test {
             // Our special scheduler
             let mut special_sched = ~Scheduler::new_special(
                 ~UvEventLoop::new(),
-                work_queue.clone(),
+                special_queue.clone(),
+                queues.clone(),
                 sleepers.clone(),
                 false,
                 Some(friend_handle));
@@ -893,21 +962,21 @@ mod test {
             //   3) task not homed, sched requeues
             //   4) task not home, send home
 
-            let task1 = ~do Task::new_root_homed(&mut special_sched.stack_pool,
+            let task1 = ~do Task::new_root_homed(&mut special_sched.stack_pool, None,
                                                  Sched(t1_handle)) || {
                 rtassert!(Task::on_appropriate_sched());
             };
             rtdebug!("task1 id: **%u**", borrow::to_uint(task1));
 
-            let task2 = ~do Task::new_root(&mut normal_sched.stack_pool) {
+            let task2 = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
                 rtassert!(Task::on_appropriate_sched());
             };
 
-            let task3 = ~do Task::new_root(&mut normal_sched.stack_pool) {
+            let task3 = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
                 rtassert!(Task::on_appropriate_sched());
             };
 
-            let task4 = ~do Task::new_root_homed(&mut special_sched.stack_pool,
+            let task4 = ~do Task::new_root_homed(&mut special_sched.stack_pool, None,
                                                  Sched(t4_handle)) {
                 rtassert!(Task::on_appropriate_sched());
             };
@@ -923,7 +992,7 @@ mod test {
             let port = Cell::new(port);
             let chan = Cell::new(chan);
 
-            let normal_task = ~do Task::new_root(&mut normal_sched.stack_pool) {
+            let normal_task = ~do Task::new_root(&mut normal_sched.stack_pool, None) {
                 rtdebug!("*about to submit task2*");
                 Scheduler::run_task(task2.take());
                 rtdebug!("*about to submit task4*");
@@ -938,7 +1007,7 @@ mod test {
 
             rtdebug!("normal task: %u", borrow::to_uint(normal_task));
 
-            let special_task = ~do Task::new_root(&mut special_sched.stack_pool) {
+            let special_task = ~do Task::new_root(&mut special_sched.stack_pool, None) {
                 rtdebug!("*about to submit task1*");
                 Scheduler::run_task(task1.take());
                 rtdebug!("*about to submit task3*");
diff --git a/src/libstd/rt/select.rs b/src/libstd/rt/select.rs
index 006b777b71b..0e8d26e9482 100644
--- a/src/libstd/rt/select.rs
+++ b/src/libstd/rt/select.rs
@@ -182,6 +182,7 @@ mod test {
     fn select_stream() {
         use util;
         use comm::GenericChan;
+        use iter::Times;
 
         // Sends 10 buffered packets, and uses select to retrieve them all.
         // Puts the port in a different spot in the vector each time.
@@ -199,9 +200,7 @@ mod test {
                 // get it back out
                 util::swap(port.get_mut_ref(), &mut ports[index]);
                 // NB. Not recv(), because optimistic_check randomly fails.
-                let (data, new_port) = port.take_unwrap().recv_ready().unwrap();
-                assert!(data == 31337);
-                port = Some(new_port);
+                assert!(port.get_ref().recv_ready().unwrap() == 31337);
             }
         }
     }
@@ -265,6 +264,7 @@ mod test {
 
         fn select_racing_senders_helper(killable: bool, send_on_chans: ~[uint]) {
             use rt::test::spawntask_random;
+            use iter::Times;
 
             do run_in_newsched_task {
                 // A bit of stress, since ordinarily this is just smoke and mirrors.
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 4c5e4bdc3c1..364439a4526 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -20,6 +20,7 @@ use libc::{c_void, uintptr_t};
 use ptr;
 use prelude::*;
 use option::{Option, Some, None};
+use rt::env;
 use rt::kill::Death;
 use rt::local::Local;
 use rt::logging::StdErrLogger;
@@ -85,12 +86,13 @@ impl Task {
 
     // A helper to build a new task using the dynamically found
     // scheduler and task. Only works in GreenTask context.
-    pub fn build_homed_child(f: ~fn(), home: SchedHome) -> ~Task {
+    pub fn build_homed_child(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
         let f = Cell::new(f);
         let home = Cell::new(home);
         do Local::borrow::<Task, ~Task> |running_task| {
             let mut sched = running_task.sched.take_unwrap();
             let new_task = ~running_task.new_child_homed(&mut sched.stack_pool,
+                                                         stack_size,
                                                          home.take(),
                                                          f.take());
             running_task.sched = Some(sched);
@@ -98,25 +100,26 @@ impl Task {
         }
     }
 
-    pub fn build_child(f: ~fn()) -> ~Task {
-        Task::build_homed_child(f, AnySched)
+    pub fn build_child(stack_size: Option<uint>, f: ~fn()) -> ~Task {
+        Task::build_homed_child(stack_size, f, AnySched)
     }
 
-    pub fn build_homed_root(f: ~fn(), home: SchedHome) -> ~Task {
+    pub fn build_homed_root(stack_size: Option<uint>, f: ~fn(), home: SchedHome) -> ~Task {
         let f = Cell::new(f);
         let home = Cell::new(home);
         do Local::borrow::<Task, ~Task> |running_task| {
             let mut sched = running_task.sched.take_unwrap();
             let new_task = ~Task::new_root_homed(&mut sched.stack_pool,
-                                                    home.take(),
-                                                    f.take());
+                                                 stack_size,
+                                                 home.take(),
+                                                 f.take());
             running_task.sched = Some(sched);
             new_task
         }
     }
 
-    pub fn build_root(f: ~fn()) -> ~Task {
-        Task::build_homed_root(f, AnySched)
+    pub fn build_root(stack_size: Option<uint>, f: ~fn()) -> ~Task {
+        Task::build_homed_root(stack_size, f, AnySched)
     }
 
     pub fn new_sched_task() -> Task {
@@ -137,17 +140,20 @@ impl Task {
     }
 
     pub fn new_root(stack_pool: &mut StackPool,
+                    stack_size: Option<uint>,
                     start: ~fn()) -> Task {
-        Task::new_root_homed(stack_pool, AnySched, start)
+        Task::new_root_homed(stack_pool, stack_size, AnySched, start)
     }
 
     pub fn new_child(&mut self,
                      stack_pool: &mut StackPool,
+                     stack_size: Option<uint>,
                      start: ~fn()) -> Task {
-        self.new_child_homed(stack_pool, AnySched, start)
+        self.new_child_homed(stack_pool, stack_size, AnySched, start)
     }
 
     pub fn new_root_homed(stack_pool: &mut StackPool,
+                          stack_size: Option<uint>,
                           home: SchedHome,
                           start: ~fn()) -> Task {
         Task {
@@ -160,7 +166,7 @@ impl Task {
             death: Death::new(),
             destroyed: false,
             name: None,
-            coroutine: Some(Coroutine::new(stack_pool, start)),
+            coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
             sched: None,
             task_type: GreenTask(Some(~home))
         }
@@ -168,6 +174,7 @@ impl Task {
 
     pub fn new_child_homed(&mut self,
                            stack_pool: &mut StackPool,
+                           stack_size: Option<uint>,
                            home: SchedHome,
                            start: ~fn()) -> Task {
         Task {
@@ -181,7 +188,7 @@ impl Task {
             death: self.death.new_child(),
             destroyed: false,
             name: None,
-            coroutine: Some(Coroutine::new(stack_pool, start)),
+            coroutine: Some(Coroutine::new(stack_pool, stack_size, start)),
             sched: None,
             task_type: GreenTask(Some(~home))
         }
@@ -325,11 +332,13 @@ impl Drop for Task {
 
 impl Coroutine {
 
-    pub fn new(stack_pool: &mut StackPool, start: ~fn()) -> Coroutine {
-        static MIN_STACK_SIZE: uint = 3000000; // XXX: Too much stack
-
+    pub fn new(stack_pool: &mut StackPool, stack_size: Option<uint>, start: ~fn()) -> Coroutine {
+        let stack_size = match stack_size {
+            Some(size) => size,
+            None => env::min_stack()
+        };
         let start = Coroutine::build_start_wrapper(start);
-        let mut stack = stack_pool.take_segment(MIN_STACK_SIZE);
+        let mut stack = stack_pool.take_segment(stack_size);
         let initial_context = Context::new(start, &mut stack);
         Coroutine {
             current_stack_segment: stack,
@@ -465,10 +474,10 @@ mod test {
         do run_in_newsched_task() {
             static key: local_data::Key<@~str> = &local_data::Key;
             local_data::set(key, @~"data");
-            assert!(*local_data::get(key, |k| k.map(|&k| *k)).unwrap() == ~"data");
+            assert!(*local_data::get(key, |k| k.map_move(|k| *k)).unwrap() == ~"data");
             static key2: local_data::Key<@~str> = &local_data::Key;
             local_data::set(key2, @~"data");
-            assert!(*local_data::get(key2, |k| k.map(|&k| *k)).unwrap() == ~"data");
+            assert!(*local_data::get(key2, |k| k.map_move(|k| *k)).unwrap() == ~"data");
         }
     }
 
diff --git a/src/libstd/rt/test.rs b/src/libstd/rt/test.rs
index 8b5215ae969..92366d5187f 100644
--- a/src/libstd/rt/test.rs
+++ b/src/libstd/rt/test.rs
@@ -15,8 +15,8 @@ use cell::Cell;
 use clone::Clone;
 use container::Container;
 use iterator::{Iterator, range};
-use vec::{OwnedVector, MutableVector};
 use super::io::net::ip::{SocketAddr, Ipv4Addr, Ipv6Addr};
+use vec::{OwnedVector, MutableVector, ImmutableVector};
 use rt::sched::Scheduler;
 use unstable::run_in_bare_thread;
 use rt::thread::Thread;
@@ -29,8 +29,12 @@ use result::{Result, Ok, Err};
 
 pub fn new_test_uv_sched() -> Scheduler {
 
+    let queue = WorkQueue::new();
+    let queues = ~[queue.clone()];
+
     let mut sched = Scheduler::new(~UvEventLoop::new(),
-                                   WorkQueue::new(),
+                                   queue,
+                                   queues,
                                    SleeperList::new());
 
     // Don't wait for the Shutdown message
@@ -57,7 +61,7 @@ pub fn run_in_newsched_task_core(f: ~fn()) {
         exit_handle.take().send(Shutdown);
         rtassert!(exit_status);
     };
-    let mut task = ~Task::new_root(&mut sched.stack_pool, f);
+    let mut task = ~Task::new_root(&mut sched.stack_pool, None, f);
     task.death.on_exit = Some(on_exit);
 
     sched.bootstrap(task);
@@ -164,15 +168,21 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
         };
 
         let sleepers = SleeperList::new();
-        let work_queue = WorkQueue::new();
 
         let mut handles = ~[];
         let mut scheds = ~[];
+        let mut work_queues = ~[];
 
         for _ in range(0u, nthreads) {
+            let work_queue = WorkQueue::new();
+            work_queues.push(work_queue);
+        }
+
+        for i in range(0u, nthreads) {
             let loop_ = ~UvEventLoop::new();
             let mut sched = ~Scheduler::new(loop_,
-                                            work_queue.clone(),
+                                            work_queues[i].clone(),
+                                            work_queues.clone(),
                                             sleepers.clone());
             let handle = sched.make_handle();
 
@@ -190,8 +200,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
 
             rtassert!(exit_status);
         };
-        let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool,
-                                        f.take());
+        let mut main_task = ~Task::new_root(&mut scheds[0].stack_pool, None, f.take());
         main_task.death.on_exit = Some(on_exit);
 
         let mut threads = ~[];
@@ -209,7 +218,7 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
 
         while !scheds.is_empty() {
             let mut sched = scheds.pop();
-            let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool) || {
+            let bootstrap_task = ~do Task::new_root(&mut sched.stack_pool, None) || {
                 rtdebug!("bootstrapping non-primary scheduler");
             };
             let bootstrap_task_cell = Cell::new(bootstrap_task);
@@ -232,12 +241,12 @@ pub fn run_in_mt_newsched_task(f: ~fn()) {
 
 /// Test tasks will abort on failure instead of unwinding
 pub fn spawntask(f: ~fn()) {
-    Scheduler::run_task(Task::build_child(f));
+    Scheduler::run_task(Task::build_child(None, f));
 }
 
 /// Create a new task and run it right now. Aborts on failure
 pub fn spawntask_later(f: ~fn()) {
-    Scheduler::run_task_later(Task::build_child(f));
+    Scheduler::run_task_later(Task::build_child(None, f));
 }
 
 pub fn spawntask_random(f: ~fn()) {
@@ -259,7 +268,7 @@ pub fn spawntask_try(f: ~fn()) -> Result<(),()> {
     let chan = Cell::new(chan);
     let on_exit: ~fn(bool) = |exit_status| chan.take().send(exit_status);
 
-    let mut new_task = Task::build_root(f);
+    let mut new_task = Task::build_root(None, f);
     new_task.death.on_exit = Some(on_exit);
 
     Scheduler::run_task(new_task);
@@ -285,7 +294,7 @@ pub fn spawntask_thread(f: ~fn()) -> Thread {
 pub fn with_test_task(blk: ~fn(~Task) -> ~Task) {
     do run_in_bare_thread {
         let mut sched = ~new_test_uv_sched();
-        let task = blk(~Task::new_root(&mut sched.stack_pool, ||{}));
+        let task = blk(~Task::new_root(&mut sched.stack_pool, None, ||{}));
         cleanup_task(task);
     }
 }
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index 72b3399c404..83e0846c351 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -634,7 +634,6 @@ fn spawn_process_os(prog: &str, args: &[~str],
 
     use libc::funcs::posix88::unistd::{fork, dup2, close, chdir, execvp};
     use libc::funcs::bsd44::getdtablesize;
-    use int;
 
     mod rustrt {
         use libc::c_void;
@@ -667,10 +666,9 @@ fn spawn_process_os(prog: &str, args: &[~str],
             fail!("failure in dup3(err_fd, 2): %s", os::last_os_error());
         }
         // close all other fds
-        do int::range_rev(getdtablesize() as int, 3) |fd| {
+        for fd in range(3, getdtablesize()).invert() {
             close(fd as c_int);
-            true
-        };
+        }
 
         do with_dirp(dir) |dirp| {
             if !dirp.is_null() && chdir(dirp) == -1 {
@@ -780,14 +778,14 @@ fn with_dirp<T>(d: Option<&Path>, cb: &fn(*libc::c_char) -> T) -> T {
 }
 
 #[cfg(windows)]
-priv fn free_handle(handle: *()) {
+fn free_handle(handle: *()) {
     unsafe {
         libc::funcs::extra::kernel32::CloseHandle(cast::transmute(handle));
     }
 }
 
 #[cfg(unix)]
-priv fn free_handle(_handle: *()) {
+fn free_handle(_handle: *()) {
     // unix has no process handle object, just a pid
 }
 
@@ -842,7 +840,7 @@ pub fn process_output(prog: &str, args: &[~str]) -> ProcessOutput {
  * operate on a none-existant process or, even worse, on a newer process
  * with the same id.
  */
-priv fn waitpid(pid: pid_t) -> int {
+fn waitpid(pid: pid_t) -> int {
     return waitpid_os(pid);
 
     #[cfg(windows)]
diff --git a/src/libstd/std.rs b/src/libstd/std.rs
index 236103ec886..480c0786e6e 100644
--- a/src/libstd/std.rs
+++ b/src/libstd/std.rs
@@ -178,6 +178,7 @@ pub mod rand;
 pub mod run;
 pub mod sys;
 pub mod cast;
+pub mod fmt;
 pub mod repr;
 pub mod cleanup;
 pub mod reflect;
@@ -217,4 +218,6 @@ mod std {
     pub use unstable;
     pub use str;
     pub use os;
+    pub use fmt;
+    pub use to_bytes;
 }
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index d08879c68cc..724fbcac891 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -855,7 +855,7 @@ pub fn count_bytes<'b>(s: &'b str, start: uint, n: uint) -> uint {
 }
 
 // https://tools.ietf.org/html/rfc3629
-priv static UTF8_CHAR_WIDTH: [u8, ..256] = [
+static UTF8_CHAR_WIDTH: [u8, ..256] = [
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
@@ -898,15 +898,15 @@ macro_rules! utf8_acc_cont_byte(
 )
 
 // UTF-8 tags and ranges
-priv static TAG_CONT_U8: u8 = 128u8;
-priv static TAG_CONT: uint = 128u;
-priv static MAX_ONE_B: uint = 128u;
-priv static TAG_TWO_B: uint = 192u;
-priv static MAX_TWO_B: uint = 2048u;
-priv static TAG_THREE_B: uint = 224u;
-priv static MAX_THREE_B: uint = 65536u;
-priv static TAG_FOUR_B: uint = 240u;
-priv static MAX_UNICODE: uint = 1114112u;
+static TAG_CONT_U8: u8 = 128u8;
+static TAG_CONT: uint = 128u;
+static MAX_ONE_B: uint = 128u;
+static TAG_TWO_B: uint = 192u;
+static MAX_TWO_B: uint = 2048u;
+static TAG_THREE_B: uint = 224u;
+static MAX_THREE_B: uint = 65536u;
+static TAG_FOUR_B: uint = 240u;
+static MAX_UNICODE: uint = 1114112u;
 
 /// Unsafe operations
 pub mod raw {
@@ -2085,7 +2085,7 @@ impl<'self> StrSlice<'self> for &'self str {
         } else {
             self.matches_index_iter(needle)
                 .next()
-                .map_consume(|(start, _end)| start)
+                .map_move(|(start, _end)| start)
         }
     }
 
diff --git a/src/libstd/str/ascii.rs b/src/libstd/str/ascii.rs
index b4d3e4b0ad1..02a6247428c 100644
--- a/src/libstd/str/ascii.rs
+++ b/src/libstd/str/ascii.rs
@@ -305,7 +305,7 @@ pub fn to_ascii_lower(string: &str) -> ~str {
 }
 
 #[inline]
-priv fn map_bytes(string: &str, map: &'static [u8]) -> ~str {
+fn map_bytes(string: &str, map: &'static [u8]) -> ~str {
     let len = string.len();
     let mut result = str::with_capacity(len);
     unsafe {
@@ -329,7 +329,7 @@ pub fn eq_ignore_ascii_case(a: &str, b: &str) -> bool {
         |(byte_a, byte_b)| ASCII_LOWER_MAP[*byte_a] == ASCII_LOWER_MAP[*byte_b])
 }
 
-priv static ASCII_LOWER_MAP: &'static [u8] = &[
+static ASCII_LOWER_MAP: &'static [u8] = &[
     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
@@ -364,7 +364,7 @@ priv static ASCII_LOWER_MAP: &'static [u8] = &[
     0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 ];
 
-priv static ASCII_UPPER_MAP: &'static [u8] = &[
+static ASCII_UPPER_MAP: &'static [u8] = &[
     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
diff --git a/src/libstd/task/mod.rs b/src/libstd/task/mod.rs
index 225a4b8cfd2..2e0c9c1d1ad 100644
--- a/src/libstd/task/mod.rs
+++ b/src/libstd/task/mod.rs
@@ -142,7 +142,8 @@ pub struct TaskOpts {
     indestructible: bool,
     notify_chan: Option<Chan<TaskResult>>,
     name: Option<~str>,
-    sched: SchedOpts
+    sched: SchedOpts,
+    stack_size: Option<uint>
 }
 
 /**
@@ -197,7 +198,8 @@ impl TaskBuilder {
                 indestructible: self.opts.indestructible,
                 notify_chan: notify_chan,
                 name: name,
-                sched: self.opts.sched
+                sched: self.opts.sched,
+                stack_size: self.opts.stack_size
             },
             gen_body: gen_body,
             can_not_copy: None,
@@ -351,7 +353,8 @@ impl TaskBuilder {
             indestructible: x.opts.indestructible,
             notify_chan: notify_chan,
             name: name,
-            sched: x.opts.sched
+            sched: x.opts.sched,
+            stack_size: x.opts.stack_size
         };
         let f = match gen_body {
             Some(gen) => {
@@ -422,7 +425,8 @@ pub fn default_task_opts() -> TaskOpts {
         name: None,
         sched: SchedOpts {
             mode: DefaultScheduler,
-        }
+        },
+        stack_size: None
     }
 }
 
@@ -655,6 +659,7 @@ pub unsafe fn rekillable<U>(f: &fn() -> U) -> U {
     }
 }
 
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_kill_unkillable_task() {
     use rt::test::*;
@@ -675,6 +680,7 @@ fn test_kill_unkillable_task() {
     }
 }
 
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_kill_rekillable_task() {
     use rt::test::*;
@@ -716,6 +722,7 @@ fn test_cant_dup_task_builder() {
 #[cfg(test)]
 fn block_forever() { let (po, _ch) = stream::<()>(); po.recv(); }
 
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port
     use rt::test::run_in_newsched_task;
@@ -734,6 +741,7 @@ fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port
         po.recv();
     }
 }
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_unlinked_unsup_no_fail_up() { // child unlinked fails
     use rt::test::run_in_newsched_task;
@@ -741,6 +749,7 @@ fn test_spawn_unlinked_unsup_no_fail_up() { // child unlinked fails
         do spawn_unlinked { fail!(); }
     }
 }
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_unlinked_sup_no_fail_up() { // child unlinked fails
     use rt::test::run_in_newsched_task;
@@ -750,6 +759,7 @@ fn test_spawn_unlinked_sup_no_fail_up() { // child unlinked fails
         do 16.times { task::yield(); }
     }
 }
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_unlinked_sup_fail_down() {
     use rt::test::run_in_newsched_task;
@@ -762,6 +772,7 @@ fn test_spawn_unlinked_sup_fail_down() {
     }
 }
 
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_linked_sup_fail_up() { // child fails; parent fails
     use rt::test::run_in_newsched_task;
@@ -782,6 +793,7 @@ fn test_spawn_linked_sup_fail_up() { // child fails; parent fails
         assert!(result.is_err());
     }
 }
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_linked_sup_fail_down() { // parent fails; child fails
     use rt::test::run_in_newsched_task;
@@ -798,6 +810,7 @@ fn test_spawn_linked_sup_fail_down() { // parent fails; child fails
         assert!(result.is_err());
     }
 }
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_linked_unsup_fail_up() { // child fails; parent fails
     use rt::test::run_in_newsched_task;
@@ -810,6 +823,7 @@ fn test_spawn_linked_unsup_fail_up() { // child fails; parent fails
         assert!(result.is_err());
     }
 }
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_linked_unsup_fail_down() { // parent fails; child fails
     use rt::test::run_in_newsched_task;
@@ -822,6 +836,7 @@ fn test_spawn_linked_unsup_fail_down() { // parent fails; child fails
         assert!(result.is_err());
     }
 }
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_linked_unsup_default_opts() { // parent fails; child fails
     use rt::test::run_in_newsched_task;
@@ -840,6 +855,7 @@ fn test_spawn_linked_unsup_default_opts() { // parent fails; child fails
 // A couple bonus linked failure tests - testing for failure propagation even
 // when the middle task exits successfully early before kill signals are sent.
 
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_failure_propagate_grandchild() {
     use rt::test::run_in_newsched_task;
@@ -856,6 +872,7 @@ fn test_spawn_failure_propagate_grandchild() {
     }
 }
 
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_failure_propagate_secondborn() {
     use rt::test::run_in_newsched_task;
@@ -872,6 +889,7 @@ fn test_spawn_failure_propagate_secondborn() {
     }
 }
 
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_failure_propagate_nephew_or_niece() {
     use rt::test::run_in_newsched_task;
@@ -888,6 +906,7 @@ fn test_spawn_failure_propagate_nephew_or_niece() {
     }
 }
 
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_linked_sup_propagate_sibling() {
     use rt::test::run_in_newsched_task;
@@ -1191,6 +1210,7 @@ fn test_avoid_copying_the_body_unlinked() {
     }
 }
 
+#[ignore(reason = "linked failure")]
 #[test]
 #[ignore(cfg(windows))]
 #[should_fail]
@@ -1226,6 +1246,7 @@ fn test_unkillable() {
     po.recv();
 }
 
+#[ignore(reason = "linked failure")]
 #[test]
 #[ignore(cfg(windows))]
 #[should_fail]
@@ -1292,6 +1313,7 @@ fn test_simple_newsched_spawn() {
     }
 }
 
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_watched() {
     use rt::test::run_in_newsched_task;
@@ -1314,6 +1336,7 @@ fn test_spawn_watched() {
     }
 }
 
+#[ignore(reason = "linked failure")]
 #[test] #[ignore(cfg(windows))]
 fn test_indestructible() {
     use rt::test::run_in_newsched_task;
diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs
index 527b20b0e90..05a17f8539c 100644
--- a/src/libstd/task/spawn.rs
+++ b/src/libstd/task/spawn.rs
@@ -98,6 +98,7 @@ use rt::kill::KillHandle;
 use rt::sched::Scheduler;
 use rt::uv::uvio::UvEventLoop;
 use rt::thread::Thread;
+use rt::work_queue::WorkQueue;
 
 #[cfg(test)] use task::default_task_opts;
 #[cfg(test)] use comm;
@@ -500,7 +501,7 @@ impl RuntimeGlue {
             OldTask(ptr) => rt::rust_task_kill_other(ptr),
             NewTask(handle) => {
                 let mut handle = handle;
-                do handle.kill().map_consume |killed_task| {
+                do handle.kill().map_move |killed_task| {
                     let killed_task = Cell::new(killed_task);
                     do Local::borrow::<Scheduler, ()> |sched| {
                         sched.enqueue_task(killed_task.take());
@@ -682,7 +683,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
         // Child task runs this code.
 
         // If child data is 'None', the enlist is vacuously successful.
-        let enlist_success = do child_data.take().map_consume_default(true) |child_data| {
+        let enlist_success = do child_data.take().map_move_default(true) |child_data| {
             let child_data = Cell::new(child_data); // :(
             do Local::borrow::<Task, bool> |me| {
                 let (child_tg, ancestors, is_main) = child_data.take();
@@ -713,19 +714,25 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
     let mut task = unsafe {
         if opts.sched.mode != SingleThreaded {
             if opts.watched {
-                Task::build_child(child_wrapper)
+                Task::build_child(opts.stack_size, child_wrapper)
             } else {
-                Task::build_root(child_wrapper)
+                Task::build_root(opts.stack_size, child_wrapper)
             }
         } else {
             // Creating a 1:1 task:thread ...
             let sched = Local::unsafe_borrow::<Scheduler>();
             let sched_handle = (*sched).make_handle();
 
+            // Since this is a 1:1 scheduler we create a queue not in
+            // the stealee set. The run_anything flag is set false
+            // which will disable stealing.
+            let work_queue = WorkQueue::new();
+
             // Create a new scheduler to hold the new task
             let new_loop = ~UvEventLoop::new();
             let mut new_sched = ~Scheduler::new_special(new_loop,
-                                                        (*sched).work_queue.clone(),
+                                                        work_queue,
+                                                        (*sched).work_queues.clone(),
                                                         (*sched).sleeper_list.clone(),
                                                         false,
                                                         Some(sched_handle));
@@ -736,16 +743,16 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
 
             // Pin the new task to the new scheduler
             let new_task = if opts.watched {
-                Task::build_homed_child(child_wrapper, Sched(new_sched_handle))
+                Task::build_homed_child(opts.stack_size, child_wrapper, Sched(new_sched_handle))
             } else {
-                Task::build_homed_root(child_wrapper, Sched(new_sched_handle))
+                Task::build_homed_root(opts.stack_size, child_wrapper, Sched(new_sched_handle))
             };
 
             // Create a task that will later be used to join with the new scheduler
             // thread when it is ready to terminate
             let (thread_port, thread_chan) = oneshot();
             let thread_port_cell = Cell::new(thread_port);
-            let join_task = do Task::build_child() {
+            let join_task = do Task::build_child(None) {
                 rtdebug!("running join task");
                 let thread_port = thread_port_cell.take();
                 let thread: Thread = thread_port.recv();
@@ -762,8 +769,8 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) {
                 let mut orig_sched_handle = orig_sched_handle_cell.take();
                 let join_task = join_task_cell.take();
 
-                let bootstrap_task = ~do Task::new_root(&mut new_sched.stack_pool) || {
-                    rtdebug!("bootstrapping a 1:1 scheduler");
+                let bootstrap_task = ~do Task::new_root(&mut new_sched.stack_pool, None) || {
+                    rtdebug!("boostrapping a 1:1 scheduler");
                 };
                 new_sched.bootstrap(bootstrap_task);
 
@@ -854,7 +861,7 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
             // Even if the below code fails to kick the child off, we must
             // send Something on the notify channel.
 
-            let notifier = notify_chan.map_consume(|c| AutoNotify(c));
+            let notifier = notify_chan.map_move(|c| AutoNotify(c));
 
             if enlist_many(OldTask(child), &child_arc, &mut ancestors) {
                 let group = @@mut Taskgroup(child_arc, ancestors, is_main, notifier);
diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs
index 6f61d29780f..5ef5526e516 100644
--- a/src/libstd/trie.rs
+++ b/src/libstd/trie.rs
@@ -271,8 +271,8 @@ impl<T> TrieNode<T> {
 
 impl<T> TrieNode<T> {
     fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool {
-        for idx in range(0u, self.children.len()) {
-            match self.children[idx] {
+        for elt in self.children.iter() {
+            match *elt {
                 Internal(ref x) => if !x.each(|i,t| f(i,t)) { return false },
                 External(k, ref v) => if !f(&k, v) { return false },
                 Nothing => ()
@@ -282,13 +282,14 @@ impl<T> TrieNode<T> {
     }
 
     fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool {
-        do uint::range_rev(self.children.len(), 0) |idx| {
-            match self.children[idx] {
-                Internal(ref x) => x.each_reverse(|i,t| f(i,t)),
-                External(k, ref v) => f(&k, v),
-                Nothing => true
+        for elt in self.children.rev_iter() {
+            match *elt {
+                Internal(ref x) => if !x.each_reverse(|i,t| f(i,t)) { return false },
+                External(k, ref v) => if !f(&k, v) { return false },
+                Nothing => ()
             }
         }
+        true
     }
 
     fn mutate_values<'a>(&'a mut self, f: &fn(&uint, &mut T) -> bool) -> bool {
@@ -539,10 +540,9 @@ mod test_map {
     fn test_each_break() {
         let mut m = TrieMap::new();
 
-        do uint::range_rev(uint::max_value, uint::max_value - 10000) |x| {
+        for x in range(uint::max_value - 10000, uint::max_value).invert() {
             m.insert(x, x / 2);
-            true
-        };
+        }
 
         let mut n = uint::max_value - 10000;
         do m.each |k, v| {
@@ -580,10 +580,9 @@ mod test_map {
     fn test_each_reverse_break() {
         let mut m = TrieMap::new();
 
-        do uint::range_rev(uint::max_value, uint::max_value - 10000) |x| {
+        for x in range(uint::max_value - 10000, uint::max_value).invert() {
             m.insert(x, x / 2);
-            true
-        };
+        }
 
         let mut n = uint::max_value - 1;
         do m.each_reverse |k, v| {
@@ -634,10 +633,9 @@ mod test_map {
         let last = uint::max_value;
 
         let mut map = TrieMap::new();
-        do uint::range_rev(last, first) |x| {
+        for x in range(first, last).invert() {
             map.insert(x, x / 2);
-            true
-        };
+        }
 
         let mut i = 0;
         for (k, &v) in map.iter() {
diff --git a/src/libstd/unstable/lang.rs b/src/libstd/unstable/lang.rs
index 1ea815f721c..c41712eb80a 100644
--- a/src/libstd/unstable/lang.rs
+++ b/src/libstd/unstable/lang.rs
@@ -136,7 +136,7 @@ pub fn start(main: *u8, argc: int, argv: **c_char,
     use os;
 
     unsafe {
-        let use_old_rt = os::getenv("RUST_NEWRT").is_none();
+        let use_old_rt = os::getenv("RUST_OLDRT").is_some();
         if use_old_rt {
             return rust_start(main as *c_void, argc as c_int, argv,
                               crate_map as *c_void) as int;
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 36201dc5e82..0f6d94bb771 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -1602,8 +1602,8 @@ impl<T:Clone> OwnedCopyableVector<T> for ~[T] {
         let new_len = self.len() + rhs.len();
         self.reserve(new_len);
 
-        for i in range(0u, rhs.len()) {
-            self.push(unsafe { raw::get(rhs, i) })
+        for elt in rhs.iter() {
+            self.push((*elt).clone())
         }
     }