about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-16 11:27:35 +0000
committerbors <bors@rust-lang.org>2014-11-16 11:27:35 +0000
commit0c7a3d6c167c4656e8d35a1d428d142993e0aaab (patch)
treebf70393828be01b5042bdc76031d0a9ec7cb4900
parentcb51567e1911452f3da4b924a91e5360f5efe67c (diff)
parent892d4e28f4021ffa815649ec3a52f22f929b3708 (diff)
auto merge of #18978 : jakub-/rust/roll-up, r=cmr
-rw-r--r--src/compiletest/common.rs2
-rw-r--r--src/compiletest/compiletest.rs2
-rw-r--r--src/compiletest/header.rs8
-rw-r--r--src/doc/complement-design-faq.md2
-rw-r--r--src/doc/guide-pointers.md16
-rw-r--r--src/doc/guide-strings.md2
-rw-r--r--src/doc/reference.md15
-rw-r--r--src/etc/snapshot.py6
-rw-r--r--src/etc/vim/syntax/rust.vim2
-rw-r--r--src/liballoc/rc.rs4
-rw-r--r--src/libcollections/str.rs1
-rw-r--r--src/libcollections/string.rs53
-rw-r--r--src/libcollections/tree/set.rs8
-rw-r--r--src/libcollections/vec.rs8
-rw-r--r--src/libcore/any.rs4
-rw-r--r--src/libcore/atomic.rs52
-rw-r--r--src/libcore/cell.rs19
-rw-r--r--src/libcore/num/f32.rs11
-rw-r--r--src/libcore/num/f64.rs11
-rw-r--r--src/libcore/num/mod.rs289
-rw-r--r--src/libcore/option.rs5
-rw-r--r--src/libcore/prelude.rs1
-rw-r--r--src/libcore/result.rs7
-rw-r--r--src/libcore/str.rs36
-rw-r--r--src/libcoretest/cell.rs13
-rw-r--r--src/libcoretest/num/int_macros.rs46
-rw-r--r--src/libcoretest/num/mod.rs70
-rw-r--r--src/libcoretest/str.rs7
-rw-r--r--src/libregex/re.rs1
-rw-r--r--src/librustc/driver/config.rs38
-rw-r--r--src/librustc/driver/mod.rs12
-rw-r--r--src/librustc/driver/pretty.rs2
-rw-r--r--src/librustc/middle/trans/type_of.rs7
-rw-r--r--src/librustdoc/html/static/main.css6
-rw-r--r--src/librustdoc/stability_summary.rs5
-rw-r--r--src/libserialize/json.rs17
-rw-r--r--src/libstd/ascii.rs5
-rw-r--r--src/libstd/from_str.rs71
-rw-r--r--src/libstd/io/net/ip.rs5
-rw-r--r--src/libstd/io/net/tcp.rs46
-rw-r--r--src/libstd/io/process.rs2
-rw-r--r--src/libstd/lib.rs4
-rw-r--r--src/libstd/num/f32.rs64
-rw-r--r--src/libstd/num/f64.rs59
-rw-r--r--src/libstd/num/i16.rs5
-rw-r--r--src/libstd/num/i32.rs5
-rw-r--r--src/libstd/num/i64.rs5
-rw-r--r--src/libstd/num/i8.rs5
-rw-r--r--src/libstd/num/int.rs5
-rw-r--r--src/libstd/num/int_macros.rs127
-rw-r--r--src/libstd/num/mod.rs20
-rw-r--r--src/libstd/num/strconv.rs253
-rw-r--r--src/libstd/num/u16.rs5
-rw-r--r--src/libstd/num/u32.rs5
-rw-r--r--src/libstd/num/u64.rs5
-rw-r--r--src/libstd/num/u8.rs5
-rw-r--r--src/libstd/num/uint.rs5
-rw-r--r--src/libstd/num/uint_macros.rs16
-rw-r--r--src/libstd/os.rs3
-rw-r--r--src/libstd/path/posix.rs3
-rw-r--r--src/libstd/path/windows.rs3
-rw-r--r--src/libstd/prelude.rs5
-rw-r--r--src/libstd/rt/backtrace.rs3
-rw-r--r--src/libstd/rt/util.rs4
-rw-r--r--src/libstd/sync/task_pool.rs230
-rw-r--r--src/libstd/task.rs3
-rw-r--r--src/libstd/time/duration.rs2
-rw-r--r--src/libstd/to_string.rs66
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs71
-rw-r--r--src/libtest/lib.rs2
-rw-r--r--src/test/run-make/codegen-options-parsing/Makefile24
-rw-r--r--src/test/run-make/codegen-options-parsing/dummy.rs11
-rw-r--r--src/test/run-pass/class-cast-to-trait-cross-crate-2.rs2
-rw-r--r--src/test/run-pass/send_str_treemap.rs2
74 files changed, 1011 insertions, 933 deletions
diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs
index 2c917f7aefe..b7d4596b0fe 100644
--- a/src/compiletest/common.rs
+++ b/src/compiletest/common.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::from_str::FromStr;
 use std::fmt;
+use std::str::FromStr;
 use regex::Regex;
 
 #[deriving(Clone, PartialEq)]
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index caf1c8c314d..d49ff0258ab 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -22,7 +22,7 @@ extern crate regex;
 use std::os;
 use std::io;
 use std::io::fs;
-use std::from_str::FromStr;
+use std::str::FromStr;
 use getopts::{optopt, optflag, reqopt};
 use common::Config;
 use common::{Pretty, DebugInfoGdb, DebugInfoLldb, Codegen};
diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs
index b7b94ca6d0d..60ef76528e8 100644
--- a/src/compiletest/header.rs
+++ b/src/compiletest/header.rs
@@ -12,8 +12,6 @@ use common::Config;
 use common;
 use util;
 
-use std::from_str::FromStr;
-
 pub struct TestProps {
     // Lines that should be expected, in order, on standard out
     pub error_patterns: Vec<String> ,
@@ -353,8 +351,8 @@ pub fn gdb_version_to_int(version_string: &str) -> int {
         panic!("{}", error_string);
     }
 
-    let major: int = FromStr::from_str(components[0]).expect(error_string);
-    let minor: int = FromStr::from_str(components[1]).expect(error_string);
+    let major: int = from_str(components[0]).expect(error_string);
+    let minor: int = from_str(components[1]).expect(error_string);
 
     return major * 1000 + minor;
 }
@@ -364,6 +362,6 @@ pub fn lldb_version_to_int(version_string: &str) -> int {
         "Encountered LLDB version string with unexpected format: {}",
         version_string);
     let error_string = error_string.as_slice();
-    let major: int = FromStr::from_str(version_string).expect(error_string);
+    let major: int = from_str(version_string).expect(error_string);
     return major;
 }
diff --git a/src/doc/complement-design-faq.md b/src/doc/complement-design-faq.md
index 9a2531f094c..e57953db3a2 100644
--- a/src/doc/complement-design-faq.md
+++ b/src/doc/complement-design-faq.md
@@ -95,7 +95,7 @@ code should need to run is a stack.
 `match` being exhaustive has some useful properties. First, if every
 possibility is covered by the `match`, adding further variants to the `enum`
 in the future will prompt a compilation failure, rather than runtime panic.
-Second, it makes cost explicit. In general, only safe way to have a
+Second, it makes cost explicit. In general, the only safe way to have a
 non-exhaustive match would be to panic the task if nothing is matched, though
 it could fall through if the type of the `match` expression is `()`. This sort
 of hidden cost and special casing is against the language's philosophy. It's
diff --git a/src/doc/guide-pointers.md b/src/doc/guide-pointers.md
index 87eb91d3ec7..2c6388a6180 100644
--- a/src/doc/guide-pointers.md
+++ b/src/doc/guide-pointers.md
@@ -133,11 +133,11 @@ pass-by-reference. Basically, languages can make two choices (this is made
 up syntax, it's not Rust):
 
 ```{notrust,ignore}
-fn foo(x) {
+func foo(x) {
     x = 5
 }
 
-fn main() {
+func main() {
     i = 1
     foo(i)
     // what is the value of i here?
@@ -153,11 +153,11 @@ So what do pointers have to do with this? Well, since pointers point to a
 location in memory...
 
 ```{notrust,ignore}
-fn foo(&int x) {
+func foo(&int x) {
     *x = 5
 }
 
-fn main() {
+func main() {
     i = 1
     foo(&i)
     // what is the value of i here?
@@ -192,13 +192,13 @@ When you combine pointers and functions, it's easy to accidentally invalidate
 the memory the pointer is pointing to. For example:
 
 ```{notrust,ignore}
-fn make_pointer(): &int {
+func make_pointer(): &int {
     x = 5;
 
     return &x;
 }
 
-fn main() {
+func main() {
     &int i = make_pointer();
     *i = 5; // uh oh!
 }
@@ -214,11 +214,11 @@ issue. Two pointers are said to alias when they point at the same location
 in memory. Like this:
 
 ```{notrust,ignore}
-fn mutate(&int i, int j) {
+func mutate(&int i, int j) {
     *i = j;
 }
 
-fn main() {
+func main() {
   x = 5;
   y = &x;
   z = &x; //y and z are aliased
diff --git a/src/doc/guide-strings.md b/src/doc/guide-strings.md
index 1c7cb1a3b4e..071c9ff013c 100644
--- a/src/doc/guide-strings.md
+++ b/src/doc/guide-strings.md
@@ -155,7 +155,7 @@ println!("{}", s[0]);
 This does not compile. This is on purpose. In the world of UTF-8, direct
 indexing is basically never what you want to do. The reason is that each
 character can be a variable number of bytes. This means that you have to iterate
-through the characters anyway, which is a O(n) operation. 
+through the characters anyway, which is an O(n) operation.
 
 There's 3 basic levels of unicode (and its encodings):
 
diff --git a/src/doc/reference.md b/src/doc/reference.md
index d05705562d2..5d1401e27ba 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -2526,7 +2526,7 @@ The currently implemented features of the reference compiler are:
 
 * `plugin_registrar` - Indicates that a crate has [compiler plugins][plugin] that it
                        wants to load. As with `phase`, the implementation is
-                       in need of a overhaul, and it is not clear that plugins
+                       in need of an overhaul, and it is not clear that plugins
                        defined using this will continue to work.
 
 * `quote` - Allows use of the `quote_*!` family of macros, which are
@@ -2583,7 +2583,7 @@ there isn't a parser error first). The directive in this case is no longer
 necessary, and it's likely that existing code will break if the feature isn't
 removed.
 
-If a unknown feature is found in a directive, it results in a compiler error.
+If an unknown feature is found in a directive, it results in a compiler error.
 An unknown feature is one which has never been recognized by the compiler.
 
 # Statements and expressions
@@ -2685,7 +2685,7 @@ When an lvalue is evaluated in an _lvalue context_, it denotes a memory
 location; when evaluated in an _rvalue context_, it denotes the value held _in_
 that memory location.
 
-When an rvalue is used in lvalue context, a temporary un-named lvalue is
+When an rvalue is used in an lvalue context, a temporary un-named lvalue is
 created and used instead. A temporary's lifetime equals the largest lifetime
 of any reference that points to it.
 
@@ -2833,7 +2833,7 @@ foo().x;
 ```
 
 A field access is an [lvalue](#lvalues,-rvalues-and-temporaries) referring to
-the value of that field. When the type providing the field inherits mutabilty,
+the value of that field. When the type providing the field inherits mutability,
 it can be [assigned](#assignment-expressions) to.
 
 Also, if the type of the expression to the left of the dot is a pointer, it is
@@ -3108,11 +3108,10 @@ then the expression completes.
 Some examples of call expressions:
 
 ```
-# use std::from_str::FromStr;
 # fn add(x: int, y: int) -> int { 0 }
 
 let x: int = add(1, 2);
-let pi: Option<f32> = FromStr::from_str("3.14");
+let pi: Option<f32> = from_str("3.14");
 ```
 
 ### Lambda expressions
@@ -3321,7 +3320,7 @@ between `_` and `..` is that the pattern `C(_)` is only type-correct if `C` has
 exactly one argument, while the pattern `C(..)` is type-correct for any enum
 variant `C`, regardless of how many arguments `C` has.
 
-Used inside a array pattern, `..` stands for any number of elements, when the
+Used inside an array pattern, `..` stands for any number of elements, when the
 `advanced_slice_patterns` feature gate is turned on. This wildcard can be used
 at most once for a given array, which implies that it cannot be used to
 specifically match elements that are at an unknown distance from both ends of a
@@ -3584,7 +3583,7 @@ is not a surrogate), represented as a 32-bit unsigned word in the 0x0000 to
 0xD7FF or 0xE000 to 0x10FFFF range. A `[char]` array is effectively an UCS-4 /
 UTF-32 string.
 
-A value of type `str` is a Unicode string, represented as a array of 8-bit
+A value of type `str` is a Unicode string, represented as an array of 8-bit
 unsigned bytes holding a sequence of UTF-8 codepoints. Since `str` is of
 unknown size, it is not a _first class_ type, but can only be instantiated
 through a pointer type, such as `&str` or `String`.
diff --git a/src/etc/snapshot.py b/src/etc/snapshot.py
index e0610bfbdfe..cb99da8092d 100644
--- a/src/etc/snapshot.py
+++ b/src/etc/snapshot.py
@@ -75,7 +75,11 @@ def full_snapshot_name(date, rev, platform, hsh):
 
 
 def get_kernel(triple):
-    os_name = triple.split('-')[2]
+    t = triple.split('-')
+    if len(t) == 2:
+      os_name = t[1]
+    else:
+      os_name = t[2]
     if os_name == "windows":
         return "winnt"
     if os_name == "darwin":
diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim
index 710092a3e5f..1b1b65bd560 100644
--- a/src/etc/vim/syntax/rust.vim
+++ b/src/etc/vim/syntax/rust.vim
@@ -105,7 +105,7 @@ syn keyword rustTrait RawPtr
 syn keyword rustTrait Buffer Writer Reader Seek
 syn keyword rustTrait Str StrVector StrSlice
 syn keyword rustTrait IntoMaybeOwned StrAllocating UnicodeStrSlice
-syn keyword rustTrait ToString IntoStr
+syn keyword rustTrait ToString IntoString
 syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4
 syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
 syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 049bf4eb1b0..501f915461a 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -179,9 +179,9 @@ pub struct Rc<T> {
     _noshare: marker::NoSync
 }
 
-#[stable]
 impl<T> Rc<T> {
     /// Constructs a new reference-counted pointer.
+    #[stable]
     pub fn new(value: T) -> Rc<T> {
         unsafe {
             Rc {
@@ -200,9 +200,7 @@ impl<T> Rc<T> {
             }
         }
     }
-}
 
-impl<T> Rc<T> {
     /// Downgrades the reference-counted pointer to a weak reference.
     #[experimental = "Weak pointers may not belong in this module"]
     pub fn downgrade(&self) -> Weak<T> {
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 20aa29fbb3d..a2f89dfecbc 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -73,6 +73,7 @@ pub use core::str::{CharSplitsN, AnyLines, MatchIndices, StrSplits};
 pub use core::str::{Utf16CodeUnits, eq_slice, is_utf8, is_utf16, Utf16Items};
 pub use core::str::{Utf16Item, ScalarValue, LoneSurrogate, utf16_items};
 pub use core::str::{truncate_utf16_at_nul, utf8_char_width, CharRange};
+pub use core::str::{FromStr, from_str};
 pub use core::str::{Str, StrPrelude};
 pub use unicode::str::{UnicodeStrPrelude, Words, Graphemes, GraphemeIndices};
 
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 5872afc6fde..3c75198a368 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -25,7 +25,7 @@ use core::raw::Slice as RawSlice;
 use hash;
 use slice::CloneSliceAllocPrelude;
 use str;
-use str::{CharRange, StrAllocating, MaybeOwned, Owned};
+use str::{CharRange, FromStr, StrAllocating, MaybeOwned, Owned};
 use str::Slice as MaybeOwnedSlice; // So many `Slice`s...
 use vec::{DerefVec, Vec, as_vec};
 
@@ -795,6 +795,33 @@ pub fn as_string<'a>(x: &'a str) -> DerefString<'a> {
     DerefString { x: as_vec(x.as_bytes()) }
 }
 
+impl FromStr for String {
+    #[inline]
+    fn from_str(s: &str) -> Option<String> {
+        Some(String::from_str(s))
+    }
+}
+
+/// Trait for converting a type to a string, consuming it in the process.
+pub trait IntoString {
+    /// Consume and convert to a string.
+    fn into_string(self) -> String;
+}
+
+/// A generic trait for converting a value to a string
+pub trait ToString {
+    /// Converts the value of `self` to an owned string
+    fn to_string(&self) -> String;
+}
+
+impl<T: fmt::Show> ToString for T {
+    fn to_string(&self) -> String {
+        let mut buf = Vec::<u8>::new();
+        let _ = format_args!(|args| fmt::write(&mut buf, args), "{}", self);
+        String::from_utf8(buf).unwrap()
+    }
+}
+
 /// Unsafe operations
 #[unstable = "waiting on raw module conventions"]
 pub mod raw {
@@ -860,7 +887,7 @@ mod tests {
 
     use str;
     use str::{Str, StrPrelude, Owned};
-    use super::{as_string, String};
+    use super::{as_string, String, ToString};
     use vec::Vec;
     use slice::CloneSliceAllocPrelude;
 
@@ -1164,6 +1191,28 @@ mod tests {
         assert_eq!("oob", s[1..4]);
     }
 
+    #[test]
+    fn test_simple_types() {
+        assert_eq!(1i.to_string(), "1".to_string());
+        assert_eq!((-1i).to_string(), "-1".to_string());
+        assert_eq!(200u.to_string(), "200".to_string());
+        assert_eq!(2u8.to_string(), "2".to_string());
+        assert_eq!(true.to_string(), "true".to_string());
+        assert_eq!(false.to_string(), "false".to_string());
+        assert_eq!(().to_string(), "()".to_string());
+        assert_eq!(("hi".to_string()).to_string(), "hi".to_string());
+    }
+
+    #[test]
+    fn test_vectors() {
+        let x: Vec<int> = vec![];
+        assert_eq!(x.to_string(), "[]".to_string());
+        assert_eq!((vec![1i]).to_string(), "[1]".to_string());
+        assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]".to_string());
+        assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_string() ==
+               "[[], [1], [1, 1]]".to_string());
+    }
+
     #[bench]
     fn bench_with_capacity(b: &mut Bencher) {
         b.iter(|| {
diff --git a/src/libcollections/tree/set.rs b/src/libcollections/tree/set.rs
index 45904259c66..1005732a1e2 100644
--- a/src/libcollections/tree/set.rs
+++ b/src/libcollections/tree/set.rs
@@ -504,9 +504,9 @@ impl<T: Ord> TreeSet<T> {
     /// # Example
     ///
     /// ```
-    /// use std::collections::BTreeSet;
+    /// use std::collections::TreeSet;
     ///
-    /// let mut set = BTreeSet::new();
+    /// let mut set = TreeSet::new();
     ///
     /// assert_eq!(set.insert(2i), true);
     /// assert_eq!(set.insert(2i), false);
@@ -522,9 +522,9 @@ impl<T: Ord> TreeSet<T> {
     /// # Example
     ///
     /// ```
-    /// use std::collections::BTreeSet;
+    /// use std::collections::TreeSet;
     ///
-    /// let mut set = BTreeSet::new();
+    /// let mut set = TreeSet::new();
     ///
     /// set.insert(2i);
     /// assert_eq!(set.remove(&2), true);
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 2b68de932d2..fdee089380b 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -645,7 +645,6 @@ impl<T> Vec<T> {
     /// assert!(vec.capacity() >= 3);
     /// ```
     #[stable]
-    #[unstable = "matches collection reform specification, waiting for dust to settle"]
     pub fn shrink_to_fit(&mut self) {
         if mem::size_of::<T>() == 0 { return }
 
@@ -1653,6 +1652,13 @@ impl<T> Vec<T> {
     }
 }
 
+impl<'a> fmt::FormatWriter for Vec<u8> {
+    fn write(&mut self, buf: &[u8]) -> fmt::Result {
+        self.push_all(buf);
+        Ok(())
+    }
+}
+
 #[cfg(test)]
 mod tests {
     extern crate test;
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index 021f575b0ac..5511266b4cd 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -88,6 +88,7 @@ use intrinsics::TypeId;
 #[stable]
 pub trait Any: 'static {
     /// Get the `TypeId` of `self`
+    #[stable]
     fn get_type_id(&self) -> TypeId;
 }
 
@@ -117,7 +118,6 @@ pub trait AnyRefExt<'a> {
 #[stable]
 impl<'a> AnyRefExt<'a> for &'a Any {
     #[inline]
-    #[stable]
     fn is<T: 'static>(self) -> bool {
         // Get TypeId of the type this function is instantiated with
         let t = TypeId::of::<T>();
@@ -130,7 +130,6 @@ impl<'a> AnyRefExt<'a> for &'a Any {
     }
 
     #[inline]
-    #[unstable = "naming conventions around acquiring references may change"]
     fn downcast_ref<T: 'static>(self) -> Option<&'a T> {
         if self.is::<T>() {
             unsafe {
@@ -159,7 +158,6 @@ pub trait AnyMutRefExt<'a> {
 #[stable]
 impl<'a> AnyMutRefExt<'a> for &'a mut Any {
     #[inline]
-    #[unstable = "naming conventions around acquiring references may change"]
     fn downcast_mut<T: 'static>(self) -> Option<&'a mut T> {
         if self.is::<T>() {
             unsafe {
diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs
index 352beeb473a..d84a7875df1 100644
--- a/src/libcore/atomic.rs
+++ b/src/libcore/atomic.rs
@@ -58,20 +58,25 @@ pub struct AtomicPtr<T> {
 #[stable]
 pub enum Ordering {
     /// No ordering constraints, only atomic operations
+    #[stable]
     Relaxed,
     /// When coupled with a store, all previous writes become visible
     /// to another thread that performs a load with `Acquire` ordering
     /// on the same value
+    #[stable]
     Release,
     /// When coupled with a load, all subsequent loads will see data
     /// written before a store with `Release` ordering on the same value
     /// in another thread
+    #[stable]
     Acquire,
     /// When coupled with a load, uses `Acquire` ordering, and with a store
     /// `Release` ordering
+    #[stable]
     AcqRel,
     /// Like `AcqRel` with the additional guarantee that all threads see all
     /// sequentially consistent operations in the same order.
+    #[stable]
     SeqCst
 }
 
@@ -91,10 +96,10 @@ pub const INIT_ATOMIC_UINT: AtomicUint =
 // NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
 const UINT_TRUE: uint = -1;
 
-#[stable]
 impl AtomicBool {
     /// Create a new `AtomicBool`
     #[inline]
+    #[stable]
     pub fn new(v: bool) -> AtomicBool {
         let val = if v { UINT_TRUE } else { 0 };
         AtomicBool { v: UnsafeCell::new(val), nocopy: marker::NoCopy }
@@ -106,6 +111,7 @@ impl AtomicBool {
     ///
     /// Panics if `order` is `Release` or `AcqRel`.
     #[inline]
+    #[stable]
     pub fn load(&self, order: Ordering) -> bool {
         unsafe { atomic_load(self.v.get() as *const uint, order) > 0 }
     }
@@ -116,6 +122,7 @@ impl AtomicBool {
     ///
     /// Panics if `order` is `Acquire` or `AcqRel`.
     #[inline]
+    #[stable]
     pub fn store(&self, val: bool, order: Ordering) {
         let val = if val { UINT_TRUE } else { 0 };
 
@@ -124,6 +131,7 @@ impl AtomicBool {
 
     /// Store a value, returning the old value
     #[inline]
+    #[stable]
     pub fn swap(&self, val: bool, order: Ordering) -> bool {
         let val = if val { UINT_TRUE } else { 0 };
 
@@ -174,6 +182,7 @@ impl AtomicBool {
     /// }
     /// ```
     #[inline]
+    #[stable]
     pub fn compare_and_swap(&self, old: bool, new: bool, order: Ordering) -> bool {
         let old = if old { UINT_TRUE } else { 0 };
         let new = if new { UINT_TRUE } else { 0 };
@@ -205,6 +214,7 @@ impl AtomicBool {
     /// assert_eq!(false, foo.load(SeqCst));
     /// ```
     #[inline]
+    #[stable]
     pub fn fetch_and(&self, val: bool, order: Ordering) -> bool {
         let val = if val { UINT_TRUE } else { 0 };
 
@@ -236,6 +246,7 @@ impl AtomicBool {
     /// assert_eq!(true, foo.load(SeqCst));
     /// ```
     #[inline]
+    #[stable]
     pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool {
         let val = if val { UINT_TRUE } else { 0 };
 
@@ -266,6 +277,7 @@ impl AtomicBool {
     /// assert_eq!(false, foo.load(SeqCst));
     /// ```
     #[inline]
+    #[stable]
     pub fn fetch_or(&self, val: bool, order: Ordering) -> bool {
         let val = if val { UINT_TRUE } else { 0 };
 
@@ -296,6 +308,7 @@ impl AtomicBool {
     /// assert_eq!(false, foo.load(SeqCst));
     /// ```
     #[inline]
+    #[stable]
     pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
         let val = if val { UINT_TRUE } else { 0 };
 
@@ -303,10 +316,10 @@ impl AtomicBool {
     }
 }
 
-#[stable]
 impl AtomicInt {
     /// Create a new `AtomicInt`
     #[inline]
+    #[stable]
     pub fn new(v: int) -> AtomicInt {
         AtomicInt {v: UnsafeCell::new(v), nocopy: marker::NoCopy}
     }
@@ -317,6 +330,7 @@ impl AtomicInt {
     ///
     /// Panics if `order` is `Release` or `AcqRel`.
     #[inline]
+    #[stable]
     pub fn load(&self, order: Ordering) -> int {
         unsafe { atomic_load(self.v.get() as *const int, order) }
     }
@@ -327,12 +341,14 @@ impl AtomicInt {
     ///
     /// Panics if `order` is `Acquire` or `AcqRel`.
     #[inline]
+    #[stable]
     pub fn store(&self, val: int, order: Ordering) {
         unsafe { atomic_store(self.v.get(), val, order); }
     }
 
     /// Store a value, returning the old value
     #[inline]
+    #[stable]
     pub fn swap(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_swap(self.v.get(), val, order) }
     }
@@ -343,6 +359,7 @@ impl AtomicInt {
     /// replace the current value with `new`. Return the previous value.
     /// If the return value is equal to `old` then the value was updated.
     #[inline]
+    #[stable]
     pub fn compare_and_swap(&self, old: int, new: int, order: Ordering) -> int {
         unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
     }
@@ -359,6 +376,7 @@ impl AtomicInt {
     /// assert_eq!(10, foo.load(SeqCst));
     /// ```
     #[inline]
+    #[stable]
     pub fn fetch_add(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_add(self.v.get(), val, order) }
     }
@@ -375,6 +393,7 @@ impl AtomicInt {
     /// assert_eq!(-10, foo.load(SeqCst));
     /// ```
     #[inline]
+    #[stable]
     pub fn fetch_sub(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_sub(self.v.get(), val, order) }
     }
@@ -390,6 +409,7 @@ impl AtomicInt {
     /// assert_eq!(0b101101, foo.fetch_and(0b110011, SeqCst));
     /// assert_eq!(0b100001, foo.load(SeqCst));
     #[inline]
+    #[stable]
     pub fn fetch_and(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_and(self.v.get(), val, order) }
     }
@@ -405,6 +425,7 @@ impl AtomicInt {
     /// assert_eq!(0b101101, foo.fetch_or(0b110011, SeqCst));
     /// assert_eq!(0b111111, foo.load(SeqCst));
     #[inline]
+    #[stable]
     pub fn fetch_or(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_or(self.v.get(), val, order) }
     }
@@ -420,15 +441,16 @@ impl AtomicInt {
     /// assert_eq!(0b101101, foo.fetch_xor(0b110011, SeqCst));
     /// assert_eq!(0b011110, foo.load(SeqCst));
     #[inline]
+    #[stable]
     pub fn fetch_xor(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_xor(self.v.get(), val, order) }
     }
 }
 
-#[stable]
 impl AtomicUint {
     /// Create a new `AtomicUint`
     #[inline]
+    #[stable]
     pub fn new(v: uint) -> AtomicUint {
         AtomicUint { v: UnsafeCell::new(v), nocopy: marker::NoCopy }
     }
@@ -439,6 +461,7 @@ impl AtomicUint {
     ///
     /// Panics if `order` is `Release` or `AcqRel`.
     #[inline]
+    #[stable]
     pub fn load(&self, order: Ordering) -> uint {
         unsafe { atomic_load(self.v.get() as *const uint, order) }
     }
@@ -449,12 +472,14 @@ impl AtomicUint {
     ///
     /// Panics if `order` is `Acquire` or `AcqRel`.
     #[inline]
+    #[stable]
     pub fn store(&self, val: uint, order: Ordering) {
         unsafe { atomic_store(self.v.get(), val, order); }
     }
 
     /// Store a value, returning the old value
     #[inline]
+    #[stable]
     pub fn swap(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_swap(self.v.get(), val, order) }
     }
@@ -465,6 +490,7 @@ impl AtomicUint {
     /// replace the current value with `new`. Return the previous value.
     /// If the return value is equal to `old` then the value was updated.
     #[inline]
+    #[stable]
     pub fn compare_and_swap(&self, old: uint, new: uint, order: Ordering) -> uint {
         unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
     }
@@ -481,6 +507,7 @@ impl AtomicUint {
     /// assert_eq!(10, foo.load(SeqCst));
     /// ```
     #[inline]
+    #[stable]
     pub fn fetch_add(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_add(self.v.get(), val, order) }
     }
@@ -497,6 +524,7 @@ impl AtomicUint {
     /// assert_eq!(0, foo.load(SeqCst));
     /// ```
     #[inline]
+    #[stable]
     pub fn fetch_sub(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_sub(self.v.get(), val, order) }
     }
@@ -512,6 +540,7 @@ impl AtomicUint {
     /// assert_eq!(0b101101, foo.fetch_and(0b110011, SeqCst));
     /// assert_eq!(0b100001, foo.load(SeqCst));
     #[inline]
+    #[stable]
     pub fn fetch_and(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_and(self.v.get(), val, order) }
     }
@@ -527,6 +556,7 @@ impl AtomicUint {
     /// assert_eq!(0b101101, foo.fetch_or(0b110011, SeqCst));
     /// assert_eq!(0b111111, foo.load(SeqCst));
     #[inline]
+    #[stable]
     pub fn fetch_or(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_or(self.v.get(), val, order) }
     }
@@ -542,15 +572,16 @@ impl AtomicUint {
     /// assert_eq!(0b101101, foo.fetch_xor(0b110011, SeqCst));
     /// assert_eq!(0b011110, foo.load(SeqCst));
     #[inline]
+    #[stable]
     pub fn fetch_xor(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_xor(self.v.get(), val, order) }
     }
 }
 
-#[stable]
 impl<T> AtomicPtr<T> {
     /// Create a new `AtomicPtr`
     #[inline]
+    #[stable]
     pub fn new(p: *mut T) -> AtomicPtr<T> {
         AtomicPtr { p: UnsafeCell::new(p as uint), nocopy: marker::NoCopy }
     }
@@ -561,6 +592,7 @@ impl<T> AtomicPtr<T> {
     ///
     /// Panics if `order` is `Release` or `AcqRel`.
     #[inline]
+    #[stable]
     pub fn load(&self, order: Ordering) -> *mut T {
         unsafe {
             atomic_load(self.p.get() as *const *mut T, order) as *mut T
@@ -573,12 +605,14 @@ impl<T> AtomicPtr<T> {
     ///
     /// Panics if `order` is `Acquire` or `AcqRel`.
     #[inline]
+    #[stable]
     pub fn store(&self, ptr: *mut T, order: Ordering) {
         unsafe { atomic_store(self.p.get(), ptr as uint, order); }
     }
 
     /// Store a value, returning the old value
     #[inline]
+    #[stable]
     pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T {
         unsafe { atomic_swap(self.p.get(), ptr as uint, order) as *mut T }
     }
@@ -589,6 +623,7 @@ impl<T> AtomicPtr<T> {
     /// replace the current value with `new`. Return the previous value.
     /// If the return value is equal to `old` then the value was updated.
     #[inline]
+    #[stable]
     pub fn compare_and_swap(&self, old: *mut T, new: *mut T, order: Ordering) -> *mut T {
         unsafe {
             atomic_compare_and_swap(self.p.get(), old as uint,
@@ -609,6 +644,7 @@ unsafe fn atomic_store<T>(dst: *mut T, val: T, order:Ordering) {
 }
 
 #[inline]
+#[stable]
 unsafe fn atomic_load<T>(dst: *const T, order:Ordering) -> T {
     match order {
         Acquire => intrinsics::atomic_load_acq(dst),
@@ -620,6 +656,7 @@ unsafe fn atomic_load<T>(dst: *const T, order:Ordering) -> T {
 }
 
 #[inline]
+#[stable]
 unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
         Acquire => intrinsics::atomic_xchg_acq(dst, val),
@@ -632,6 +669,7 @@ unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
 
 /// Returns the old value (like __sync_fetch_and_add).
 #[inline]
+#[stable]
 unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
         Acquire => intrinsics::atomic_xadd_acq(dst, val),
@@ -644,6 +682,7 @@ unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T {
 
 /// Returns the old value (like __sync_fetch_and_sub).
 #[inline]
+#[stable]
 unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
         Acquire => intrinsics::atomic_xsub_acq(dst, val),
@@ -655,6 +694,7 @@ unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T {
 }
 
 #[inline]
+#[stable]
 unsafe fn atomic_compare_and_swap<T>(dst: *mut T, old:T, new:T, order: Ordering) -> T {
     match order {
         Acquire => intrinsics::atomic_cxchg_acq(dst, old, new),
@@ -666,6 +706,7 @@ unsafe fn atomic_compare_and_swap<T>(dst: *mut T, old:T, new:T, order: Ordering)
 }
 
 #[inline]
+#[stable]
 unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
         Acquire => intrinsics::atomic_and_acq(dst, val),
@@ -677,6 +718,7 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
 }
 
 #[inline]
+#[stable]
 unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
         Acquire => intrinsics::atomic_nand_acq(dst, val),
@@ -689,6 +731,7 @@ unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T {
 
 
 #[inline]
+#[stable]
 unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
         Acquire => intrinsics::atomic_or_acq(dst, val),
@@ -701,6 +744,7 @@ unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T {
 
 
 #[inline]
+#[stable]
 unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
         Acquire => intrinsics::atomic_xor_acq(dst, val),
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 6f87ff52662..0b7389b2019 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -157,6 +157,7 @@
 
 use clone::Clone;
 use cmp::PartialEq;
+use default::Default;
 use kinds::{marker, Copy};
 use ops::{Deref, DerefMut, Drop};
 use option::{None, Option, Some};
@@ -168,9 +169,9 @@ pub struct Cell<T> {
     noshare: marker::NoSync,
 }
 
-#[stable]
 impl<T:Copy> Cell<T> {
     /// Creates a new `Cell` containing the given value.
+    #[stable]
     pub fn new(value: T) -> Cell<T> {
         Cell {
             value: UnsafeCell::new(value),
@@ -180,12 +181,14 @@ impl<T:Copy> Cell<T> {
 
     /// Returns a copy of the contained value.
     #[inline]
+    #[stable]
     pub fn get(&self) -> T {
         unsafe{ *self.value.get() }
     }
 
     /// Sets the contained value.
     #[inline]
+    #[stable]
     pub fn set(&self, value: T) {
         unsafe {
             *self.value.get() = value;
@@ -211,6 +214,13 @@ impl<T:Copy> Clone for Cell<T> {
     }
 }
 
+#[unstable]
+impl<T:Default + Copy> Default for Cell<T> {
+    fn default() -> Cell<T> {
+        Cell::new(Default::default())
+    }
+}
+
 #[unstable = "waiting for `PartialEq` trait to become stable"]
 impl<T:PartialEq + Copy> PartialEq for Cell<T> {
     fn eq(&self, other: &Cell<T>) -> bool {
@@ -337,6 +347,13 @@ impl<T: Clone> Clone for RefCell<T> {
     }
 }
 
+#[unstable]
+impl<T:Default> Default for RefCell<T> {
+    fn default() -> RefCell<T> {
+        RefCell::new(Default::default())
+    }
+}
+
 #[unstable = "waiting for `PartialEq` to become stable"]
 impl<T: PartialEq> PartialEq for RefCell<T> {
     fn eq(&self, other: &RefCell<T>) -> bool {
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index ba03bb8f3d5..e7b0f626bf8 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -16,8 +16,8 @@
 
 use intrinsics;
 use mem;
-use num::{FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
-use num::Float;
+use num::{Float, FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
+use num::from_str_radix;
 use option::Option;
 
 pub const RADIX: uint = 2u;
@@ -424,3 +424,10 @@ impl Float for f32 {
         self * (value / 180.0f32)
     }
 }
+
+#[inline]
+#[allow(missing_docs)]
+#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
+pub fn from_str_hex(src: &str) -> Option<f32> {
+    from_str_radix(src, 16)
+}
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index f1af4f0272c..e82be190110 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -16,8 +16,8 @@
 
 use intrinsics;
 use mem;
-use num::{FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
-use num::Float;
+use num::{Float, FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN};
+use num::from_str_radix;
 use option::Option;
 
 // FIXME(#5527): These constants should be deprecated once associated
@@ -430,3 +430,10 @@ impl Float for f64 {
         self * (value / 180.0)
     }
 }
+
+#[inline]
+#[allow(missing_docs)]
+#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
+pub fn from_str_hex(src: &str) -> Option<f64> {
+    from_str_radix(src, 16)
+}
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 216d140ac48..f5505ff8e76 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -14,18 +14,21 @@
 
 #![allow(missing_docs)]
 
-use intrinsics;
 use {int, i8, i16, i32, i64};
 use {uint, u8, u16, u32, u64};
 use {f32, f64};
+use char::Char;
 use clone::Clone;
 use cmp::{PartialEq, Eq};
 use cmp::{PartialOrd, Ord};
+use intrinsics;
+use iter::Iterator;
 use kinds::Copy;
 use mem::size_of;
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
 use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
 use option::{Option, Some, None};
+use str::{FromStr, from_str, StrPrelude};
 
 /// Simultaneous division and remainder
 #[inline]
@@ -1372,6 +1375,290 @@ pub trait Float
     fn to_radians(self) -> Self;
 }
 
+/// A generic trait for converting a string with a radix (base) to a value
+#[experimental = "might need to return Result"]
+pub trait FromStrRadix {
+    fn from_str_radix(str: &str, radix: uint) -> Option<Self>;
+}
+
+/// A utility function that just calls FromStrRadix::from_str_radix.
+#[experimental = "might need to return Result"]
+pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint) -> Option<T> {
+    FromStrRadix::from_str_radix(str, radix)
+}
+
+macro_rules! from_str_radix_float_impl {
+    ($T:ty) => {
+        #[experimental = "might need to return Result"]
+        impl FromStr for $T {
+            /// Convert a string in base 10 to a float.
+            /// Accepts an optional decimal exponent.
+            ///
+            /// This function accepts strings such as
+            ///
+            /// * '3.14'
+            /// * '+3.14', equivalent to '3.14'
+            /// * '-3.14'
+            /// * '2.5E10', or equivalently, '2.5e10'
+            /// * '2.5E-10'
+            /// * '.' (understood as 0)
+            /// * '5.'
+            /// * '.5', or, equivalently,  '0.5'
+            /// * '+inf', 'inf', '-inf', 'NaN'
+            ///
+            /// Leading and trailing whitespace represent an error.
+            ///
+            /// # Arguments
+            ///
+            /// * src - A string
+            ///
+            /// # Return value
+            ///
+            /// `None` if the string did not represent a valid number.  Otherwise,
+            /// `Some(n)` where `n` is the floating-point number represented by `src`.
+            #[inline]
+            fn from_str(src: &str) -> Option<$T> {
+                from_str_radix(src, 10)
+            }
+        }
+
+        #[experimental = "might need to return Result"]
+        impl FromStrRadix for $T {
+            /// Convert a string in a given base to a float.
+            ///
+            /// Due to possible conflicts, this function does **not** accept
+            /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
+            /// does it recognize exponents of any kind.
+            ///
+            /// Leading and trailing whitespace represent an error.
+            ///
+            /// # Arguments
+            ///
+            /// * src - A string
+            /// * radix - The base to use. Must lie in the range [2 .. 36]
+            ///
+            /// # Return value
+            ///
+            /// `None` if the string did not represent a valid number. Otherwise,
+            /// `Some(n)` where `n` is the floating-point number represented by `src`.
+            fn from_str_radix(src: &str, radix: uint) -> Option<$T> {
+               assert!(radix >= 2 && radix <= 36,
+                       "from_str_radix_float: must lie in the range `[2, 36]` - found {}",
+                       radix);
+
+                // Special values
+                match src {
+                    "inf"   => return Some(Float::infinity()),
+                    "-inf"  => return Some(Float::neg_infinity()),
+                    "NaN"   => return Some(Float::nan()),
+                    _       => {},
+                }
+
+                let (is_positive, src) =  match src.slice_shift_char() {
+                    (None, _)        => return None,
+                    (Some('-'), "")  => return None,
+                    (Some('-'), src) => (false, src),
+                    (Some(_), _)     => (true,  src),
+                };
+
+                // The significand to accumulate
+                let mut sig = if is_positive { 0.0 } else { -0.0 };
+                // Necessary to detect overflow
+                let mut prev_sig = sig;
+                let mut cs = src.chars().enumerate();
+                // Exponent prefix and exponent index offset
+                let mut exp_info = None::<(char, uint)>;
+
+                // Parse the integer part of the significand
+                for (i, c) in cs {
+                    match c.to_digit(radix) {
+                        Some(digit) => {
+                            // shift significand one digit left
+                            sig = sig * (radix as $T);
+
+                            // add/subtract current digit depending on sign
+                            if is_positive {
+                                sig = sig + ((digit as int) as $T);
+                            } else {
+                                sig = sig - ((digit as int) as $T);
+                            }
+
+                            // Detect overflow by comparing to last value, except
+                            // if we've not seen any non-zero digits.
+                            if prev_sig != 0.0 {
+                                if is_positive && sig <= prev_sig
+                                    { return Some(Float::infinity()); }
+                                if !is_positive && sig >= prev_sig
+                                    { return Some(Float::neg_infinity()); }
+
+                                // Detect overflow by reversing the shift-and-add process
+                                if is_positive && (prev_sig != (sig - digit as $T) / radix as $T)
+                                    { return Some(Float::infinity()); }
+                                if !is_positive && (prev_sig != (sig + digit as $T) / radix as $T)
+                                    { return Some(Float::neg_infinity()); }
+                            }
+                            prev_sig = sig;
+                        },
+                        None => match c {
+                            'e' | 'E' | 'p' | 'P' => {
+                                exp_info = Some((c, i + 1));
+                                break;  // start of exponent
+                            },
+                            '.' => {
+                                break;  // start of fractional part
+                            },
+                            _ => {
+                                return None;
+                            },
+                        },
+                    }
+                }
+
+                // If we are not yet at the exponent parse the fractional
+                // part of the significand
+                if exp_info.is_none() {
+                    let mut power = 1.0;
+                    for (i, c) in cs {
+                        match c.to_digit(radix) {
+                            Some(digit) => {
+                                // Decrease power one order of magnitude
+                                power = power / (radix as $T);
+                                // add/subtract current digit depending on sign
+                                sig = if is_positive {
+                                    sig + (digit as $T) * power
+                                } else {
+                                    sig - (digit as $T) * power
+                                };
+                                // Detect overflow by comparing to last value
+                                if is_positive && sig < prev_sig
+                                    { return Some(Float::infinity()); }
+                                if !is_positive && sig > prev_sig
+                                    { return Some(Float::neg_infinity()); }
+                                prev_sig = sig;
+                            },
+                            None => match c {
+                                'e' | 'E' | 'p' | 'P' => {
+                                    exp_info = Some((c, i + 1));
+                                    break; // start of exponent
+                                },
+                                _ => {
+                                    return None; // invalid number
+                                },
+                            },
+                        }
+                    }
+                }
+
+                // Parse and calculate the exponent
+                let exp = match exp_info {
+                    Some((c, offset)) => {
+                        let base = match c {
+                            'E' | 'e' if radix == 10 => 10u as $T,
+                            'P' | 'p' if radix == 16 => 2u as $T,
+                            _ => return None,
+                        };
+
+                        // Parse the exponent as decimal integer
+                        let src = src[offset..];
+                        let (is_positive, exp) = match src.slice_shift_char() {
+                            (Some('-'), src) => (false, from_str::<uint>(src)),
+                            (Some('+'), src) => (true,  from_str::<uint>(src)),
+                            (Some(_), _)     => (true,  from_str::<uint>(src)),
+                            (None, _)        => return None,
+                        };
+
+                        match (is_positive, exp) {
+                            (true,  Some(exp)) => base.powi(exp as i32),
+                            (false, Some(exp)) => 1.0 / base.powi(exp as i32),
+                            (_, None)          => return None,
+                        }
+                    },
+                    None => 1.0, // no exponent
+                };
+
+                Some(sig * exp)
+            }
+        }
+    }
+}
+from_str_radix_float_impl!(f32)
+from_str_radix_float_impl!(f64)
+
+macro_rules! from_str_radix_int_impl {
+    ($T:ty) => {
+        #[experimental = "might need to return Result"]
+        impl FromStr for $T {
+            #[inline]
+            fn from_str(src: &str) -> Option<$T> {
+                from_str_radix(src, 10)
+            }
+        }
+
+        #[experimental = "might need to return Result"]
+        impl FromStrRadix for $T {
+            fn from_str_radix(src: &str, radix: uint) -> Option<$T> {
+                assert!(radix >= 2 && radix <= 36,
+                       "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
+                       radix);
+
+                let is_signed_ty = (0 as $T) > Int::min_value();
+
+                match src.slice_shift_char() {
+                    (Some('-'), src) if is_signed_ty => {
+                        // The number is negative
+                        let mut result = 0;
+                        for c in src.chars() {
+                            let x = match c.to_digit(radix) {
+                                Some(x) => x,
+                                None => return None,
+                            };
+                            result = match result.checked_mul(radix as $T) {
+                                Some(result) => result,
+                                None => return None,
+                            };
+                            result = match result.checked_sub(x as $T) {
+                                Some(result) => result,
+                                None => return None,
+                            };
+                        }
+                        Some(result)
+                    },
+                    (Some(_), _) => {
+                        // The number is signed
+                        let mut result = 0;
+                        for c in src.chars() {
+                            let x = match c.to_digit(radix) {
+                                Some(x) => x,
+                                None => return None,
+                            };
+                            result = match result.checked_mul(radix as $T) {
+                                Some(result) => result,
+                                None => return None,
+                            };
+                            result = match result.checked_add(x as $T) {
+                                Some(result) => result,
+                                None => return None,
+                            };
+                        }
+                        Some(result)
+                    },
+                    (None, _) => None,
+                }
+            }
+        }
+    }
+}
+from_str_radix_int_impl!(int)
+from_str_radix_int_impl!(i8)
+from_str_radix_int_impl!(i16)
+from_str_radix_int_impl!(i32)
+from_str_radix_int_impl!(i64)
+from_str_radix_int_impl!(uint)
+from_str_radix_int_impl!(u8)
+from_str_radix_int_impl!(u16)
+from_str_radix_int_impl!(u32)
+from_str_radix_int_impl!(u64)
+
 // DEPRECATED
 
 macro_rules! trait_impl {
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 2964a6b6853..d41dbb11adb 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -716,7 +716,6 @@ impl<T: Default> Option<T> {
 impl<T> AsSlice<T> for Option<T> {
     /// Convert from `Option<T>` to `&[T]` (without copying)
     #[inline]
-    #[stable]
     fn as_slice<'a>(&'a self) -> &'a [T] {
         match *self {
             Some(ref x) => slice::ref_slice(x),
@@ -728,6 +727,7 @@ impl<T> AsSlice<T> for Option<T> {
     }
 }
 
+#[stable]
 impl<T> Default for Option<T> {
     #[inline]
     fn default() -> Option<T> { None }
@@ -772,9 +772,10 @@ impl<A> DoubleEndedIterator<A> for Item<A> {
 impl<A> ExactSize<A> for Item<A> {}
 
 /////////////////////////////////////////////////////////////////////////////
-// Free functions
+// FromIterator
 /////////////////////////////////////////////////////////////////////////////
 
+#[stable]
 impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
     /// Takes each element in the `Iterator`: if it is `None`, no further
     /// elements are taken, and the `None` is returned. Should no `None` occur, a
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
index 60012ab149f..101eb7ac74c 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude.rs
@@ -41,6 +41,7 @@ pub use ops::{Fn, FnMut, FnOnce};
 // Reexported functions
 pub use iter::{range, repeat};
 pub use mem::drop;
+pub use str::from_str;
 
 // Reexported types and traits
 
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 69802aef4c2..5a6d0917af2 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -878,9 +878,10 @@ impl<A> DoubleEndedIterator<A> for Item<A> {
 impl<A> ExactSize<A> for Item<A> {}
 
 /////////////////////////////////////////////////////////////////////////////
-// Free functions
+// FromIterator
 /////////////////////////////////////////////////////////////////////////////
 
+#[stable]
 impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
     /// Takes each element in the `Iterator`: if it is an `Err`, no further
     /// elements are taken, and the `Err` is returned. Should no `Err` occur, a
@@ -933,6 +934,10 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
     }
 }
 
+/////////////////////////////////////////////////////////////////////////////
+// FromIterator
+/////////////////////////////////////////////////////////////////////////////
+
 /// Perform a fold operation over the result values from an iterator.
 ///
 /// If an `Err` is encountered, it is immediately returned.
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 745de5f179e..ab4e50c58d9 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -31,6 +31,42 @@ use raw::Repr;
 use slice::{mod, SlicePrelude};
 use uint;
 
+/// A trait to abstract the idea of creating a new instance of a type from a
+/// string.
+#[experimental = "might need to return Result"]
+pub trait FromStr {
+    /// Parses a string `s` to return an optional value of this type. If the
+    /// string is ill-formatted, the None is returned.
+    fn from_str(s: &str) -> Option<Self>;
+}
+
+/// A utility function that just calls FromStr::from_str
+pub fn from_str<A: FromStr>(s: &str) -> Option<A> {
+    FromStr::from_str(s)
+}
+
+impl FromStr for bool {
+    /// Parse a `bool` from a string.
+    ///
+    /// Yields an `Option<bool>`, because `s` may or may not actually be parseable.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// assert_eq!(from_str::<bool>("true"), Some(true));
+    /// assert_eq!(from_str::<bool>("false"), Some(false));
+    /// assert_eq!(from_str::<bool>("not even a boolean"), None);
+    /// ```
+    #[inline]
+    fn from_str(s: &str) -> Option<bool> {
+        match s {
+            "true"  => Some(true),
+            "false" => Some(false),
+            _       => None,
+        }
+    }
+}
+
 /*
 Section: Creating a string
 */
diff --git a/src/libcoretest/cell.rs b/src/libcoretest/cell.rs
index 59365045f43..6444cf7ee0e 100644
--- a/src/libcoretest/cell.rs
+++ b/src/libcoretest/cell.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use core::cell::*;
+use core::default::Default;
 use std::mem::drop;
 
 #[test]
@@ -146,3 +147,15 @@ fn as_unsafe_cell() {
     unsafe { *r2.as_unsafe_cell().get() = 1u; }
     assert_eq!(1u, *r2.borrow());
 }
+
+#[test]
+fn cell_default() {
+    let cell: Cell<u32> = Default::default();
+    assert_eq!(0, cell.get());
+}
+
+#[test]
+fn refcell_default() {
+    let cell: RefCell<u64> = Default::default();
+    assert_eq!(0, *cell.borrow());
+}
diff --git a/src/libcoretest/num/int_macros.rs b/src/libcoretest/num/int_macros.rs
index 5e2530ef2a9..e25f10bd0da 100644
--- a/src/libcoretest/num/int_macros.rs
+++ b/src/libcoretest/num/int_macros.rs
@@ -15,7 +15,8 @@ macro_rules! int_module (($T:ty, $T_i:ident) => (
 mod tests {
     use core::$T_i::*;
     use core::int;
-    use core::num::{Int, SignedInt};
+    use core::num::{FromStrRadix, Int, SignedInt};
+    use core::str::from_str;
     use num;
 
     #[test]
@@ -156,6 +157,49 @@ mod tests {
         assert!(5i.checked_div(0) == None);
         assert!(int::MIN.checked_div(-1) == None);
     }
+
+    #[test]
+    fn test_from_str() {
+        assert_eq!(from_str::<$T>("0"), Some(0 as $T));
+        assert_eq!(from_str::<$T>("3"), Some(3 as $T));
+        assert_eq!(from_str::<$T>("10"), Some(10 as $T));
+        assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
+        assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
+
+        assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
+        assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
+        assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
+        assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
+        assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
+
+        assert_eq!(from_str::<$T>(""), None);
+        assert_eq!(from_str::<$T>(" "), None);
+        assert_eq!(from_str::<$T>("x"), None);
+    }
+
+    #[test]
+    fn test_from_str_radix() {
+        assert_eq!(FromStrRadix::from_str_radix("123", 10), Some(123 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("1001", 2), Some(9 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("123", 8), Some(83 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("123", 16), Some(291 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("ffff", 16), Some(65535 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("FFFF", 16), Some(65535 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("z", 36), Some(35 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("Z", 36), Some(35 as $T));
+
+        assert_eq!(FromStrRadix::from_str_radix("-123", 10), Some(-123 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("-1001", 2), Some(-9 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("-123", 8), Some(-83 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("-123", 16), Some(-291 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("-ffff", 16), Some(-65535 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("-FFFF", 16), Some(-65535 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("-z", 36), Some(-35 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("-Z", 36), Some(-35 as $T));
+
+        assert_eq!(FromStrRadix::from_str_radix("Z", 35), None::<$T>);
+        assert_eq!(FromStrRadix::from_str_radix("-9", 2), None::<$T>);
+    }
 }
 
 ))
diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs
index 38502321c1d..0cd1ded21d6 100644
--- a/src/libcoretest/num/mod.rs
+++ b/src/libcoretest/num/mod.rs
@@ -45,3 +45,73 @@ pub fn test_num<T>(ten: T, two: T) where
     assert_eq!(ten.div(&two),  ten / two);
     assert_eq!(ten.rem(&two),  ten % two);
 }
+
+#[cfg(test)]
+mod test {
+    use core::option::{Option, Some, None};
+    use core::num::Float;
+    use core::num::from_str_radix;
+
+    #[test]
+    fn from_str_issue7588() {
+        let u : Option<u8> = from_str_radix("1000", 10);
+        assert_eq!(u, None);
+        let s : Option<i16> = from_str_radix("80000", 10);
+        assert_eq!(s, None);
+        let f : Option<f32> = from_str_radix("10000000000000000000000000000000000000000", 10);
+        assert_eq!(f, Some(Float::infinity()))
+        let fe : Option<f32> = from_str_radix("1e40", 10);
+        assert_eq!(fe, Some(Float::infinity()))
+    }
+
+    #[test]
+    fn test_from_str_radix_float() {
+        let x1 : Option<f64> = from_str_radix("-123.456", 10);
+        assert_eq!(x1, Some(-123.456));
+        let x2 : Option<f32> = from_str_radix("123.456", 10);
+        assert_eq!(x2, Some(123.456));
+        let x3 : Option<f32> = from_str_radix("-0.0", 10);
+        assert_eq!(x3, Some(-0.0));
+        let x4 : Option<f32> = from_str_radix("0.0", 10);
+        assert_eq!(x4, Some(0.0));
+        let x4 : Option<f32> = from_str_radix("1.0", 10);
+        assert_eq!(x4, Some(1.0));
+        let x5 : Option<f32> = from_str_radix("-1.0", 10);
+        assert_eq!(x5, Some(-1.0));
+    }
+
+    #[test]
+    fn test_int_from_str_overflow() {
+        let mut i8_val: i8 = 127_i8;
+        assert_eq!(from_str::<i8>("127"), Some(i8_val));
+        assert_eq!(from_str::<i8>("128"), None);
+
+        i8_val += 1 as i8;
+        assert_eq!(from_str::<i8>("-128"), Some(i8_val));
+        assert_eq!(from_str::<i8>("-129"), None);
+
+        let mut i16_val: i16 = 32_767_i16;
+        assert_eq!(from_str::<i16>("32767"), Some(i16_val));
+        assert_eq!(from_str::<i16>("32768"), None);
+
+        i16_val += 1 as i16;
+        assert_eq!(from_str::<i16>("-32768"), Some(i16_val));
+        assert_eq!(from_str::<i16>("-32769"), None);
+
+        let mut i32_val: i32 = 2_147_483_647_i32;
+        assert_eq!(from_str::<i32>("2147483647"), Some(i32_val));
+        assert_eq!(from_str::<i32>("2147483648"), None);
+
+        i32_val += 1 as i32;
+        assert_eq!(from_str::<i32>("-2147483648"), Some(i32_val));
+        assert_eq!(from_str::<i32>("-2147483649"), None);
+
+        let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
+        assert_eq!(from_str::<i64>("9223372036854775807"), Some(i64_val));
+        assert_eq!(from_str::<i64>("9223372036854775808"), None);
+
+        i64_val += 1 as i64;
+        assert_eq!(from_str::<i64>("-9223372036854775808"), Some(i64_val));
+        assert_eq!(from_str::<i64>("-9223372036854775809"), None);
+    }
+}
diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs
index d3f77c47c44..5f44fd807cc 100644
--- a/src/libcoretest/str.rs
+++ b/src/libcoretest/str.rs
@@ -8,6 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[test]
+fn test_bool_from_str() {
+    assert_eq!(from_str::<bool>("true"), Some(true));
+    assert_eq!(from_str::<bool>("false"), Some(false));
+    assert_eq!(from_str::<bool>("not even a boolean"), None);
+}
+
 fn check_contains_all_substrings(s: &str) {
     assert!(s.contains(""));
     for i in range(0, s.len()) {
diff --git a/src/libregex/re.rs b/src/libregex/re.rs
index df5bfccd18d..c7540852970 100644
--- a/src/libregex/re.rs
+++ b/src/libregex/re.rs
@@ -10,7 +10,6 @@
 
 use std::collections::HashMap;
 use std::fmt;
-use std::from_str::from_str;
 use std::str::{MaybeOwned, Owned, Slice};
 
 use compile::Program;
diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs
index 8c1d7c839ac..9768b3ce1ab 100644
--- a/src/librustc/driver/config.rs
+++ b/src/librustc/driver/config.rs
@@ -268,8 +268,21 @@ macro_rules! cgoptions(
 
     pub type CodegenSetter = fn(&mut CodegenOptions, v: Option<&str>) -> bool;
     pub const CG_OPTIONS: &'static [(&'static str, CodegenSetter,
-                                      &'static str)] =
-        &[ $( (stringify!($opt), cgsetters::$opt, $desc) ),* ];
+                                     Option<&'static str>, &'static str)] =
+        &[ $( (stringify!($opt), cgsetters::$opt, cg_type_descs::$parse, $desc) ),* ];
+
+    #[allow(non_upper_case_globals)]
+    mod cg_type_descs {
+        pub const parse_bool: Option<&'static str> = None;
+        pub const parse_opt_bool: Option<&'static str> = None;
+        pub const parse_string: Option<&'static str> = Some("a string");
+        pub const parse_opt_string: Option<&'static str> = Some("a string");
+        pub const parse_list: Option<&'static str> = Some("a space-separated list of strings");
+        pub const parse_opt_list: Option<&'static str> = Some("a space-separated list of strings");
+        pub const parse_uint: Option<&'static str> = Some("a number");
+        pub const parse_passes: Option<&'static str> =
+            Some("a space-separated list of passes, or `all`");
+    }
 
     mod cgsetters {
         use super::{CodegenOptions, Passes, SomePasses, AllPasses};
@@ -334,8 +347,7 @@ macro_rules! cgoptions(
         }
 
         fn parse_uint(slot: &mut uint, v: Option<&str>) -> bool {
-            use std::from_str::FromStr;
-            match v.and_then(FromStr::from_str) {
+            match v.and_then(from_str) {
                 Some(i) => { *slot = i; true },
                 None => false
             }
@@ -421,19 +433,25 @@ pub fn build_codegen_options(matches: &getopts::Matches) -> CodegenOptions
         let value = iter.next();
         let option_to_lookup = key.replace("-", "_");
         let mut found = false;
-        for &(candidate, setter, _) in CG_OPTIONS.iter() {
+        for &(candidate, setter, opt_type_desc, _) in CG_OPTIONS.iter() {
             if option_to_lookup.as_slice() != candidate { continue }
             if !setter(&mut cg, value) {
-                match value {
-                    Some(..) => {
+                match (value, opt_type_desc) {
+                    (Some(..), None) => {
                         early_error(format!("codegen option `{}` takes no \
                                              value", key).as_slice())
                     }
-                    None => {
+                    (None, Some(type_desc)) => {
                         early_error(format!("codegen option `{0}` requires \
-                                             a value (-C {0}=<value>)",
-                                            key).as_slice())
+                                             {1} (-C {0}=<value>)",
+                                            key, type_desc).as_slice())
+                    }
+                    (Some(value), Some(type_desc)) => {
+                        early_error(format!("incorrect value `{}` for codegen \
+                                             option `{}` - {} was expected",
+                                             value, key, type_desc).as_slice())
                     }
+                    (None, None) => unreachable!()
                 }
             }
             found = true;
diff --git a/src/librustc/driver/mod.rs b/src/librustc/driver/mod.rs
index edd82b42876..546469c3c0e 100644
--- a/src/librustc/driver/mod.rs
+++ b/src/librustc/driver/mod.rs
@@ -299,14 +299,10 @@ fn describe_debug_flags() {
 
 fn describe_codegen_flags() {
     println!("\nAvailable codegen options:\n");
-    let mut cg = config::basic_codegen_options();
-    for &(name, parser, desc) in config::CG_OPTIONS.iter() {
-        // we invoke the parser function on `None` to see if this option needs
-        // an argument or not.
-        let (width, extra) = if parser(&mut cg, None) {
-            (25, "")
-        } else {
-            (21, "=val")
+    for &(name, _, opt_type_desc, desc) in config::CG_OPTIONS.iter() {
+        let (width, extra) = match opt_type_desc {
+            Some(..) => (21, "=val"),
+            None => (25, "")
         };
         println!("    -C {:>width$s}{} -- {}", name.replace("_", "-"),
                  extra, desc, width=width);
diff --git a/src/librustc/driver/pretty.rs b/src/librustc/driver/pretty.rs
index 0a7cfdeeadc..7b6de088319 100644
--- a/src/librustc/driver/pretty.rs
+++ b/src/librustc/driver/pretty.rs
@@ -31,8 +31,8 @@ use syntax::print::{pp, pprust};
 use graphviz as dot;
 
 use std::io::{mod, MemReader};
-use std::from_str::FromStr;
 use std::option;
+use std::str::FromStr;
 use arena::TypedArena;
 
 #[deriving(PartialEq, Show)]
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index a597325015c..9530c86a94c 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -455,7 +455,12 @@ pub fn llvm_type_name(cx: &CrateContext,
 
     let base = ty::item_path_str(cx.tcx(), did);
     let strings: Vec<String> = tps.iter().map(|t| t.repr(cx.tcx())).collect();
-    let tstr = format!("{}<{}>", base, strings);
+    let tstr = if strings.is_empty() {
+        base
+    } else {
+        format!("{}<{}>", base, strings)
+    };
+
     if did.krate == 0 {
         format!("{}.{}", name, tstr)
     } else {
diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css
index 7cc34798f99..b28da098a57 100644
--- a/src/librustdoc/html/static/main.css
+++ b/src/librustdoc/html/static/main.css
@@ -584,3 +584,9 @@ pre.rust { position: relative; }
         height: 1.5em;
     }
 }
+
+@media print {
+    nav.sub, .content .out-of-band, .collapse-toggle {
+        display: none;
+    }
+}
diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs
index b0e1aeea3a1..7ec59f0139d 100644
--- a/src/librustdoc/stability_summary.rs
+++ b/src/librustdoc/stability_summary.rs
@@ -19,7 +19,7 @@ use std::num::Zero;
 use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked};
 use syntax::ast::Public;
 
-use clean::{Crate, Item, ModuleItem, Module, StructItem, Struct, EnumItem, Enum};
+use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
 use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
 use clean::{TypeTraitItem, ViewItemItem, PrimitiveItem, Stability};
 
@@ -146,13 +146,12 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
     // considered to have no children.
     match item.inner {
         // Require explicit `pub` to be visible
-        StructItem(Struct { fields: ref subitems, .. }) |
         ImplItem(Impl { items: ref subitems, trait_: None, .. }) => {
             let subcounts = subitems.iter().filter(|i| visible(*i))
                                            .map(summarize_item)
                                            .map(|s| s.val0())
                                            .fold(Counts::zero(), |acc, x| acc + x);
-            (item_counts + subcounts, None)
+            (subcounts, None)
         }
         // `pub` automatically
         EnumItem(Enum { variants: ref subitems, .. }) => {
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 524638155ac..a074d6f43b9 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -200,7 +200,7 @@ use std::{char, f64, fmt, io, num, str};
 use std::io::MemWriter;
 use std::mem::{swap, transmute};
 use std::num::{Float, FPNaN, FPInfinite, Int};
-use std::str::ScalarValue;
+use std::str::{FromStr, ScalarValue};
 use std::string;
 use std::vec::Vec;
 use std::ops;
@@ -1988,7 +1988,7 @@ macro_rules! read_primitive {
                 String(s) => {
                     // re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
                     // is going to have a string here, as per JSON spec.
-                    match std::from_str::from_str(s.as_slice()) {
+                    match std::str::from_str(s.as_slice()) {
                         Some(f) => Ok(f),
                         None => Err(ExpectedError("Number".to_string(), s)),
                     }
@@ -2027,7 +2027,7 @@ impl ::Decoder<DecoderError> for Decoder {
             String(s) => {
                 // re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
                 // is going to have a string here, as per JSON spec.
-                match std::from_str::from_str(s.as_slice()) {
+                match std::str::from_str(s.as_slice()) {
                     Some(f) => Ok(f),
                     None => Err(ExpectedError("Number".to_string(), s)),
                 }
@@ -2315,6 +2315,10 @@ impl ToJson for bool {
     fn to_json(&self) -> Json { Boolean(*self) }
 }
 
+impl ToJson for str {
+    fn to_json(&self) -> Json { String(self.into_string()) }
+}
+
 impl ToJson for string::String {
     fn to_json(&self) -> Json { String((*self).clone()) }
 }
@@ -2395,7 +2399,7 @@ impl fmt::Show for Json {
     }
 }
 
-impl std::from_str::FromStr for Json {
+impl FromStr for Json {
     fn from_str(s: &str) -> Option<Json> {
         from_str(s).ok()
     }
@@ -2480,7 +2484,7 @@ mod tests {
     #[test]
     fn test_from_str_trait() {
         let s = "null";
-        assert!(::std::from_str::from_str::<Json>(s).unwrap() == from_str(s).unwrap());
+        assert!(::std::str::from_str::<Json>(s).unwrap() == from_str(s).unwrap());
     }
 
     #[test]
@@ -3714,7 +3718,8 @@ mod tests {
         assert_eq!(f64::NAN.to_json(), Null);
         assert_eq!(true.to_json(), Boolean(true));
         assert_eq!(false.to_json(), Boolean(false));
-        assert_eq!("abc".to_string().to_json(), String("abc".to_string()));
+        assert_eq!("abc".to_json(), String("abc".into_string()));
+        assert_eq!("abc".into_string().to_json(), String("abc".into_string()));
         assert_eq!((1u, 2u).to_json(), list2);
         assert_eq!((1u, 2u, 3u).to_json(), list3);
         assert_eq!([1u, 2].to_json(), list2);
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index ff83027d280..923349b1bf7 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -21,8 +21,7 @@ use mem;
 use option::{Option, Some, None};
 use slice::{SlicePrelude, AsSlice};
 use str::{Str, StrPrelude};
-use string::{mod, String};
-use to_string::IntoStr;
+use string::{mod, String, IntoString};
 use vec::Vec;
 
 /// Datatype to hold one ascii character. It wraps a `u8`, with the highest bit always zero.
@@ -326,7 +325,7 @@ impl AsciiStr for [Ascii] {
     }
 }
 
-impl IntoStr for Vec<Ascii> {
+impl IntoString for Vec<Ascii> {
     #[inline]
     fn into_string(self) -> String {
         unsafe {
diff --git a/src/libstd/from_str.rs b/src/libstd/from_str.rs
deleted file mode 100644
index 21b1e0560a5..00000000000
--- a/src/libstd/from_str.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2012 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.
-
-//! The `FromStr` trait for types that can be created from strings
-
-#![experimental]
-
-use option::{Option, Some, None};
-use string::String;
-
-/// A trait to abstract the idea of creating a new instance of a type from a
-/// string.
-#[experimental = "might need to return Result"]
-pub trait FromStr {
-    /// Parses a string `s` to return an optional value of this type. If the
-    /// string is ill-formatted, the None is returned.
-    fn from_str(s: &str) -> Option<Self>;
-}
-
-/// A utility function that just calls FromStr::from_str
-pub fn from_str<A: FromStr>(s: &str) -> Option<A> {
-    FromStr::from_str(s)
-}
-
-impl FromStr for bool {
-    /// Parse a `bool` from a string.
-    ///
-    /// Yields an `Option<bool>`, because `s` may or may not actually be parseable.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// assert_eq!(from_str::<bool>("true"), Some(true));
-    /// assert_eq!(from_str::<bool>("false"), Some(false));
-    /// assert_eq!(from_str::<bool>("not even a boolean"), None);
-    /// ```
-    #[inline]
-    fn from_str(s: &str) -> Option<bool> {
-        match s {
-            "true"  => Some(true),
-            "false" => Some(false),
-            _       => None,
-        }
-    }
-}
-
-impl FromStr for String {
-    #[inline]
-    fn from_str(s: &str) -> Option<String> {
-        Some(String::from_str(s))
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use prelude::*;
-
-    #[test]
-    fn test_bool_from_str() {
-        assert_eq!(from_str::<bool>("true"), Some(true));
-        assert_eq!(from_str::<bool>("false"), Some(false));
-        assert_eq!(from_str::<bool>("not even a boolean"), None);
-    }
-}
diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs
index 2a2d978ef49..7ba5e173182 100644
--- a/src/libstd/io/net/ip.rs
+++ b/src/libstd/io/net/ip.rs
@@ -16,13 +16,12 @@
 #![allow(missing_docs)]
 
 use fmt;
-use from_str::FromStr;
 use io::{mod, IoResult, IoError};
 use io::net;
 use iter::Iterator;
 use option::{Option, None, Some};
 use result::{Ok, Err};
-use str::StrPrelude;
+use str::{FromStr, StrPrelude};
 use slice::{CloneSlicePrelude, SlicePrelude};
 use vec::Vec;
 
@@ -540,7 +539,7 @@ impl<'a> ToSocketAddr for &'a str {
 mod test {
     use prelude::*;
     use super::*;
-    use from_str::FromStr;
+    use str::FromStr;
 
     #[test]
     fn test_from_str_ipv4() {
diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs
index 2545e07cbb5..24fc2998ee6 100644
--- a/src/libstd/io/net/tcp.rs
+++ b/src/libstd/io/net/tcp.rs
@@ -661,23 +661,22 @@ mod test {
         let addr = next_test_ip4();
         let mut acceptor = TcpListener::bind(addr).listen();
 
+        let (tx, rx) = channel();
         spawn(proc() {
-            let _stream = TcpStream::connect(addr);
-            // Close
+            drop(TcpStream::connect(addr));
+            tx.send(());
         });
 
         let mut stream = acceptor.accept();
+        rx.recv();
         let buf = [0];
-        loop {
-            match stream.write(buf) {
-                Ok(..) => {}
-                Err(e) => {
-                    assert!(e.kind == ConnectionReset ||
-                            e.kind == BrokenPipe ||
-                            e.kind == ConnectionAborted,
-                            "unknown error: {}", e);
-                    break;
-                }
+        match stream.write(buf) {
+            Ok(..) => {}
+            Err(e) => {
+                assert!(e.kind == ConnectionReset ||
+                        e.kind == BrokenPipe ||
+                        e.kind == ConnectionAborted,
+                        "unknown error: {}", e);
             }
         }
     }
@@ -687,23 +686,22 @@ mod test {
         let addr = next_test_ip6();
         let mut acceptor = TcpListener::bind(addr).listen();
 
+        let (tx, rx) = channel();
         spawn(proc() {
-            let _stream = TcpStream::connect(addr);
-            // Close
+            drop(TcpStream::connect(addr));
+            tx.send(());
         });
 
         let mut stream = acceptor.accept();
+        rx.recv();
         let buf = [0];
-        loop {
-            match stream.write(buf) {
-                Ok(..) => {}
-                Err(e) => {
-                    assert!(e.kind == ConnectionReset ||
-                            e.kind == BrokenPipe ||
-                            e.kind == ConnectionAborted,
-                            "unknown error: {}", e);
-                    break;
-                }
+        match stream.write(buf) {
+            Ok(..) => {}
+            Err(e) => {
+                assert!(e.kind == ConnectionReset ||
+                        e.kind == BrokenPipe ||
+                        e.kind == ConnectionAborted,
+                        "unknown error: {}", e);
             }
         }
     }
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index d71bab0b48f..5b5bb618151 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -1190,7 +1190,7 @@ mod tests {
             Path::new("/dev/null")
         };
 
-        let mut fdes = match fs::open(&path, Truncate, Write) {
+        let fdes = match fs::open(&path, Truncate, Write) {
             Ok(f) => f,
             Err(_) => panic!("failed to open file descriptor"),
         };
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 3940d7db66e..612613134d4 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -54,7 +54,7 @@
 //!
 //! For converting to strings use the [`format!`](fmt/index.html)
 //! macro, and for converting from strings use the
-//! [`FromStr`](from_str/index.html) trait.
+//! [`FromStr`](str/trait.FromStr.html) trait.
 //!
 //! ## Platform abstractions
 //!
@@ -219,9 +219,7 @@ pub mod time;
 /* Common traits */
 
 pub mod error;
-pub mod from_str;
 pub mod num;
-pub mod to_string;
 
 /* Common data structures */
 
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index 3f46cc8af50..207fa649930 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -17,12 +17,10 @@
 
 use prelude::*;
 
-use from_str::FromStr;
 use intrinsics;
 use libc::c_int;
 use num::{Float, FloatMath};
 use num::strconv;
-use num;
 
 pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
 pub use core::f32::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
@@ -339,68 +337,6 @@ pub fn to_str_exp_digits(num: f32, dig: uint, upper: bool) -> String {
     r
 }
 
-#[inline]
-#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
-pub fn from_str_hex(src: &str) -> Option<f32> {
-    strconv::from_str_radix_float(src, 16)
-}
-
-impl FromStr for f32 {
-    /// Convert a string in base 10 to a float.
-    /// Accepts an optional decimal exponent.
-    ///
-    /// This function accepts strings such as
-    ///
-    /// * '3.14'
-    /// * '+3.14', equivalent to '3.14'
-    /// * '-3.14'
-    /// * '2.5E10', or equivalently, '2.5e10'
-    /// * '2.5E-10'
-    /// * '.' (understood as 0)
-    /// * '5.'
-    /// * '.5', or, equivalently,  '0.5'
-    /// * '+inf', 'inf', '-inf', 'NaN'
-    ///
-    /// Leading and trailing whitespace represent an error.
-    ///
-    /// # Arguments
-    ///
-    /// * src - A string
-    ///
-    /// # Return value
-    ///
-    /// `None` if the string did not represent a valid number.  Otherwise,
-    /// `Some(n)` where `n` is the floating-point number represented by `src`.
-    #[inline]
-    fn from_str(src: &str) -> Option<f32> {
-        strconv::from_str_radix_float(src, 10u)
-    }
-}
-
-impl num::FromStrRadix for f32 {
-    /// Convert a string in a given base to a float.
-    ///
-    /// Due to possible conflicts, this function does **not** accept
-    /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
-    /// does it recognize exponents of any kind.
-    ///
-    /// Leading and trailing whitespace represent an error.
-    ///
-    /// # Arguments
-    ///
-    /// * src - A string
-    /// * radix - The base to use. Must lie in the range [2 .. 36]
-    ///
-    /// # Return value
-    ///
-    /// `None` if the string did not represent a valid number. Otherwise,
-    /// `Some(n)` where `n` is the floating-point number represented by `src`.
-    #[inline]
-    fn from_str_radix(src: &str, radix: uint) -> Option<f32> {
-        strconv::from_str_radix_float(src, radix)
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use f32::*;
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index 4d691fc9676..543d50596e8 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -16,12 +16,10 @@
 
 use prelude::*;
 
-use from_str::FromStr;
 use intrinsics;
 use libc::c_int;
 use num::{Float, FloatMath};
 use num::strconv;
-use num;
 
 pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
 pub use core::f64::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
@@ -347,63 +345,6 @@ pub fn to_str_exp_digits(num: f64, dig: uint, upper: bool) -> String {
     r
 }
 
-#[inline]
-#[deprecated="Use `FromStrRadix::from_str_radix(src, 16)`"]
-pub fn from_str_hex(src: &str) -> Option<f64> {
-    strconv::from_str_radix_float(src, 16)
-}
-
-impl FromStr for f64 {
-    /// Convert a string in base 10 to a float.
-    /// Accepts an optional decimal exponent.
-    ///
-    /// This function accepts strings such as:
-    ///
-    /// * '3.14'
-    /// * '-3.14'
-    /// * '2.5E10', or equivalently, '2.5e10'
-    /// * '2.5E-10'
-    /// * '.' (understood as 0)
-    /// * '5.'
-    /// * '.5', or, equivalently,  '0.5'
-    /// * inf', '-inf', 'NaN'
-    ///
-    /// Leading and trailing whitespace represent an error.
-    ///
-    /// # Arguments
-    ///
-    /// * src - A string
-    ///
-    /// # Return value
-    ///
-    /// `none` if the string did not represent a valid number.  Otherwise,
-    /// `Some(n)` where `n` is the floating-point number represented by `src`.
-    #[inline]
-    fn from_str(src: &str) -> Option<f64> {
-        strconv::from_str_radix_float(src, 10u)
-    }
-}
-
-impl num::FromStrRadix for f64 {
-    /// Convert a string in a given base to a float.
-    ///
-    /// Leading and trailing whitespace represent an error.
-    ///
-    /// # Arguments
-    ///
-    /// * src - A string
-    /// * radix - The base to use. Must lie in the range [2 .. 36]
-    ///
-    /// # Return value
-    ///
-    /// `None` if the string did not represent a valid number. Otherwise,
-    /// `Some(n)` where `n` is the floating-point number represented by `src`.
-    #[inline]
-    fn from_str_radix(src: &str, radix: uint) -> Option<f64> {
-        strconv::from_str_radix_float(src, radix)
-    }
-}
-
 #[cfg(test)]
 mod tests {
     use f64::*;
diff --git a/src/libstd/num/i16.rs b/src/libstd/num/i16.rs
index d7732b474db..6455c10736a 100644
--- a/src/libstd/num/i16.rs
+++ b/src/libstd/num/i16.rs
@@ -13,11 +13,6 @@
 #![unstable]
 #![doc(primitive = "i16")]
 
-use from_str::FromStr;
-use num::FromStrRadix;
-use num::strconv;
-use option::Option;
-
 pub use core::i16::{BITS, BYTES, MIN, MAX};
 
 int_module!(i16)
diff --git a/src/libstd/num/i32.rs b/src/libstd/num/i32.rs
index 778f1c6748c..39b179c8274 100644
--- a/src/libstd/num/i32.rs
+++ b/src/libstd/num/i32.rs
@@ -13,11 +13,6 @@
 #![unstable]
 #![doc(primitive = "i32")]
 
-use from_str::FromStr;
-use num::FromStrRadix;
-use num::strconv;
-use option::Option;
-
 pub use core::i32::{BITS, BYTES, MIN, MAX};
 
 int_module!(i32)
diff --git a/src/libstd/num/i64.rs b/src/libstd/num/i64.rs
index ae3d57eeac6..a0c474c479a 100644
--- a/src/libstd/num/i64.rs
+++ b/src/libstd/num/i64.rs
@@ -13,11 +13,6 @@
 #![unstable]
 #![doc(primitive = "i64")]
 
-use from_str::FromStr;
-use num::FromStrRadix;
-use num::strconv;
-use option::Option;
-
 pub use core::i64::{BITS, BYTES, MIN, MAX};
 
 int_module!(i64)
diff --git a/src/libstd/num/i8.rs b/src/libstd/num/i8.rs
index 8a3f379893c..e911ed1de9a 100644
--- a/src/libstd/num/i8.rs
+++ b/src/libstd/num/i8.rs
@@ -13,11 +13,6 @@
 #![unstable]
 #![doc(primitive = "i8")]
 
-use from_str::FromStr;
-use num::FromStrRadix;
-use num::strconv;
-use option::Option;
-
 pub use core::i8::{BITS, BYTES, MIN, MAX};
 
 int_module!(i8)
diff --git a/src/libstd/num/int.rs b/src/libstd/num/int.rs
index 51af04b32d4..36c021efe0a 100644
--- a/src/libstd/num/int.rs
+++ b/src/libstd/num/int.rs
@@ -13,11 +13,6 @@
 #![unstable]
 #![doc(primitive = "int")]
 
-use from_str::FromStr;
-use num::FromStrRadix;
-use num::strconv;
-use option::Option;
-
 pub use core::int::{BITS, BYTES, MIN, MAX};
 
 int_module!(int)
diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs
index 9ae146c840a..2f1162d28e5 100644
--- a/src/libstd/num/int_macros.rs
+++ b/src/libstd/num/int_macros.rs
@@ -14,131 +14,4 @@
 
 macro_rules! int_module (($T:ty) => (
 
-#[experimental = "might need to return Result"]
-impl FromStr for $T {
-    #[inline]
-    fn from_str(s: &str) -> Option<$T> {
-        strconv::from_str_radix_int(s, 10)
-    }
-}
-
-#[experimental = "might need to return Result"]
-impl FromStrRadix for $T {
-    #[inline]
-    fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
-        strconv::from_str_radix_int(s, radix)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use num::FromStrRadix;
-
-    #[test]
-    fn test_from_str() {
-        assert_eq!(from_str::<$T>("0"), Some(0 as $T));
-        assert_eq!(from_str::<$T>("3"), Some(3 as $T));
-        assert_eq!(from_str::<$T>("10"), Some(10 as $T));
-        assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
-        assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
-
-        assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
-        assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
-        assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
-        assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
-        assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
-
-        assert_eq!(from_str::<$T>(""), None);
-        assert_eq!(from_str::<$T>(" "), None);
-        assert_eq!(from_str::<$T>("x"), None);
-    }
-
-    #[test]
-    fn test_from_str_radix() {
-        assert_eq!(FromStrRadix::from_str_radix("123", 10), Some(123 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("1001", 2), Some(9 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("123", 8), Some(83 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("123", 16), Some(291 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("ffff", 16), Some(65535 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("FFFF", 16), Some(65535 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("z", 36), Some(35 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("Z", 36), Some(35 as $T));
-
-        assert_eq!(FromStrRadix::from_str_radix("-123", 10), Some(-123 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("-1001", 2), Some(-9 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("-123", 8), Some(-83 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("-123", 16), Some(-291 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("-ffff", 16), Some(-65535 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("-FFFF", 16), Some(-65535 as i32));
-        assert_eq!(FromStrRadix::from_str_radix("-z", 36), Some(-35 as $T));
-        assert_eq!(FromStrRadix::from_str_radix("-Z", 36), Some(-35 as $T));
-
-        assert_eq!(FromStrRadix::from_str_radix("Z", 35), None::<$T>);
-        assert_eq!(FromStrRadix::from_str_radix("-9", 2), None::<$T>);
-    }
-
-    #[test]
-    fn test_int_to_str_overflow() {
-        let mut i8_val: i8 = 127_i8;
-        assert_eq!(i8_val.to_string(), "127".to_string());
-
-        i8_val += 1 as i8;
-        assert_eq!(i8_val.to_string(), "-128".to_string());
-
-        let mut i16_val: i16 = 32_767_i16;
-        assert_eq!(i16_val.to_string(), "32767".to_string());
-
-        i16_val += 1 as i16;
-        assert_eq!(i16_val.to_string(), "-32768".to_string());
-
-        let mut i32_val: i32 = 2_147_483_647_i32;
-        assert_eq!(i32_val.to_string(), "2147483647".to_string());
-
-        i32_val += 1 as i32;
-        assert_eq!(i32_val.to_string(), "-2147483648".to_string());
-
-        let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
-        assert_eq!(i64_val.to_string(), "9223372036854775807".to_string());
-
-        i64_val += 1 as i64;
-        assert_eq!(i64_val.to_string(), "-9223372036854775808".to_string());
-    }
-
-    #[test]
-    fn test_int_from_str_overflow() {
-        let mut i8_val: i8 = 127_i8;
-        assert_eq!(from_str::<i8>("127"), Some(i8_val));
-        assert_eq!(from_str::<i8>("128"), None);
-
-        i8_val += 1 as i8;
-        assert_eq!(from_str::<i8>("-128"), Some(i8_val));
-        assert_eq!(from_str::<i8>("-129"), None);
-
-        let mut i16_val: i16 = 32_767_i16;
-        assert_eq!(from_str::<i16>("32767"), Some(i16_val));
-        assert_eq!(from_str::<i16>("32768"), None);
-
-        i16_val += 1 as i16;
-        assert_eq!(from_str::<i16>("-32768"), Some(i16_val));
-        assert_eq!(from_str::<i16>("-32769"), None);
-
-        let mut i32_val: i32 = 2_147_483_647_i32;
-        assert_eq!(from_str::<i32>("2147483647"), Some(i32_val));
-        assert_eq!(from_str::<i32>("2147483648"), None);
-
-        i32_val += 1 as i32;
-        assert_eq!(from_str::<i32>("-2147483648"), Some(i32_val));
-        assert_eq!(from_str::<i32>("-2147483649"), None);
-
-        let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
-        assert_eq!(from_str::<i64>("9223372036854775807"), Some(i64_val));
-        assert_eq!(from_str::<i64>("9223372036854775808"), None);
-
-        i64_val += 1 as i64;
-        assert_eq!(from_str::<i64>("-9223372036854775808"), Some(i64_val));
-        assert_eq!(from_str::<i64>("-9223372036854775809"), None);
-    }
-}
-
 ))
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index 0afc8ce0452..2ce6c0e6e71 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -16,8 +16,6 @@
 #![experimental]
 #![allow(missing_docs)]
 
-use option::Option;
-
 #[cfg(test)] use cmp::PartialEq;
 #[cfg(test)] use fmt::Show;
 #[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
@@ -31,6 +29,7 @@ pub use core::num::{checked_next_power_of_two};
 pub use core::num::{from_int, from_i8, from_i16, from_i32, from_i64};
 pub use core::num::{from_uint, from_u8, from_u16, from_u32, from_u64};
 pub use core::num::{from_f32, from_f64};
+pub use core::num::{FromStrRadix, from_str_radix};
 pub use core::num::{FPCategory, FPNaN, FPInfinite, FPZero, FPSubnormal};
 pub use core::num::{FPNormal, Float};
 
@@ -115,18 +114,6 @@ pub trait FloatMath: Float {
     fn atanh(self) -> Self;
 }
 
-/// A generic trait for converting a string with a radix (base) to a value
-#[experimental = "might need to return Result"]
-pub trait FromStrRadix {
-    fn from_str_radix(str: &str, radix: uint) -> Option<Self>;
-}
-
-/// A utility function that just calls FromStrRadix::from_str_radix.
-#[experimental = "might need to return Result"]
-pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint) -> Option<T> {
-    FromStrRadix::from_str_radix(str, radix)
-}
-
 // DEPRECATED
 
 #[deprecated = "Use `FloatMath::abs_sub`"]
@@ -764,8 +751,9 @@ mod tests {
 
     #[test]
     fn test_pow() {
-        fn naive_pow<T: One + Mul<T, T>>(base: T, exp: uint) -> T {
-            range(0, exp).fold(one::<T>(), |acc, _| acc * base)
+        fn naive_pow<T: Int>(base: T, exp: uint) -> T {
+            let one: T = Int::one();
+            range(0, exp).fold(one, |acc, _| acc * base)
         }
         macro_rules! assert_pow(
             (($num:expr, $exp:expr) => $expected:expr) => {{
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index fff31b332e1..d1a89d72621 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -13,12 +13,8 @@
 #![allow(missing_docs)]
 
 use char;
-use char::Char;
-use from_str::from_str;
-use iter::Iterator;
 use num;
 use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive};
-use option::{None, Option, Some};
 use slice::{SlicePrelude, CloneSliceAllocPrelude};
 use str::StrPrelude;
 use string::String;
@@ -425,242 +421,35 @@ pub fn float_to_str_common<T: Float>(
 static DIGIT_P_RADIX: uint = ('p' as uint) - ('a' as uint) + 11u;
 static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
 
-pub fn from_str_radix_float<T: Float>(src: &str, radix: uint) -> Option<T> {
-   assert!(radix >= 2 && radix <= 36,
-           "from_str_radix_float: must lie in the range `[2, 36]` - found {}",
-           radix);
-
-    let _0: T = Float::zero();
-    let _1: T = Float::one();
-    let radix_t: T = num::cast(radix as int).unwrap();
-
-    // Special values
-    match src {
-        "inf"   => return Some(Float::infinity()),
-        "-inf"  => return Some(Float::neg_infinity()),
-        "NaN"   => return Some(Float::nan()),
-        _       => {},
-    }
-
-    let (is_positive, src) =  match src.slice_shift_char() {
-        (None, _)        => return None,
-        (Some('-'), "")  => return None,
-        (Some('-'), src) => (false, src),
-        (Some(_), _)     => (true,  src),
-    };
-
-    // The significand to accumulate
-    let mut sig = if is_positive { _0 } else { -_0 };
-    // Necessary to detect overflow
-    let mut prev_sig = sig;
-    let mut cs = src.chars().enumerate();
-    // Exponent prefix and exponent index offset
-    let mut exp_info = None::<(char, uint)>;
-
-    // Parse the integer part of the significand
-    for (i, c) in cs {
-        match c.to_digit(radix) {
-            Some(digit) => {
-                // shift significand one digit left
-                sig = sig * radix_t;
-
-                // add/subtract current digit depending on sign
-                if is_positive {
-                    sig = sig + num::cast(digit as int).unwrap();
-                } else {
-                    sig = sig - num::cast(digit as int).unwrap();
-                }
-
-                // Detect overflow by comparing to last value, except
-                // if we've not seen any non-zero digits.
-                if prev_sig != _0 {
-                    if is_positive && sig <= prev_sig
-                        { return Some(Float::infinity()); }
-                    if !is_positive && sig >= prev_sig
-                        { return Some(Float::neg_infinity()); }
-
-                    // Detect overflow by reversing the shift-and-add process
-                    let digit: T = num::cast(digit as int).unwrap();
-                    if is_positive && (prev_sig != ((sig - digit) / radix_t))
-                        { return Some(Float::infinity()); }
-                    if !is_positive && (prev_sig != ((sig + digit) / radix_t))
-                        { return Some(Float::neg_infinity()); }
-                }
-                prev_sig = sig;
-            },
-            None => match c {
-                'e' | 'E' | 'p' | 'P' => {
-                    exp_info = Some((c, i + 1));
-                    break;  // start of exponent
-                },
-                '.' => {
-                    break;  // start of fractional part
-                },
-                _ => {
-                    return None;
-                },
-            },
-        }
-    }
-
-    // If we are not yet at the exponent parse the fractional
-    // part of the significand
-    if exp_info.is_none() {
-        let mut power = _1;
-        for (i, c) in cs {
-            match c.to_digit(radix) {
-                Some(digit) => {
-                    let digit: T = num::cast(digit).unwrap();
-                    // Decrease power one order of magnitude
-                    power = power / radix_t;
-                    // add/subtract current digit depending on sign
-                    sig = if is_positive {
-                        sig + digit * power
-                    } else {
-                        sig - digit * power
-                    };
-                    // Detect overflow by comparing to last value
-                    if is_positive && sig < prev_sig
-                        { return Some(Float::infinity()); }
-                    if !is_positive && sig > prev_sig
-                        { return Some(Float::neg_infinity()); }
-                    prev_sig = sig;
-                },
-                None => match c {
-                    'e' | 'E' | 'p' | 'P' => {
-                        exp_info = Some((c, i + 1));
-                        break; // start of exponent
-                    },
-                    _ => {
-                        return None; // invalid number
-                    },
-                },
-            }
-        }
-    }
-
-    // Parse and calculate the exponent
-    let exp = match exp_info {
-        Some((c, offset)) => {
-            let base: T = match c {
-                'E' | 'e' if radix == 10 => num::cast(10u).unwrap(),
-                'P' | 'p' if radix == 16 => num::cast(2u).unwrap(),
-                _ => return None,
-            };
-
-            // Parse the exponent as decimal integer
-            let src = src[offset..];
-            let (is_positive, exp) = match src.slice_shift_char() {
-                (Some('-'), src) => (false, from_str::<uint>(src)),
-                (Some('+'), src) => (true,  from_str::<uint>(src)),
-                (Some(_), _)     => (true,  from_str::<uint>(src)),
-                (None, _)        => return None,
-            };
-
-            match (is_positive, exp) {
-                (true,  Some(exp)) => base.powi(exp as i32),
-                (false, Some(exp)) => _1 / base.powi(exp as i32),
-                (_, None)          => return None,
-            }
-        },
-        None => _1, // no exponent
-    };
+#[cfg(test)]
+mod tests {
+    use string::ToString;
 
-    Some(sig * exp)
-}
+    #[test]
+    fn test_int_to_str_overflow() {
+        let mut i8_val: i8 = 127_i8;
+        assert_eq!(i8_val.to_string(), "127".to_string());
 
-pub fn from_str_radix_int<T: Int>(src: &str, radix: uint) -> Option<T> {
-   assert!(radix >= 2 && radix <= 36,
-           "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
-           radix);
+        i8_val += 1 as i8;
+        assert_eq!(i8_val.to_string(), "-128".to_string());
 
-    fn cast<T: Int>(x: uint) -> T {
-        num::cast(x).unwrap()
-    }
+        let mut i16_val: i16 = 32_767_i16;
+        assert_eq!(i16_val.to_string(), "32767".to_string());
 
-    let _0: T = Int::zero();
-    let _1: T = Int::one();
-    let is_signed = _0 > Int::min_value();
+        i16_val += 1 as i16;
+        assert_eq!(i16_val.to_string(), "-32768".to_string());
 
-    let (is_positive, src) =  match src.slice_shift_char() {
-        (Some('-'), src) if is_signed => (false, src),
-        (Some(_), _) => (true, src),
-        (None, _) => return None,
-    };
+        let mut i32_val: i32 = 2_147_483_647_i32;
+        assert_eq!(i32_val.to_string(), "2147483647".to_string());
 
-    let mut xs = src.chars().map(|c| {
-        c.to_digit(radix).map(cast)
-    });
-    let radix = cast(radix);
-    let mut result = _0;
-
-    if is_positive {
-        for x in xs {
-            let x = match x {
-                Some(x) => x,
-                None => return None,
-            };
-            result = match result.checked_mul(radix) {
-                Some(result) => result,
-                None => return None,
-            };
-            result = match result.checked_add(x) {
-                Some(result) => result,
-                None => return None,
-            };
-        }
-    } else {
-        for x in xs {
-            let x = match x {
-                Some(x) => x,
-                None => return None,
-            };
-            result = match result.checked_mul(radix) {
-                Some(result) => result,
-                None => return None,
-            };
-            result = match result.checked_sub(x) {
-                Some(result) => result,
-                None => return None,
-            };
-        }
-    }
+        i32_val += 1 as i32;
+        assert_eq!(i32_val.to_string(), "-2147483648".to_string());
 
-    Some(result)
-}
+        let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
+        assert_eq!(i64_val.to_string(), "9223372036854775807".to_string());
 
-#[cfg(test)]
-mod test {
-    use super::*;
-    use option::*;
-    use num::Float;
-
-    #[test]
-    fn from_str_issue7588() {
-        let u : Option<u8> = from_str_radix_int("1000", 10);
-        assert_eq!(u, None);
-        let s : Option<i16> = from_str_radix_int("80000", 10);
-        assert_eq!(s, None);
-        let f : Option<f32> = from_str_radix_float("10000000000000000000000000000000000000000", 10);
-        assert_eq!(f, Some(Float::infinity()))
-        let fe : Option<f32> = from_str_radix_float("1e40", 10);
-        assert_eq!(fe, Some(Float::infinity()))
-    }
-
-    #[test]
-    fn test_from_str_radix_float() {
-        let x1 : Option<f64> = from_str_radix_float("-123.456", 10);
-        assert_eq!(x1, Some(-123.456));
-        let x2 : Option<f32> = from_str_radix_float("123.456", 10);
-        assert_eq!(x2, Some(123.456));
-        let x3 : Option<f32> = from_str_radix_float("-0.0", 10);
-        assert_eq!(x3, Some(-0.0));
-        let x4 : Option<f32> = from_str_radix_float("0.0", 10);
-        assert_eq!(x4, Some(0.0));
-        let x4 : Option<f32> = from_str_radix_float("1.0", 10);
-        assert_eq!(x4, Some(1.0));
-        let x5 : Option<f32> = from_str_radix_float("-1.0", 10);
-        assert_eq!(x5, Some(-1.0));
+        i64_val += 1 as i64;
+        assert_eq!(i64_val.to_string(), "-9223372036854775808".to_string());
     }
 }
 
diff --git a/src/libstd/num/u16.rs b/src/libstd/num/u16.rs
index bb619b5b2f5..246224ddb2b 100644
--- a/src/libstd/num/u16.rs
+++ b/src/libstd/num/u16.rs
@@ -13,11 +13,6 @@
 #![unstable]
 #![doc(primitive = "u16")]
 
-use from_str::FromStr;
-use num::FromStrRadix;
-use num::strconv;
-use option::Option;
-
 pub use core::u16::{BITS, BYTES, MIN, MAX};
 
 uint_module!(u16)
diff --git a/src/libstd/num/u32.rs b/src/libstd/num/u32.rs
index 754103ba5da..143b45010c2 100644
--- a/src/libstd/num/u32.rs
+++ b/src/libstd/num/u32.rs
@@ -13,11 +13,6 @@
 #![unstable]
 #![doc(primitive = "u32")]
 
-use from_str::FromStr;
-use num::FromStrRadix;
-use num::strconv;
-use option::Option;
-
 pub use core::u32::{BITS, BYTES, MIN, MAX};
 
 uint_module!(u32)
diff --git a/src/libstd/num/u64.rs b/src/libstd/num/u64.rs
index da497d2cbe4..92c5380f980 100644
--- a/src/libstd/num/u64.rs
+++ b/src/libstd/num/u64.rs
@@ -13,11 +13,6 @@
 #![unstable]
 #![doc(primitive = "u64")]
 
-use from_str::FromStr;
-use num::FromStrRadix;
-use num::strconv;
-use option::Option;
-
 pub use core::u64::{BITS, BYTES, MIN, MAX};
 
 uint_module!(u64)
diff --git a/src/libstd/num/u8.rs b/src/libstd/num/u8.rs
index bdfcdb2c5a5..faa6d167065 100644
--- a/src/libstd/num/u8.rs
+++ b/src/libstd/num/u8.rs
@@ -13,11 +13,6 @@
 #![unstable]
 #![doc(primitive = "u8")]
 
-use from_str::FromStr;
-use num::FromStrRadix;
-use num::strconv;
-use option::Option;
-
 pub use core::u8::{BITS, BYTES, MIN, MAX};
 
 uint_module!(u8)
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs
index 5090219d3de..a425aab3aa1 100644
--- a/src/libstd/num/uint.rs
+++ b/src/libstd/num/uint.rs
@@ -13,11 +13,6 @@
 #![unstable]
 #![doc(primitive = "uint")]
 
-use from_str::FromStr;
-use num::FromStrRadix;
-use num::strconv;
-use option::Option;
-
 pub use core::uint::{BITS, BYTES, MIN, MAX};
 
 uint_module!(uint)
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index aa8e58bab02..ef9e809ed2b 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -15,22 +15,6 @@
 
 macro_rules! uint_module (($T:ty) => (
 
-#[experimental = "might need to return Result"]
-impl FromStr for $T {
-    #[inline]
-    fn from_str(s: &str) -> Option<$T> {
-        strconv::from_str_radix_int(s, 10)
-    }
-}
-
-#[experimental = "might need to return Result"]
-impl FromStrRadix for $T {
-    #[inline]
-    fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
-        strconv::from_str_radix_int(s, radix)
-    }
-}
-
 // String conversion functions and impl num -> str
 
 /// Convert to a string as a byte slice in a given base.
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 1402d3a3559..23e57a028de 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -51,8 +51,7 @@ use result::{Err, Ok, Result};
 use slice::{AsSlice, SlicePrelude, PartialEqSlicePrelude};
 use slice::CloneSliceAllocPrelude;
 use str::{Str, StrPrelude, StrAllocating};
-use string::String;
-use to_string::ToString;
+use string::{String, ToString};
 use sync::atomic::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
 use vec::Vec;
 
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index 794f6978642..e2ff824a7c9 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -13,12 +13,11 @@
 use c_str::{CString, ToCStr};
 use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
-use from_str::FromStr;
 use hash;
 use io::Writer;
 use iter::{DoubleEndedIterator, AdditiveIterator, Extend, Iterator, Map};
 use option::{Option, None, Some};
-use str::Str;
+use str::{FromStr, Str};
 use str;
 use slice::{CloneSliceAllocPrelude, Splits, AsSlice, VectorVector,
             PartialEqSlicePrelude, SlicePrelude};
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index 2da2159653e..b8016e3e8f4 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -16,14 +16,13 @@ use ascii::AsciiCast;
 use c_str::{CString, ToCStr};
 use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
-use from_str::FromStr;
 use hash;
 use io::Writer;
 use iter::{AdditiveIterator, DoubleEndedIterator, Extend, Iterator, Map};
 use mem;
 use option::{Option, Some, None};
 use slice::{AsSlice, SlicePrelude};
-use str::{CharSplits, Str, StrAllocating, StrVector, StrPrelude};
+use str::{CharSplits, FromStr, Str, StrAllocating, StrVector, StrPrelude};
 use string::String;
 use unicode::char::UnicodeChar;
 use vec::Vec;
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index e9793ea65ad..a9e99940c46 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -50,9 +50,9 @@
 #[doc(no_inline)] pub use ops::{Fn, FnMut, FnOnce};
 
 // Reexported functions
-#[doc(no_inline)] pub use from_str::from_str;
 #[doc(no_inline)] pub use iter::{range, repeat};
 #[doc(no_inline)] pub use mem::drop;
+#[doc(no_inline)] pub use str::from_str;
 
 // Reexported types and traits
 
@@ -76,14 +76,13 @@
 #[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek, BufferPrelude};
 #[doc(no_inline)] pub use str::{Str, StrVector, StrPrelude};
 #[doc(no_inline)] pub use str::{IntoMaybeOwned, StrAllocating, UnicodeStrPrelude};
-#[doc(no_inline)] pub use to_string::{ToString, IntoStr};
 #[doc(no_inline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
 #[doc(no_inline)] pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
 #[doc(no_inline)] pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
 #[doc(no_inline)] pub use slice::{SlicePrelude, AsSlice, CloneSlicePrelude};
 #[doc(no_inline)] pub use slice::{VectorVector, PartialEqSlicePrelude, OrdSlicePrelude};
 #[doc(no_inline)] pub use slice::{CloneSliceAllocPrelude, OrdSliceAllocPrelude, SliceAllocPrelude};
-#[doc(no_inline)] pub use string::String;
+#[doc(no_inline)] pub use string::{IntoString, String, ToString};
 #[doc(no_inline)] pub use vec::Vec;
 
 // Reexported runtime types
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index b08b92b8587..8b457d1639d 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -12,13 +12,12 @@
 
 #![allow(non_camel_case_types)]
 
-use from_str::from_str;
 use io::{IoResult, Writer};
 use iter::Iterator;
 use option::{Some, None};
 use os;
 use result::{Ok, Err};
-use str::StrPrelude;
+use str::{StrPrelude, from_str};
 use sync::atomic;
 use unicode::char::UnicodeChar;
 
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 56f2dbf667a..92657d1b59b 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -8,12 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use from_str::FromStr;
-use from_str::from_str;
 use libc::uintptr_t;
 use option::{Some, None, Option};
 use os;
-use str::Str;
+use str::{FromStr, from_str, Str};
 use sync::atomic;
 
 /// Dynamically inquire about whether we're running under V.
diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs
index d4a60fb5844..4ae5cd054f6 100644
--- a/src/libstd/sync/task_pool.rs
+++ b/src/libstd/sync/task_pool.rs
@@ -1,4 +1,4 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -12,91 +12,195 @@
 
 use core::prelude::*;
 
-use task;
 use task::spawn;
-use vec::Vec;
-use comm::{channel, Sender};
+use comm::{channel, Sender, Receiver};
+use sync::{Arc, Mutex};
 
-enum Msg<T> {
-    Execute(proc(&T):Send),
-    Quit
+struct Sentinel<'a> {
+    jobs: &'a Arc<Mutex<Receiver<proc(): Send>>>,
+    active: bool
 }
 
-/// A task pool used to execute functions in parallel.
-pub struct TaskPool<T> {
-    channels: Vec<Sender<Msg<T>>>,
-    next_index: uint,
+impl<'a> Sentinel<'a> {
+    fn new(jobs: &Arc<Mutex<Receiver<proc(): Send>>>) -> Sentinel {
+        Sentinel {
+            jobs: jobs,
+            active: true
+        }
+    }
+
+    // Cancel and destroy this sentinel.
+    fn cancel(mut self) {
+        self.active = false;
+    }
 }
 
 #[unsafe_destructor]
-impl<T> Drop for TaskPool<T> {
+impl<'a> Drop for Sentinel<'a> {
     fn drop(&mut self) {
-        for channel in self.channels.iter_mut() {
-            channel.send(Quit);
+        if self.active {
+            spawn_in_pool(self.jobs.clone())
         }
     }
 }
 
-impl<T> TaskPool<T> {
-    /// Spawns a new task pool with `n_tasks` tasks. The provided
-    /// `init_fn_factory` returns a function which, given the index of the
-    /// task, should return local data to be kept around in that task.
+/// A task pool used to execute functions in parallel.
+///
+/// Spawns `n` worker tasks and replenishes the pool if any worker tasks
+/// panic.
+///
+/// # Example
+///
+/// ```rust
+/// # use std::sync::TaskPool;
+/// # use std::iter::AdditiveIterator;
+///
+/// let pool = TaskPool::new(4u);
+///
+/// let (tx, rx) = channel();
+/// for _ in range(0, 8u) {
+///     let tx = tx.clone();
+///     pool.execute(proc() {
+///         tx.send(1u);
+///     });
+/// }
+///
+/// assert_eq!(rx.iter().take(8u).sum(), 8u);
+/// ```
+pub struct TaskPool {
+    // How the taskpool communicates with subtasks.
+    //
+    // This is the only such Sender, so when it is dropped all subtasks will
+    // quit.
+    jobs: Sender<proc(): Send>
+}
+
+impl TaskPool {
+    /// Spawns a new task pool with `tasks` tasks.
     ///
     /// # Panics
     ///
-    /// This function will panic if `n_tasks` is less than 1.
-    pub fn new(n_tasks: uint,
-               init_fn_factory: || -> proc(uint):Send -> T)
-               -> TaskPool<T> {
-        assert!(n_tasks >= 1);
-
-        let channels = Vec::from_fn(n_tasks, |i| {
-            let (tx, rx) = channel::<Msg<T>>();
-            let init_fn = init_fn_factory();
-
-            let task_body = proc() {
-                let local_data = init_fn(i);
-                loop {
-                    match rx.recv() {
-                        Execute(f) => f(&local_data),
-                        Quit => break
-                    }
-                }
-            };
+    /// This function will panic if `tasks` is 0.
+    pub fn new(tasks: uint) -> TaskPool {
+        assert!(tasks >= 1);
 
-            // Run on this scheduler.
-            task::spawn(task_body);
+        let (tx, rx) = channel::<proc(): Send>();
+        let rx = Arc::new(Mutex::new(rx));
 
-            tx
-        });
+        // Taskpool tasks.
+        for _ in range(0, tasks) {
+            spawn_in_pool(rx.clone());
+        }
 
-        return TaskPool {
-            channels: channels,
-            next_index: 0,
-        };
+        TaskPool { jobs: tx }
     }
 
-    /// Executes the function `f` on a task in the pool. The function
-    /// receives a reference to the local data returned by the `init_fn`.
-    pub fn execute(&mut self, f: proc(&T):Send) {
-        self.channels[self.next_index].send(Execute(f));
-        self.next_index += 1;
-        if self.next_index == self.channels.len() { self.next_index = 0; }
+    /// Executes the function `job` on a task in the pool.
+    pub fn execute(&self, job: proc():Send) {
+        self.jobs.send(job);
     }
 }
 
-#[test]
-fn test_task_pool() {
-    let f: || -> proc(uint):Send -> uint = || { proc(i) i };
-    let mut pool = TaskPool::new(4, f);
-    for _ in range(0u, 8) {
-        pool.execute(proc(i) println!("Hello from thread {}!", *i));
-    }
+fn spawn_in_pool(jobs: Arc<Mutex<Receiver<proc(): Send>>>) {
+    spawn(proc() {
+        // Will spawn a new task on panic unless it is cancelled.
+        let sentinel = Sentinel::new(&jobs);
+
+        loop {
+            let message = {
+                // Only lock jobs for the time it takes
+                // to get a job, not run it.
+                let lock = jobs.lock();
+                lock.recv_opt()
+            };
+
+            match message {
+                Ok(job) => job(),
+
+                // The Taskpool was dropped.
+                Err(..) => break
+            }
+        }
+
+        sentinel.cancel();
+    })
 }
 
-#[test]
-#[should_fail]
-fn test_zero_tasks_panic() {
-    let f: || -> proc(uint):Send -> uint = || { proc(i) i };
-    TaskPool::new(0, f);
+#[cfg(test)]
+mod test {
+    use core::prelude::*;
+    use super::*;
+    use comm::channel;
+    use iter::range;
+
+    const TEST_TASKS: uint = 4u;
+
+    #[test]
+    fn test_works() {
+        use iter::AdditiveIterator;
+
+        let pool = TaskPool::new(TEST_TASKS);
+
+        let (tx, rx) = channel();
+        for _ in range(0, TEST_TASKS) {
+            let tx = tx.clone();
+            pool.execute(proc() {
+                tx.send(1u);
+            });
+        }
+
+        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_zero_tasks_panic() {
+        TaskPool::new(0);
+    }
+
+    #[test]
+    fn test_recovery_from_subtask_panic() {
+        use iter::AdditiveIterator;
+
+        let pool = TaskPool::new(TEST_TASKS);
+
+        // Panic all the existing tasks.
+        for _ in range(0, TEST_TASKS) {
+            pool.execute(proc() { panic!() });
+        }
+
+        // Ensure new tasks were spawned to compensate.
+        let (tx, rx) = channel();
+        for _ in range(0, TEST_TASKS) {
+            let tx = tx.clone();
+            pool.execute(proc() {
+                tx.send(1u);
+            });
+        }
+
+        assert_eq!(rx.iter().take(TEST_TASKS).sum(), TEST_TASKS);
+    }
+
+    #[test]
+    fn test_should_not_panic_on_drop_if_subtasks_panic_after_drop() {
+        use sync::{Arc, Barrier};
+
+        let pool = TaskPool::new(TEST_TASKS);
+        let waiter = Arc::new(Barrier::new(TEST_TASKS + 1));
+
+        // Panic all the existing tasks in a bit.
+        for _ in range(0, TEST_TASKS) {
+            let waiter = waiter.clone();
+            pool.execute(proc() {
+                waiter.wait();
+                panic!();
+            });
+        }
+
+        drop(pool);
+
+        // Kick off the failure.
+        waiter.wait();
+    }
 }
+
diff --git a/src/libstd/task.rs b/src/libstd/task.rs
index f0bb8a0f4bc..c7e31dae3d4 100644
--- a/src/libstd/task.rs
+++ b/src/libstd/task.rs
@@ -105,9 +105,8 @@ use rt::local::Local;
 use rt::task;
 use rt::task::Task;
 use str::{Str, SendStr, IntoMaybeOwned};
-use string::String;
+use string::{String, ToString};
 use sync::Future;
-use to_string::ToString;
 
 /// A means of spawning a task
 pub trait Spawner {
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 5c4e8bda84c..83340c9faac 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -388,7 +388,7 @@ mod tests {
     use super::{Duration, MIN, MAX};
     use {i32, i64};
     use option::{Some, None};
-    use to_string::ToString;
+    use string::ToString;
 
     #[test]
     fn test_duration() {
diff --git a/src/libstd/to_string.rs b/src/libstd/to_string.rs
deleted file mode 100644
index c19fd81b570..00000000000
--- a/src/libstd/to_string.rs
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2012-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.
-
-/*!
-
-The `ToString` trait for converting to strings
-
-*/
-
-#![experimental]
-
-use fmt;
-use string::String;
-
-/// A generic trait for converting a value to a string
-pub trait ToString {
-    /// Converts the value of `self` to an owned string
-    fn to_string(&self) -> String;
-}
-
-/// Trait for converting a type to a string, consuming it in the process.
-pub trait IntoStr {
-    /// Consume and convert to a string.
-    fn into_string(self) -> String;
-}
-
-impl<T: fmt::Show> ToString for T {
-    fn to_string(&self) -> String {
-        format!("{}", *self)
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use super::*;
-
-    #[test]
-    fn test_simple_types() {
-        assert_eq!(1i.to_string(), "1".to_string());
-        assert_eq!((-1i).to_string(), "-1".to_string());
-        assert_eq!(200u.to_string(), "200".to_string());
-        assert_eq!(2u8.to_string(), "2".to_string());
-        assert_eq!(true.to_string(), "true".to_string());
-        assert_eq!(false.to_string(), "false".to_string());
-        assert_eq!(().to_string(), "()".to_string());
-        assert_eq!(("hi".to_string()).to_string(), "hi".to_string());
-    }
-
-    #[test]
-    fn test_vectors() {
-        let x: Vec<int> = vec![];
-        assert_eq!(x.to_string(), "[]".to_string());
-        assert_eq!((vec![1i]).to_string(), "[1]".to_string());
-        assert_eq!((vec![1i, 2, 3]).to_string(), "[1, 2, 3]".to_string());
-        assert!((vec![vec![], vec![1i], vec![1i, 1]]).to_string() ==
-               "[[], [1], [1, 1]]".to_string());
-    }
-}
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 103253560df..69eb260b8c4 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -22,19 +22,23 @@
 //! would generate two implementations like:
 //!
 //! ```ignore
-//! impl<S:serialize::Encoder> Encodable<S> for Node {
-//!     fn encode(&self, s: &S) {
-//!         s.emit_struct("Node", 1, || {
-//!             s.emit_field("id", 0, || s.emit_uint(self.id))
+//! impl<S: Encoder<E>, E> Encodable<S, E> for Node {
+//!     fn encode(&self, s: &mut S) -> Result<(), E> {
+//!         s.emit_struct("Node", 1, |this| {
+//!             this.emit_struct_field("id", 0, |this| {
+//!                 Encodable::encode(&self.id, this)
+//!                 /* this.emit_uint(self.id) can also be used */
+//!             })
 //!         })
 //!     }
 //! }
 //!
-//! impl<D:Decoder> Decodable for node_id {
-//!     fn decode(d: &D) -> Node {
-//!         d.read_struct("Node", 1, || {
-//!             Node {
-//!                 id: d.read_field("x".to_string(), 0, || decode(d))
+//! impl<D: Decoder<E>, E> Decodable<D, E> for Node {
+//!     fn decode(d: &mut D) -> Result<Node, E> {
+//!         d.read_struct("Node", 1, |this| {
+//!             match this.read_struct_field("id", 0, |this| Decodable::decode(this)) {
+//!                 Ok(id) => Ok(Node { id: id }),
+//!                 Err(e) => Err(e),
 //!             }
 //!         })
 //!     }
@@ -46,37 +50,42 @@
 //!
 //! ```ignore
 //! #[deriving(Encodable, Decodable)]
-//! struct spanned<T> { node: T, span: Span }
+//! struct Spanned<T> { node: T, span: Span }
 //! ```
 //!
 //! would yield functions like:
 //!
 //! ```ignore
-//!     impl<
-//!         S: Encoder,
-//!         T: Encodable<S>
-//!     > spanned<T>: Encodable<S> {
-//!         fn encode<S:Encoder>(s: &S) {
-//!             s.emit_rec(|| {
-//!                 s.emit_field("node", 0, || self.node.encode(s));
-//!                 s.emit_field("span", 1, || self.span.encode(s));
-//!             })
-//!         }
+//! impl<
+//!     S: Encoder<E>,
+//!     E,
+//!     T: Encodable<S, E>
+//! > Encodable<S, E> for Spanned<T> {
+//!     fn encode(&self, s: &mut S) -> Result<(), E> {
+//!         s.emit_struct("Spanned", 2, |this| {
+//!             this.emit_struct_field("node", 0, |this| self.node.encode(this))
+//!                 .ok().unwrap();
+//!             this.emit_struct_field("span", 1, |this| self.span.encode(this))
+//!         })
 //!     }
+//! }
 //!
-//!     impl<
-//!         D: Decoder,
-//!         T: Decodable<D>
-//!     > spanned<T>: Decodable<D> {
-//!         fn decode(d: &D) -> spanned<T> {
-//!             d.read_rec(|| {
-//!                 {
-//!                     node: d.read_field("node".to_string(), 0, || decode(d)),
-//!                     span: d.read_field("span".to_string(), 1, || decode(d)),
-//!                 }
+//! impl<
+//!     D: Decoder<E>,
+//!     E,
+//!     T: Decodable<D, E>
+//! > Decodable<D, E> for Spanned<T> {
+//!     fn decode(d: &mut D) -> Result<Spanned<T>, E> {
+//!         d.read_struct("Spanned", 2, |this| {
+//!             Ok(Spanned {
+//!                 node: this.read_struct_field("node", 0, |this| Decodable::decode(this))
+//!                     .ok().unwrap(),
+//!                 span: this.read_struct_field("span", 1, |this| Decodable::decode(this))
+//!                     .ok().unwrap(),
 //!             })
-//!         }
+//!         })
 //!     }
+//! }
 //! ```
 
 use ast::{MetaItem, Item, Expr, ExprRet, MutMutable, LitNil};
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 986f90389e7..ff96f806fac 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -53,13 +53,13 @@ use std::cmp;
 use std::f64;
 use std::fmt::Show;
 use std::fmt;
-use std::from_str::FromStr;
 use std::io::fs::PathExtensions;
 use std::io::stdio::StdWriter;
 use std::io::{File, ChanReader, ChanWriter};
 use std::io;
 use std::num::{Float, FloatMath, Int};
 use std::os;
+use std::str::FromStr;
 use std::string::String;
 use std::task::TaskBuilder;
 use std::time::Duration;
diff --git a/src/test/run-make/codegen-options-parsing/Makefile b/src/test/run-make/codegen-options-parsing/Makefile
new file mode 100644
index 00000000000..e439b27a190
--- /dev/null
+++ b/src/test/run-make/codegen-options-parsing/Makefile
@@ -0,0 +1,24 @@
+-include ../tools.mk
+
+all:
+	#Option taking a number
+	$(RUSTC) -C codegen-units dummy.rs 2>&1 | \
+		grep 'codegen option `codegen-units` requires a number'
+	$(RUSTC) -C codegen-units= dummy.rs 2>&1 | \
+		grep 'incorrect value `` for codegen option `codegen-units` - a number was expected'
+	$(RUSTC) -C codegen-units=foo dummy.rs 2>&1 | \
+		grep 'incorrect value `foo` for codegen option `codegen-units` - a number was expected'
+	$(RUSTC) -C codegen-units=1 dummy.rs
+	#Option taking a string
+	$(RUSTC) -C extra-filename dummy.rs 2>&1 | \
+		grep 'codegen option `extra-filename` requires a string'
+	$(RUSTC) -C extra-filename= dummy.rs 2>&1
+	$(RUSTC) -C extra-filename=foo dummy.rs 2>&1
+	#Option taking no argument
+	$(RUSTC) -C lto= dummy.rs 2>&1 | \
+		grep 'codegen option `lto` takes no value'
+	$(RUSTC) -C lto=1 dummy.rs 2>&1 | \
+		grep 'codegen option `lto` takes no value'
+	$(RUSTC) -C lto=foo dummy.rs 2>&1 | \
+		grep 'codegen option `lto` takes no value'
+	$(RUSTC) -C lto dummy.rs
diff --git a/src/test/run-make/codegen-options-parsing/dummy.rs b/src/test/run-make/codegen-options-parsing/dummy.rs
new file mode 100644
index 00000000000..8ae3d072362
--- /dev/null
+++ b/src/test/run-make/codegen-options-parsing/dummy.rs
@@ -0,0 +1,11 @@
+// Copyright 2014 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.
+
+fn main() {}
diff --git a/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs b/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs
index cfee1a81231..a041bbfe8ad 100644
--- a/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs
+++ b/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs
@@ -11,7 +11,7 @@
 // aux-build:cci_class_cast.rs
 extern crate cci_class_cast;
 
-use std::to_string::ToString;
+use std::string::ToString;
 use cci_class_cast::kitty::cat;
 
 fn print_out(thing: Box<ToString>, expected: String) {
diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs
index c52f9458f99..0d881419847 100644
--- a/src/test/run-pass/send_str_treemap.rs
+++ b/src/test/run-pass/send_str_treemap.rs
@@ -11,7 +11,7 @@
 extern crate collections;
 
 use std::str::{SendStr, Owned, Slice};
-use std::to_string::ToString;
+use std::string::ToString;
 use self::collections::TreeMap;
 use std::option::Some;