about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-30 12:03:20 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-30 12:03:20 -0800
commitac1a03d7422ba52749e4e513a46c8d2129c2c817 (patch)
treecefa26a551d7703c5f8534cc6661432348c93e06
parent0ba812fbf00e3026b29282e1a72d58ea7959833e (diff)
parent0cdde6e5e015ee6f6d9381ab624a312af7c9b069 (diff)
downloadrust-ac1a03d7422ba52749e4e513a46c8d2129c2c817.tar.gz
rust-ac1a03d7422ba52749e4e513a46c8d2129c2c817.zip
rollup merge of #21718: alexcrichton/stabilize-from-str
This commits adds an associated type to the `FromStr` trait representing an
error payload for parses which do not succeed. The previous return value,
`Option<Self>` did not allow for this form of payload. After the associated type
was added, the following attributes were applied:

* `FromStr` is now stable
* `FromStr::Err` is now stable
* `FromStr::from_str` is now stable
* `StrExt::parse` is now stable
* `FromStr for bool` is now stable
* `FromStr for $float` is now stable
* `FromStr for $integral` is now stable
* Errors returned from stable `FromStr` implementations are stable
* Errors implement `Display` and `Error` (both impl blocks being `#[stable]`)

Closes #15138
-rw-r--r--src/compiletest/common.rs21
-rw-r--r--src/compiletest/compiletest.rs5
-rw-r--r--src/compiletest/header.rs6
-rw-r--r--src/doc/reference.md2
-rw-r--r--src/doc/trpl/guessing-game.md24
-rw-r--r--src/libcollections/str.rs10
-rw-r--r--src/libcollections/string.rs8
-rw-r--r--src/libcore/num/mod.rs174
-rw-r--r--src/libcore/option.rs4
-rw-r--r--src/libcore/str/mod.rs53
-rw-r--r--src/libcoretest/num/int_macros.rs42
-rw-r--r--src/libcoretest/num/mod.rs52
-rw-r--r--src/libcoretest/str.rs6
-rw-r--r--src/liblog/directive.rs2
-rw-r--r--src/librustc/lint/builtin.rs2
-rw-r--r--src/librustc/metadata/decoder.rs2
-rw-r--r--src/librustc/metadata/tydecode.rs8
-rw-r--r--src/librustc/middle/infer/region_inference/graphviz.rs2
-rw-r--r--src/librustc/middle/recursion_limit.rs3
-rw-r--r--src/librustc/session/config.rs4
-rw-r--r--src/librustc_driver/pretty.rs14
-rw-r--r--src/libserialize/json.rs9
-rw-r--r--src/libstd/num/uint_macros.rs20
-rw-r--r--src/libstd/old_io/net/ip.rs108
-rw-r--r--src/libstd/path/posix.rs13
-rw-r--r--src/libstd/path/windows.rs13
-rw-r--r--src/libstd/rt/util.rs4
-rw-r--r--src/libsyntax/parse/lexer/mod.rs4
-rw-r--r--src/libsyntax/parse/mod.rs8
-rw-r--r--src/libsyntax/parse/parser.rs4
-rw-r--r--src/libsyntax/show_span.rs9
-rw-r--r--src/libtest/lib.rs3
-rw-r--r--src/test/auxiliary/static-methods-crate.rs2
-rw-r--r--src/test/bench/shootout-chameneos-redux.rs2
-rw-r--r--src/test/bench/shootout-fannkuch-redux.rs2
-rw-r--r--src/test/bench/shootout-nbody.rs2
-rw-r--r--src/test/bench/shootout-threadring.rs4
-rw-r--r--src/test/run-pass/match-with-ret-arm.rs2
-rw-r--r--src/test/run-pass/wait-forked-but-failed-child.rs2
39 files changed, 392 insertions, 263 deletions
diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs
index b1deb8a36ad..df2981a6c83 100644
--- a/src/compiletest/common.rs
+++ b/src/compiletest/common.rs
@@ -25,17 +25,18 @@ pub enum Mode {
 }
 
 impl FromStr for Mode {
-    fn from_str(s: &str) -> Option<Mode> {
+    type Err = ();
+    fn from_str(s: &str) -> Result<Mode, ()> {
         match s {
-          "compile-fail" => Some(CompileFail),
-          "run-fail" => Some(RunFail),
-          "run-pass" => Some(RunPass),
-          "run-pass-valgrind" => Some(RunPassValgrind),
-          "pretty" => Some(Pretty),
-          "debuginfo-lldb" => Some(DebugInfoLldb),
-          "debuginfo-gdb" => Some(DebugInfoGdb),
-          "codegen" => Some(Codegen),
-          _ => None,
+          "compile-fail" => Ok(CompileFail),
+          "run-fail" => Ok(RunFail),
+          "run-pass" => Ok(RunPass),
+          "run-pass-valgrind" => Ok(RunPassValgrind),
+          "pretty" => Ok(Pretty),
+          "debuginfo-lldb" => Ok(DebugInfoLldb),
+          "debuginfo-gdb" => Ok(DebugInfoGdb),
+          "codegen" => Ok(Codegen),
+          _ => Err(()),
         }
     }
 }
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index 357ccec7cf3..ea733c84a97 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -35,7 +35,6 @@ extern crate log;
 use std::os;
 use std::old_io;
 use std::old_io::fs;
-use std::str::FromStr;
 use std::thunk::Thunk;
 use getopts::{optopt, optflag, reqopt};
 use common::Config;
@@ -140,9 +139,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
         build_base: opt_path(matches, "build-base"),
         aux_base: opt_path(matches, "aux-base"),
         stage_id: matches.opt_str("stage-id").unwrap(),
-        mode: FromStr::from_str(matches.opt_str("mode")
-                                       .unwrap()
-                                       .as_slice()).expect("invalid mode"),
+        mode: matches.opt_str("mode").unwrap().parse().ok().expect("invalid mode"),
         run_ignored: matches.opt_present("ignored"),
         filter: filter,
         logfile: matches.opt_str("logfile").map(|s| Path::new(s)),
diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs
index f83c27b75d6..66059d2d13d 100644
--- a/src/compiletest/header.rs
+++ b/src/compiletest/header.rs
@@ -352,8 +352,8 @@ pub fn gdb_version_to_int(version_string: &str) -> int {
         panic!("{}", error_string);
     }
 
-    let major: int = components[0].parse().expect(error_string);
-    let minor: int = components[1].parse().expect(error_string);
+    let major: int = components[0].parse().ok().expect(error_string);
+    let minor: int = components[1].parse().ok().expect(error_string);
 
     return major * 1000 + minor;
 }
@@ -363,6 +363,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 = version_string.parse().expect(error_string);
+    let major: int = version_string.parse().ok().expect(error_string);
     return major;
 }
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 59ac173f97a..686820eb813 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -2994,7 +2994,7 @@ Some examples of call expressions:
 # fn add(x: i32, y: i32) -> i32 { 0 }
 
 let x: i32 = add(1i32, 2i32);
-let pi: Option<f32> = "3.14".parse();
+let pi: Option<f32> = "3.14".parse().ok();
 ```
 
 ### Lambda expressions
diff --git a/src/doc/trpl/guessing-game.md b/src/doc/trpl/guessing-game.md
index f01b62223ca..162e533d8bb 100644
--- a/src/doc/trpl/guessing-game.md
+++ b/src/doc/trpl/guessing-game.md
@@ -400,7 +400,7 @@ a function for that:
 let input = old_io::stdin().read_line()
                        .ok()
                        .expect("Failed to read line");
-let input_num: Option<u32> = input.parse();
+let input_num: Option<u32> = input.parse().ok();
 ```
 
 The `parse` function takes in a `&str` value and converts it into something.
@@ -422,11 +422,13 @@ In this case, we say `x` is a `u32` explicitly, so Rust is able to properly
 tell `random()` what to generate. In a similar fashion, both of these work:
 
 ```{rust,ignore}
-let input_num = "5".parse::<u32>(); // input_num: Option<u32>
-let input_num: Option<u32> = "5".parse(); // input_num: Option<u32>
+let input_num = "5".parse::<u32>().ok(); // input_num: Option<u32>
+let input_num: Option<u32> = "5".parse().ok(); // input_num: Option<u32>
 ```
 
-Anyway, with us now converting our input to a number, our code looks like this:
+Here we're converting the `Result` returned by `parse` to an `Option` by using
+the `ok` method as well.  Anyway, with us now converting our input to a number,
+our code looks like this:
 
 ```{rust,ignore}
 use std::old_io;
@@ -445,7 +447,7 @@ fn main() {
     let input = old_io::stdin().read_line()
                            .ok()
                            .expect("Failed to read line");
-    let input_num: Option<u32> = input.parse();
+    let input_num: Option<u32> = input.parse().ok();
 
     println!("You guessed: {}", input_num);
 
@@ -495,7 +497,7 @@ fn main() {
     let input = old_io::stdin().read_line()
                            .ok()
                            .expect("Failed to read line");
-    let input_num: Option<u32> = input.parse();
+    let input_num: Option<u32> = input.parse().ok();
 
     let num = match input_num {
         Some(num) => num,
@@ -562,7 +564,7 @@ fn main() {
     let input = old_io::stdin().read_line()
                            .ok()
                            .expect("Failed to read line");
-    let input_num: Option<u32> = input.trim().parse();
+    let input_num: Option<u32> = input.trim().parse().ok();
 
     let num = match input_num {
         Some(num) => num,
@@ -638,7 +640,7 @@ fn main() {
         let input = old_io::stdin().read_line()
                                .ok()
                                .expect("Failed to read line");
-        let input_num: Option<u32> = input.trim().parse();
+        let input_num: Option<u32> = input.trim().parse().ok();
 
         let num = match input_num {
             Some(num) => num,
@@ -714,7 +716,7 @@ fn main() {
         let input = old_io::stdin().read_line()
                                .ok()
                                .expect("Failed to read line");
-        let input_num: Option<u32> = input.trim().parse();
+        let input_num: Option<u32> = input.trim().parse().ok();
 
         let num = match input_num {
             Some(num) => num,
@@ -770,7 +772,7 @@ fn main() {
         let input = old_io::stdin().read_line()
                                .ok()
                                .expect("Failed to read line");
-        let input_num: Option<u32> = input.trim().parse();
+        let input_num: Option<u32> = input.trim().parse().ok();
 
         let num = match input_num {
             Some(num) => num,
@@ -847,7 +849,7 @@ fn main() {
         let input = old_io::stdin().read_line()
                                .ok()
                                .expect("Failed to read line");
-        let input_num: Option<u32> = input.trim().parse();
+        let input_num: Option<u32> = input.trim().parse().ok();
 
         let num = match input_num {
             Some(num) => num,
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index d6ee4dc5f67..f6ba2b0ebaf 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -68,6 +68,7 @@ use core::ops::FullRange;
 #[cfg(not(stage0))]
 use core::ops::RangeFull;
 use core::option::Option::{self, Some, None};
+use core::result::Result;
 use core::slice::AsSlice;
 use core::str as core_str;
 use unicode::str::{UnicodeStr, Utf16Encoder};
@@ -1231,13 +1232,12 @@ pub trait StrExt: Index<RangeFull, Output = str> {
     /// # Example
     ///
     /// ```
-    /// assert_eq!("4".parse::<u32>(), Some(4));
-    /// assert_eq!("j".parse::<u32>(), None);
+    /// assert_eq!("4".parse::<u32>(), Ok(4));
+    /// assert!("j".parse::<u32>().is_err());
     /// ```
     #[inline]
-    #[unstable(feature = "collections",
-               reason = "this method was just created")]
-    fn parse<F: FromStr>(&self) -> Option<F> {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
         core_str::StrExt::parse(&self[])
     }
 
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 035529c7365..fa399ca3414 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -940,10 +940,12 @@ pub fn as_string<'a>(x: &'a str) -> DerefString<'a> {
     DerefString { x: as_vec(x.as_bytes()) }
 }
 
+#[unstable(feature = "collections", reason = "associated error type may change")]
 impl FromStr for String {
+    type Err = ();
     #[inline]
-    fn from_str(s: &str) -> Option<String> {
-        Some(String::from_str(s))
+    fn from_str(s: &str) -> Result<String, ()> {
+        Ok(String::from_str(s))
     }
 }
 
@@ -1016,7 +1018,7 @@ mod tests {
 
     #[test]
     fn test_from_str() {
-      let owned: Option<::std::string::String> = "string".parse();
+      let owned: Option<::std::string::String> = "string".parse().ok();
       assert_eq!(owned.as_ref().map(|s| s.as_slice()), Some("string"));
     }
 
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 1be7a0fb066..206e63c7a17 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -17,16 +17,17 @@
 
 use char::CharExt;
 use clone::Clone;
-use cmp::{PartialEq, Eq};
-use cmp::{PartialOrd, Ord};
+use cmp::{PartialEq, Eq, PartialOrd, Ord};
+use error::Error;
+use fmt;
 use intrinsics;
 use iter::IteratorExt;
 use marker::Copy;
 use mem::size_of;
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
 use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
-use option::Option;
-use option::Option::{Some, None};
+use option::Option::{self, Some, None};
+use result::Result::{self, Ok, Err};
 use str::{FromStr, StrExt};
 
 /// A built-in signed or unsigned integer.
@@ -1428,22 +1429,25 @@ pub trait Float
 }
 
 /// A generic trait for converting a string with a radix (base) to a value
-#[unstable(feature = "core", reason = "might need to return Result")]
+#[unstable(feature = "core", reason = "needs reevaluation")]
 pub trait FromStrRadix {
-    fn from_str_radix(str: &str, radix: uint) -> Option<Self>;
+    type Err;
+    fn from_str_radix(str: &str, radix: uint) -> Result<Self, Self::Err>;
 }
 
 /// A utility function that just calls FromStrRadix::from_str_radix.
-#[unstable(feature = "core", reason = "might need to return Result")]
-pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint) -> Option<T> {
+#[unstable(feature = "core", reason = "needs reevaluation")]
+pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint)
+                                       -> Result<T, T::Err> {
     FromStrRadix::from_str_radix(str, radix)
 }
 
 macro_rules! from_str_radix_float_impl {
     ($T:ty) => {
-        #[unstable(feature = "core",
-                   reason = "might need to return Result")]
+        #[stable(feature = "rust1", since = "1.0.0")]
         impl FromStr for $T {
+            type Err = ParseFloatError;
+
             /// Convert a string in base 10 to a float.
             /// Accepts an optional decimal exponent.
             ///
@@ -1470,14 +1474,15 @@ macro_rules! from_str_radix_float_impl {
             /// `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> {
+            fn from_str(src: &str) -> Result<$T, ParseFloatError> {
                 from_str_radix(src, 10)
             }
         }
 
-        #[unstable(feature = "core",
-                   reason = "might need to return Result")]
+        #[stable(feature = "rust1", since = "1.0.0")]
         impl FromStrRadix for $T {
+            type Err = ParseFloatError;
+
             /// Convert a string in a given base to a float.
             ///
             /// Due to possible conflicts, this function does **not** accept
@@ -1493,24 +1498,28 @@ macro_rules! from_str_radix_float_impl {
             ///
             /// # 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,
+            /// `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)
+                              -> Result<$T, ParseFloatError> {
+                use self::FloatErrorKind::*;
+                use self::ParseFloatError as PFE;
+                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()),
+                    "inf"   => return Ok(Float::infinity()),
+                    "-inf"  => return Ok(Float::neg_infinity()),
+                    "NaN"   => return Ok(Float::nan()),
                     _       => {},
                 }
 
                 let (is_positive, src) =  match src.slice_shift_char() {
-                    None             => return None,
-                    Some(('-', ""))  => return None,
+                    None             => return Err(PFE { kind: Empty }),
+                    Some(('-', ""))  => return Err(PFE { kind: Empty }),
                     Some(('-', src)) => (false, src),
                     Some((_, _))     => (true,  src),
                 };
@@ -1541,15 +1550,15 @@ macro_rules! from_str_radix_float_impl {
                             // if we've not seen any non-zero digits.
                             if prev_sig != 0.0 {
                                 if is_positive && sig <= prev_sig
-                                    { return Some(Float::infinity()); }
+                                    { return Ok(Float::infinity()); }
                                 if !is_positive && sig >= prev_sig
-                                    { return Some(Float::neg_infinity()); }
+                                    { return Ok(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()); }
+                                    { return Ok(Float::infinity()); }
                                 if !is_positive && (prev_sig != (sig + digit as $T) / radix as $T)
-                                    { return Some(Float::neg_infinity()); }
+                                    { return Ok(Float::neg_infinity()); }
                             }
                             prev_sig = sig;
                         },
@@ -1562,7 +1571,7 @@ macro_rules! from_str_radix_float_impl {
                                 break;  // start of fractional part
                             },
                             _ => {
-                                return None;
+                                return Err(PFE { kind: Invalid });
                             },
                         },
                     }
@@ -1585,9 +1594,9 @@ macro_rules! from_str_radix_float_impl {
                                 };
                                 // Detect overflow by comparing to last value
                                 if is_positive && sig < prev_sig
-                                    { return Some(Float::infinity()); }
+                                    { return Ok(Float::infinity()); }
                                 if !is_positive && sig > prev_sig
-                                    { return Some(Float::neg_infinity()); }
+                                    { return Ok(Float::neg_infinity()); }
                                 prev_sig = sig;
                             },
                             None => match c {
@@ -1596,7 +1605,7 @@ macro_rules! from_str_radix_float_impl {
                                     break; // start of exponent
                                 },
                                 _ => {
-                                    return None; // invalid number
+                                    return Err(PFE { kind: Invalid });
                                 },
                             },
                         }
@@ -1609,7 +1618,7 @@ macro_rules! from_str_radix_float_impl {
                         let base = match c {
                             'E' | 'e' if radix == 10 => 10.0,
                             'P' | 'p' if radix == 16 => 2.0,
-                            _ => return None,
+                            _ => return Err(PFE { kind: Invalid }),
                         };
 
                         // Parse the exponent as decimal integer
@@ -1618,19 +1627,19 @@ macro_rules! from_str_radix_float_impl {
                             Some(('-', src)) => (false, src.parse::<uint>()),
                             Some(('+', src)) => (true,  src.parse::<uint>()),
                             Some((_, _))     => (true,  src.parse::<uint>()),
-                            None             => return None,
+                            None             => return Err(PFE { kind: Invalid }),
                         };
 
                         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,
+                            (true,  Ok(exp)) => base.powi(exp as i32),
+                            (false, Ok(exp)) => 1.0 / base.powi(exp as i32),
+                            (_, Err(_))      => return Err(PFE { kind: Invalid }),
                         }
                     },
                     None => 1.0, // no exponent
                 };
 
-                Some(sig * exp)
+                Ok(sig * exp)
             }
         }
     }
@@ -1640,19 +1649,22 @@ from_str_radix_float_impl! { f64 }
 
 macro_rules! from_str_radix_int_impl {
     ($T:ty) => {
-        #[unstable(feature = "core",
-                   reason = "might need to return Result")]
+        #[stable(feature = "rust1", since = "1.0.0")]
         impl FromStr for $T {
+            type Err = ParseIntError;
             #[inline]
-            fn from_str(src: &str) -> Option<$T> {
+            fn from_str(src: &str) -> Result<$T, ParseIntError> {
                 from_str_radix(src, 10)
             }
         }
 
-        #[unstable(feature = "core",
-                   reason = "might need to return Result")]
+        #[stable(feature = "rust1", since = "1.0.0")]
         impl FromStrRadix for $T {
-            fn from_str_radix(src: &str, radix: uint) -> Option<$T> {
+            type Err = ParseIntError;
+            fn from_str_radix(src: &str, radix: uint)
+                              -> Result<$T, ParseIntError> {
+                use self::IntErrorKind::*;
+                use self::ParseIntError as PIE;
                 assert!(radix >= 2 && radix <= 36,
                        "from_str_radix_int: must lie in the range `[2, 36]` - found {}",
                        radix);
@@ -1666,18 +1678,18 @@ macro_rules! from_str_radix_int_impl {
                         for c in src.chars() {
                             let x = match c.to_digit(radix) {
                                 Some(x) => x,
-                                None => return None,
+                                None => return Err(PIE { kind: InvalidDigit }),
                             };
                             result = match result.checked_mul(radix as $T) {
                                 Some(result) => result,
-                                None => return None,
+                                None => return Err(PIE { kind: Underflow }),
                             };
                             result = match result.checked_sub(x as $T) {
                                 Some(result) => result,
-                                None => return None,
+                                None => return Err(PIE { kind: Underflow }),
                             };
                         }
-                        Some(result)
+                        Ok(result)
                     },
                     Some((_, _)) => {
                         // The number is signed
@@ -1685,20 +1697,20 @@ macro_rules! from_str_radix_int_impl {
                         for c in src.chars() {
                             let x = match c.to_digit(radix) {
                                 Some(x) => x,
-                                None => return None,
+                                None => return Err(PIE { kind: InvalidDigit }),
                             };
                             result = match result.checked_mul(radix as $T) {
                                 Some(result) => result,
-                                None => return None,
+                                None => return Err(PIE { kind: Overflow }),
                             };
                             result = match result.checked_add(x as $T) {
                                 Some(result) => result,
-                                None => return None,
+                                None => return Err(PIE { kind: Overflow }),
                             };
                         }
-                        Some(result)
+                        Ok(result)
                     },
-                    None => None,
+                    None => Err(ParseIntError { kind: Empty }),
                 }
             }
         }
@@ -1714,3 +1726,63 @@ from_str_radix_int_impl! { u8 }
 from_str_radix_int_impl! { u16 }
 from_str_radix_int_impl! { u32 }
 from_str_radix_int_impl! { u64 }
+
+/// An error which can be returned when parsing an integer.
+#[derive(Show, Clone, PartialEq)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ParseIntError { kind: IntErrorKind }
+
+#[derive(Show, Clone, PartialEq)]
+enum IntErrorKind {
+    Empty,
+    InvalidDigit,
+    Overflow,
+    Underflow,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for ParseIntError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.description().fmt(f)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for ParseIntError {
+    fn description(&self) -> &str {
+        match self.kind {
+            IntErrorKind::Empty => "cannot parse integer from empty string",
+            IntErrorKind::InvalidDigit => "invalid digit found in string",
+            IntErrorKind::Overflow => "number too large to fit in target type",
+            IntErrorKind::Underflow => "number too small to fit in target type",
+        }
+    }
+}
+
+/// An error which can be returned when parsing a float.
+#[derive(Show, Clone, PartialEq)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ParseFloatError { kind: FloatErrorKind }
+
+#[derive(Show, Clone, PartialEq)]
+enum FloatErrorKind {
+    Empty,
+    Invalid,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for ParseFloatError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.description().fmt(f)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for ParseFloatError {
+    fn description(&self) -> &str {
+        match self.kind {
+            FloatErrorKind::Empty => "cannot parse float from empty string",
+            FloatErrorKind::Invalid => "invalid float literal",
+        }
+    }
+}
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 5cb8e5e5565..2f261b0628f 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -728,8 +728,8 @@ impl<T: Default> Option<T> {
     /// ```
     /// let good_year_from_input = "1909";
     /// let bad_year_from_input = "190blarg";
-    /// let good_year = good_year_from_input.parse().unwrap_or_default();
-    /// let bad_year = bad_year_from_input.parse().unwrap_or_default();
+    /// let good_year = good_year_from_input.parse().ok().unwrap_or_default();
+    /// let bad_year = bad_year_from_input.parse().ok().unwrap_or_default();
     ///
     /// assert_eq!(1909, good_year);
     /// assert_eq!(0, bad_year);
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index f545c56a060..93942d0b836 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -109,37 +109,62 @@ macro_rules! delegate_iter {
 
 /// A trait to abstract the idea of creating a new instance of a type from a
 /// string.
-// FIXME(#17307): there should be an `E` associated type for a `Result` return
-#[unstable(feature = "core",
-           reason = "will return a Result once associated types are working")]
+#[stable(feature = "rust1", since = "1.0.0")]
 pub trait FromStr {
+    /// The associated error which can be returned from parsing.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Err;
+
     /// 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>;
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn from_str(s: &str) -> Result<Self, Self::Err>;
 }
 
+#[stable(feature = "rust1", since = "1.0.0")]
 impl FromStr for bool {
+    type Err = ParseBoolError;
+
     /// Parse a `bool` from a string.
     ///
-    /// Yields an `Option<bool>`, because `s` may or may not actually be parseable.
+    /// Yields an `Option<bool>`, because `s` may or may not actually be
+    /// parseable.
     ///
     /// # Examples
     ///
     /// ```rust
-    /// assert_eq!("true".parse(), Some(true));
-    /// assert_eq!("false".parse(), Some(false));
-    /// assert_eq!("not even a boolean".parse::<bool>(), None);
+    /// assert_eq!("true".parse(), Ok(true));
+    /// assert_eq!("false".parse(), Ok(false));
+    /// assert!("not even a boolean".parse::<bool>().is_err());
     /// ```
     #[inline]
-    fn from_str(s: &str) -> Option<bool> {
+    fn from_str(s: &str) -> Result<bool, ParseBoolError> {
         match s {
-            "true"  => Some(true),
-            "false" => Some(false),
-            _       => None,
+            "true"  => Ok(true),
+            "false" => Ok(false),
+            _       => Err(ParseBoolError { _priv: () }),
         }
     }
 }
 
+/// An error returned when parsing a `bool` from a string fails.
+#[derive(Show, Clone, PartialEq)]
+#[allow(missing_copy_implementations)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ParseBoolError { _priv: () }
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Display for ParseBoolError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        "provided string was not `true` or `false`".fmt(f)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Error for ParseBoolError {
+    fn description(&self) -> &str { "failed to parse bool" }
+}
+
 /*
 Section: Creating a string
 */
@@ -1356,7 +1381,7 @@ pub trait StrExt {
     fn as_ptr(&self) -> *const u8;
     fn len(&self) -> uint;
     fn is_empty(&self) -> bool;
-    fn parse<T: FromStr>(&self) -> Option<T>;
+    fn parse<T: FromStr>(&self) -> Result<T, T::Err>;
 }
 
 #[inline(never)]
@@ -1671,7 +1696,7 @@ impl StrExt for str {
     fn is_empty(&self) -> bool { self.len() == 0 }
 
     #[inline]
-    fn parse<T: FromStr>(&self) -> Option<T> { FromStr::from_str(self) }
+    fn parse<T: FromStr>(&self) -> Result<T, T::Err> { FromStr::from_str(self) }
 }
 
 /// Pluck a code point out of a UTF-8-like byte slice and return the
diff --git a/src/libcoretest/num/int_macros.rs b/src/libcoretest/num/int_macros.rs
index b98432e26b2..d956cd4816b 100644
--- a/src/libcoretest/num/int_macros.rs
+++ b/src/libcoretest/num/int_macros.rs
@@ -159,7 +159,7 @@ mod tests {
     #[test]
     fn test_from_str() {
         fn from_str<T: ::std::str::FromStr>(t: &str) -> Option<T> {
-            ::std::str::FromStr::from_str(t)
+            ::std::str::FromStr::from_str(t).ok()
         }
         assert_eq!(from_str::<$T>("0"), Some(0 as $T));
         assert_eq!(from_str::<$T>("3"), Some(3 as $T));
@@ -180,26 +180,26 @@ mod tests {
 
     #[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>);
+        assert_eq!(FromStrRadix::from_str_radix("123", 10), Ok(123 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("1001", 2), Ok(9 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("123", 8), Ok(83 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("123", 16), Ok(291 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("ffff", 16), Ok(65535 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("FFFF", 16), Ok(65535 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("z", 36), Ok(35 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("Z", 36), Ok(35 as $T));
+
+        assert_eq!(FromStrRadix::from_str_radix("-123", 10), Ok(-123 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("-1001", 2), Ok(-9 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("-123", 8), Ok(-83 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("-123", 16), Ok(-291 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("-ffff", 16), Ok(-65535 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("-FFFF", 16), Ok(-65535 as i32));
+        assert_eq!(FromStrRadix::from_str_radix("-z", 36), Ok(-35 as $T));
+        assert_eq!(FromStrRadix::from_str_radix("-Z", 36), Ok(-35 as $T));
+
+        assert_eq!(FromStrRadix::from_str_radix("Z", 35).ok(), None::<$T>);
+        assert_eq!(FromStrRadix::from_str_radix("-9", 2).ok(), None::<$T>);
     }
 }
 
diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs
index e0623bade5c..f93c07eac5f 100644
--- a/src/libcoretest/num/mod.rs
+++ b/src/libcoretest/num/mod.rs
@@ -62,64 +62,64 @@ mod test {
 
     #[test]
     fn from_str_issue7588() {
-        let u : Option<u8> = from_str_radix("1000", 10);
+        let u : Option<u8> = from_str_radix("1000", 10).ok();
         assert_eq!(u, None);
-        let s : Option<i16> = from_str_radix("80000", 10);
+        let s : Option<i16> = from_str_radix("80000", 10).ok();
         assert_eq!(s, None);
-        let f : Option<f32> = from_str_radix("10000000000000000000000000000000000000000", 10);
+        let f : Option<f32> = from_str_radix("10000000000000000000000000000000000000000", 10).ok();
         assert_eq!(f, Some(Float::infinity()));
-        let fe : Option<f32> = from_str_radix("1e40", 10);
+        let fe : Option<f32> = from_str_radix("1e40", 10).ok();
         assert_eq!(fe, Some(Float::infinity()));
     }
 
     #[test]
     fn test_from_str_radix_float() {
-        let x1 : Option<f64> = from_str_radix("-123.456", 10);
+        let x1 : Option<f64> = from_str_radix("-123.456", 10).ok();
         assert_eq!(x1, Some(-123.456));
-        let x2 : Option<f32> = from_str_radix("123.456", 10);
+        let x2 : Option<f32> = from_str_radix("123.456", 10).ok();
         assert_eq!(x2, Some(123.456));
-        let x3 : Option<f32> = from_str_radix("-0.0", 10);
+        let x3 : Option<f32> = from_str_radix("-0.0", 10).ok();
         assert_eq!(x3, Some(-0.0));
-        let x4 : Option<f32> = from_str_radix("0.0", 10);
+        let x4 : Option<f32> = from_str_radix("0.0", 10).ok();
         assert_eq!(x4, Some(0.0));
-        let x4 : Option<f32> = from_str_radix("1.0", 10);
+        let x4 : Option<f32> = from_str_radix("1.0", 10).ok();
         assert_eq!(x4, Some(1.0));
-        let x5 : Option<f32> = from_str_radix("-1.0", 10);
+        let x5 : Option<f32> = from_str_radix("-1.0", 10).ok();
         assert_eq!(x5, Some(-1.0));
     }
 
     #[test]
     fn test_int_from_str_overflow() {
         let mut i8_val: i8 = 127_i8;
-        assert_eq!("127".parse::<i8>(), Some(i8_val));
-        assert_eq!("128".parse::<i8>(), None);
+        assert_eq!("127".parse::<i8>().ok(), Some(i8_val));
+        assert_eq!("128".parse::<i8>().ok(), None);
 
         i8_val += 1 as i8;
-        assert_eq!("-128".parse::<i8>(), Some(i8_val));
-        assert_eq!("-129".parse::<i8>(), None);
+        assert_eq!("-128".parse::<i8>().ok(), Some(i8_val));
+        assert_eq!("-129".parse::<i8>().ok(), None);
 
         let mut i16_val: i16 = 32_767_i16;
-        assert_eq!("32767".parse::<i16>(), Some(i16_val));
-        assert_eq!("32768".parse::<i16>(), None);
+        assert_eq!("32767".parse::<i16>().ok(), Some(i16_val));
+        assert_eq!("32768".parse::<i16>().ok(), None);
 
         i16_val += 1 as i16;
-        assert_eq!("-32768".parse::<i16>(), Some(i16_val));
-        assert_eq!("-32769".parse::<i16>(), None);
+        assert_eq!("-32768".parse::<i16>().ok(), Some(i16_val));
+        assert_eq!("-32769".parse::<i16>().ok(), None);
 
         let mut i32_val: i32 = 2_147_483_647_i32;
-        assert_eq!("2147483647".parse::<i32>(), Some(i32_val));
-        assert_eq!("2147483648".parse::<i32>(), None);
+        assert_eq!("2147483647".parse::<i32>().ok(), Some(i32_val));
+        assert_eq!("2147483648".parse::<i32>().ok(), None);
 
         i32_val += 1 as i32;
-        assert_eq!("-2147483648".parse::<i32>(), Some(i32_val));
-        assert_eq!("-2147483649".parse::<i32>(), None);
+        assert_eq!("-2147483648".parse::<i32>().ok(), Some(i32_val));
+        assert_eq!("-2147483649".parse::<i32>().ok(), None);
 
         let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
-        assert_eq!("9223372036854775807".parse::<i64>(), Some(i64_val));
-        assert_eq!("9223372036854775808".parse::<i64>(), None);
+        assert_eq!("9223372036854775807".parse::<i64>().ok(), Some(i64_val));
+        assert_eq!("9223372036854775808".parse::<i64>().ok(), None);
 
         i64_val += 1 as i64;
-        assert_eq!("-9223372036854775808".parse::<i64>(), Some(i64_val));
-        assert_eq!("-9223372036854775809".parse::<i64>(), None);
+        assert_eq!("-9223372036854775808".parse::<i64>().ok(), Some(i64_val));
+        assert_eq!("-9223372036854775809".parse::<i64>().ok(), None);
     }
 }
diff --git a/src/libcoretest/str.rs b/src/libcoretest/str.rs
index 938755113b5..f2a1b0ac584 100644
--- a/src/libcoretest/str.rs
+++ b/src/libcoretest/str.rs
@@ -10,9 +10,9 @@
 
 #[test]
 fn test_bool_from_str() {
-    assert_eq!("true".parse(), Some(true));
-    assert_eq!("false".parse(), Some(false));
-    assert_eq!("not even a boolean".parse::<bool>(), None);
+    assert_eq!("true".parse().ok(), Some(true));
+    assert_eq!("false".parse().ok(), Some(false));
+    assert_eq!("not even a boolean".parse::<bool>().ok(), None);
 }
 
 fn check_contains_all_substrings(s: &str) {
diff --git a/src/liblog/directive.rs b/src/liblog/directive.rs
index edd93358bfa..46b9b2ed865 100644
--- a/src/liblog/directive.rs
+++ b/src/liblog/directive.rs
@@ -22,7 +22,7 @@ pub static LOG_LEVEL_NAMES: [&'static str; 4] = ["ERROR", "WARN", "INFO",
 
 /// Parse an individual log level that is either a number or a symbolic log level
 fn parse_log_level(level: &str) -> Option<u32> {
-    level.parse::<u32>().or_else(|| {
+    level.parse::<u32>().ok().or_else(|| {
         let pos = LOG_LEVEL_NAMES.iter().position(|&name| name.eq_ignore_ascii_case(level));
         pos.map(|p| p as u32 + 1)
     }).map(|p| cmp::min(p, ::MAX_LOG_LEVEL))
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 4e2ab82cd4e..2248562352d 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -254,7 +254,7 @@ impl LintPass for TypeLimits {
                         let lit_val: f64 = match lit.node {
                             ast::LitFloat(ref v, _) |
                             ast::LitFloatUnsuffixed(ref v) => {
-                                match v.parse() {
+                                match v.parse().ok() {
                                     Some(f) => f,
                                     None => return
                                 }
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 933fd873aeb..bb4b52378ea 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -223,7 +223,7 @@ fn each_reexport<F>(d: rbml::Doc, f: F) -> bool where
 fn variant_disr_val(d: rbml::Doc) -> Option<ty::Disr> {
     reader::maybe_get_doc(d, tag_disr_val).and_then(|val_doc| {
         reader::with_doc_data(val_doc, |data| {
-            str::from_utf8(data).ok().and_then(|s| s.parse())
+            str::from_utf8(data).ok().and_then(|s| s.parse().ok())
         })
     })
 }
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 943479ff35e..6d19107096a 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -717,12 +717,16 @@ pub fn parse_def_id(buf: &[u8]) -> ast::DefId {
     let crate_part = &buf[0u..colon_idx];
     let def_part = &buf[colon_idx + 1u..len];
 
-    let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| s.parse::<uint>()) {
+    let crate_num = match str::from_utf8(crate_part).ok().and_then(|s| {
+        s.parse::<uint>().ok()
+    }) {
        Some(cn) => cn as ast::CrateNum,
        None => panic!("internal error: parse_def_id: crate number expected, found {:?}",
                      crate_part)
     };
-    let def_num = match str::from_utf8(def_part).ok().and_then(|s| s.parse::<uint>()) {
+    let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
+        s.parse::<uint>().ok()
+    }) {
        Some(dn) => dn as ast::NodeId,
        None => panic!("internal error: parse_def_id: id expected, found {:?}",
                      def_part)
diff --git a/src/librustc/middle/infer/region_inference/graphviz.rs b/src/librustc/middle/infer/region_inference/graphviz.rs
index 215c4945ea9..92d8419484a 100644
--- a/src/librustc/middle/infer/region_inference/graphviz.rs
+++ b/src/librustc/middle/infer/region_inference/graphviz.rs
@@ -59,7 +59,7 @@ pub fn maybe_print_constraints_for<'a, 'tcx>(region_vars: &RegionVarBindings<'a,
     }
 
     let requested_node : Option<ast::NodeId> =
-        os::getenv("RUST_REGION_GRAPH_NODE").and_then(|s| s.parse());
+        os::getenv("RUST_REGION_GRAPH_NODE").and_then(|s| s.parse().ok());
 
     if requested_node.is_some() && requested_node != Some(subject_node) {
         return;
diff --git a/src/librustc/middle/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs
index 81cbdf13c51..da83833fba3 100644
--- a/src/librustc/middle/recursion_limit.rs
+++ b/src/librustc/middle/recursion_limit.rs
@@ -18,7 +18,6 @@
 use session::Session;
 use syntax::ast;
 use syntax::attr::AttrMetaMethods;
-use std::str::FromStr;
 
 pub fn update_recursion_limit(sess: &Session, krate: &ast::Crate) {
     for attr in krate.attrs.iter() {
@@ -27,7 +26,7 @@ pub fn update_recursion_limit(sess: &Session, krate: &ast::Crate) {
         }
 
         if let Some(s) = attr.value_str() {
-            if let Some(n) = FromStr::from_str(s.get()) {
+            if let Some(n) = s.parse().ok() {
                 sess.recursion_limit.set(n);
                 return;
             }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 2fc68e6244a..125fbaa40e0 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -424,7 +424,7 @@ macro_rules! options {
         }
 
         fn parse_uint(slot: &mut uint, v: Option<&str>) -> bool {
-            match v.and_then(|s| s.parse()) {
+            match v.and_then(|s| s.parse().ok()) {
                 Some(i) => { *slot = i; true },
                 None => false
             }
@@ -432,7 +432,7 @@ macro_rules! options {
 
         fn parse_opt_uint(slot: &mut Option<uint>, v: Option<&str>) -> bool {
             match v {
-                Some(s) => { *slot = s.parse(); slot.is_some() }
+                Some(s) => { *slot = s.parse().ok(); slot.is_some() }
                 None => { *slot = None; true }
             }
         }
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 4ee13f5a542..bd7ad51de37 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -99,7 +99,7 @@ pub fn parse_pretty(sess: &Session,
             }
         }
     };
-    let opt_second = opt_second.and_then(|s| s.parse::<UserIdentifiedItem>());
+    let opt_second = opt_second.and_then(|s| s.parse::<UserIdentifiedItem>().ok());
     (first, opt_second)
 }
 
@@ -345,13 +345,11 @@ pub enum UserIdentifiedItem {
 }
 
 impl FromStr for UserIdentifiedItem {
-    fn from_str(s: &str) -> Option<UserIdentifiedItem> {
-        s.parse().map(ItemViaNode).or_else(|| {
-            let v : Vec<_> = s.split_str("::")
-                .map(|x|x.to_string())
-                .collect();
-            Some(ItemViaPath(v))
-        })
+    type Err = ();
+    fn from_str(s: &str) -> Result<UserIdentifiedItem, ()> {
+        Ok(s.parse().map(ItemViaNode).unwrap_or_else(|_| {
+            ItemViaPath(s.split_str("::").map(|s| s.to_string()).collect())
+        }))
     }
 }
 
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 2e7a6fd4923..b50f12deb44 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -2127,7 +2127,7 @@ macro_rules! read_primitive {
                 Json::F64(f) => Err(ExpectedError("Integer".to_string(), format!("{}", f))),
                 // re: #12967.. a type w/ numeric keys (ie HashMap<uint, V> etc)
                 // is going to have a string here, as per JSON spec.
-                Json::String(s) => match s.parse() {
+                Json::String(s) => match s.parse().ok() {
                     Some(f) => Ok(f),
                     None => Err(ExpectedError("Number".to_string(), s)),
                 },
@@ -2165,7 +2165,7 @@ impl ::Decoder for Decoder {
             Json::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 s.parse() {
+                match s.parse().ok() {
                     Some(f) => Ok(f),
                     None => Err(ExpectedError("Number".to_string(), s)),
                 }
@@ -2597,8 +2597,9 @@ impl<'a, T: Encodable> fmt::Display for AsPrettyJson<'a, T> {
 }
 
 impl FromStr for Json {
-    fn from_str(s: &str) -> Option<Json> {
-        from_str(s).ok()
+    type Err = BuilderError;
+    fn from_str(s: &str) -> Result<Json, BuilderError> {
+        from_str(s)
     }
 }
 
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index 82c55d7b5b8..4cd6391318f 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -20,7 +20,7 @@ mod tests {
     use num::FromStrRadix;
 
     fn from_str<T: ::str::FromStr>(t: &str) -> Option<T> {
-        ::str::FromStr::from_str(t)
+        ::str::FromStr::from_str(t).ok()
     }
 
     #[test]
@@ -38,15 +38,15 @@ mod tests {
 
     #[test]
     pub fn test_parse_bytes() {
-        assert_eq!(FromStrRadix::from_str_radix("123", 10), Some(123u as $T));
-        assert_eq!(FromStrRadix::from_str_radix("1001", 2), Some(9u as $T));
-        assert_eq!(FromStrRadix::from_str_radix("123", 8), Some(83u as $T));
-        assert_eq!(FromStrRadix::from_str_radix("123", 16), Some(291u as u16));
-        assert_eq!(FromStrRadix::from_str_radix("ffff", 16), Some(65535u as u16));
-        assert_eq!(FromStrRadix::from_str_radix("z", 36), Some(35u as $T));
-
-        assert_eq!(FromStrRadix::from_str_radix("Z", 10), None::<$T>);
-        assert_eq!(FromStrRadix::from_str_radix("_", 2), None::<$T>);
+        assert_eq!(FromStrRadix::from_str_radix("123", 10), Ok(123u as $T));
+        assert_eq!(FromStrRadix::from_str_radix("1001", 2), Ok(9u as $T));
+        assert_eq!(FromStrRadix::from_str_radix("123", 8), Ok(83u as $T));
+        assert_eq!(FromStrRadix::from_str_radix("123", 16), Ok(291u as u16));
+        assert_eq!(FromStrRadix::from_str_radix("ffff", 16), Ok(65535u as u16));
+        assert_eq!(FromStrRadix::from_str_radix("z", 36), Ok(35u as $T));
+
+        assert_eq!(FromStrRadix::from_str_radix("Z", 10).ok(), None::<$T>);
+        assert_eq!(FromStrRadix::from_str_radix("_", 2).ok(), None::<$T>);
     }
 
     #[test]
diff --git a/src/libstd/old_io/net/ip.rs b/src/libstd/old_io/net/ip.rs
index f0b73bd37f2..3e2e69f75a6 100644
--- a/src/libstd/old_io/net/ip.rs
+++ b/src/libstd/old_io/net/ip.rs
@@ -25,7 +25,7 @@ use iter::{Iterator, IteratorExt};
 use ops::{FnOnce, FnMut};
 use option::Option;
 use option::Option::{None, Some};
-use result::Result::{Ok, Err};
+use result::Result::{self, Ok, Err};
 use slice::SliceExt;
 use str::{FromStr, StrExt};
 use vec::Vec;
@@ -350,17 +350,28 @@ impl<'a> Parser<'a> {
 }
 
 impl FromStr for IpAddr {
-    fn from_str(s: &str) -> Option<IpAddr> {
-        Parser::new(s).read_till_eof(|p| p.read_ip_addr())
+    type Err = ParseError;
+    fn from_str(s: &str) -> Result<IpAddr, ParseError> {
+        match Parser::new(s).read_till_eof(|p| p.read_ip_addr()) {
+            Some(s) => Ok(s),
+            None => Err(ParseError),
+        }
     }
 }
 
 impl FromStr for SocketAddr {
-    fn from_str(s: &str) -> Option<SocketAddr> {
-        Parser::new(s).read_till_eof(|p| p.read_socket_addr())
+    type Err = ParseError;
+    fn from_str(s: &str) -> Result<SocketAddr, ParseError> {
+        match Parser::new(s).read_till_eof(|p| p.read_socket_addr()) {
+            Some(s) => Ok(s),
+            None => Err(ParseError),
+        }
     }
 }
 
+#[derive(Show, Clone, PartialEq, Copy)]
+pub struct ParseError;
+
 /// A trait for objects which can be converted or resolved to one or more `SocketAddr` values.
 ///
 /// Implementing types minimally have to implement either `to_socket_addr` or `to_socket_addr_all`
@@ -493,7 +504,7 @@ fn parse_and_resolve_socket_addr(s: &str) -> IoResult<Vec<SocketAddr>> {
     let mut parts_iter = s.rsplitn(2, ':');
     let port_str = try_opt!(parts_iter.next(), "invalid socket address");
     let host = try_opt!(parts_iter.next(), "invalid socket address");
-    let port: u16 = try_opt!(FromStr::from_str(port_str), "invalid port value");
+    let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
     resolve_socket_addr(host, port)
 }
 
@@ -502,7 +513,7 @@ impl<'a> ToSocketAddr for (&'a str, u16) {
         let (host, port) = *self;
 
         // try to parse the host as a regular IpAddr first
-        match FromStr::from_str(host) {
+        match host.parse().ok() {
             Some(addr) => return Ok(vec![SocketAddr {
                 ip: addr,
                 port: port
@@ -518,7 +529,7 @@ impl<'a> ToSocketAddr for (&'a str, u16) {
 impl<'a> ToSocketAddr for &'a str {
     fn to_socket_addr(&self) -> IoResult<SocketAddr> {
         // try to parse as a regular SocketAddr first
-        match FromStr::from_str(*self) {
+        match self.parse().ok() {
             Some(addr) => return Ok(addr),
             None => {}
         }
@@ -535,7 +546,7 @@ impl<'a> ToSocketAddr for &'a str {
 
     fn to_socket_addr_all(&self) -> IoResult<Vec<SocketAddr>> {
         // try to parse as a regular SocketAddr first
-        match FromStr::from_str(*self) {
+        match self.parse().ok() {
             Some(addr) => return Ok(vec![addr]),
             None => {}
         }
@@ -553,95 +564,94 @@ mod test {
 
     #[test]
     fn test_from_str_ipv4() {
-        assert_eq!(Some(Ipv4Addr(127, 0, 0, 1)), FromStr::from_str("127.0.0.1"));
-        assert_eq!(Some(Ipv4Addr(255, 255, 255, 255)), FromStr::from_str("255.255.255.255"));
-        assert_eq!(Some(Ipv4Addr(0, 0, 0, 0)), FromStr::from_str("0.0.0.0"));
+        assert_eq!(Ok(Ipv4Addr(127, 0, 0, 1)), "127.0.0.1".parse());
+        assert_eq!(Ok(Ipv4Addr(255, 255, 255, 255)), "255.255.255.255".parse());
+        assert_eq!(Ok(Ipv4Addr(0, 0, 0, 0)), "0.0.0.0".parse());
 
         // out of range
-        let none: Option<IpAddr> = FromStr::from_str("256.0.0.1");
+        let none: Option<IpAddr> = "256.0.0.1".parse().ok();
         assert_eq!(None, none);
         // too short
-        let none: Option<IpAddr> = FromStr::from_str("255.0.0");
+        let none: Option<IpAddr> = "255.0.0".parse().ok();
         assert_eq!(None, none);
         // too long
-        let none: Option<IpAddr> = FromStr::from_str("255.0.0.1.2");
+        let none: Option<IpAddr> = "255.0.0.1.2".parse().ok();
         assert_eq!(None, none);
         // no number between dots
-        let none: Option<IpAddr> = FromStr::from_str("255.0..1");
+        let none: Option<IpAddr> = "255.0..1".parse().ok();
         assert_eq!(None, none);
     }
 
     #[test]
     fn test_from_str_ipv6() {
-        assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), FromStr::from_str("0:0:0:0:0:0:0:0"));
-        assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), FromStr::from_str("0:0:0:0:0:0:0:1"));
+        assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), "0:0:0:0:0:0:0:0".parse());
+        assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), "0:0:0:0:0:0:0:1".parse());
 
-        assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), FromStr::from_str("::1"));
-        assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), FromStr::from_str("::"));
+        assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 1)), "::1".parse());
+        assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0, 0, 0)), "::".parse());
 
-        assert_eq!(Some(Ipv6Addr(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)),
-                FromStr::from_str("2a02:6b8::11:11"));
+        assert_eq!(Ok(Ipv6Addr(0x2a02, 0x6b8, 0, 0, 0, 0, 0x11, 0x11)),
+                "2a02:6b8::11:11".parse());
 
         // too long group
-        let none: Option<IpAddr> = FromStr::from_str("::00000");
+        let none: Option<IpAddr> = "::00000".parse().ok();
         assert_eq!(None, none);
         // too short
-        let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7");
+        let none: Option<IpAddr> = "1:2:3:4:5:6:7".parse().ok();
         assert_eq!(None, none);
         // too long
-        let none: Option<IpAddr> = FromStr::from_str("1:2:3:4:5:6:7:8:9");
+        let none: Option<IpAddr> = "1:2:3:4:5:6:7:8:9".parse().ok();
         assert_eq!(None, none);
         // triple colon
-        let none: Option<IpAddr> = FromStr::from_str("1:2:::6:7:8");
+        let none: Option<IpAddr> = "1:2:::6:7:8".parse().ok();
         assert_eq!(None, none);
         // two double colons
-        let none: Option<IpAddr> = FromStr::from_str("1:2::6::8");
+        let none: Option<IpAddr> = "1:2::6::8".parse().ok();
         assert_eq!(None, none);
     }
 
     #[test]
     fn test_from_str_ipv4_in_ipv6() {
-        assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0, 49152, 545)),
-                FromStr::from_str("::192.0.2.33"));
-        assert_eq!(Some(Ipv6Addr(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)),
-                FromStr::from_str("::FFFF:192.0.2.33"));
-        assert_eq!(Some(Ipv6Addr(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)),
-                FromStr::from_str("64:ff9b::192.0.2.33"));
-        assert_eq!(Some(Ipv6Addr(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)),
-                FromStr::from_str("2001:db8:122:c000:2:2100:192.0.2.33"));
+        assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0, 49152, 545)),
+                "::192.0.2.33".parse());
+        assert_eq!(Ok(Ipv6Addr(0, 0, 0, 0, 0, 0xFFFF, 49152, 545)),
+                "::FFFF:192.0.2.33".parse());
+        assert_eq!(Ok(Ipv6Addr(0x64, 0xff9b, 0, 0, 0, 0, 49152, 545)),
+                "64:ff9b::192.0.2.33".parse());
+        assert_eq!(Ok(Ipv6Addr(0x2001, 0xdb8, 0x122, 0xc000, 0x2, 0x2100, 49152, 545)),
+                "2001:db8:122:c000:2:2100:192.0.2.33".parse());
 
         // colon after v4
-        let none: Option<IpAddr> = FromStr::from_str("::127.0.0.1:");
+        let none: Option<IpAddr> = "::127.0.0.1:".parse().ok();
         assert_eq!(None, none);
         // not enough groups
-        let none: Option<IpAddr> = FromStr::from_str("1.2.3.4.5:127.0.0.1");
+        let none: Option<IpAddr> = "1.2.3.4.5:127.0.0.1".parse().ok();
         assert_eq!(None, none);
         // too many groups
-        let none: Option<IpAddr> =
-            FromStr::from_str("1.2.3.4.5:6:7:127.0.0.1");
+        let none: Option<IpAddr> = "1.2.3.4.5:6:7:127.0.0.1".parse().ok();
         assert_eq!(None, none);
     }
 
     #[test]
     fn test_from_str_socket_addr() {
-        assert_eq!(Some(SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 80 }),
-                FromStr::from_str("77.88.21.11:80"));
-        assert_eq!(Some(SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 }),
-                FromStr::from_str("[2a02:6b8:0:1::1]:53"));
-        assert_eq!(Some(SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0x7F00, 1), port: 22 }),
-                FromStr::from_str("[::127.0.0.1]:22"));
+        assert_eq!(Ok(SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 80 }),
+                "77.88.21.11:80".parse());
+        assert_eq!(Ok(SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 }),
+                "[2a02:6b8:0:1::1]:53".parse());
+        assert_eq!(Ok(SocketAddr { ip: Ipv6Addr(0, 0, 0, 0, 0, 0, 0x7F00, 1), port: 22 }),
+                "[::127.0.0.1]:22".parse());
 
         // without port
-        let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1");
+        let none: Option<SocketAddr> = "127.0.0.1".parse().ok();
         assert_eq!(None, none);
         // without port
-        let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:");
+        let none: Option<SocketAddr> = "127.0.0.1:".parse().ok();
         assert_eq!(None, none);
         // wrong brackets around v4
-        let none: Option<SocketAddr> = FromStr::from_str("[127.0.0.1]:22");
+        let none: Option<SocketAddr> = "[127.0.0.1]:22".parse().ok();
         assert_eq!(None, none);
         // port out of range
-        let none: Option<SocketAddr> = FromStr::from_str("127.0.0.1:123456");
+        let none: Option<SocketAddr> = "127.0.0.1:123456".parse().ok();
         assert_eq!(None, none);
     }
 
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index 588f724134e..72c41f2399e 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -19,6 +19,7 @@ use iter::{AdditiveIterator, Extend};
 use iter::{Iterator, IteratorExt, Map};
 use marker::Sized;
 use option::Option::{self, Some, None};
+use result::Result::{self, Ok, Err};
 use slice::{AsSlice, Split, SliceExt, SliceConcatExt};
 use str::{self, FromStr, StrExt};
 use vec::Vec;
@@ -86,11 +87,19 @@ impl Ord for Path {
 }
 
 impl FromStr for Path {
-    fn from_str(s: &str) -> Option<Path> {
-        Path::new_opt(s)
+    type Err = ParsePathError;
+    fn from_str(s: &str) -> Result<Path, ParsePathError> {
+        match Path::new_opt(s) {
+            Some(p) => Ok(p),
+            None => Err(ParsePathError),
+        }
     }
 }
 
+/// Valuelue indicating that a path could not be parsed from a string.
+#[derive(Show, Clone, PartialEq, Copy)]
+pub struct ParsePathError;
+
 impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path {
     #[inline]
     fn hash(&self, state: &mut S) {
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index 98e0320cd14..e04f697b2a4 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -27,6 +27,7 @@ use mem;
 use option::Option::{self, Some, None};
 #[cfg(stage0)]
 use ops::FullRange;
+use result::Result::{self, Ok, Err};
 use slice::{SliceExt, SliceConcatExt};
 use str::{SplitTerminator, FromStr, StrExt};
 use string::{String, ToString};
@@ -115,11 +116,19 @@ impl Ord for Path {
 }
 
 impl FromStr for Path {
-    fn from_str(s: &str) -> Option<Path> {
-        Path::new_opt(s)
+    type Err = ParsePathError;
+    fn from_str(s: &str) -> Result<Path, ParsePathError> {
+        match Path::new_opt(s) {
+            Some(p) => Ok(p),
+            None => Err(ParsePathError),
+        }
     }
 }
 
+/// Value indicating that a path could not be parsed from a string.
+#[derive(Show, Clone, PartialEq, Copy)]
+pub struct ParsePathError;
+
 impl<S: hash::Writer + hash::Hasher> hash::Hash<S> for Path {
     #[cfg(not(test))]
     #[inline]
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 4023a0a4c10..f5727a38b69 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -51,7 +51,7 @@ pub fn min_stack() -> uint {
         0 => {}
         n => return n - 1,
     }
-    let amt = os::getenv("RUST_MIN_STACK").and_then(|s| s.parse());
+    let amt = os::getenv("RUST_MIN_STACK").and_then(|s| s.parse().ok());
     let amt = amt.unwrap_or(2 * 1024 * 1024);
     // 0 is our sentinel value, so ensure that we'll never see 0 after
     // initialization has run
@@ -64,7 +64,7 @@ pub fn min_stack() -> uint {
 pub fn default_sched_threads() -> uint {
     match os::getenv("RUST_THREADS") {
         Some(nstr) => {
-            let opt_n: Option<uint> = nstr.parse();
+            let opt_n: Option<uint> = nstr.parse().ok();
             match opt_n {
                 Some(n) if n > 0 => n,
                 _ => panic!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 493a97c24cf..2cf6058a433 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -613,7 +613,7 @@ impl<'a> StringReader<'a> {
         // find the integer representing the name
         self.scan_digits(base);
         let encoded_name : u32 = self.with_str_from(start_bpos, |s| {
-            num::from_str_radix(s, 10).unwrap_or_else(|| {
+            num::from_str_radix(s, 10).ok().unwrap_or_else(|| {
                 panic!("expected digits representing a name, got {:?}, {}, range [{:?},{:?}]",
                       s, whence, start_bpos, self.last_pos);
             })
@@ -631,7 +631,7 @@ impl<'a> StringReader<'a> {
         let start_bpos = self.last_pos;
         self.scan_digits(base);
         let encoded_ctxt : ast::SyntaxContext = self.with_str_from(start_bpos, |s| {
-            num::from_str_radix(s, 10).unwrap_or_else(|| {
+            num::from_str_radix(s, 10).ok().unwrap_or_else(|| {
                 panic!("expected digits representing a ctxt, got {:?}, {}", s, whence);
             })
         });
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 1c146968fd5..e7be876edbb 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -401,7 +401,7 @@ pub fn char_lit(lit: &str) -> (char, isize) {
     let msg2 = &msg[];
 
     fn esc(len: usize, lit: &str) -> Option<(char, isize)> {
-        num::from_str_radix(&lit[2..len], 16)
+        num::from_str_radix(&lit[2..len], 16).ok()
         .and_then(char::from_u32)
         .map(|x| (x, len as isize))
     }
@@ -410,7 +410,7 @@ pub fn char_lit(lit: &str) -> (char, isize) {
         if lit.as_bytes()[2] == b'{' {
             let idx = lit.find('}').expect(msg2);
             let subslice = &lit[3..idx];
-            num::from_str_radix(subslice, 16)
+            num::from_str_radix(subslice, 16).ok()
                 .and_then(char::from_u32)
                 .map(|x| (x, subslice.chars().count() as isize + 4))
         } else {
@@ -583,7 +583,7 @@ pub fn byte_lit(lit: &str) -> (u8, usize) {
             b'\'' => b'\'',
             b'0' => b'\0',
             _ => {
-                match ::std::num::from_str_radix::<u64>(&lit[2..4], 16) {
+                match ::std::num::from_str_radix::<u64>(&lit[2..4], 16).ok() {
                     Some(c) =>
                         if c > 0xFF {
                             panic!(err(2))
@@ -732,7 +732,7 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
     debug!("integer_lit: the type is {:?}, base {:?}, the new string is {:?}, the original \
            string was {:?}, the original suffix was {:?}", ty, base, s, orig, suffix);
 
-    let res: u64 = match ::std::num::from_str_radix(s, base) {
+    let res: u64 = match ::std::num::from_str_radix(s, base).ok() {
         Some(r) => r,
         None => { sd.span_err(sp, "int literal is too large"); 0 }
     };
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index c4224db8e18..d99095eeba3 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2459,7 +2459,7 @@ impl<'a> Parser<'a> {
                     hi = self.span.hi;
                     self.bump();
 
-                    let index = n.as_str().parse::<usize>();
+                    let index = n.as_str().parse::<usize>().ok();
                     match index {
                         Some(n) => {
                             let id = spanned(dot, hi, n);
@@ -2479,7 +2479,7 @@ impl<'a> Parser<'a> {
                     self.span_err(last_span,
                                   &format!("unexpected token: `{}`", n.as_str())[]);
                     if fstr.chars().all(|x| "0123456789.".contains_char(x)) {
-                        let float = match fstr.parse::<f64>() {
+                        let float = match fstr.parse::<f64>().ok() {
                             Some(f) => f,
                             None => continue,
                         };
diff --git a/src/libsyntax/show_span.rs b/src/libsyntax/show_span.rs
index 57520257fe1..6492cd4b095 100644
--- a/src/libsyntax/show_span.rs
+++ b/src/libsyntax/show_span.rs
@@ -27,14 +27,15 @@ enum Mode {
 }
 
 impl FromStr for Mode {
-    fn from_str(s: &str) -> Option<Mode> {
+    type Err = ();
+    fn from_str(s: &str) -> Result<Mode, ()> {
         let mode = match s {
             "expr" => Mode::Expression,
             "pat" => Mode::Pattern,
             "ty" => Mode::Type,
-            _ => return None
+            _ => return Err(())
         };
-        Some(mode)
+        Ok(mode)
     }
 }
 
@@ -73,7 +74,7 @@ impl<'a, 'v> Visitor<'v> for ShowSpanVisitor<'a> {
 pub fn run(span_diagnostic: &diagnostic::SpanHandler,
            mode: &str,
            krate: &ast::Crate) {
-    let mode = match mode.parse() {
+    let mode = match mode.parse().ok() {
         Some(mode) => mode,
         None => return
     };
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 4497832ba7e..da893ec251a 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -76,7 +76,6 @@ use std::old_io;
 use std::iter::repeat;
 use std::num::{Float, Int};
 use std::os;
-use std::str::FromStr;
 use std::sync::mpsc::{channel, Sender};
 use std::thread::{self, Thread};
 use std::thunk::{Thunk, Invoke};
@@ -820,7 +819,7 @@ fn get_concurrency() -> uint {
     use std::rt;
     match os::getenv("RUST_TEST_TASKS") {
         Some(s) => {
-            let opt_n: Option<uint> = FromStr::from_str(s.as_slice());
+            let opt_n: Option<uint> = s.parse().ok();
             match opt_n {
                 Some(n) if n > 0 => n,
                 _ => panic!("RUST_TEST_TASKS is `{}`, should be a positive integer.", s)
diff --git a/src/test/auxiliary/static-methods-crate.rs b/src/test/auxiliary/static-methods-crate.rs
index 1b18571cf8c..6cb16f04ce1 100644
--- a/src/test/auxiliary/static-methods-crate.rs
+++ b/src/test/auxiliary/static-methods-crate.rs
@@ -19,7 +19,7 @@ pub trait read {
 
 impl read for int {
     fn readMaybe(s: String) -> Option<int> {
-        s.parse()
+        s.parse().ok()
     }
 }
 
diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs
index 7fad2c9b4be..15a63e153b9 100644
--- a/src/test/bench/shootout-chameneos-redux.rs
+++ b/src/test/bench/shootout-chameneos-redux.rs
@@ -232,7 +232,7 @@ fn main() {
     } else {
         std::os::args().as_slice()
                        .get(1)
-                       .and_then(|arg| arg.parse())
+                       .and_then(|arg| arg.parse().ok())
                        .unwrap_or(600u)
     };
 
diff --git a/src/test/bench/shootout-fannkuch-redux.rs b/src/test/bench/shootout-fannkuch-redux.rs
index e12a9e7cb16..03666c84d57 100644
--- a/src/test/bench/shootout-fannkuch-redux.rs
+++ b/src/test/bench/shootout-fannkuch-redux.rs
@@ -182,7 +182,7 @@ fn fannkuch(n: i32) -> (i32, i32) {
 fn main() {
     let n = std::os::args().as_slice()
         .get(1)
-        .and_then(|arg| arg.parse())
+        .and_then(|arg| arg.parse().ok())
         .unwrap_or(2i32);
 
     let (checksum, maxflips) = fannkuch(n);
diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs
index 7325b8a4738..b2161000322 100644
--- a/src/test/bench/shootout-nbody.rs
+++ b/src/test/bench/shootout-nbody.rs
@@ -174,7 +174,7 @@ fn main() {
         5000000
     } else {
         std::os::args().get(1)
-            .and_then(|arg| arg.parse())
+            .and_then(|arg| arg.parse().ok())
             .unwrap_or(1000)
     };
     let mut bodies = BODIES;
diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs
index 47f17997e84..ebe8a0751c3 100644
--- a/src/test/bench/shootout-threadring.rs
+++ b/src/test/bench/shootout-threadring.rs
@@ -68,10 +68,10 @@ fn main() {
     let token = if std::os::getenv("RUST_BENCH").is_some() {
         2000000
     } else {
-        args.get(1).and_then(|arg| arg.parse()).unwrap_or(1000)
+        args.get(1).and_then(|arg| arg.parse().ok()).unwrap_or(1000)
     };
     let n_tasks = args.get(2)
-                      .and_then(|arg| arg.parse())
+                      .and_then(|arg| arg.parse().ok())
                       .unwrap_or(503);
 
     start(n_tasks, token);
diff --git a/src/test/run-pass/match-with-ret-arm.rs b/src/test/run-pass/match-with-ret-arm.rs
index a1537e63e57..05c6aac90e3 100644
--- a/src/test/run-pass/match-with-ret-arm.rs
+++ b/src/test/run-pass/match-with-ret-arm.rs
@@ -14,7 +14,7 @@ pub fn main() {
     // sometimes we have had trouble finding
     // the right type for f, as we unified
     // bot and u32 here
-    let f = match "1234".parse::<uint>() {
+    let f = match "1234".parse::<uint>().ok() {
         None => return (),
         Some(num) => num as u32
     };
diff --git a/src/test/run-pass/wait-forked-but-failed-child.rs b/src/test/run-pass/wait-forked-but-failed-child.rs
index ef48bdff11d..12de40129fd 100644
--- a/src/test/run-pass/wait-forked-but-failed-child.rs
+++ b/src/test/run-pass/wait-forked-but-failed-child.rs
@@ -41,7 +41,7 @@ fn find_zombies() {
         if 0 < line_no && 0 < line.len() &&
            my_pid == line.split(' ').filter(|w| 0 < w.len()).nth(1)
                          .expect("1st column should be PPID")
-                         .parse()
+                         .parse().ok()
                          .expect("PPID string into integer") &&
            line.contains("defunct") {
             panic!("Zombie child {}", line);