about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-02-03 10:41:34 -0800
committerbors <bors@rust-lang.org>2014-02-03 10:41:34 -0800
commitcb40eba4b1ce12914612914b94bdccd251a9f554 (patch)
tree5cb922f942920dc7d6b0f3606e9cd914360b2707
parentbe4fc638092bf896c5c6c0672136b83b71e491ee (diff)
parentc765a8e7ad314651b92ff860cda0159c79dbec6e (diff)
downloadrust-cb40eba4b1ce12914612914b94bdccd251a9f554.tar.gz
rust-cb40eba4b1ce12914612914b94bdccd251a9f554.zip
auto merge of #11946 : alexcrichton/rust/no-io-error, r=brson
Turns out this was a little more far-reaching than I thought it was.

The first commit is the crux of this stack of commits. The `io::io_error` condition is completely removed and the `read` and `write` methods are altered to return `IoResult<T>`. This turned out to be an incredibly far-reaching change!

Overall, I'm very happy with how this turned out (in addition with the `unused_must_use` lint). I had to almost rewrite the pretty printer in `libsyntax` as well as the the formatting in `librustdoc` (as one would expect). These two modules do *tons* of I/O, and I believe that it's definitely improved.

This pull request also introduces the `if_ok!()` macro for returning-early from something that returns a result. I made quite liberal use of this in mostly the pretty printer and html renderer, and I found its usage generally quite pleasant and convenient to have. I didn't really feel like adding any other macro while I was using it, and I figured that pretty printing could be nicer, but it's nowhere near horrid today.

This may be a controversial issue closing, but I'm going to say it.

Closes #6163
-rw-r--r--src/compiletest/compiletest.rs10
-rw-r--r--src/compiletest/procsrv.rs12
-rw-r--r--src/compiletest/runtest.rs20
-rw-r--r--src/doc/guide-conditions.md35
-rwxr-xr-xsrc/etc/combine-tests.py1
-rw-r--r--src/libextra/arc.rs20
-rw-r--r--src/libextra/base64.rs2
-rw-r--r--src/libextra/ebml.rs34
-rw-r--r--src/libextra/hex.rs2
-rw-r--r--src/libextra/json.rs145
-rw-r--r--src/libextra/lib.rs5
-rw-r--r--src/libextra/stats.rs43
-rw-r--r--src/libextra/sync.rs2
-rw-r--r--src/libextra/tempfile.rs5
-rw-r--r--src/libextra/test.rs211
-rw-r--r--src/libextra/time.rs16
-rw-r--r--src/libextra/url.rs26
-rw-r--r--src/libextra/uuid.rs2
-rw-r--r--src/libextra/workcache.rs23
-rw-r--r--src/libglob/lib.rs3
-rw-r--r--src/libgreen/macros.rs5
-rw-r--r--src/libnative/bookkeeping.rs2
-rw-r--r--src/libnative/io/file.rs29
-rw-r--r--src/libnative/io/net.rs4
-rw-r--r--src/libnative/io/process.rs45
-rw-r--r--src/libnative/io/timer_helper.rs4
-rw-r--r--src/libnative/io/timer_other.rs5
-rw-r--r--src/libnative/io/timer_timerfd.rs7
-rw-r--r--src/libnative/io/timer_win32.rs12
-rw-r--r--src/libnative/lib.rs4
-rw-r--r--src/libnative/task.rs3
-rw-r--r--src/librustc/back/archive.rs29
-rw-r--r--src/librustc/back/link.rs86
-rw-r--r--src/librustc/driver/driver.rs89
-rw-r--r--src/librustc/lib.rs11
-rw-r--r--src/librustc/metadata/decoder.rs33
-rw-r--r--src/librustc/metadata/encoder.rs75
-rw-r--r--src/librustc/metadata/filesearch.rs9
-rw-r--r--src/librustc/metadata/loader.rs4
-rw-r--r--src/librustc/metadata/tyencode.rs6
-rw-r--r--src/librustc/middle/dataflow.rs21
-rw-r--r--src/librustc/middle/liveness.rs6
-rw-r--r--src/librustdoc/html/escape.rs9
-rw-r--r--src/librustdoc/html/format.rs211
-rw-r--r--src/librustdoc/html/layout.rs3
-rw-r--r--src/librustdoc/html/markdown.rs13
-rw-r--r--src/librustdoc/html/render.rs652
-rw-r--r--src/librustdoc/lib.rs22
-rw-r--r--src/librustdoc/test.rs4
-rw-r--r--src/librustuv/file.rs9
-rw-r--r--src/librustuv/homing.rs4
-rw-r--r--src/librustuv/idle.rs4
-rw-r--r--src/librustuv/lib.rs5
-rw-r--r--src/librustuv/macros.rs11
-rw-r--r--src/librustuv/net.rs12
-rw-r--r--src/librustuv/pipe.rs2
-rw-r--r--src/librustuv/queue.rs2
-rw-r--r--src/librustuv/signal.rs2
-rw-r--r--src/librustuv/timer.rs18
-rw-r--r--src/librustuv/uvio.rs2
-rw-r--r--src/libstd/comm/mod.rs2
-rw-r--r--src/libstd/fmt/mod.rs227
-rw-r--r--src/libstd/hash.rs16
-rw-r--r--src/libstd/io/buffered.rs194
-rw-r--r--src/libstd/io/comm_adapters.rs62
-rw-r--r--src/libstd/io/extensions.rs134
-rw-r--r--src/libstd/io/fs.rs769
-rw-r--r--src/libstd/io/mem.rs222
-rw-r--r--src/libstd/io/mod.rs732
-rw-r--r--src/libstd/io/net/addrinfo.rs17
-rw-r--r--src/libstd/io/net/tcp.rs274
-rw-r--r--src/libstd/io/net/udp.rs124
-rw-r--r--src/libstd/io/net/unix.rs128
-rw-r--r--src/libstd/io/option.rs154
-rw-r--r--src/libstd/io/pipe.rs46
-rw-r--r--src/libstd/io/process.rs42
-rw-r--r--src/libstd/io/result.rs128
-rw-r--r--src/libstd/io/signal.rs39
-rw-r--r--src/libstd/io/stdio.rs95
-rw-r--r--src/libstd/io/timer.rs7
-rw-r--r--src/libstd/io/util.rs95
-rw-r--r--src/libstd/logging.rs11
-rw-r--r--src/libstd/macros.rs5
-rw-r--r--src/libstd/option.rs2
-rw-r--r--src/libstd/os.rs27
-rw-r--r--src/libstd/path/mod.rs2
-rw-r--r--src/libstd/rand/os.rs2
-rw-r--r--src/libstd/rand/reader.rs18
-rw-r--r--src/libstd/reflect.rs2
-rw-r--r--src/libstd/repr.rs206
-rw-r--r--src/libstd/result.rs2
-rw-r--r--src/libstd/rt/rtio.rs23
-rw-r--r--src/libstd/rt/task.rs5
-rw-r--r--src/libstd/rt/unwind.rs7
-rw-r--r--src/libstd/rt/util.rs7
-rw-r--r--src/libstd/run.rs120
-rw-r--r--src/libstd/task.rs2
-rw-r--r--src/libstd/to_bytes.rs2
-rw-r--r--src/libstd/unstable/sync.rs2
-rw-r--r--src/libsyntax/diagnostic.rs112
-rw-r--r--src/libsyntax/ext/expand.rs9
-rw-r--r--src/libsyntax/ext/source_util.rs9
-rw-r--r--src/libsyntax/fold.rs6
-rw-r--r--src/libsyntax/lib.rs5
-rw-r--r--src/libsyntax/parse/comments.rs3
-rw-r--r--src/libsyntax/parse/mod.rs5
-rw-r--r--src/libsyntax/parse/token.rs4
-rw-r--r--src/libsyntax/print/pp.rs105
-rw-r--r--src/libsyntax/print/pprust.rs2139
-rw-r--r--src/libsyntax/util/parser_testing.rs18
-rw-r--r--src/libterm/lib.rs52
-rw-r--r--src/libterm/terminfo/parser/compiled.rs33
-rw-r--r--src/libterm/terminfo/searcher.rs6
-rw-r--r--src/test/bench/shootout-mandelbrot.rs3
-rw-r--r--src/test/bench/shootout-reverse-complement.rs3
-rw-r--r--src/test/run-pass/capturing-logging.rs2
-rw-r--r--src/test/run-pass/core-run-destroy.rs19
-rw-r--r--src/test/run-pass/ifmt.rs15
-rw-r--r--src/test/run-pass/issue-8398.rs2
-rw-r--r--src/test/run-pass/logging-only-prints-once.rs3
-rw-r--r--src/test/run-pass/signal-exit-status.rs3
-rw-r--r--src/test/run-pass/stat.rs6
122 files changed, 4359 insertions, 4246 deletions
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index cbe4c52b47e..8896b44f060 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -234,7 +234,13 @@ pub fn run_tests(config: &config) {
     // For context, see #8904
     io::test::raise_fd_limit();
     let res = test::run_tests_console(&opts, tests);
-    if !res { fail!("Some tests failed"); }
+    match res {
+        Ok(true) => {}
+        Ok(false) => fail!("Some tests failed"),
+        Err(e) => {
+            println!("I/O failure during tests: {}", e);
+        }
+    }
 }
 
 pub fn test_opts(config: &config) -> test::TestOpts {
@@ -255,7 +261,7 @@ pub fn make_tests(config: &config) -> ~[test::TestDescAndFn] {
     debug!("making tests from {}",
            config.src_base.display());
     let mut tests = ~[];
-    let dirs = fs::readdir(&config.src_base);
+    let dirs = fs::readdir(&config.src_base).unwrap();
     for file in dirs.iter() {
         let file = file.clone();
         debug!("inspecting file {}", file.display());
diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs
index 83fb267b0e7..019803a9337 100644
--- a/src/compiletest/procsrv.rs
+++ b/src/compiletest/procsrv.rs
@@ -58,9 +58,9 @@ pub fn run(lib_path: &str,
     });
 
     match opt_process {
-        Some(ref mut process) => {
+        Ok(ref mut process) => {
             for input in input.iter() {
-                process.input().write(input.as_bytes());
+                process.input().write(input.as_bytes()).unwrap();
             }
             let run::ProcessOutput { status, output, error } = process.finish_with_output();
 
@@ -70,7 +70,7 @@ pub fn run(lib_path: &str,
                 err: str::from_utf8_owned(error).unwrap()
             })
         },
-        None => None
+        Err(..) => None
     }
 }
 
@@ -90,13 +90,13 @@ pub fn run_background(lib_path: &str,
     });
 
     match opt_process {
-        Some(mut process) => {
+        Ok(mut process) => {
             for input in input.iter() {
-                process.input().write(input.as_bytes());
+                process.input().write(input.as_bytes()).unwrap();
             }
 
             Some(process)
         },
-        None => None
+        Err(..) => None
     }
 }
diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index c57d2492d45..0503790ae94 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -153,7 +153,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
     let rounds =
         match props.pp_exact { Some(_) => 1, None => 2 };
 
-    let src = File::open(testfile).read_to_end();
+    let src = File::open(testfile).read_to_end().unwrap();
     let src = str::from_utf8_owned(src).unwrap();
     let mut srcs = ~[src];
 
@@ -175,7 +175,7 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
     let mut expected = match props.pp_exact {
         Some(ref file) => {
             let filepath = testfile.dir_path().join(file);
-            let s = File::open(&filepath).read_to_end();
+            let s = File::open(&filepath).read_to_end().unwrap();
             str::from_utf8_owned(s).unwrap()
           }
           None => { srcs[srcs.len() - 2u].clone() }
@@ -318,8 +318,10 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
                 //waiting 1 second for gdbserver start
                 timer::sleep(1000);
                 let result = task::try(proc() {
-                    tcp::TcpStream::connect(
-                        SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 5039 });
+                    tcp::TcpStream::connect(SocketAddr {
+                        ip: Ipv4Addr(127, 0, 0, 1),
+                        port: 5039,
+                    }).unwrap();
                 });
                 if result.is_err() {
                     continue;
@@ -361,7 +363,7 @@ fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
                                stdout: out,
                                stderr: err,
                                cmdline: cmdline};
-            process.force_destroy();
+            process.force_destroy().unwrap();
         }
 
         _=> {
@@ -727,7 +729,7 @@ fn compose_and_run_compiler(
 
 fn ensure_dir(path: &Path) {
     if path.is_dir() { return; }
-    fs::mkdir(path, io::UserRWX);
+    fs::mkdir(path, io::UserRWX).unwrap();
 }
 
 fn compose_and_run(config: &config, testfile: &Path,
@@ -852,7 +854,7 @@ fn dump_output(config: &config, testfile: &Path, out: &str, err: &str) {
 fn dump_output_file(config: &config, testfile: &Path,
                     out: &str, extension: &str) {
     let outfile = make_out_name(config, testfile, extension);
-    File::create(&outfile).write(out.as_bytes());
+    File::create(&outfile).write(out.as_bytes()).unwrap();
 }
 
 fn make_out_name(config: &config, testfile: &Path, extension: &str) -> Path {
@@ -1003,7 +1005,7 @@ fn _arm_exec_compiled_test(config: &config, props: &TestProps,
 fn _arm_push_aux_shared_library(config: &config, testfile: &Path) {
     let tdir = aux_output_dir_name(config, testfile);
 
-    let dirs = fs::readdir(&tdir);
+    let dirs = fs::readdir(&tdir).unwrap();
     for file in dirs.iter() {
         if file.extension_str() == Some("so") {
             // FIXME (#9639): This needs to handle non-utf8 paths
@@ -1099,7 +1101,7 @@ fn disassemble_extract(config: &config, _props: &TestProps,
 
 
 fn count_extracted_lines(p: &Path) -> uint {
-    let x = File::open(&p.with_extension("ll")).read_to_end();
+    let x = File::open(&p.with_extension("ll")).read_to_end().unwrap();
     let x = str::from_utf8_owned(x).unwrap();
     x.lines().len()
 }
diff --git a/src/doc/guide-conditions.md b/src/doc/guide-conditions.md
index d97de779902..5b7494c0618 100644
--- a/src/doc/guide-conditions.md
+++ b/src/doc/guide-conditions.md
@@ -47,7 +47,7 @@ An example program that does this task reads like this:
 # #[allow(unused_imports)];
 use std::io::{BufferedReader, File};
 # mod BufferedReader {
-#     use std::io::File;
+#     use std::io::{File, IoResult};
 #     use std::io::MemReader;
 #     use std::io::BufferedReader;
 #     static s : &'static [u8] = bytes!("1 2\n\
@@ -55,7 +55,7 @@ use std::io::{BufferedReader, File};
 #                                        789 123\n\
 #                                        45 67\n\
 #                                        ");
-#     pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
+#     pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
 #           BufferedReader::new(MemReader::new(s.to_owned()))
 #     }
 # }
@@ -71,7 +71,6 @@ fn read_int_pairs() -> ~[(int,int)] {
     let mut pairs = ~[];
 
     // Path takes a generic by-value, rather than by reference
-#    let _g = std::io::ignore_io_error();
     let path = Path::new(&"foo.txt");
     let mut reader = BufferedReader::new(File::open(&path));
 
@@ -245,7 +244,7 @@ and trapping its exit status using `task::try`:
 use std::io::{BufferedReader, File};
 use std::task;
 # mod BufferedReader {
-#     use std::io::File;
+#     use std::io::{File, IoResult};
 #     use std::io::MemReader;
 #     use std::io::BufferedReader;
 #     static s : &'static [u8] = bytes!("1 2\n\
@@ -253,7 +252,7 @@ use std::task;
 #                                        789 123\n\
 #                                        45 67\n\
 #                                        ");
-#     pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
+#     pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
 #           BufferedReader::new(MemReader::new(s.to_owned()))
 #     }
 # }
@@ -277,7 +276,6 @@ fn main() {
 
 fn read_int_pairs() -> ~[(int,int)] {
     let mut pairs = ~[];
-#    let _g = std::io::ignore_io_error();
     let path = Path::new(&"foo.txt");
 
     let mut reader = BufferedReader::new(File::open(&path));
@@ -347,7 +345,7 @@ but similarly clear as the version that used `fail!` in the logic where the erro
 # #[allow(unused_imports)];
 use std::io::{BufferedReader, File};
 # mod BufferedReader {
-#     use std::io::File;
+#     use std::io::{File, IoResult};
 #     use std::io::MemReader;
 #     use std::io::BufferedReader;
 #     static s : &'static [u8] = bytes!("1 2\n\
@@ -355,7 +353,7 @@ use std::io::{BufferedReader, File};
 #                                        789 123\n\
 #                                        45 67\n\
 #                                        ");
-#     pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
+#     pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
 #           BufferedReader::new(MemReader::new(s.to_owned()))
 #     }
 # }
@@ -374,7 +372,6 @@ fn main() {
 
 fn read_int_pairs() -> ~[(int,int)] {
     let mut pairs = ~[];
-#    let _g = std::io::ignore_io_error();
     let path = Path::new(&"foo.txt");
 
     let mut reader = BufferedReader::new(File::open(&path));
@@ -415,7 +412,7 @@ and replaces bad input lines with the pair `(-1,-1)`:
 # #[allow(unused_imports)];
 use std::io::{BufferedReader, File};
 # mod BufferedReader {
-#     use std::io::File;
+#     use std::io::{File, IoResult};
 #     use std::io::MemReader;
 #     use std::io::BufferedReader;
 #     static s : &'static [u8] = bytes!("1 2\n\
@@ -423,7 +420,7 @@ use std::io::{BufferedReader, File};
 #                                        789 123\n\
 #                                        45 67\n\
 #                                        ");
-#     pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
+#     pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
 #           BufferedReader::new(MemReader::new(s.to_owned()))
 #     }
 # }
@@ -447,7 +444,6 @@ fn main() {
 
 fn read_int_pairs() -> ~[(int,int)] {
     let mut pairs = ~[];
-#    let _g = std::io::ignore_io_error();
     let path = Path::new(&"foo.txt");
 
     let mut reader = BufferedReader::new(File::open(&path));
@@ -489,7 +485,7 @@ Changing the condition's return type from `(int,int)` to `Option<(int,int)>` wil
 # #[allow(unused_imports)];
 use std::io::{BufferedReader, File};
 # mod BufferedReader {
-#     use std::io::File;
+#     use std::io::{IoResult, File};
 #     use std::io::MemReader;
 #     use std::io::BufferedReader;
 #     static s : &'static [u8] = bytes!("1 2\n\
@@ -497,7 +493,7 @@ use std::io::{BufferedReader, File};
 #                                        789 123\n\
 #                                        45 67\n\
 #                                        ");
-#     pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
+#     pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
 #           BufferedReader::new(MemReader::new(s.to_owned()))
 #     }
 # }
@@ -522,7 +518,6 @@ fn main() {
 
 fn read_int_pairs() -> ~[(int,int)] {
     let mut pairs = ~[];
-#    let _g = std::io::ignore_io_error();
     let path = Path::new(&"foo.txt");
 
     let mut reader = BufferedReader::new(File::open(&path));
@@ -573,7 +568,7 @@ This can be encoded in the handler API by introducing a helper type: `enum Malfo
 # #[allow(unused_imports)];
 use std::io::{BufferedReader, File};
 # mod BufferedReader {
-#     use std::io::File;
+#     use std::io::{File, IoResult};
 #     use std::io::MemReader;
 #     use std::io::BufferedReader;
 #     static s : &'static [u8] = bytes!("1 2\n\
@@ -581,7 +576,7 @@ use std::io::{BufferedReader, File};
 #                                        789 123\n\
 #                                        45 67\n\
 #                                        ");
-#     pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
+#     pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
 #           BufferedReader::new(MemReader::new(s.to_owned()))
 #     }
 # }
@@ -615,7 +610,6 @@ fn main() {
 
 fn read_int_pairs() -> ~[(int,int)] {
     let mut pairs = ~[];
-#    let _g = std::io::ignore_io_error();
     let path = Path::new(&"foo.txt");
 
     let mut reader = BufferedReader::new(File::open(&path));
@@ -696,7 +690,7 @@ a second condition and a helper function will suffice:
 # #[allow(unused_imports)];
 use std::io::{BufferedReader, File};
 # mod BufferedReader {
-#     use std::io::File;
+#     use std::io::{File, IoResult};
 #     use std::io::MemReader;
 #     use std::io::BufferedReader;
 #     static s : &'static [u8] = bytes!("1 2\n\
@@ -704,7 +698,7 @@ use std::io::{BufferedReader, File};
 #                                        789 123\n\
 #                                        45 67\n\
 #                                        ");
-#     pub fn new(_inner: Option<File>) -> BufferedReader<MemReader> {
+#     pub fn new(_inner: IoResult<File>) -> BufferedReader<MemReader> {
 #           BufferedReader::new(MemReader::new(s.to_owned()))
 #     }
 # }
@@ -752,7 +746,6 @@ fn parse_int(x: &str) -> int {
 
 fn read_int_pairs() -> ~[(int,int)] {
     let mut pairs = ~[];
-#    let _g = std::io::ignore_io_error();
     let path = Path::new(&"foo.txt");
 
     let mut reader = BufferedReader::new(File::open(&path));
diff --git a/src/etc/combine-tests.py b/src/etc/combine-tests.py
index e87187abbcb..457c0b683ac 100755
--- a/src/etc/combine-tests.py
+++ b/src/etc/combine-tests.py
@@ -69,6 +69,7 @@ extern mod run_pass_stage2;
 use run_pass_stage2::*;
 use std::io;
 use std::io::Writer;
+#[allow(warnings)]
 fn main() {
     let mut out = io::stdout();
 """
diff --git a/src/libextra/arc.rs b/src/libextra/arc.rs
index 43366d2aa6d..9615bdc2ad7 100644
--- a/src/libextra/arc.rs
+++ b/src/libextra/arc.rs
@@ -637,7 +637,7 @@ mod tests {
     fn test_mutex_arc_poison() {
         let arc = ~MutexArc::new(1);
         let arc2 = ~arc.clone();
-        task::try(proc() {
+        let _ = task::try(proc() {
             arc2.access(|one| {
                 assert_eq!(*one, 2);
             })
@@ -668,7 +668,7 @@ mod tests {
     fn test_mutex_arc_access_in_unwind() {
         let arc = MutexArc::new(1i);
         let arc2 = arc.clone();
-        task::try::<()>(proc() {
+        let _ = task::try::<()>(proc() {
             struct Unwinder {
                 i: MutexArc<int>
             }
@@ -687,7 +687,7 @@ mod tests {
     fn test_rw_arc_poison_wr() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        task::try(proc() {
+        let _ = task::try(proc() {
             arc2.write(|one| {
                 assert_eq!(*one, 2);
             })
@@ -701,7 +701,7 @@ mod tests {
     fn test_rw_arc_poison_ww() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        task::try(proc() {
+        let _ = task::try(proc() {
             arc2.write(|one| {
                 assert_eq!(*one, 2);
             })
@@ -714,7 +714,7 @@ mod tests {
     fn test_rw_arc_poison_dw() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        task::try(proc() {
+        let _ = task::try(proc() {
             arc2.write_downgrade(|mut write_mode| {
                 write_mode.write(|one| {
                     assert_eq!(*one, 2);
@@ -729,7 +729,7 @@ mod tests {
     fn test_rw_arc_no_poison_rr() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        task::try(proc() {
+        let _ = task::try(proc() {
             arc2.read(|one| {
                 assert_eq!(*one, 2);
             })
@@ -742,7 +742,7 @@ mod tests {
     fn test_rw_arc_no_poison_rw() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        task::try(proc() {
+        let _ = task::try(proc() {
             arc2.read(|one| {
                 assert_eq!(*one, 2);
             })
@@ -755,7 +755,7 @@ mod tests {
     fn test_rw_arc_no_poison_dr() {
         let arc = RWArc::new(1);
         let arc2 = arc.clone();
-        task::try(proc() {
+        let _ = task::try(proc() {
             arc2.write_downgrade(|write_mode| {
                 let read_mode = arc2.downgrade(write_mode);
                 read_mode.read(|one| {
@@ -800,7 +800,7 @@ mod tests {
 
         // Wait for children to pass their asserts
         for r in children.mut_iter() {
-            r.recv();
+            let _ = r.recv();
         }
 
         // Wait for writer to finish
@@ -814,7 +814,7 @@ mod tests {
     fn test_rw_arc_access_in_unwind() {
         let arc = RWArc::new(1i);
         let arc2 = arc.clone();
-        task::try::<()>(proc() {
+        let _ = task::try::<()>(proc() {
             struct Unwinder {
                 i: RWArc<int>
             }
diff --git a/src/libextra/base64.rs b/src/libextra/base64.rs
index 738afcd5c5f..556032af1ac 100644
--- a/src/libextra/base64.rs
+++ b/src/libextra/base64.rs
@@ -359,7 +359,7 @@ mod test {
                  ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
         let b = s.as_bytes().to_base64(STANDARD);
         bh.iter(|| {
-            b.from_base64();
+            b.from_base64().unwrap();
         });
         bh.bytes = b.len() as u64;
     }
diff --git a/src/libextra/ebml.rs b/src/libextra/ebml.rs
index 5bbea491ac2..1900313ab6c 100644
--- a/src/libextra/ebml.rs
+++ b/src/libextra/ebml.rs
@@ -12,6 +12,10 @@
 
 use std::str;
 
+macro_rules! if_ok( ($e:expr) => (
+    match $e { Ok(e) => e, Err(e) => { self.last_error = Err(e); return } }
+) )
+
 // Simple Extensible Binary Markup Language (ebml) reader and writer on a
 // cursor model. See the specification here:
 //     http://www.matroska.org/technical/specs/rfc/index.html
@@ -595,9 +599,15 @@ pub mod writer {
 
     // ebml writing
     pub struct Encoder<'a> {
-        // FIXME(#5665): this should take a trait object
+        // FIXME(#5665): this should take a trait object. Note that if you
+        //               delete this comment you should consider removing the
+        //               unwrap()'s below of the results of the calls to
+        //               write(). We're guaranteed that writing into a MemWriter
+        //               won't fail, but this is not true for all I/O streams in
+        //               general.
         writer: &'a mut MemWriter,
         priv size_positions: ~[uint],
+        last_error: io::IoResult<()>,
     }
 
     fn write_sized_vuint(w: &mut MemWriter, n: uint, size: uint) {
@@ -609,7 +619,7 @@ pub mod writer {
             4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
                             (n >> 8_u) as u8, n as u8]),
             _ => fail!("vint to write too big: {}", n)
-        };
+        }.unwrap()
     }
 
     fn write_vuint(w: &mut MemWriter, n: uint) {
@@ -624,7 +634,8 @@ pub mod writer {
         let size_positions: ~[uint] = ~[];
         Encoder {
             writer: w,
-            size_positions: size_positions
+            size_positions: size_positions,
+            last_error: Ok(()),
         }
     }
 
@@ -635,6 +646,7 @@ pub mod writer {
             Encoder {
                 writer: cast::transmute_copy(&self.writer),
                 size_positions: self.size_positions.clone(),
+                last_error: Ok(()),
             }
         }
 
@@ -645,18 +657,18 @@ pub mod writer {
             write_vuint(self.writer, tag_id);
 
             // Write a placeholder four-byte size.
-            self.size_positions.push(self.writer.tell() as uint);
+            self.size_positions.push(if_ok!(self.writer.tell()) as uint);
             let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
-            self.writer.write(zeroes);
+            if_ok!(self.writer.write(zeroes));
         }
 
         pub fn end_tag(&mut self) {
             let last_size_pos = self.size_positions.pop().unwrap();
-            let cur_pos = self.writer.tell();
-            self.writer.seek(last_size_pos as i64, io::SeekSet);
+            let cur_pos = if_ok!(self.writer.tell());
+            if_ok!(self.writer.seek(last_size_pos as i64, io::SeekSet));
             let size = (cur_pos as uint - last_size_pos - 4);
             write_sized_vuint(self.writer, size, 4u);
-            self.writer.seek(cur_pos as i64, io::SeekSet);
+            if_ok!(self.writer.seek(cur_pos as i64, io::SeekSet));
 
             debug!("End tag (size = {})", size);
         }
@@ -670,7 +682,7 @@ pub mod writer {
         pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) {
             write_vuint(self.writer, tag_id);
             write_vuint(self.writer, b.len());
-            self.writer.write(b);
+            self.writer.write(b).unwrap();
         }
 
         pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) {
@@ -723,12 +735,12 @@ pub mod writer {
 
         pub fn wr_bytes(&mut self, b: &[u8]) {
             debug!("Write {} bytes", b.len());
-            self.writer.write(b);
+            self.writer.write(b).unwrap();
         }
 
         pub fn wr_str(&mut self, s: &str) {
             debug!("Write str: {}", s);
-            self.writer.write(s.as_bytes());
+            self.writer.write(s.as_bytes()).unwrap();
         }
     }
 
diff --git a/src/libextra/hex.rs b/src/libextra/hex.rs
index 4fd59bb3aa5..d4e1ae12337 100644
--- a/src/libextra/hex.rs
+++ b/src/libextra/hex.rs
@@ -201,7 +201,7 @@ mod tests {
                  ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
         let b = s.as_bytes().to_hex();
         bh.iter(|| {
-            b.from_hex();
+            b.from_hex().unwrap();
         });
         bh.bytes = b.len() as u64;
     }
diff --git a/src/libextra/json.rs b/src/libextra/json.rs
index f8b1c216529..ef8e0999521 100644
--- a/src/libextra/json.rs
+++ b/src/libextra/json.rs
@@ -234,6 +234,10 @@ use serialize::Encodable;
 use serialize;
 use treemap::TreeMap;
 
+macro_rules! if_ok( ($e:expr) => (
+    match $e { Ok(e) => e, Err(e) => { self.error = Err(e); return } }
+) )
+
 /// Represents a json value
 #[deriving(Clone, Eq)]
 pub enum Json {
@@ -260,6 +264,14 @@ pub struct Error {
     priv msg: ~str,
 }
 
+fn io_error_to_error(io: io::IoError) -> Error {
+    Error {
+        line: 0,
+        col: 0,
+        msg: format!("io error: {}", io)
+    }
+}
+
 fn escape_str(s: &str) -> ~str {
     let mut escaped = ~"\"";
     for c in s.chars() {
@@ -289,13 +301,14 @@ fn spaces(n: uint) -> ~str {
 /// A structure for implementing serialization to JSON.
 pub struct Encoder<'a> {
     priv wr: &'a mut io::Writer,
+    priv error: io::IoResult<()>,
 }
 
 impl<'a> Encoder<'a> {
     /// Creates a new JSON encoder whose output will be written to the writer
     /// specified.
     pub fn new<'a>(wr: &'a mut io::Writer) -> Encoder<'a> {
-        Encoder { wr: wr }
+        Encoder { wr: wr, error: Ok(()) }
     }
 
     /// Encode the specified struct into a json [u8]
@@ -317,7 +330,7 @@ impl<'a> Encoder<'a> {
 }
 
 impl<'a> serialize::Encoder for Encoder<'a> {
-    fn emit_nil(&mut self) { write!(self.wr, "null") }
+    fn emit_nil(&mut self) { if_ok!(write!(self.wr, "null")) }
 
     fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); }
     fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); }
@@ -333,20 +346,20 @@ impl<'a> serialize::Encoder for Encoder<'a> {
 
     fn emit_bool(&mut self, v: bool) {
         if v {
-            write!(self.wr, "true");
+            if_ok!(write!(self.wr, "true"));
         } else {
-            write!(self.wr, "false");
+            if_ok!(write!(self.wr, "false"));
         }
     }
 
     fn emit_f64(&mut self, v: f64) {
-        write!(self.wr, "{}", f64::to_str_digits(v, 6u))
+        if_ok!(write!(self.wr, "{}", f64::to_str_digits(v, 6u)))
     }
     fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); }
 
     fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) }
     fn emit_str(&mut self, v: &str) {
-        write!(self.wr, "{}", escape_str(v))
+        if_ok!(write!(self.wr, "{}", escape_str(v)))
     }
 
     fn emit_enum(&mut self, _name: &str, f: |&mut Encoder<'a>|) { f(self) }
@@ -360,19 +373,19 @@ impl<'a> serialize::Encoder for Encoder<'a> {
         // Bunny => "Bunny"
         // Kangaroo(34,"William") => {"variant": "Kangaroo", "fields": [34,"William"]}
         if cnt == 0 {
-            write!(self.wr, "{}", escape_str(name));
+            if_ok!(write!(self.wr, "{}", escape_str(name)));
         } else {
-            write!(self.wr, "\\{\"variant\":");
-            write!(self.wr, "{}", escape_str(name));
-            write!(self.wr, ",\"fields\":[");
+            if_ok!(write!(self.wr, "\\{\"variant\":"));
+            if_ok!(write!(self.wr, "{}", escape_str(name)));
+            if_ok!(write!(self.wr, ",\"fields\":["));
             f(self);
-            write!(self.wr, "]\\}");
+            if_ok!(write!(self.wr, "]\\}"));
         }
     }
 
     fn emit_enum_variant_arg(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
         if idx != 0 {
-            write!(self.wr, ",");
+            if_ok!(write!(self.wr, ","));
         }
         f(self);
     }
@@ -393,17 +406,17 @@ impl<'a> serialize::Encoder for Encoder<'a> {
     }
 
     fn emit_struct(&mut self, _: &str, _: uint, f: |&mut Encoder<'a>|) {
-        write!(self.wr, r"\{");
+        if_ok!(write!(self.wr, r"\{"));
         f(self);
-        write!(self.wr, r"\}");
+        if_ok!(write!(self.wr, r"\}"));
     }
 
     fn emit_struct_field(&mut self,
                          name: &str,
                          idx: uint,
                          f: |&mut Encoder<'a>|) {
-        if idx != 0 { write!(self.wr, ",") }
-        write!(self.wr, "{}:", escape_str(name));
+        if idx != 0 { if_ok!(write!(self.wr, ",")) }
+        if_ok!(write!(self.wr, "{}:", escape_str(name)));
         f(self);
     }
 
@@ -429,31 +442,31 @@ impl<'a> serialize::Encoder for Encoder<'a> {
     fn emit_option_some(&mut self, f: |&mut Encoder<'a>|) { f(self); }
 
     fn emit_seq(&mut self, _len: uint, f: |&mut Encoder<'a>|) {
-        write!(self.wr, "[");
+        if_ok!(write!(self.wr, "["));
         f(self);
-        write!(self.wr, "]");
+        if_ok!(write!(self.wr, "]"));
     }
 
     fn emit_seq_elt(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
         if idx != 0 {
-            write!(self.wr, ",");
+            if_ok!(write!(self.wr, ","));
         }
         f(self)
     }
 
     fn emit_map(&mut self, _len: uint, f: |&mut Encoder<'a>|) {
-        write!(self.wr, r"\{");
+        if_ok!(write!(self.wr, r"\{"));
         f(self);
-        write!(self.wr, r"\}");
+        if_ok!(write!(self.wr, r"\}"));
     }
 
     fn emit_map_elt_key(&mut self, idx: uint, f: |&mut Encoder<'a>|) {
-        if idx != 0 { write!(self.wr, ",") }
+        if idx != 0 { if_ok!(write!(self.wr, ",")) }
         f(self)
     }
 
     fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut Encoder<'a>|) {
-        write!(self.wr, ":");
+        if_ok!(write!(self.wr, ":"));
         f(self)
     }
 }
@@ -463,6 +476,7 @@ impl<'a> serialize::Encoder for Encoder<'a> {
 pub struct PrettyEncoder<'a> {
     priv wr: &'a mut io::Writer,
     priv indent: uint,
+    priv error: io::IoResult<()>,
 }
 
 impl<'a> PrettyEncoder<'a> {
@@ -471,12 +485,13 @@ impl<'a> PrettyEncoder<'a> {
         PrettyEncoder {
             wr: wr,
             indent: 0,
+            error: Ok(())
         }
     }
 }
 
 impl<'a> serialize::Encoder for PrettyEncoder<'a> {
-    fn emit_nil(&mut self) { write!(self.wr, "null") }
+    fn emit_nil(&mut self) { if_ok!(write!(self.wr, "null")); }
 
     fn emit_uint(&mut self, v: uint) { self.emit_f64(v as f64); }
     fn emit_u64(&mut self, v: u64) { self.emit_f64(v as f64); }
@@ -492,19 +507,21 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
 
     fn emit_bool(&mut self, v: bool) {
         if v {
-            write!(self.wr, "true");
+            if_ok!(write!(self.wr, "true"));
         } else {
-            write!(self.wr, "false");
+            if_ok!(write!(self.wr, "false"));
         }
     }
 
     fn emit_f64(&mut self, v: f64) {
-        write!(self.wr, "{}", f64::to_str_digits(v, 6u))
+        if_ok!(write!(self.wr, "{}", f64::to_str_digits(v, 6u)));
     }
     fn emit_f32(&mut self, v: f32) { self.emit_f64(v as f64); }
 
     fn emit_char(&mut self, v: char) { self.emit_str(str::from_char(v)) }
-    fn emit_str(&mut self, v: &str) { write!(self.wr, "{}", escape_str(v)); }
+    fn emit_str(&mut self, v: &str) {
+        if_ok!(write!(self.wr, "{}", escape_str(v)));
+    }
 
     fn emit_enum(&mut self, _name: &str, f: |&mut PrettyEncoder<'a>|) {
         f(self)
@@ -516,13 +533,14 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
                          cnt: uint,
                          f: |&mut PrettyEncoder<'a>|) {
         if cnt == 0 {
-            write!(self.wr, "{}", escape_str(name));
+            if_ok!(write!(self.wr, "{}", escape_str(name)));
         } else {
             self.indent += 2;
-            write!(self.wr, "[\n{}{},\n", spaces(self.indent), escape_str(name));
+            if_ok!(write!(self.wr, "[\n{}{},\n", spaces(self.indent),
+                          escape_str(name)));
             f(self);
             self.indent -= 2;
-            write!(self.wr, "\n{}]", spaces(self.indent));
+            if_ok!(write!(self.wr, "\n{}]", spaces(self.indent)));
         }
     }
 
@@ -530,9 +548,9 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
                              idx: uint,
                              f: |&mut PrettyEncoder<'a>|) {
         if idx != 0 {
-            write!(self.wr, ",\n");
+            if_ok!(write!(self.wr, ",\n"));
         }
-        write!(self.wr, "{}", spaces(self.indent));
+        if_ok!(write!(self.wr, "{}", spaces(self.indent)));
         f(self)
     }
 
@@ -557,13 +575,13 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
                    len: uint,
                    f: |&mut PrettyEncoder<'a>|) {
         if len == 0 {
-            write!(self.wr, "\\{\\}");
+            if_ok!(write!(self.wr, "\\{\\}"));
         } else {
-            write!(self.wr, "\\{");
+            if_ok!(write!(self.wr, "\\{"));
             self.indent += 2;
             f(self);
             self.indent -= 2;
-            write!(self.wr, "\n{}\\}", spaces(self.indent));
+            if_ok!(write!(self.wr, "\n{}\\}", spaces(self.indent)));
         }
     }
 
@@ -572,11 +590,11 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
                          idx: uint,
                          f: |&mut PrettyEncoder<'a>|) {
         if idx == 0 {
-            write!(self.wr, "\n");
+            if_ok!(write!(self.wr, "\n"));
         } else {
-            write!(self.wr, ",\n");
+            if_ok!(write!(self.wr, ",\n"));
         }
-        write!(self.wr, "{}{}: ", spaces(self.indent), escape_str(name));
+        if_ok!(write!(self.wr, "{}{}: ", spaces(self.indent), escape_str(name)));
         f(self);
     }
 
@@ -605,50 +623,50 @@ impl<'a> serialize::Encoder for PrettyEncoder<'a> {
 
     fn emit_seq(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) {
         if len == 0 {
-            write!(self.wr, "[]");
+            if_ok!(write!(self.wr, "[]"));
         } else {
-            write!(self.wr, "[");
+            if_ok!(write!(self.wr, "["));
             self.indent += 2;
             f(self);
             self.indent -= 2;
-            write!(self.wr, "\n{}]", spaces(self.indent));
+            if_ok!(write!(self.wr, "\n{}]", spaces(self.indent)));
         }
     }
 
     fn emit_seq_elt(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) {
         if idx == 0 {
-            write!(self.wr, "\n");
+            if_ok!(write!(self.wr, "\n"));
         } else {
-            write!(self.wr, ",\n");
+            if_ok!(write!(self.wr, ",\n"));
         }
-        write!(self.wr, "{}", spaces(self.indent));
+        if_ok!(write!(self.wr, "{}", spaces(self.indent)));
         f(self)
     }
 
     fn emit_map(&mut self, len: uint, f: |&mut PrettyEncoder<'a>|) {
         if len == 0 {
-            write!(self.wr, "\\{\\}");
+            if_ok!(write!(self.wr, "\\{\\}"));
         } else {
-            write!(self.wr, "\\{");
+            if_ok!(write!(self.wr, "\\{"));
             self.indent += 2;
             f(self);
             self.indent -= 2;
-            write!(self.wr, "\n{}\\}", spaces(self.indent));
+            if_ok!(write!(self.wr, "\n{}\\}", spaces(self.indent)));
         }
     }
 
     fn emit_map_elt_key(&mut self, idx: uint, f: |&mut PrettyEncoder<'a>|) {
         if idx == 0 {
-            write!(self.wr, "\n");
+            if_ok!(write!(self.wr, "\n"));
         } else {
-            write!(self.wr, ",\n");
+            if_ok!(write!(self.wr, ",\n"));
         }
-        write!(self.wr, "{}", spaces(self.indent));
+        if_ok!(write!(self.wr, "{}", spaces(self.indent)));
         f(self);
     }
 
     fn emit_map_elt_val(&mut self, _idx: uint, f: |&mut PrettyEncoder<'a>|) {
-        write!(self.wr, ": ");
+        if_ok!(write!(self.wr, ": "));
         f(self);
     }
 }
@@ -668,22 +686,24 @@ impl<E: serialize::Encoder> serialize::Encodable<E> for Json {
 
 impl Json{
     /// Encodes a json value into a io::writer.  Uses a single line.
-    pub fn to_writer(&self, wr: &mut io::Writer) {
+    pub fn to_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> {
         let mut encoder = Encoder::new(wr);
-        self.encode(&mut encoder)
+        self.encode(&mut encoder);
+        encoder.error
     }
 
     /// Encodes a json value into a io::writer.
     /// Pretty-prints in a more readable format.
-    pub fn to_pretty_writer(&self, wr: &mut io::Writer) {
+    pub fn to_pretty_writer(&self, wr: &mut io::Writer) -> io::IoResult<()> {
         let mut encoder = PrettyEncoder::new(wr);
-        self.encode(&mut encoder)
+        self.encode(&mut encoder);
+        encoder.error
     }
 
     /// Encodes a json value into a string
     pub fn to_pretty_str(&self) -> ~str {
         let mut s = MemWriter::new();
-        self.to_pretty_writer(&mut s as &mut io::Writer);
+        self.to_pretty_writer(&mut s as &mut io::Writer).unwrap();
         str::from_utf8_owned(s.unwrap()).unwrap()
     }
 }
@@ -1067,7 +1087,14 @@ impl<T : Iterator<char>> Parser<T> {
 
 /// Decodes a json value from an `&mut io::Reader`
 pub fn from_reader(rdr: &mut io::Reader) -> Result<Json, Error> {
-    let s = str::from_utf8_owned(rdr.read_to_end()).unwrap();
+    let contents = match rdr.read_to_end() {
+        Ok(c) => c,
+        Err(e) => return Err(io_error_to_error(e))
+    };
+    let s = match str::from_utf8_owned(contents) {
+        Some(s) => s,
+        None => return Err(Error { line: 0, col: 0, msg: ~"contents not utf-8" })
+    };
     let mut parser = Parser::new(s.chars());
     parser.parse()
 }
@@ -1540,7 +1567,7 @@ impl to_str::ToStr for Json {
     /// Encodes a json value into a string
     fn to_str(&self) -> ~str {
         let mut s = MemWriter::new();
-        self.to_writer(&mut s as &mut io::Writer);
+        self.to_writer(&mut s as &mut io::Writer).unwrap();
         str::from_utf8_owned(s.unwrap()).unwrap()
     }
 }
diff --git a/src/libextra/lib.rs b/src/libextra/lib.rs
index e2a4b52c810..358dca5e5ac 100644
--- a/src/libextra/lib.rs
+++ b/src/libextra/lib.rs
@@ -34,6 +34,11 @@ Rust extras are part of the standard Rust distribution.
 #[deny(non_camel_case_types)];
 #[deny(missing_doc)];
 
+#[cfg(stage0)]
+macro_rules! if_ok (
+    ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
+)
+
 // Utility modules
 
 pub mod c_vec;
diff --git a/src/libextra/stats.rs b/src/libextra/stats.rs
index 096e5882774..8752020f564 100644
--- a/src/libextra/stats.rs
+++ b/src/libextra/stats.rs
@@ -322,14 +322,15 @@ pub fn winsorize(samples: &mut [f64], pct: f64) {
 }
 
 /// Render writes the min, max and quartiles of the provided `Summary` to the provided `Writer`.
-pub fn write_5_number_summary(w: &mut io::Writer, s: &Summary) {
+pub fn write_5_number_summary(w: &mut io::Writer,
+                              s: &Summary) -> io::IoResult<()> {
     let (q1,q2,q3) = s.quartiles;
     write!(w, "(min={}, q1={}, med={}, q3={}, max={})",
                      s.min,
                      q1,
                      q2,
                      q3,
-                     s.max);
+                     s.max)
 }
 
 /// Render a boxplot to the provided writer. The boxplot shows the min, max and quartiles of the
@@ -344,7 +345,8 @@ pub fn write_5_number_summary(w: &mut io::Writer, s: &Summary) {
 ///   10 |        [--****#******----------]          | 40
 /// ~~~~
 
-pub fn write_boxplot(w: &mut io::Writer, s: &Summary, width_hint: uint) {
+pub fn write_boxplot(w: &mut io::Writer, s: &Summary,
+                     width_hint: uint) -> io::IoResult<()> {
 
     let (q1,q2,q3) = s.quartiles;
 
@@ -374,48 +376,49 @@ pub fn write_boxplot(w: &mut io::Writer, s: &Summary, width_hint: uint) {
     let range_width = width_hint - overhead_width;;
     let char_step = range / (range_width as f64);
 
-    write!(w, "{} |", lostr);
+    if_ok!(write!(w, "{} |", lostr));
 
     let mut c = 0;
     let mut v = lo;
 
     while c < range_width && v < s.min {
-        write!(w, " ");
+        if_ok!(write!(w, " "));
         v += char_step;
         c += 1;
     }
-    write!(w, "[");
+    if_ok!(write!(w, "["));
     c += 1;
     while c < range_width && v < q1 {
-        write!(w, "-");
+        if_ok!(write!(w, "-"));
         v += char_step;
         c += 1;
     }
     while c < range_width && v < q2 {
-        write!(w, "*");
+        if_ok!(write!(w, "*"));
         v += char_step;
         c += 1;
     }
-    write!(w, r"\#");
+    if_ok!(write!(w, r"\#"));
     c += 1;
     while c < range_width && v < q3 {
-        write!(w, "*");
+        if_ok!(write!(w, "*"));
         v += char_step;
         c += 1;
     }
     while c < range_width && v < s.max {
-        write!(w, "-");
+        if_ok!(write!(w, "-"));
         v += char_step;
         c += 1;
     }
-    write!(w, "]");
+    if_ok!(write!(w, "]"));
     while c < range_width {
-        write!(w, " ");
+        if_ok!(write!(w, " "));
         v += char_step;
         c += 1;
     }
 
-    write!(w, "| {}", histr);
+    if_ok!(write!(w, "| {}", histr));
+    Ok(())
 }
 
 /// Returns a HashMap with the number of occurrences of every element in the
@@ -453,11 +456,11 @@ mod tests {
 
         let mut w = io::stdout();
         let w = &mut w as &mut io::Writer;
-        write!(w, "\n");
-        write_5_number_summary(w, &summ2);
-        write!(w, "\n");
-        write_boxplot(w, &summ2, 50);
-        write!(w, "\n");
+        (write!(w, "\n")).unwrap();
+        write_5_number_summary(w, &summ2).unwrap();
+        (write!(w, "\n")).unwrap();
+        write_boxplot(w, &summ2, 50).unwrap();
+        (write!(w, "\n")).unwrap();
 
         assert_eq!(summ.sum, summ2.sum);
         assert_eq!(summ.min, summ2.min);
@@ -1000,7 +1003,7 @@ mod tests {
         fn t(s: &Summary, expected: ~str) {
             use std::io::MemWriter;
             let mut m = MemWriter::new();
-            write_boxplot(&mut m as &mut io::Writer, s, 30);
+            write_boxplot(&mut m as &mut io::Writer, s, 30).unwrap();
             let out = str::from_utf8_owned(m.unwrap()).unwrap();
             assert_eq!(out, expected);
         }
diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs
index 26a555a646c..0a29fd18982 100644
--- a/src/libextra/sync.rs
+++ b/src/libextra/sync.rs
@@ -959,7 +959,7 @@ mod tests {
     fn test_mutex_cond_no_waiter() {
         let m = Mutex::new();
         let m2 = m.clone();
-        task::try(proc() {
+        let _ = task::try(proc() {
             m.lock_cond(|_x| { })
         });
         m2.lock_cond(|cond| {
diff --git a/src/libextra/tempfile.rs b/src/libextra/tempfile.rs
index c9ea556f23a..5948f356a65 100644
--- a/src/libextra/tempfile.rs
+++ b/src/libextra/tempfile.rs
@@ -38,7 +38,7 @@ impl TempDir {
         let mut r = rand::rng();
         for _ in range(0u, 1000) {
             let p = tmpdir.join(r.gen_ascii_str(16) + suffix);
-            match io::result(|| fs::mkdir(&p, io::UserRWX)) {
+            match fs::mkdir(&p, io::UserRWX) {
                 Err(..) => {}
                 Ok(()) => return Some(TempDir { path: Some(p) })
             }
@@ -73,7 +73,8 @@ impl Drop for TempDir {
     fn drop(&mut self) {
         for path in self.path.iter() {
             if path.exists() {
-                fs::rmdir_recursive(path);
+                // FIXME: is failing the right thing to do?
+                fs::rmdir_recursive(path).unwrap();
             }
         }
     }
diff --git a/src/libextra/test.rs b/src/libextra/test.rs
index ef5a05b6a3e..c4d27b25b55 100644
--- a/src/libextra/test.rs
+++ b/src/libextra/test.rs
@@ -163,7 +163,11 @@ pub fn test_main(args: &[~str], tests: ~[TestDescAndFn]) {
             Some(Err(msg)) => fail!("{}", msg),
             None => return
         };
-    if !run_tests_console(&opts, tests) { fail!("Some tests failed"); }
+    match run_tests_console(&opts, tests) {
+        Ok(true) => {}
+        Ok(false) => fail!("Some tests failed"),
+        Err(e) => fail!("io error when running tests: {}", e),
+    }
 }
 
 // A variant optimized for invocation with a static test vector.
@@ -359,16 +363,17 @@ struct ConsoleTestState<T> {
 }
 
 impl<T: Writer> ConsoleTestState<T> {
-    pub fn new(opts: &TestOpts, _: Option<T>) -> ConsoleTestState<StdWriter> {
+    pub fn new(opts: &TestOpts,
+               _: Option<T>) -> io::IoResult<ConsoleTestState<StdWriter>> {
         let log_out = match opts.logfile {
-            Some(ref path) => File::create(path),
+            Some(ref path) => Some(if_ok!(File::create(path))),
             None => None
         };
         let out = match term::Terminal::new(io::stdout()) {
             Err(_) => Raw(io::stdout()),
             Ok(t) => Pretty(t)
         };
-        ConsoleTestState {
+        Ok(ConsoleTestState {
             out: out,
             log_out: log_out,
             use_color: use_color(),
@@ -380,100 +385,103 @@ impl<T: Writer> ConsoleTestState<T> {
             metrics: MetricMap::new(),
             failures: ~[],
             max_name_len: 0u,
-        }
+        })
     }
 
-    pub fn write_ok(&mut self) {
-        self.write_pretty("ok", term::color::GREEN);
+    pub fn write_ok(&mut self) -> io::IoResult<()> {
+        self.write_pretty("ok", term::color::GREEN)
     }
 
-    pub fn write_failed(&mut self) {
-        self.write_pretty("FAILED", term::color::RED);
+    pub fn write_failed(&mut self) -> io::IoResult<()> {
+        self.write_pretty("FAILED", term::color::RED)
     }
 
-    pub fn write_ignored(&mut self) {
-        self.write_pretty("ignored", term::color::YELLOW);
+    pub fn write_ignored(&mut self) -> io::IoResult<()> {
+        self.write_pretty("ignored", term::color::YELLOW)
     }
 
-    pub fn write_metric(&mut self) {
-        self.write_pretty("metric", term::color::CYAN);
+    pub fn write_metric(&mut self) -> io::IoResult<()> {
+        self.write_pretty("metric", term::color::CYAN)
     }
 
-    pub fn write_bench(&mut self) {
-        self.write_pretty("bench", term::color::CYAN);
+    pub fn write_bench(&mut self) -> io::IoResult<()> {
+        self.write_pretty("bench", term::color::CYAN)
     }
 
-    pub fn write_added(&mut self) {
-        self.write_pretty("added", term::color::GREEN);
+    pub fn write_added(&mut self) -> io::IoResult<()> {
+        self.write_pretty("added", term::color::GREEN)
     }
 
-    pub fn write_improved(&mut self) {
-        self.write_pretty("improved", term::color::GREEN);
+    pub fn write_improved(&mut self) -> io::IoResult<()> {
+        self.write_pretty("improved", term::color::GREEN)
     }
 
-    pub fn write_removed(&mut self) {
-        self.write_pretty("removed", term::color::YELLOW);
+    pub fn write_removed(&mut self) -> io::IoResult<()> {
+        self.write_pretty("removed", term::color::YELLOW)
     }
 
-    pub fn write_regressed(&mut self) {
-        self.write_pretty("regressed", term::color::RED);
+    pub fn write_regressed(&mut self) -> io::IoResult<()> {
+        self.write_pretty("regressed", term::color::RED)
     }
 
     pub fn write_pretty(&mut self,
                         word: &str,
-                        color: term::color::Color) {
+                        color: term::color::Color) -> io::IoResult<()> {
         match self.out {
             Pretty(ref mut term) => {
                 if self.use_color {
-                    term.fg(color);
+                    if_ok!(term.fg(color));
                 }
-                term.write(word.as_bytes());
+                if_ok!(term.write(word.as_bytes()));
                 if self.use_color {
-                    term.reset();
+                    if_ok!(term.reset());
                 }
+                Ok(())
             }
             Raw(ref mut stdout) => stdout.write(word.as_bytes())
         }
     }
 
-    pub fn write_plain(&mut self, s: &str) {
+    pub fn write_plain(&mut self, s: &str) -> io::IoResult<()> {
         match self.out {
             Pretty(ref mut term) => term.write(s.as_bytes()),
             Raw(ref mut stdout) => stdout.write(s.as_bytes())
         }
     }
 
-    pub fn write_run_start(&mut self, len: uint) {
+    pub fn write_run_start(&mut self, len: uint) -> io::IoResult<()> {
         self.total = len;
         let noun = if len != 1 { &"tests" } else { &"test" };
-        self.write_plain(format!("\nrunning {} {}\n", len, noun));
+        self.write_plain(format!("\nrunning {} {}\n", len, noun))
     }
 
-    pub fn write_test_start(&mut self, test: &TestDesc, align: NamePadding) {
+    pub fn write_test_start(&mut self, test: &TestDesc,
+                            align: NamePadding) -> io::IoResult<()> {
         let name = test.padded_name(self.max_name_len, align);
-        self.write_plain(format!("test {} ... ", name));
+        self.write_plain(format!("test {} ... ", name))
     }
 
-    pub fn write_result(&mut self, result: &TestResult) {
-        match *result {
+    pub fn write_result(&mut self, result: &TestResult) -> io::IoResult<()> {
+        if_ok!(match *result {
             TrOk => self.write_ok(),
             TrFailed => self.write_failed(),
             TrIgnored => self.write_ignored(),
             TrMetrics(ref mm) => {
-                self.write_metric();
-                self.write_plain(format!(": {}", fmt_metrics(mm)));
+                if_ok!(self.write_metric());
+                self.write_plain(format!(": {}", fmt_metrics(mm)))
             }
             TrBench(ref bs) => {
-                self.write_bench();
-                self.write_plain(format!(": {}", fmt_bench_samples(bs)));
+                if_ok!(self.write_bench());
+                self.write_plain(format!(": {}", fmt_bench_samples(bs)))
             }
-        }
-        self.write_plain("\n");
+        });
+        self.write_plain("\n")
     }
 
-    pub fn write_log(&mut self, test: &TestDesc, result: &TestResult) {
+    pub fn write_log(&mut self, test: &TestDesc,
+                     result: &TestResult) -> io::IoResult<()> {
         match self.log_out {
-            None => (),
+            None => Ok(()),
             Some(ref mut o) => {
                 let s = format!("{} {}\n", match *result {
                         TrOk => ~"ok",
@@ -482,24 +490,25 @@ impl<T: Writer> ConsoleTestState<T> {
                         TrMetrics(ref mm) => fmt_metrics(mm),
                         TrBench(ref bs) => fmt_bench_samples(bs)
                     }, test.name.to_str());
-                o.write(s.as_bytes());
+                o.write(s.as_bytes())
             }
         }
     }
 
-    pub fn write_failures(&mut self) {
-        self.write_plain("\nfailures:\n");
+    pub fn write_failures(&mut self) -> io::IoResult<()> {
+        if_ok!(self.write_plain("\nfailures:\n"));
         let mut failures = ~[];
         for f in self.failures.iter() {
             failures.push(f.name.to_str());
         }
         failures.sort();
         for name in failures.iter() {
-            self.write_plain(format!("    {}\n", name.to_str()));
+            if_ok!(self.write_plain(format!("    {}\n", name.to_str())));
         }
+        Ok(())
     }
 
-    pub fn write_metric_diff(&mut self, diff: &MetricDiff) {
+    pub fn write_metric_diff(&mut self, diff: &MetricDiff) -> io::IoResult<()> {
         let mut noise = 0;
         let mut improved = 0;
         let mut regressed = 0;
@@ -511,77 +520,82 @@ impl<T: Writer> ConsoleTestState<T> {
                 LikelyNoise => noise += 1,
                 MetricAdded => {
                     added += 1;
-                    self.write_added();
-                    self.write_plain(format!(": {}\n", *k));
+                    if_ok!(self.write_added());
+                    if_ok!(self.write_plain(format!(": {}\n", *k)));
                 }
                 MetricRemoved => {
                     removed += 1;
-                    self.write_removed();
-                    self.write_plain(format!(": {}\n", *k));
+                    if_ok!(self.write_removed());
+                    if_ok!(self.write_plain(format!(": {}\n", *k)));
                 }
                 Improvement(pct) => {
                     improved += 1;
-                    self.write_plain(format!(": {}", *k));
-                    self.write_improved();
-                    self.write_plain(format!(" by {:.2f}%\n", pct as f64));
+                    if_ok!(self.write_plain(format!(": {}", *k)));
+                    if_ok!(self.write_improved());
+                    if_ok!(self.write_plain(format!(" by {:.2f}%\n", pct as f64)));
                 }
                 Regression(pct) => {
                     regressed += 1;
-                    self.write_plain(format!(": {}", *k));
-                    self.write_regressed();
-                    self.write_plain(format!(" by {:.2f}%\n", pct as f64));
+                    if_ok!(self.write_plain(format!(": {}", *k)));
+                    if_ok!(self.write_regressed());
+                    if_ok!(self.write_plain(format!(" by {:.2f}%\n", pct as f64)));
                 }
             }
         }
-        self.write_plain(format!("result of ratchet: {} matrics added, {} removed, \
-                                  {} improved, {} regressed, {} noise\n",
-                                 added, removed, improved, regressed, noise));
+        if_ok!(self.write_plain(format!("result of ratchet: {} matrics added, \
+                                        {} removed, {} improved, {} regressed, \
+                                        {} noise\n",
+                                       added, removed, improved, regressed,
+                                       noise)));
         if regressed == 0 {
-            self.write_plain("updated ratchet file\n");
+            if_ok!(self.write_plain("updated ratchet file\n"));
         } else {
-            self.write_plain("left ratchet file untouched\n");
+            if_ok!(self.write_plain("left ratchet file untouched\n"));
         }
+        Ok(())
     }
 
     pub fn write_run_finish(&mut self,
                             ratchet_metrics: &Option<Path>,
-                            ratchet_pct: Option<f64>) -> bool {
+                            ratchet_pct: Option<f64>) -> io::IoResult<bool> {
         assert!(self.passed + self.failed + self.ignored + self.measured == self.total);
 
         let ratchet_success = match *ratchet_metrics {
             None => true,
             Some(ref pth) => {
-                self.write_plain(format!("\nusing metrics ratcher: {}\n", pth.display()));
+                if_ok!(self.write_plain(format!("\nusing metrics ratcher: {}\n",
+                                        pth.display())));
                 match ratchet_pct {
                     None => (),
                     Some(pct) =>
-                        self.write_plain(format!("with noise-tolerance forced to: {}%\n",
-                                                 pct))
+                        if_ok!(self.write_plain(format!("with noise-tolerance \
+                                                         forced to: {}%\n",
+                                                        pct)))
                 }
                 let (diff, ok) = self.metrics.ratchet(pth, ratchet_pct);
-                self.write_metric_diff(&diff);
+                if_ok!(self.write_metric_diff(&diff));
                 ok
             }
         };
 
         let test_success = self.failed == 0u;
         if !test_success {
-            self.write_failures();
+            if_ok!(self.write_failures());
         }
 
         let success = ratchet_success && test_success;
 
-        self.write_plain("\ntest result: ");
+        if_ok!(self.write_plain("\ntest result: "));
         if success {
             // There's no parallelism at this point so it's safe to use color
-            self.write_ok();
+            if_ok!(self.write_ok());
         } else {
-            self.write_failed();
+            if_ok!(self.write_failed());
         }
         let s = format!(". {} passed; {} failed; {} ignored; {} measured\n\n",
                         self.passed, self.failed, self.ignored, self.measured);
-        self.write_plain(s);
-        return success;
+        if_ok!(self.write_plain(s));
+        return Ok(success);
     }
 }
 
@@ -611,15 +625,16 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> ~str {
 
 // A simple console test runner
 pub fn run_tests_console(opts: &TestOpts,
-                         tests: ~[TestDescAndFn]) -> bool {
-    fn callback<T: Writer>(event: &TestEvent, st: &mut ConsoleTestState<T>) {
+                         tests: ~[TestDescAndFn]) -> io::IoResult<bool> {
+    fn callback<T: Writer>(event: &TestEvent,
+                           st: &mut ConsoleTestState<T>) -> io::IoResult<()> {
         debug!("callback(event={:?})", event);
         match (*event).clone() {
             TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
             TeWait(ref test, padding) => st.write_test_start(test, padding),
             TeResult(test, result) => {
-                st.write_log(&test, &result);
-                st.write_result(&result);
+                if_ok!(st.write_log(&test, &result));
+                if_ok!(st.write_result(&result));
                 match result {
                     TrOk => st.passed += 1,
                     TrIgnored => st.ignored += 1,
@@ -643,10 +658,11 @@ pub fn run_tests_console(opts: &TestOpts,
                         st.failures.push(test);
                     }
                 }
+                Ok(())
             }
         }
     }
-    let mut st = ConsoleTestState::new(opts, None::<StdWriter>);
+    let mut st = if_ok!(ConsoleTestState::new(opts, None::<StdWriter>));
     fn len_if_padded(t: &TestDescAndFn) -> uint {
         match t.testfn.padding() {
             PadNone => 0u,
@@ -661,12 +677,13 @@ pub fn run_tests_console(opts: &TestOpts,
         },
         None => {}
     }
-    run_tests(opts, tests, |x| callback(&x, &mut st));
+    if_ok!(run_tests(opts, tests, |x| callback(&x, &mut st)));
     match opts.save_metrics {
         None => (),
         Some(ref pth) => {
-            st.metrics.save(pth);
-            st.write_plain(format!("\nmetrics saved to: {}", pth.display()));
+            if_ok!(st.metrics.save(pth));
+            if_ok!(st.write_plain(format!("\nmetrics saved to: {}",
+                                          pth.display())));
         }
     }
     return st.write_run_finish(&opts.ratchet_metrics, opts.ratchet_noise_percent);
@@ -703,7 +720,7 @@ fn should_sort_failures_before_printing_them() {
         failures: ~[test_b, test_a]
     };
 
-    st.write_failures();
+    st.write_failures().unwrap();
     let s = match st.out {
         Raw(ref m) => str::from_utf8(m.get_ref()).unwrap(),
         Pretty(_) => unreachable!()
@@ -728,11 +745,11 @@ pub type MonitorMsg = (TestDesc, TestResult);
 
 fn run_tests(opts: &TestOpts,
              tests: ~[TestDescAndFn],
-             callback: |e: TestEvent|) {
+             callback: |e: TestEvent| -> io::IoResult<()>) -> io::IoResult<()> {
     let filtered_tests = filter_tests(opts, tests);
     let filtered_descs = filtered_tests.map(|t| t.desc.clone());
 
-    callback(TeFiltered(filtered_descs));
+    if_ok!(callback(TeFiltered(filtered_descs)));
 
     let (filtered_tests, filtered_benchs_and_metrics) =
         filtered_tests.partition(|e| {
@@ -760,7 +777,7 @@ fn run_tests(opts: &TestOpts,
                 // We are doing one test at a time so we can print the name
                 // of the test before we run it. Useful for debugging tests
                 // that hang forever.
-                callback(TeWait(test.desc.clone(), test.testfn.padding()));
+                if_ok!(callback(TeWait(test.desc.clone(), test.testfn.padding())));
             }
             run_test(!opts.run_tests, test, ch.clone());
             pending += 1;
@@ -768,20 +785,21 @@ fn run_tests(opts: &TestOpts,
 
         let (desc, result) = p.recv();
         if concurrency != 1 {
-            callback(TeWait(desc.clone(), PadNone));
+            if_ok!(callback(TeWait(desc.clone(), PadNone)));
         }
-        callback(TeResult(desc, result));
+        if_ok!(callback(TeResult(desc, result)));
         pending -= 1;
     }
 
     // All benchmarks run at the end, in serial.
     // (this includes metric fns)
     for b in filtered_benchs_and_metrics.move_iter() {
-        callback(TeWait(b.desc.clone(), b.testfn.padding()));
+        if_ok!(callback(TeWait(b.desc.clone(), b.testfn.padding())));
         run_test(!opts.run_benchmarks, b, ch.clone());
         let (test, result) = p.recv();
-        callback(TeResult(test, result));
+        if_ok!(callback(TeResult(test, result)));
     }
+    Ok(())
 }
 
 fn get_concurrency() -> uint {
@@ -943,17 +961,22 @@ impl MetricMap {
     }
 
     /// Load MetricDiff from a file.
+    ///
+    /// # Failure
+    ///
+    /// This function will fail if the path does not exist or the path does not
+    /// contain a valid metric map.
     pub fn load(p: &Path) -> MetricMap {
         assert!(p.exists());
-        let mut f = File::open(p);
+        let mut f = File::open(p).unwrap();
         let value = json::from_reader(&mut f as &mut io::Reader).unwrap();
         let mut decoder = json::Decoder::new(value);
         MetricMap(Decodable::decode(&mut decoder))
     }
 
     /// Write MetricDiff to a file.
-    pub fn save(&self, p: &Path) {
-        let mut file = File::create(p);
+    pub fn save(&self, p: &Path) -> io::IoResult<()> {
+        let mut file = if_ok!(File::create(p));
         let MetricMap(ref map) = *self;
         map.to_json().to_pretty_writer(&mut file)
     }
@@ -1060,7 +1083,7 @@ impl MetricMap {
 
         if ok {
             debug!("rewriting file '{:?}' with updated metrics", p);
-            self.save(p);
+            self.save(p).unwrap();
         }
         return (diff, ok)
     }
@@ -1462,7 +1485,7 @@ mod tests {
         m2.insert_metric("runtime", 1100.0, 2.0);
         m2.insert_metric("throughput", 50.0, 2.0);
 
-        m1.save(&pth);
+        m1.save(&pth).unwrap();
 
         // Ask for a ratchet that should fail to advance.
         let (diff1, ok1) = m2.ratchet(&pth, None);
diff --git a/src/libextra/time.rs b/src/libextra/time.rs
index 3e5b9b797d3..0a122ad58bd 100644
--- a/src/libextra/time.rs
+++ b/src/libextra/time.rs
@@ -766,14 +766,14 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ~str> {
 
         let mut buf = [0];
         let c = match rdr.read(buf) {
-            Some(..) => buf[0] as char,
-            None => break
+            Ok(..) => buf[0] as char,
+            Err(..) => break
         };
         match c {
             '%' => {
                 let ch = match rdr.read(buf) {
-                    Some(..) => buf[0] as char,
-                    None => break
+                    Ok(..) => buf[0] as char,
+                    Err(..) => break
                 };
                 match parse_type(s, pos, ch, &mut tm) {
                     Ok(next) => pos = next,
@@ -787,7 +787,7 @@ pub fn strptime(s: &str, format: &str) -> Result<Tm, ~str> {
         }
     }
 
-    if pos == len && rdr.tell() as uint == format.len() {
+    if pos == len && rdr.tell().unwrap() == format.len() as u64 {
         Ok(Tm {
             tm_sec: tm.tm_sec,
             tm_min: tm.tm_min,
@@ -1017,12 +1017,12 @@ pub fn strftime(format: &str, tm: &Tm) -> ~str {
     loop {
         let mut b = [0];
         let ch = match rdr.read(b) {
-            Some(..) => b[0],
-            None => break,
+            Ok(..) => b[0],
+            Err(..) => break,
         };
         match ch as char {
             '%' => {
-                rdr.read(b);
+                rdr.read(b).unwrap();
                 let s = parse_type(b[0] as char, tm);
                 buf.push_all(s.as_bytes());
             }
diff --git a/src/libextra/url.rs b/src/libextra/url.rs
index 35c53c9307c..6138c5416f2 100644
--- a/src/libextra/url.rs
+++ b/src/libextra/url.rs
@@ -102,8 +102,8 @@ fn encode_inner(s: &str, full_url: bool) -> ~str {
     loop {
         let mut buf = [0];
         let ch = match rdr.read(buf) {
-            None => break,
-            Some(..) => buf[0] as char,
+            Err(..) => break,
+            Ok(..) => buf[0] as char,
         };
 
         match ch {
@@ -166,14 +166,14 @@ fn decode_inner(s: &str, full_url: bool) -> ~str {
     loop {
         let mut buf = [0];
         let ch = match rdr.read(buf) {
-            None => break,
-            Some(..) => buf[0] as char
+            Err(..) => break,
+            Ok(..) => buf[0] as char
         };
         match ch {
           '%' => {
             let mut bytes = [0, 0];
             match rdr.read(bytes) {
-                Some(2) => {}
+                Ok(2) => {}
                 _ => fail!() // FIXME: malformed url?
             }
             let ch = uint::parse_bytes(bytes, 16u).unwrap() as u8 as char;
@@ -228,8 +228,8 @@ fn encode_plus(s: &str) -> ~str {
     loop {
         let mut buf = [0];
         let ch = match rdr.read(buf) {
-            Some(..) => buf[0] as char,
-            None => break,
+            Ok(..) => buf[0] as char,
+            Err(..) => break,
         };
         match ch {
           'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '.' | '-' => {
@@ -282,8 +282,8 @@ pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<~str, ~[~str]> {
     loop {
         let mut buf = [0];
         let ch = match rdr.read(buf) {
-            Some(..) => buf[0] as char,
-            None => break,
+            Ok(..) => buf[0] as char,
+            Err(..) => break,
         };
         match ch {
             '&' | ';' => {
@@ -307,7 +307,7 @@ pub fn decode_form_urlencoded(s: &[u8]) -> HashMap<~str, ~[~str]> {
                     '%' => {
                         let mut bytes = [0, 0];
                         match rdr.read(bytes) {
-                            Some(2) => {}
+                            Ok(2) => {}
                             _ => fail!() // FIXME: malformed?
                         }
                         uint::parse_bytes(bytes, 16u).unwrap() as u8 as char
@@ -347,12 +347,12 @@ fn split_char_first(s: &str, c: char) -> (~str, ~str) {
     loop {
         let mut buf = [0];
         let ch = match rdr.read(buf) {
-            Some(..) => buf[0] as char,
-            None => break,
+            Ok(..) => buf[0] as char,
+            Err(..) => break,
         };
         if ch == c {
             // found a match, adjust markers
-            index = (rdr.tell() as uint) - 1;
+            index = (rdr.tell().unwrap() as uint) - 1;
             mat = 1;
             break;
         }
diff --git a/src/libextra/uuid.rs b/src/libextra/uuid.rs
index 9163a892039..29d3066b2f5 100644
--- a/src/libextra/uuid.rs
+++ b/src/libextra/uuid.rs
@@ -821,7 +821,7 @@ mod bench {
     pub fn parse_str(bh: &mut BenchHarness) {
         let s = "urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4";
         bh.iter(|| {
-            Uuid::parse_string(s);
+            Uuid::parse_string(s).unwrap();
         })
     }
 }
diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs
index 70bbe02d32f..4d8e7e50dcf 100644
--- a/src/libextra/workcache.rs
+++ b/src/libextra/workcache.rs
@@ -172,20 +172,19 @@ impl Database {
     }
 
     // FIXME #4330: This should have &mut self and should set self.db_dirty to false.
-    fn save(&self) {
+    fn save(&self) -> io::IoResult<()> {
         let mut f = File::create(&self.db_filename);
-        self.db_cache.to_json().to_pretty_writer(&mut f);
+        self.db_cache.to_json().to_pretty_writer(&mut f)
     }
 
     fn load(&mut self) {
         assert!(!self.db_dirty);
         assert!(self.db_filename.exists());
-        match io::result(|| File::open(&self.db_filename)) {
+        match File::open(&self.db_filename) {
             Err(e) => fail!("Couldn't load workcache database {}: {}",
                             self.db_filename.display(),
-                            e.desc),
-            Ok(r) => {
-                let mut stream = r.unwrap();
+                            e),
+            Ok(mut stream) => {
                 match json::from_reader(&mut stream) {
                     Err(e) => fail!("Couldn't parse workcache database (from file {}): {}",
                                     self.db_filename.display(), e.to_str()),
@@ -203,7 +202,8 @@ impl Database {
 impl Drop for Database {
     fn drop(&mut self) {
         if self.db_dirty {
-            self.save();
+            // FIXME: is failing the right thing to do here
+            self.save().unwrap();
         }
     }
 }
@@ -473,13 +473,13 @@ fn test() {
     fn make_path(filename: ~str) -> Path {
         let pth = os::self_exe_path().expect("workcache::test failed").with_filename(filename);
         if pth.exists() {
-            fs::unlink(&pth);
+            fs::unlink(&pth).unwrap();
         }
         return pth;
     }
 
     let pth = make_path(~"foo.c");
-    File::create(&pth).write(bytes!("int main() { return 0; }"));
+    File::create(&pth).write(bytes!("int main() { return 0; }")).unwrap();
 
     let db_path = make_path(~"db.json");
 
@@ -491,7 +491,8 @@ fn test() {
         let subcx = cx.clone();
         let pth = pth.clone();
 
-        let file_content = from_utf8_owned(File::open(&pth).read_to_end()).unwrap();
+        let contents = File::open(&pth).read_to_end().unwrap();
+        let file_content = from_utf8_owned(contents).unwrap();
 
         // FIXME (#9639): This needs to handle non-utf8 paths
         prep.declare_input("file", pth.as_str().unwrap(), file_content);
@@ -500,7 +501,7 @@ fn test() {
             // FIXME (#9639): This needs to handle non-utf8 paths
             run::process_status("gcc", [pth.as_str().unwrap().to_owned(),
                                         ~"-o",
-                                        out.as_str().unwrap().to_owned()]);
+                                        out.as_str().unwrap().to_owned()]).unwrap();
 
             let _proof_of_concept = subcx.prep("subfn");
             // Could run sub-rules inside here.
diff --git a/src/libglob/lib.rs b/src/libglob/lib.rs
index 98bf5533210..c6ecb7697da 100644
--- a/src/libglob/lib.rs
+++ b/src/libglob/lib.rs
@@ -29,7 +29,6 @@
 #[license = "MIT/ASL2"];
 
 use std::{os, path};
-use std::io;
 use std::io::fs;
 use std::path::is_sep;
 
@@ -153,7 +152,7 @@ impl Iterator<Path> for Paths {
 }
 
 fn list_dir_sorted(path: &Path) -> ~[Path] {
-    match io::result(|| fs::readdir(path)) {
+    match fs::readdir(path) {
         Ok(mut children) => {
             children.sort_by(|p1, p2| p2.filename().cmp(&p1.filename()));
             children
diff --git a/src/libgreen/macros.rs b/src/libgreen/macros.rs
index e07cc1ca000..ef2c77fc8e2 100644
--- a/src/libgreen/macros.rs
+++ b/src/libgreen/macros.rs
@@ -56,16 +56,17 @@ pub fn dumb_println(args: &fmt::Arguments) {
 
     struct Stderr;
     impl io::Writer for Stderr {
-        fn write(&mut self, data: &[u8]) {
+        fn write(&mut self, data: &[u8]) -> io::IoResult<()> {
             unsafe {
                 libc::write(libc::STDERR_FILENO,
                             data.as_ptr() as *libc::c_void,
                             data.len() as libc::size_t);
             }
+            Ok(()) // just ignore the result
         }
     }
     let mut w = Stderr;
-    fmt::writeln(&mut w as &mut io::Writer, args);
+    let _ = fmt::writeln(&mut w as &mut io::Writer, args);
 }
 
 pub fn abort(msg: &str) -> ! {
diff --git a/src/libnative/bookkeeping.rs b/src/libnative/bookkeeping.rs
index b07e4271ee4..868586b3691 100644
--- a/src/libnative/bookkeeping.rs
+++ b/src/libnative/bookkeeping.rs
@@ -23,7 +23,7 @@ static mut TASK_COUNT: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
 static mut TASK_LOCK: Mutex = MUTEX_INIT;
 
 pub fn increment() {
-    unsafe { TASK_COUNT.fetch_add(1, atomics::SeqCst); }
+    let _ = unsafe { TASK_COUNT.fetch_add(1, atomics::SeqCst) };
 }
 
 pub fn decrement() {
diff --git a/src/libnative/io/file.rs b/src/libnative/io/file.rs
index acab7ce3a91..cc5b0770d4d 100644
--- a/src/libnative/io/file.rs
+++ b/src/libnative/io/file.rs
@@ -111,17 +111,14 @@ impl FileDesc {
 }
 
 impl io::Reader for FileDesc {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
-        match self.inner_read(buf) { Ok(n) => Some(n), Err(..) => None }
+    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
+        self.inner_read(buf)
     }
 }
 
 impl io::Writer for FileDesc {
-    fn write(&mut self, buf: &[u8]) {
-        match self.inner_write(buf) {
-            Ok(()) => {}
-            Err(e) => { io::io_error::cond.raise(e); }
-        }
+    fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
+        self.inner_write(buf)
     }
 }
 
@@ -425,7 +422,7 @@ impl rtio::RtioFileStream for CFile {
 
 impl Drop for CFile {
     fn drop(&mut self) {
-        unsafe { libc::fclose(self.file); }
+        unsafe { let _ = libc::fclose(self.file); }
     }
 }
 
@@ -515,7 +512,7 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
                     paths.push(Path::new(cstr));
                     entry_ptr = readdir(dir_ptr);
                 }
-                closedir(dir_ptr);
+                assert_eq!(closedir(dir_ptr), 0);
                 Ok(paths)
             } else {
                 Err(super::last_error())
@@ -564,7 +561,7 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
                         }
                         more_files = FindNextFileW(find_handle, wfd_ptr as HANDLE);
                     }
-                    FindClose(find_handle);
+                    assert!(FindClose(find_handle) != 0);
                     free(wfd_ptr as *mut c_void);
                     Ok(paths)
                 } else {
@@ -686,7 +683,9 @@ pub fn readlink(p: &CString) -> IoResult<Path> {
                                   ptr::mut_null())
             })
         };
-        if handle == ptr::mut_null() { return Err(super::last_error()) }
+        if handle as int == libc::INVALID_HANDLE_VALUE as int {
+            return Err(super::last_error())
+        }
         let ret = fill_utf16_buf_and_decode(|buf, sz| {
             unsafe {
                 libc::GetFinalPathNameByHandleW(handle, buf as *u16, sz,
@@ -697,7 +696,7 @@ pub fn readlink(p: &CString) -> IoResult<Path> {
             Some(s) => Ok(Path::new(s)),
             None => Err(super::last_error()),
         };
-        unsafe { libc::CloseHandle(handle) };
+        assert!(unsafe { libc::CloseHandle(handle) } != 0);
         return ret;
 
     }
@@ -935,7 +934,7 @@ mod tests {
             let mut reader = FileDesc::new(input, true);
             let mut writer = FileDesc::new(out, true);
 
-            writer.inner_write(bytes!("test"));
+            writer.inner_write(bytes!("test")).unwrap();
             let mut buf = [0u8, ..4];
             match reader.inner_read(buf) {
                 Ok(4) => {
@@ -960,9 +959,9 @@ mod tests {
             assert!(!f.is_null());
             let mut file = CFile::new(f);
 
-            file.write(bytes!("test"));
+            file.write(bytes!("test")).unwrap();
             let mut buf = [0u8, ..4];
-            file.seek(0, io::SeekSet);
+            let _ = file.seek(0, io::SeekSet).unwrap();
             match file.read(buf) {
                 Ok(4) => {
                     assert_eq!(buf[0], 't' as u8);
diff --git a/src/libnative/io/net.rs b/src/libnative/io/net.rs
index 2f4bec22755..ac68b1523d7 100644
--- a/src/libnative/io/net.rs
+++ b/src/libnative/io/net.rs
@@ -112,8 +112,8 @@ fn setsockopt<T>(fd: sock_t, opt: libc::c_int, val: libc::c_int,
     }
 }
 
-#[cfg(windows)] unsafe fn close(sock: sock_t) { libc::closesocket(sock); }
-#[cfg(unix)]    unsafe fn close(sock: sock_t) { libc::close(sock); }
+#[cfg(windows)] unsafe fn close(sock: sock_t) { let _ = libc::closesocket(sock); }
+#[cfg(unix)]    unsafe fn close(sock: sock_t) { let _ = libc::close(sock); }
 
 fn sockname(fd: sock_t,
             f: extern "system" unsafe fn(sock_t, *mut libc::sockaddr,
diff --git a/src/libnative/io/process.rs b/src/libnative/io/process.rs
index 13dd4298777..2a061c5f9b2 100644
--- a/src/libnative/io/process.rs
+++ b/src/libnative/io/process.rs
@@ -102,9 +102,9 @@ impl Process {
                                    cwd.as_ref(), in_fd, out_fd, err_fd);
 
         unsafe {
-            for pipe in in_pipe.iter() { libc::close(pipe.input); }
-            for pipe in out_pipe.iter() { libc::close(pipe.out); }
-            for pipe in err_pipe.iter() { libc::close(pipe.out); }
+            for pipe in in_pipe.iter() { let _ = libc::close(pipe.input); }
+            for pipe in out_pipe.iter() { let _ = libc::close(pipe.out); }
+            for pipe in err_pipe.iter() { let _ = libc::close(pipe.out); }
         }
 
         match res {
@@ -149,9 +149,8 @@ impl rtio::RtioProcess for Process {
         unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
             match signal {
                 io::process::PleaseExitSignal | io::process::MustDieSignal => {
-                    libc::funcs::extra::kernel32::TerminateProcess(
-                        cast::transmute(pid), 1);
-                    Ok(())
+                    let ret = libc::TerminateProcess(pid as libc::HANDLE, 1);
+                    super::mkerr_winbool(ret)
                 }
                 _ => Err(io::IoError {
                     kind: io::OtherIoError,
@@ -163,8 +162,8 @@ impl rtio::RtioProcess for Process {
 
         #[cfg(not(windows))]
         unsafe fn killpid(pid: pid_t, signal: int) -> Result<(), io::IoError> {
-            libc::funcs::posix88::signal::kill(pid, signal as c_int);
-            Ok(())
+            let r = libc::funcs::posix88::signal::kill(pid, signal as c_int);
+            super::mkerr_libc(r)
         }
     }
 }
@@ -255,9 +254,9 @@ fn spawn_process_os(prog: &str, args: &[~str],
             })
         });
 
-        CloseHandle(si.hStdInput);
-        CloseHandle(si.hStdOutput);
-        CloseHandle(si.hStdError);
+        assert!(CloseHandle(si.hStdInput) != 0);
+        assert!(CloseHandle(si.hStdOutput) != 0);
+        assert!(CloseHandle(si.hStdError) != 0);
 
         match create_err {
             Some(err) => return Err(err),
@@ -269,7 +268,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
         // able to close it later. We don't close the process handle however
         // because std::we want the process id to stay valid at least until the
         // calling code closes the process handle.
-        CloseHandle(pi.hThread);
+        assert!(CloseHandle(pi.hThread) != 0);
 
         Ok(SpawnProcessResult {
             pid: pi.dwProcessId as pid_t,
@@ -445,24 +444,24 @@ fn spawn_process_os(prog: &str, args: &[~str],
         rustrt::rust_unset_sigprocmask();
 
         if in_fd == -1 {
-            libc::close(libc::STDIN_FILENO);
+            let _ = libc::close(libc::STDIN_FILENO);
         } else if retry(|| dup2(in_fd, 0)) == -1 {
             fail!("failure in dup2(in_fd, 0): {}", os::last_os_error());
         }
         if out_fd == -1 {
-            libc::close(libc::STDOUT_FILENO);
+            let _ = libc::close(libc::STDOUT_FILENO);
         } else if retry(|| dup2(out_fd, 1)) == -1 {
             fail!("failure in dup2(out_fd, 1): {}", os::last_os_error());
         }
         if err_fd == -1 {
-            libc::close(libc::STDERR_FILENO);
+            let _ = libc::close(libc::STDERR_FILENO);
         } else if retry(|| dup2(err_fd, 2)) == -1 {
             fail!("failure in dup3(err_fd, 2): {}", os::last_os_error());
         }
         // close all other fds
         for fd in range(3, getdtablesize()).rev() {
             if fd != output.fd() {
-                close(fd as c_int);
+                let _ = close(fd as c_int);
             }
         }
 
@@ -478,7 +477,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
             }
         });
         with_argv(prog, args, |argv| {
-            execvp(*argv, argv);
+            let _ = execvp(*argv, argv);
             let errno = os::errno();
             let bytes = [
                 (errno << 24) as u8,
@@ -576,9 +575,9 @@ fn with_dirp<T>(d: Option<&Path>, cb: |*libc::c_char| -> T) -> T {
 
 #[cfg(windows)]
 fn free_handle(handle: *()) {
-    unsafe {
-        libc::funcs::extra::kernel32::CloseHandle(cast::transmute(handle));
-    }
+    assert!(unsafe {
+        libc::CloseHandle(cast::transmute(handle)) != 0
+    })
 }
 
 #[cfg(unix)]
@@ -629,15 +628,15 @@ fn waitpid(pid: pid_t) -> p::ProcessExit {
             loop {
                 let mut status = 0;
                 if GetExitCodeProcess(process, &mut status) == FALSE {
-                    CloseHandle(process);
+                    assert!(CloseHandle(process) != 0);
                     fail!("failure in GetExitCodeProcess: {}", os::last_os_error());
                 }
                 if status != STILL_ACTIVE {
-                    CloseHandle(process);
+                    assert!(CloseHandle(process) != 0);
                     return p::ExitStatus(status as int);
                 }
                 if WaitForSingleObject(process, INFINITE) == WAIT_FAILED {
-                    CloseHandle(process);
+                    assert!(CloseHandle(process) != 0);
                     fail!("failure in WaitForSingleObject: {}", os::last_os_error());
                 }
             }
diff --git a/src/libnative/io/timer_helper.rs b/src/libnative/io/timer_helper.rs
index 74759b467d4..7311be46e8b 100644
--- a/src/libnative/io/timer_helper.rs
+++ b/src/libnative/io/timer_helper.rs
@@ -126,11 +126,11 @@ mod imp {
     }
 
     pub fn signal(handle: HANDLE) {
-        unsafe { SetEvent(handle); }
+        assert!(unsafe { SetEvent(handle) != 0 });
     }
 
     pub fn close(handle: HANDLE) {
-        unsafe { CloseHandle(handle); }
+        assert!(unsafe { CloseHandle(handle) != 0 });
     }
 
     extern "system" {
diff --git a/src/libnative/io/timer_other.rs b/src/libnative/io/timer_other.rs
index bc005f2fe8d..cda239329dc 100644
--- a/src/libnative/io/timer_other.rs
+++ b/src/libnative/io/timer_other.rs
@@ -187,7 +187,7 @@ fn helper(input: libc::c_int, messages: Port<Req>) {
 
                 // drain the file descriptor
                 let mut buf = [0];
-                fd.inner_read(buf).unwrap();
+                assert_eq!(fd.inner_read(buf).unwrap(), 1);
             }
 
             -1 if os::errno() == libc::EINTR as int => {}
@@ -216,7 +216,8 @@ impl Timer {
     }
 
     pub fn sleep(ms: u64) {
-        unsafe { libc::usleep((ms * 1000) as libc::c_uint); }
+        // FIXME: this can fail because of EINTR, what do do?
+        let _ = unsafe { libc::usleep((ms * 1000) as libc::c_uint) };
     }
 
     fn inner(&mut self) -> ~Inner {
diff --git a/src/libnative/io/timer_timerfd.rs b/src/libnative/io/timer_timerfd.rs
index ca20314997e..7c22e90bbff 100644
--- a/src/libnative/io/timer_timerfd.rs
+++ b/src/libnative/io/timer_timerfd.rs
@@ -96,7 +96,7 @@ fn helper(input: libc::c_int, messages: Port<Req>) {
             if fd == input {
                 let mut buf = [0, ..1];
                 // drain the input file descriptor of its input
-                FileDesc::new(fd, false).inner_read(buf).unwrap();
+                let _ = FileDesc::new(fd, false).inner_read(buf).unwrap();
                 incoming = true;
             } else {
                 let mut bits = [0, ..8];
@@ -104,7 +104,7 @@ fn helper(input: libc::c_int, messages: Port<Req>) {
                 //
                 // FIXME: should this perform a send() this number of
                 //      times?
-                FileDesc::new(fd, false).inner_read(bits).unwrap();
+                let _ = FileDesc::new(fd, false).inner_read(bits).unwrap();
                 let remove = {
                     match map.find(&fd).expect("fd unregistered") {
                         &(ref c, oneshot) => !c.try_send(()) || oneshot
@@ -166,7 +166,8 @@ impl Timer {
     }
 
     pub fn sleep(ms: u64) {
-        unsafe { libc::usleep((ms * 1000) as libc::c_uint); }
+        // FIXME: this can fail because of EINTR, what do do?
+        let _ = unsafe { libc::usleep((ms * 1000) as libc::c_uint) };
     }
 
     fn remove(&mut self) {
diff --git a/src/libnative/io/timer_win32.rs b/src/libnative/io/timer_win32.rs
index e359d99eedf..6b472d2f46d 100644
--- a/src/libnative/io/timer_win32.rs
+++ b/src/libnative/io/timer_win32.rs
@@ -62,8 +62,8 @@ fn helper(input: libc::HANDLE, messages: Port<Req>) {
                         c.send(());
                         match objs.iter().position(|&o| o == obj) {
                             Some(i) => {
-                                objs.remove(i);
-                                chans.remove(i - 1);
+                                drop(objs.remove(i));
+                                drop(chans.remove(i - 1));
                             }
                             None => {}
                         }
@@ -83,8 +83,8 @@ fn helper(input: libc::HANDLE, messages: Port<Req>) {
                 }
             };
             if remove {
-                objs.remove(idx as uint);
-                chans.remove(idx as uint - 1);
+                drop(objs.remove(idx as uint));
+                drop(chans.remove(idx as uint - 1));
             }
         }
     }
@@ -133,7 +133,7 @@ impl rtio::RtioTimer for Timer {
                                   ptr::mut_null(), 0)
         }, 1);
 
-        unsafe { imp::WaitForSingleObject(self.obj, libc::INFINITE); }
+        let _ = unsafe { imp::WaitForSingleObject(self.obj, libc::INFINITE) };
     }
 
     fn oneshot(&mut self, msecs: u64) -> Port<()> {
@@ -173,7 +173,7 @@ impl rtio::RtioTimer for Timer {
 impl Drop for Timer {
     fn drop(&mut self) {
         self.remove();
-        unsafe { libc::CloseHandle(self.obj); }
+        assert!(unsafe { libc::CloseHandle(self.obj) != 0 });
     }
 }
 
diff --git a/src/libnative/lib.rs b/src/libnative/lib.rs
index f69ad8fc1aa..1e4317af397 100644
--- a/src/libnative/lib.rs
+++ b/src/libnative/lib.rs
@@ -21,6 +21,7 @@
 #[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")];
+#[deny(unused_result, unused_must_use)];
 
 // NB this crate explicitly does *not* allow glob imports, please seriously
 //    consider whether they're needed before adding that feature here (the
@@ -61,9 +62,10 @@ pub fn start(argc: int, argv: **u8, main: proc()) -> int {
     rt::init(argc, argv);
     let mut exit_code = None;
     let mut main = Some(main);
-    task::new((my_stack_bottom, my_stack_top)).run(|| {
+    let t = task::new((my_stack_bottom, my_stack_top)).run(|| {
         exit_code = Some(run(main.take_unwrap()));
     });
+    drop(t);
     unsafe { rt::cleanup(); }
     // If the exit code wasn't set, then the task block must have failed.
     return exit_code.unwrap_or(rt::DEFAULT_ERROR_CODE);
diff --git a/src/libnative/task.rs b/src/libnative/task.rs
index 37425179701..0def5cb4053 100644
--- a/src/libnative/task.rs
+++ b/src/libnative/task.rs
@@ -103,7 +103,8 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) {
         let mut f = Some(f);
         let mut task = task;
         task.put_runtime(ops as ~rt::Runtime);
-        task.run(|| { f.take_unwrap()() });
+        let t = task.run(|| { f.take_unwrap()() });
+        drop(t);
         bookkeeping::decrement();
     })
 }
diff --git a/src/librustc/back/archive.rs b/src/librustc/back/archive.rs
index 661ae5b7297..18aef17b9eb 100644
--- a/src/librustc/back/archive.rs
+++ b/src/librustc/back/archive.rs
@@ -17,6 +17,7 @@ use lib::llvm::{ArchiveRef, llvm};
 
 use std::cast;
 use std::io::fs;
+use std::io;
 use std::libc;
 use std::os;
 use std::run::{ProcessOptions, Process, ProcessOutput};
@@ -50,9 +51,8 @@ fn run_ar(sess: Session, args: &str, cwd: Option<&Path>,
         Some(p) => { debug!("inside {}", p.display()); }
         None => {}
     }
-    let mut opt_prog = Process::new(ar, args.as_slice(), opts);
-    match opt_prog {
-        Some(ref mut prog) => {
+    match Process::new(ar, args.as_slice(), opts) {
+        Ok(mut prog) => {
             let o = prog.finish_with_output();
             if !o.status.success() {
                 sess.err(format!("{} {} failed with: {}", ar, args.connect(" "),
@@ -63,8 +63,8 @@ fn run_ar(sess: Session, args: &str, cwd: Option<&Path>,
             }
             o
         },
-        None => {
-            sess.err(format!("could not exec `{}`", ar));
+        Err(e) => {
+            sess.err(format!("could not exec `{}`: {}", ar, e));
             sess.abort_if_errors();
             fail!("rustc::back::archive::run_ar() should not reach this point");
         }
@@ -94,7 +94,7 @@ impl Archive {
             let archive = os::make_absolute(&self.dst);
             run_ar(self.sess, "x", Some(loc.path()), [&archive,
                                                       &Path::new(file)]);
-            fs::File::open(&loc.path().join(file)).read_to_end()
+            fs::File::open(&loc.path().join(file)).read_to_end().unwrap()
         } else {
             run_ar(self.sess, "p", None, [&self.dst, &Path::new(file)]).output
         }
@@ -102,9 +102,9 @@ impl Archive {
 
     /// Adds all of the contents of a native library to this archive. This will
     /// search in the relevant locations for a library named `name`.
-    pub fn add_native_library(&mut self, name: &str) {
+    pub fn add_native_library(&mut self, name: &str) -> io::IoResult<()> {
         let location = self.find_library(name);
-        self.add_archive(&location, name, []);
+        self.add_archive(&location, name, [])
     }
 
     /// Adds all of the contents of the rlib at the specified path to this
@@ -112,14 +112,15 @@ impl Archive {
     ///
     /// This ignores adding the bytecode from the rlib, and if LTO is enabled
     /// then the object file also isn't added.
-    pub fn add_rlib(&mut self, rlib: &Path, name: &str, lto: bool) {
+    pub fn add_rlib(&mut self, rlib: &Path, name: &str,
+                    lto: bool) -> io::IoResult<()> {
         let object = format!("{}.o", name);
         let bytecode = format!("{}.bc", name);
         let mut ignore = ~[METADATA_FILENAME, bytecode.as_slice()];
         if lto {
             ignore.push(object.as_slice());
         }
-        self.add_archive(rlib, name, ignore);
+        self.add_archive(rlib, name, ignore)
     }
 
     /// Adds an arbitrary file to this archive
@@ -144,7 +145,8 @@ impl Archive {
         str::from_utf8(output.output).unwrap().lines().map(|s| s.to_owned()).collect()
     }
 
-    fn add_archive(&mut self, archive: &Path, name: &str, skip: &[&str]) {
+    fn add_archive(&mut self, archive: &Path, name: &str,
+                   skip: &[&str]) -> io::IoResult<()> {
         let loc = TempDir::new("rsar").unwrap();
 
         // First, extract the contents of the archive to a temporary directory
@@ -159,7 +161,7 @@ impl Archive {
         // We skip any files explicitly desired for skipping, and we also skip
         // all SYMDEF files as these are just magical placeholders which get
         // re-created when we make a new archive anyway.
-        let files = fs::readdir(loc.path());
+        let files = if_ok!(fs::readdir(loc.path()));
         let mut inputs = ~[];
         for file in files.iter() {
             let filename = file.filename_str().unwrap();
@@ -168,7 +170,7 @@ impl Archive {
 
             let filename = format!("r-{}-{}", name, filename);
             let new_filename = file.with_filename(filename);
-            fs::rename(file, &new_filename);
+            if_ok!(fs::rename(file, &new_filename));
             inputs.push(new_filename);
         }
 
@@ -176,6 +178,7 @@ impl Archive {
         let mut args = ~[&self.dst];
         args.extend(&mut inputs.iter());
         run_ar(self.sess, "r", None, args.as_slice());
+        Ok(())
     }
 
     fn find_library(&self, name: &str) -> Path {
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index fc38fa25a21..4d6576fed34 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -100,7 +100,6 @@ pub mod write {
     use util::common::time;
 
     use std::c_str::ToCStr;
-    use std::io;
     use std::libc::{c_uint, c_int};
     use std::path::Path;
     use std::run;
@@ -297,12 +296,8 @@ pub mod write {
             assembly.as_str().unwrap().to_owned()];
 
         debug!("{} '{}'", cc, args.connect("' '"));
-        let opt_prog = {
-            let _guard = io::ignore_io_error();
-            run::process_output(cc, args)
-        };
-        match opt_prog {
-            Some(prog) => {
+        match run::process_output(cc, args) {
+            Ok(prog) => {
                 if !prog.status.success() {
                     sess.err(format!("linking with `{}` failed: {}", cc, prog.status));
                     sess.note(format!("{} arguments: '{}'", cc, args.connect("' '")));
@@ -310,8 +305,8 @@ pub mod write {
                     sess.abort_if_errors();
                 }
             },
-            None => {
-                sess.err(format!("could not exec the linker `{}`", cc));
+            Err(e) => {
+                sess.err(format!("could not exec the linker `{}`: {}", cc, e));
                 sess.abort_if_errors();
             }
         }
@@ -768,6 +763,15 @@ fn get_system_tool(sess: Session, tool: &str) -> ~str {
     }
 }
 
+fn remove(sess: Session, path: &Path) {
+    match fs::unlink(path) {
+        Ok(..) => {}
+        Err(e) => {
+            sess.err(format!("failed to remove {}: {}", path.display(), e));
+        }
+    }
+}
+
 /// Perform the linkage portion of the compilation phase. This will generate all
 /// of the requested outputs for this compilation session.
 pub fn link_binary(sess: Session,
@@ -785,17 +789,15 @@ pub fn link_binary(sess: Session,
 
     // Remove the temporary object file and metadata if we aren't saving temps
     if !sess.opts.save_temps {
-        fs::unlink(obj_filename);
-        fs::unlink(&obj_filename.with_extension("metadata.o"));
+        remove(sess, obj_filename);
+        remove(sess, &obj_filename.with_extension("metadata.o"));
     }
 
     out_filenames
 }
 
 fn is_writeable(p: &Path) -> bool {
-    use std::io;
-
-    match io::result(|| p.stat()) {
+    match p.stat() {
         Err(..) => true,
         Ok(m) => m.perm & io::UserWrite == io::UserWrite
     }
@@ -884,7 +886,7 @@ fn link_rlib(sess: Session,
     for &(ref l, kind) in used_libraries.get().iter() {
         match kind {
             cstore::NativeStatic => {
-                a.add_native_library(l.as_slice());
+                a.add_native_library(l.as_slice()).unwrap();
             }
             cstore::NativeFramework | cstore::NativeUnknown => {}
         }
@@ -919,16 +921,23 @@ fn link_rlib(sess: Session,
             // the same filename for metadata (stomping over one another)
             let tmpdir = TempDir::new("rustc").expect("needs a temp dir");
             let metadata = tmpdir.path().join(METADATA_FILENAME);
-            fs::File::create(&metadata).write(trans.metadata);
+            match fs::File::create(&metadata).write(trans.metadata) {
+                Ok(..) => {}
+                Err(e) => {
+                    sess.err(format!("failed to write {}: {}",
+                                     metadata.display(), e));
+                    sess.abort_if_errors();
+                }
+            }
             a.add_file(&metadata, false);
-            fs::unlink(&metadata);
+            remove(sess, &metadata);
 
             // For LTO purposes, the bytecode of this library is also inserted
             // into the archive.
             let bc = obj_filename.with_extension("bc");
             a.add_file(&bc, false);
             if !sess.opts.save_temps {
-                fs::unlink(&bc);
+                remove(sess, &bc);
             }
 
             // After adding all files to the archive, we need to update the
@@ -959,7 +968,7 @@ fn link_rlib(sess: Session,
 // metadata file).
 fn link_staticlib(sess: Session, obj_filename: &Path, out_filename: &Path) {
     let mut a = link_rlib(sess, None, obj_filename, out_filename);
-    a.add_native_library("morestack");
+    a.add_native_library("morestack").unwrap();
 
     let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
     for &(cnum, ref path) in crates.iter() {
@@ -970,7 +979,7 @@ fn link_staticlib(sess: Session, obj_filename: &Path, out_filename: &Path) {
                 continue
             }
         };
-        a.add_rlib(&p, name, sess.lto());
+        a.add_rlib(&p, name, sess.lto()).unwrap();
         let native_libs = csearch::get_native_libraries(sess.cstore, cnum);
         for &(kind, ref lib) in native_libs.iter() {
             let name = match kind {
@@ -1004,14 +1013,10 @@ fn link_natively(sess: Session, dylib: bool, obj_filename: &Path,
 
     // Invoke the system linker
     debug!("{} {}", cc_prog, cc_args.connect(" "));
-    let opt_prog = {
-        let _guard = io::ignore_io_error();
-        time(sess.time_passes(), "running linker", (), |()|
-             run::process_output(cc_prog, cc_args))
-    };
-
-    match opt_prog {
-        Some(prog) => {
+    let prog = time(sess.time_passes(), "running linker", (), |()|
+                    run::process_output(cc_prog, cc_args));
+    match prog {
+        Ok(prog) => {
             if !prog.status.success() {
                 sess.err(format!("linking with `{}` failed: {}", cc_prog, prog.status));
                 sess.note(format!("{} arguments: '{}'", cc_prog, cc_args.connect("' '")));
@@ -1019,8 +1024,8 @@ fn link_natively(sess: Session, dylib: bool, obj_filename: &Path,
                 sess.abort_if_errors();
             }
         },
-        None => {
-            sess.err(format!("could not exec the linker `{}`", cc_prog));
+        Err(e) => {
+            sess.err(format!("could not exec the linker `{}`: {}", cc_prog, e));
             sess.abort_if_errors();
         }
     }
@@ -1030,8 +1035,14 @@ fn link_natively(sess: Session, dylib: bool, obj_filename: &Path,
     // the symbols
     if sess.targ_cfg.os == abi::OsMacos && sess.opts.debuginfo {
         // FIXME (#9639): This needs to handle non-utf8 paths
-        run::process_status("dsymutil",
-                            [out_filename.as_str().unwrap().to_owned()]);
+        match run::process_status("dsymutil",
+                                  [out_filename.as_str().unwrap().to_owned()]) {
+            Ok(..) => {}
+            Err(e) => {
+                sess.err(format!("failed to run dsymutil: {}", e));
+                sess.abort_if_errors();
+            }
+        }
     }
 }
 
@@ -1225,7 +1236,16 @@ fn add_upstream_rust_crates(args: &mut ~[~str], sess: Session,
                     time(sess.time_passes(), format!("altering {}.rlib", name),
                          (), |()| {
                         let dst = tmpdir.join(cratepath.filename().unwrap());
-                        fs::copy(&cratepath, &dst);
+                        match fs::copy(&cratepath, &dst) {
+                            Ok(..) => {}
+                            Err(e) => {
+                                sess.err(format!("failed to copy {} to {}: {}",
+                                                 cratepath.display(),
+                                                 dst.display(),
+                                                 e));
+                                sess.abort_if_errors();
+                            }
+                        }
                         let dst_str = dst.as_str().unwrap().to_owned();
                         let mut archive = Archive::open(sess, dst);
                         archive.remove_file(format!("{}.o", name));
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index b779c7e73b1..a61c297956d 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -399,7 +399,7 @@ pub fn phase_5_run_llvm_passes(sess: Session,
 
         // Remove assembly source, unless --save-temps was specified
         if !sess.opts.save_temps {
-            fs::unlink(&asm_filename);
+            fs::unlink(&asm_filename).unwrap();
         }
     } else {
         time(sess.time_passes(), "LLVM passes", (), |_|
@@ -455,33 +455,39 @@ pub fn stop_after_phase_5(sess: Session) -> bool {
     return false;
 }
 
-fn write_out_deps(sess: Session, input: &Input, outputs: &OutputFilenames, crate: &ast::Crate)
+fn write_out_deps(sess: Session, input: &Input, outputs: &OutputFilenames,
+                  crate: &ast::Crate) -> io::IoResult<()>
 {
     let lm = link::build_link_meta(sess, crate.attrs, &outputs.obj_filename,
-                                       &mut ::util::sha2::Sha256::new());
+                                   &mut ::util::sha2::Sha256::new());
 
     let sess_outputs = sess.outputs.borrow();
     let out_filenames = sess_outputs.get().iter()
-        .map(|&output| link::filename_for_input(&sess, output, &lm, &outputs.out_filename))
+        .map(|&output| link::filename_for_input(&sess, output, &lm,
+                                                &outputs.out_filename))
         .to_owned_vec();
 
-    // Write out dependency rules to the dep-info file if requested with --dep-info
+    // Write out dependency rules to the dep-info file if requested with
+    // --dep-info
     let deps_filename = match sess.opts.write_dependency_info {
         // Use filename from --dep-file argument if given
         (true, Some(ref filename)) => filename.clone(),
-        // Use default filename: crate source filename with extension replaced by ".d"
+        // Use default filename: crate source filename with extension replaced
+        // by ".d"
         (true, None) => match *input {
             FileInput(ref input_path) => {
-                let filestem = input_path.filestem().expect("input file must have stem");
-                let filename = out_filenames[0].dir_path().join(filestem).with_extension("d");
-                filename
+                let filestem = input_path.filestem().expect("input file must \
+                                                             have stem");
+                let filename = out_filenames[0].dir_path().join(filestem);
+                filename.with_extension("d")
             },
             StrInput(..) => {
-                sess.warn("can not write --dep-info without a filename when compiling stdin.");
-                return;
+                sess.warn("can not write --dep-info without a filename \
+                           when compiling stdin.");
+                return Ok(());
             },
         },
-        _ => return,
+        _ => return Ok(()),
     };
 
     // Build a list of files used to compile the output and
@@ -499,11 +505,12 @@ fn write_out_deps(sess: Session, input: &Input, outputs: &OutputFilenames, crate
              })
              .collect()
     };
-    let mut file = io::File::create(&deps_filename);
+    let mut file = if_ok!(io::File::create(&deps_filename));
     for path in out_filenames.iter() {
-        write!(&mut file as &mut Writer,
-               "{}: {}\n\n", path.display(), files.connect(" "));
+        if_ok!(write!(&mut file as &mut Writer,
+                      "{}: {}\n\n", path.display(), files.connect(" ")));
     }
+    Ok(())
 }
 
 pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
@@ -521,7 +528,7 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
         let outputs = build_output_filenames(input, outdir, output,
                                              expanded_crate.attrs, sess);
 
-        write_out_deps(sess, input, outputs, &expanded_crate);
+        write_out_deps(sess, input, outputs, &expanded_crate).unwrap();
 
         if stop_after_phase_2(sess) { return; }
 
@@ -541,32 +548,33 @@ struct IdentifiedAnnotation {
 }
 
 impl pprust::PpAnn for IdentifiedAnnotation {
-    fn pre(&self, node: pprust::AnnNode) {
+    fn pre(&self, node: pprust::AnnNode) -> io::IoResult<()> {
         match node {
             pprust::NodeExpr(s, _) => pprust::popen(s),
-            _ => ()
+            _ => Ok(())
         }
     }
-    fn post(&self, node: pprust::AnnNode) {
+    fn post(&self, node: pprust::AnnNode) -> io::IoResult<()> {
         match node {
             pprust::NodeItem(s, item) => {
-                pp::space(&mut s.s);
-                pprust::synth_comment(s, item.id.to_str());
+                if_ok!(pp::space(&mut s.s));
+                if_ok!(pprust::synth_comment(s, item.id.to_str()));
             }
             pprust::NodeBlock(s, blk) => {
-                pp::space(&mut s.s);
-                pprust::synth_comment(s, ~"block " + blk.id.to_str());
+                if_ok!(pp::space(&mut s.s));
+                if_ok!(pprust::synth_comment(s, ~"block " + blk.id.to_str()));
             }
             pprust::NodeExpr(s, expr) => {
-                pp::space(&mut s.s);
-                pprust::synth_comment(s, expr.id.to_str());
-                pprust::pclose(s);
+                if_ok!(pp::space(&mut s.s));
+                if_ok!(pprust::synth_comment(s, expr.id.to_str()));
+                if_ok!(pprust::pclose(s));
             }
             pprust::NodePat(s, pat) => {
-                pp::space(&mut s.s);
-                pprust::synth_comment(s, ~"pat " + pat.id.to_str());
+                if_ok!(pp::space(&mut s.s));
+                if_ok!(pprust::synth_comment(s, ~"pat " + pat.id.to_str()));
             }
         }
+        Ok(())
     }
 }
 
@@ -575,24 +583,26 @@ struct TypedAnnotation {
 }
 
 impl pprust::PpAnn for TypedAnnotation {
-    fn pre(&self, node: pprust::AnnNode) {
+    fn pre(&self, node: pprust::AnnNode) -> io::IoResult<()> {
         match node {
             pprust::NodeExpr(s, _) => pprust::popen(s),
-            _ => ()
+            _ => Ok(())
         }
     }
-    fn post(&self, node: pprust::AnnNode) {
+    fn post(&self, node: pprust::AnnNode) -> io::IoResult<()> {
         let tcx = self.analysis.ty_cx;
         match node {
             pprust::NodeExpr(s, expr) => {
-                pp::space(&mut s.s);
-                pp::word(&mut s.s, "as");
-                pp::space(&mut s.s);
-                pp::word(&mut s.s, ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr)));
-                pprust::pclose(s);
+                if_ok!(pp::space(&mut s.s));
+                if_ok!(pp::word(&mut s.s, "as"));
+                if_ok!(pp::space(&mut s.s));
+                if_ok!(pp::word(&mut s.s,
+                                ppaux::ty_to_str(tcx, ty::expr_ty(tcx, expr))));
+                if_ok!(pprust::pclose(s));
             }
             _ => ()
         }
+        Ok(())
     }
 }
 
@@ -638,7 +648,7 @@ pub fn pretty_print_input(sess: Session,
                         &mut rdr,
                         ~stdout as ~io::Writer,
                         annotation,
-                        is_expanded);
+                        is_expanded).unwrap();
 }
 
 pub fn get_os(triple: &str) -> Option<abi::Os> {
@@ -1167,10 +1177,11 @@ pub fn early_error(emitter: &diagnostic::Emitter, msg: &str) -> ! {
     fail!(diagnostic::FatalError);
 }
 
-pub fn list_metadata(sess: Session, path: &Path, out: &mut io::Writer) {
+pub fn list_metadata(sess: Session, path: &Path,
+                     out: &mut io::Writer) -> io::IoResult<()> {
     metadata::loader::list_file_metadata(
         token::get_ident_interner(),
-        session::sess_os_to_meta_os(sess.targ_cfg.os), path, out);
+        session::sess_os_to_meta_os(sess.targ_cfg.os), path, out)
 }
 
 #[cfg(test)]
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 7ba96516bf9..c5f7d61c224 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -54,6 +54,11 @@ use syntax::diagnostic::Emitter;
 use syntax::diagnostic;
 use syntax::parse;
 
+#[cfg(stage0)]
+macro_rules! if_ok (
+    ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
+)
+
 pub mod middle {
     pub mod trans;
     pub mod ty;
@@ -236,8 +241,8 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
       1u => {
         let ifile = matches.free[0].as_slice();
         if ifile == "-" {
-            let src =
-                str::from_utf8_owned(io::stdin().read_to_end()).unwrap();
+            let contents = io::stdin().read_to_end().unwrap();
+            let src = str::from_utf8_owned(contents).unwrap();
             (d::StrInput(src), None)
         } else {
             (d::FileInput(Path::new(ifile)), Some(Path::new(ifile)))
@@ -267,7 +272,7 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
           d::FileInput(ref ifile) => {
             let mut stdout = io::stdout();
             d::list_metadata(sess, &(*ifile),
-                                  &mut stdout as &mut io::Writer);
+                             &mut stdout as &mut io::Writer).unwrap();
           }
           d::StrInput(_) => {
             d::early_error(demitter, "can not list metadata for stdin");
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index deae31abdcb..8ba98e84dfa 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -1111,15 +1111,15 @@ fn get_attributes(md: ebml::Doc) -> ~[ast::Attribute] {
 }
 
 fn list_crate_attributes(intr: @IdentInterner, md: ebml::Doc, hash: &str,
-                         out: &mut io::Writer) {
-    write!(out, "=Crate Attributes ({})=\n", hash);
+                         out: &mut io::Writer) -> io::IoResult<()> {
+    if_ok!(write!(out, "=Crate Attributes ({})=\n", hash));
 
     let r = get_attributes(md);
     for attr in r.iter() {
-        write!(out, "{}\n", pprust::attribute_to_str(attr, intr));
+        if_ok!(write!(out, "{}\n", pprust::attribute_to_str(attr, intr)));
     }
 
-    write!(out, "\n\n");
+    write!(out, "\n\n")
 }
 
 pub fn get_crate_attributes(data: &[u8]) -> ~[ast::Attribute] {
@@ -1154,21 +1154,22 @@ pub fn get_crate_deps(data: &[u8]) -> ~[CrateDep] {
     return deps;
 }
 
-fn list_crate_deps(data: &[u8], out: &mut io::Writer) {
-    write!(out, "=External Dependencies=\n");
+fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
+    if_ok!(write!(out, "=External Dependencies=\n"));
 
     let r = get_crate_deps(data);
     for dep in r.iter() {
         let string = token::get_ident(dep.name.name);
-        write!(out,
-               "{} {}-{}-{}\n",
-               dep.cnum,
-               string.get(),
-               dep.hash,
-               dep.vers);
+        if_ok!(write!(out,
+                      "{} {}-{}-{}\n",
+                      dep.cnum,
+                      string.get(),
+                      dep.hash,
+                      dep.vers));
     }
 
-    write!(out, "\n");
+    if_ok!(write!(out, "\n"));
+    Ok(())
 }
 
 pub fn get_crate_hash(data: &[u8]) -> ~str {
@@ -1186,11 +1187,11 @@ pub fn get_crate_vers(data: &[u8]) -> ~str {
 }
 
 pub fn list_crate_metadata(intr: @IdentInterner, bytes: &[u8],
-                           out: &mut io::Writer) {
+                           out: &mut io::Writer) -> io::IoResult<()> {
     let hash = get_crate_hash(bytes);
     let md = reader::Doc(bytes);
-    list_crate_attributes(intr, md, hash, out);
-    list_crate_deps(bytes, out);
+    if_ok!(list_crate_attributes(intr, md, hash, out));
+    list_crate_deps(bytes, out)
 }
 
 // Translates a def_id from an external crate to a def_id for the current
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 6a1c3dd4b62..d56d211b713 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -10,6 +10,7 @@
 
 // Metadata encoding
 
+#[allow(unused_must_use)]; // everything is just a MemWriter, can't fail
 
 use metadata::common::*;
 use metadata::cstore;
@@ -350,7 +351,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
             let mut index = index.borrow_mut();
             index.get().push(entry {
                 val: variant.node.id as i64,
-                pos: ebml_w.writer.tell(),
+                pos: ebml_w.writer.tell().unwrap(),
             });
         }
         ebml_w.start_tag(tag_items_data_item);
@@ -668,10 +669,10 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::Explic
 
     // Encode the base self type.
     match explicit_self {
-        SelfStatic => ebml_w.writer.write(&[ 's' as u8 ]),
-        SelfValue  => ebml_w.writer.write(&[ 'v' as u8 ]),
-        SelfBox    => ebml_w.writer.write(&[ '@' as u8 ]),
-        SelfUniq   => ebml_w.writer.write(&[ '~' as u8 ]),
+        SelfStatic => { ebml_w.writer.write(&[ 's' as u8 ]); }
+        SelfValue  => { ebml_w.writer.write(&[ 'v' as u8 ]); }
+        SelfBox    => { ebml_w.writer.write(&[ '@' as u8 ]); }
+        SelfUniq   => { ebml_w.writer.write(&[ '~' as u8 ]); }
         SelfRegion(_, m) => {
             // FIXME(#4846) encode custom lifetime
             ebml_w.writer.write(&['&' as u8]);
@@ -684,8 +685,8 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::Explic
     fn encode_mutability(ebml_w: &writer::Encoder,
                          m: ast::Mutability) {
         match m {
-            MutImmutable => ebml_w.writer.write(&[ 'i' as u8 ]),
-            MutMutable => ebml_w.writer.write(&[ 'm' as u8 ]),
+            MutImmutable => { ebml_w.writer.write(&[ 'i' as u8 ]); }
+            MutMutable => { ebml_w.writer.write(&[ 'm' as u8 ]); }
         }
     }
 }
@@ -726,12 +727,12 @@ fn encode_info_for_struct(ecx: &EncodeContext,
         };
 
         let id = field.node.id;
-        index.push(entry {val: id as i64, pos: ebml_w.writer.tell()});
+        index.push(entry {val: id as i64, pos: ebml_w.writer.tell().unwrap()});
         {
             let mut global_index = global_index.borrow_mut();
             global_index.get().push(entry {
                 val: id as i64,
-                pos: ebml_w.writer.tell(),
+                pos: ebml_w.writer.tell().unwrap(),
             });
         }
         ebml_w.start_tag(tag_items_data_item);
@@ -758,7 +759,7 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
         let mut index = index.borrow_mut();
         index.get().push(entry {
             val: ctor_id as i64,
-            pos: ebml_w.writer.tell(),
+            pos: ebml_w.writer.tell().unwrap(),
         });
     }
 
@@ -921,7 +922,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
         let mut index = index.borrow_mut();
         index.get().push(entry {
             val: item.id as i64,
-            pos: ebml_w.writer.tell(),
+            pos: ebml_w.writer.tell().unwrap(),
         });
     }
     let add_to_index: || = || add_to_index(item, ebml_w, index);
@@ -1157,7 +1158,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
                 let mut index = index.borrow_mut();
                 index.get().push(entry {
                     val: m.def_id.node as i64,
-                    pos: ebml_w.writer.tell(),
+                    pos: ebml_w.writer.tell().unwrap(),
                 });
             }
             encode_info_for_method(ecx,
@@ -1219,7 +1220,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
                 let mut index = index.borrow_mut();
                 index.get().push(entry {
                     val: method_def_id.node as i64,
-                    pos: ebml_w.writer.tell(),
+                    pos: ebml_w.writer.tell().unwrap(),
                 });
             }
 
@@ -1294,7 +1295,7 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
         let mut index = index.borrow_mut();
         index.get().push(entry {
             val: nitem.id as i64,
-            pos: ebml_w.writer.tell(),
+            pos: ebml_w.writer.tell().unwrap(),
         });
     }
 
@@ -1418,7 +1419,7 @@ fn encode_info_for_items(ecx: &EncodeContext,
         let mut index = index.borrow_mut();
         index.get().push(entry {
             val: CRATE_NODE_ID as i64,
-            pos: ebml_w.writer.tell(),
+            pos: ebml_w.writer.tell().unwrap(),
         });
     }
     encode_info_for_mod(ecx,
@@ -1478,7 +1479,7 @@ fn encode_index<T:'static>(
     let mut bucket_locs = ~[];
     ebml_w.start_tag(tag_index_buckets);
     for bucket in buckets.iter() {
-        bucket_locs.push(ebml_w.writer.tell());
+        bucket_locs.push(ebml_w.writer.tell().unwrap());
         ebml_w.start_tag(tag_index_buckets_bucket);
         for elt in (**bucket).iter() {
             ebml_w.start_tag(tag_index_buckets_bucket_elt);
@@ -1895,58 +1896,58 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, crate: &Crate)
 
     encode_hash(&mut ebml_w, ecx.link_meta.crate_hash);
 
-    let mut i = ebml_w.writer.tell();
+    let mut i = ebml_w.writer.tell().unwrap();
     let crate_attrs = synthesize_crate_attrs(&ecx, crate);
     encode_attributes(&mut ebml_w, crate_attrs);
-    ecx.stats.attr_bytes.set(ebml_w.writer.tell() - i);
+    ecx.stats.attr_bytes.set(ebml_w.writer.tell().unwrap() - i);
 
-    i = ebml_w.writer.tell();
+    i = ebml_w.writer.tell().unwrap();
     encode_crate_deps(&ecx, &mut ebml_w, ecx.cstore);
-    ecx.stats.dep_bytes.set(ebml_w.writer.tell() - i);
+    ecx.stats.dep_bytes.set(ebml_w.writer.tell().unwrap() - i);
 
     // Encode the language items.
-    i = ebml_w.writer.tell();
+    i = ebml_w.writer.tell().unwrap();
     encode_lang_items(&ecx, &mut ebml_w);
-    ecx.stats.lang_item_bytes.set(ebml_w.writer.tell() - i);
+    ecx.stats.lang_item_bytes.set(ebml_w.writer.tell().unwrap() - i);
 
     // Encode the native libraries used
-    i = ebml_w.writer.tell();
+    i = ebml_w.writer.tell().unwrap();
     encode_native_libraries(&ecx, &mut ebml_w);
-    ecx.stats.native_lib_bytes.set(ebml_w.writer.tell() - i);
+    ecx.stats.native_lib_bytes.set(ebml_w.writer.tell().unwrap() - i);
 
     // Encode the macro registrar function
-    i = ebml_w.writer.tell();
+    i = ebml_w.writer.tell().unwrap();
     encode_macro_registrar_fn(&ecx, &mut ebml_w);
-    ecx.stats.macro_registrar_fn_bytes.set(ebml_w.writer.tell() - i);
+    ecx.stats.macro_registrar_fn_bytes.set(ebml_w.writer.tell().unwrap() - i);
 
     // Encode macro definitions
-    i = ebml_w.writer.tell();
+    i = ebml_w.writer.tell().unwrap();
     encode_macro_defs(&ecx, crate, &mut ebml_w);
-    ecx.stats.macro_defs_bytes.set(ebml_w.writer.tell() - i);
+    ecx.stats.macro_defs_bytes.set(ebml_w.writer.tell().unwrap() - i);
 
     // Encode the def IDs of impls, for coherence checking.
-    i = ebml_w.writer.tell();
+    i = ebml_w.writer.tell().unwrap();
     encode_impls(&ecx, crate, &mut ebml_w);
-    ecx.stats.impl_bytes.set(ebml_w.writer.tell() - i);
+    ecx.stats.impl_bytes.set(ebml_w.writer.tell().unwrap() - i);
 
     // Encode miscellaneous info.
-    i = ebml_w.writer.tell();
+    i = ebml_w.writer.tell().unwrap();
     encode_misc_info(&ecx, crate, &mut ebml_w);
-    ecx.stats.misc_bytes.set(ebml_w.writer.tell() - i);
+    ecx.stats.misc_bytes.set(ebml_w.writer.tell().unwrap() - i);
 
     // Encode and index the items.
     ebml_w.start_tag(tag_items);
-    i = ebml_w.writer.tell();
+    i = ebml_w.writer.tell().unwrap();
     let items_index = encode_info_for_items(&ecx, &mut ebml_w, crate);
-    ecx.stats.item_bytes.set(ebml_w.writer.tell() - i);
+    ecx.stats.item_bytes.set(ebml_w.writer.tell().unwrap() - i);
 
-    i = ebml_w.writer.tell();
+    i = ebml_w.writer.tell().unwrap();
     let items_buckets = create_index(items_index);
     encode_index(&mut ebml_w, items_buckets, write_i64);
-    ecx.stats.index_bytes.set(ebml_w.writer.tell() - i);
+    ecx.stats.index_bytes.set(ebml_w.writer.tell().unwrap() - i);
     ebml_w.end_tag();
 
-    ecx.stats.total_bytes.set(ebml_w.writer.tell());
+    ecx.stats.total_bytes.set(ebml_w.writer.tell().unwrap());
 
     if tcx.sess.meta_stats() {
         for e in ebml_w.writer.get_ref().iter() {
diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs
index fd8c620dc4e..7e04a36ee2e 100644
--- a/src/librustc/metadata/filesearch.rs
+++ b/src/librustc/metadata/filesearch.rs
@@ -11,7 +11,6 @@
 use std::cell::RefCell;
 use std::option;
 use std::os;
-use std::io;
 use std::io::fs;
 use std::hashmap::HashSet;
 
@@ -93,7 +92,7 @@ impl FileSearch {
     pub fn search(&self, pick: pick) {
         self.for_each_lib_search_path(|lib_search_path| {
             debug!("searching {}", lib_search_path.display());
-            match io::result(|| fs::readdir(lib_search_path)) {
+            match fs::readdir(lib_search_path) {
                 Ok(files) => {
                     let mut rslt = FileDoesntMatch;
                     let is_rlib = |p: & &Path| {
@@ -163,8 +162,8 @@ pub fn get_or_default_sysroot() -> Path {
     // Follow symlinks.  If the resolved path is relative, make it absolute.
     fn canonicalize(path: Option<Path>) -> Option<Path> {
         path.and_then(|mut path|
-            match io::io_error::cond.trap(|_| ()).inside(|| fs::readlink(&path)) {
-                Some(canon) => {
+            match fs::readlink(&path) {
+                Ok(canon) => {
                     if canon.is_absolute() {
                         Some(canon)
                     } else {
@@ -172,7 +171,7 @@ pub fn get_or_default_sysroot() -> Path {
                         Some(path.join(canon))
                     }
                 },
-                None => Some(path),
+                Err(..) => Some(path),
             })
     }
 
diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs
index 8e557560b95..abcd650ced1 100644
--- a/src/librustc/metadata/loader.rs
+++ b/src/librustc/metadata/loader.rs
@@ -381,13 +381,13 @@ pub fn read_meta_section_name(os: Os) -> &'static str {
 pub fn list_file_metadata(intr: @IdentInterner,
                           os: Os,
                           path: &Path,
-                          out: &mut io::Writer) {
+                          out: &mut io::Writer) -> io::IoResult<()> {
     match get_metadata_section(os, path) {
       option::Some(bytes) => decoder::list_crate_metadata(intr,
                                                           bytes.as_slice(),
                                                           out),
       option::None => {
-        write!(out, "could not find metadata in {}.\n", path.display())
+          write!(out, "could not find metadata in {}.\n", path.display())
       }
     }
 }
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index d17a4516543..913c5dac460 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -10,6 +10,8 @@
 
 // Type encoding
 
+#[allow(unused_must_use)]; // as with encoding, everything is a no-fail MemWriter
+
 use std::cell::RefCell;
 use std::hashmap::HashMap;
 use std::io;
@@ -92,9 +94,9 @@ pub fn enc_ty(w: &mut MemWriter, cx: @ctxt, t: ty::t) {
                   None => {}
               }
           }
-          let pos = w.tell();
+          let pos = w.tell().unwrap();
           enc_sty(w, cx, &ty::get(t).sty);
-          let end = w.tell();
+          let end = w.tell().unwrap();
           let len = end - pos;
           fn estimate_sz(u: u64) -> u64 {
               let mut n = u;
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index a957b8c7ef5..78221d2adb3 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -88,7 +88,7 @@ struct LoopScope<'a> {
 }
 
 impl<O:DataFlowOperator> pprust::PpAnn for DataFlowContext<O> {
-    fn pre(&self, node: pprust::AnnNode) {
+    fn pre(&self, node: pprust::AnnNode) -> io::IoResult<()> {
         let (ps, id) = match node {
             pprust::NodeExpr(ps, expr) => (ps, expr.id),
             pprust::NodeBlock(ps, blk) => (ps, blk.id),
@@ -117,9 +117,10 @@ impl<O:DataFlowOperator> pprust::PpAnn for DataFlowContext<O> {
 
             let comment_str = format!("id {}: {}{}{}",
                                       id, entry_str, gens_str, kills_str);
-            pprust::synth_comment(ps, comment_str);
-            pp::space(&mut ps.s);
+            if_ok!(pprust::synth_comment(ps, comment_str));
+            if_ok!(pp::space(&mut ps.s));
         }
+        Ok(())
     }
 }
 
@@ -347,18 +348,20 @@ impl<O:DataFlowOperator+Clone+'static> DataFlowContext<O> {
         debug!("Dataflow result:");
         debug!("{}", {
             let this = @(*self).clone();
-            this.pretty_print_to(~io::stderr() as ~io::Writer, blk);
+            this.pretty_print_to(~io::stderr() as ~io::Writer, blk).unwrap();
             ""
         });
     }
 
-    fn pretty_print_to(@self, wr: ~io::Writer, blk: &ast::Block) {
+    fn pretty_print_to(@self, wr: ~io::Writer,
+                       blk: &ast::Block) -> io::IoResult<()> {
         let mut ps = pprust::rust_printer_annotated(wr, self.tcx.sess.intr(),
                                                     self as @pprust::PpAnn);
-        pprust::cbox(&mut ps, pprust::indent_unit);
-        pprust::ibox(&mut ps, 0u);
-        pprust::print_block(&mut ps, blk);
-        pp::eof(&mut ps.s);
+        if_ok!(pprust::cbox(&mut ps, pprust::indent_unit));
+        if_ok!(pprust::ibox(&mut ps, 0u));
+        if_ok!(pprust::print_block(&mut ps, blk));
+        if_ok!(pp::eof(&mut ps.s));
+        Ok(())
     }
 }
 
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index fb5e548e12f..26e4a11ae49 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -736,14 +736,15 @@ impl Liveness {
     pub fn write_vars(&self,
                       wr: &mut io::Writer,
                       ln: LiveNode,
-                      test: |uint| -> LiveNode) {
+                      test: |uint| -> LiveNode) -> io::IoResult<()> {
         let node_base_idx = self.idx(ln, Variable(0));
         for var_idx in range(0u, self.ir.num_vars.get()) {
             let idx = node_base_idx + var_idx;
             if test(idx).is_valid() {
-                write!(wr, " {}", Variable(var_idx).to_str());
+                if_ok!(write!(wr, " {}", Variable(var_idx).to_str()));
             }
         }
+        Ok(())
     }
 
     pub fn find_loop_scope(&self,
@@ -781,6 +782,7 @@ impl Liveness {
         *loop_scope.get().last().unwrap()
     }
 
+    #[allow(unused_must_use)]
     pub fn ln_str(&self, ln: LiveNode) -> ~str {
         let mut wr = io::MemWriter::new();
         {
diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs
index 1aaa446fc6c..82850dffa2b 100644
--- a/src/librustdoc/html/escape.rs
+++ b/src/librustdoc/html/escape.rs
@@ -20,7 +20,7 @@ use std::fmt;
 pub struct Escape<'a>(&'a str);
 
 impl<'a> fmt::Show for Escape<'a> {
-    fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) {
+    fn fmt(s: &Escape<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
         // Because the internet is always right, turns out there's not that many
         // characters to escape: http://stackoverflow.com/questions/7381974
         let Escape(s) = *s;
@@ -29,7 +29,7 @@ impl<'a> fmt::Show for Escape<'a> {
         for (i, ch) in s.bytes().enumerate() {
             match ch as char {
                 '<' | '>' | '&' | '\'' | '"' => {
-                    fmt.buf.write(pile_o_bits.slice(last, i).as_bytes());
+                    if_ok!(fmt.buf.write(pile_o_bits.slice(last, i).as_bytes()));
                     let s = match ch as char {
                         '>' => "&gt;",
                         '<' => "&lt;",
@@ -38,7 +38,7 @@ impl<'a> fmt::Show for Escape<'a> {
                         '"' => "&quot;",
                         _ => unreachable!()
                     };
-                    fmt.buf.write(s.as_bytes());
+                    if_ok!(fmt.buf.write(s.as_bytes()));
                     last = i + 1;
                 }
                 _ => {}
@@ -46,7 +46,8 @@ impl<'a> fmt::Show for Escape<'a> {
         }
 
         if last < s.len() {
-            fmt.buf.write(pile_o_bits.slice_from(last).as_bytes());
+            if_ok!(fmt.buf.write(pile_o_bits.slice_from(last).as_bytes()));
         }
+        Ok(())
     }
 }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 6b09072ff08..92d15fbcd67 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -48,85 +48,104 @@ impl PuritySpace {
 }
 
 impl fmt::Show for clean::Generics {
-    fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) {
-        if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return }
-        f.buf.write("&lt;".as_bytes());
+    fn fmt(g: &clean::Generics, f: &mut fmt::Formatter) -> fmt::Result {
+        if g.lifetimes.len() == 0 && g.type_params.len() == 0 { return Ok(()) }
+        if_ok!(f.buf.write("&lt;".as_bytes()));
 
         for (i, life) in g.lifetimes.iter().enumerate() {
-            if i > 0 { f.buf.write(", ".as_bytes()); }
-            write!(f.buf, "{}", *life);
+            if i > 0 {
+                if_ok!(f.buf.write(", ".as_bytes()));
+            }
+            if_ok!(write!(f.buf, "{}", *life));
         }
 
         if g.type_params.len() > 0 {
-            if g.lifetimes.len() > 0 { f.buf.write(", ".as_bytes()); }
+            if g.lifetimes.len() > 0 {
+                if_ok!(f.buf.write(", ".as_bytes()));
+            }
 
             for (i, tp) in g.type_params.iter().enumerate() {
-                if i > 0 { f.buf.write(", ".as_bytes()) }
-                f.buf.write(tp.name.as_bytes());
+                if i > 0 {
+                    if_ok!(f.buf.write(", ".as_bytes()))
+                }
+                if_ok!(f.buf.write(tp.name.as_bytes()));
 
                 if tp.bounds.len() > 0 {
-                    f.buf.write(": ".as_bytes());
+                    if_ok!(f.buf.write(": ".as_bytes()));
                     for (i, bound) in tp.bounds.iter().enumerate() {
-                        if i > 0 { f.buf.write(" + ".as_bytes()); }
-                        write!(f.buf, "{}", *bound);
+                        if i > 0 {
+                            if_ok!(f.buf.write(" + ".as_bytes()));
+                        }
+                        if_ok!(write!(f.buf, "{}", *bound));
                     }
                 }
             }
         }
-        f.buf.write("&gt;".as_bytes());
+        if_ok!(f.buf.write("&gt;".as_bytes()));
+        Ok(())
     }
 }
 
 impl fmt::Show for clean::Lifetime {
-    fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) {
-        f.buf.write("'".as_bytes());
-        f.buf.write(l.get_ref().as_bytes());
+    fn fmt(l: &clean::Lifetime, f: &mut fmt::Formatter) -> fmt::Result {
+        if_ok!(f.buf.write("'".as_bytes()));
+        if_ok!(f.buf.write(l.get_ref().as_bytes()));
+        Ok(())
     }
 }
 
 impl fmt::Show for clean::TyParamBound {
-    fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) {
+    fn fmt(bound: &clean::TyParamBound, f: &mut fmt::Formatter) -> fmt::Result {
         match *bound {
             clean::RegionBound => {
                 f.buf.write("'static".as_bytes())
             }
             clean::TraitBound(ref ty) => {
-                write!(f.buf, "{}", *ty);
+                write!(f.buf, "{}", *ty)
             }
         }
     }
 }
 
 impl fmt::Show for clean::Path {
-    fn fmt(path: &clean::Path, f: &mut fmt::Formatter) {
-        if path.global { f.buf.write("::".as_bytes()) }
+    fn fmt(path: &clean::Path, f: &mut fmt::Formatter) -> fmt::Result {
+        if path.global {
+            if_ok!(f.buf.write("::".as_bytes()))
+        }
         for (i, seg) in path.segments.iter().enumerate() {
-            if i > 0 { f.buf.write("::".as_bytes()) }
-            f.buf.write(seg.name.as_bytes());
+            if i > 0 {
+                if_ok!(f.buf.write("::".as_bytes()))
+            }
+            if_ok!(f.buf.write(seg.name.as_bytes()));
 
             if seg.lifetimes.len() > 0 || seg.types.len() > 0 {
-                f.buf.write("&lt;".as_bytes());
+                if_ok!(f.buf.write("&lt;".as_bytes()));
                 let mut comma = false;
                 for lifetime in seg.lifetimes.iter() {
-                    if comma { f.buf.write(", ".as_bytes()); }
+                    if comma {
+                        if_ok!(f.buf.write(", ".as_bytes()));
+                    }
                     comma = true;
-                    write!(f.buf, "{}", *lifetime);
+                    if_ok!(write!(f.buf, "{}", *lifetime));
                 }
                 for ty in seg.types.iter() {
-                    if comma { f.buf.write(", ".as_bytes()); }
+                    if comma {
+                        if_ok!(f.buf.write(", ".as_bytes()));
+                    }
                     comma = true;
-                    write!(f.buf, "{}", *ty);
+                    if_ok!(write!(f.buf, "{}", *ty));
                 }
-                f.buf.write("&gt;".as_bytes());
+                if_ok!(f.buf.write("&gt;".as_bytes()));
             }
         }
+        Ok(())
     }
 }
 
 /// Used when rendering a `ResolvedPath` structure. This invokes the `path`
 /// rendering function with the necessary arguments for linking to a local path.
 fn resolved_path(w: &mut io::Writer, id: ast::NodeId, p: &clean::Path,
-                 print_all: bool) {
+                 print_all: bool) -> fmt::Result {
     path(w, p, print_all,
         |_cache, loc| { Some("../".repeat(loc.len())) },
         |cache| {
@@ -134,13 +153,14 @@ fn resolved_path(w: &mut io::Writer, id: ast::NodeId, p: &clean::Path,
                 None => None,
                 Some(&(ref fqp, shortty)) => Some((fqp.clone(), shortty))
             }
-        });
+        })
 }
 
 /// Used when rendering an `ExternalPath` structure. Like `resolved_path` this
 /// will invoke `path` with proper linking-style arguments.
 fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool,
-                 fqn: &[~str], kind: clean::TypeKind, crate: ast::CrateNum) {
+                 fqn: &[~str], kind: clean::TypeKind,
+                 crate: ast::CrateNum) -> fmt::Result {
     path(w, p, print_all,
         |cache, loc| {
             match *cache.extern_locations.get(&crate) {
@@ -161,7 +181,9 @@ fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool,
 
 fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
         root: |&render::Cache, &[~str]| -> Option<~str>,
-        info: |&render::Cache| -> Option<(~[~str], &'static str)>) {
+        info: |&render::Cache| -> Option<(~[~str], &'static str)>)
+    -> fmt::Result
+{
     // The generics will get written to both the title and link
     let mut generics = ~"";
     let last = path.segments.last().unwrap();
@@ -200,20 +222,20 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
                         let mut root = root;
                         for seg in path.segments.slice_to(amt).iter() {
                             if "super" == seg.name || "self" == seg.name {
-                                write!(w, "{}::", seg.name);
+                                if_ok!(write!(w, "{}::", seg.name));
                             } else {
                                 root.push_str(seg.name);
                                 root.push_str("/");
-                                write!(w, "<a class='mod'
-                                              href='{}index.html'>{}</a>::",
-                                       root,
-                                       seg.name);
+                                if_ok!(write!(w, "<a class='mod'
+                                                    href='{}index.html'>{}</a>::",
+                                              root,
+                                              seg.name));
                             }
                         }
                     }
                     None => {
                         for seg in path.segments.slice_to(amt).iter() {
-                            write!(w, "{}::", seg.name);
+                            if_ok!(write!(w, "{}::", seg.name));
                         }
                     }
                 }
@@ -241,51 +263,57 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
                         }
                     }
 
-                    write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
-                           shortty, url, fqp.connect("::"), last.name);
+                    if_ok!(write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
+                                  shortty, url, fqp.connect("::"), last.name));
                 }
 
                 _ => {
-                    write!(w, "{}", last.name);
+                    if_ok!(write!(w, "{}", last.name));
                 }
             }
-            write!(w, "{}", generics);
+            if_ok!(write!(w, "{}", generics));
+            Ok(())
         })
     })
 }
 
 /// Helper to render type parameters
-fn typarams(w: &mut io::Writer, typarams: &Option<~[clean::TyParamBound]>) {
+fn typarams(w: &mut io::Writer,
+            typarams: &Option<~[clean::TyParamBound]>) -> fmt::Result {
     match *typarams {
         Some(ref params) => {
-            write!(w, "&lt;");
+            if_ok!(write!(w, "&lt;"));
             for (i, param) in params.iter().enumerate() {
-                if i > 0 { write!(w, ", "); }
-                write!(w, "{}", *param);
+                if i > 0 {
+                    if_ok!(write!(w, ", "));
+                }
+                if_ok!(write!(w, "{}", *param));
             }
-            write!(w, "&gt;");
+            if_ok!(write!(w, "&gt;"));
+            Ok(())
         }
-        None => {}
+        None => Ok(())
     }
 }
 
 impl fmt::Show for clean::Type {
-    fn fmt(g: &clean::Type, f: &mut fmt::Formatter) {
+    fn fmt(g: &clean::Type, f: &mut fmt::Formatter) -> fmt::Result {
         match *g {
             clean::TyParamBinder(id) | clean::Generic(id) => {
                 local_data::get(cache_key, |cache| {
                     let m = cache.unwrap().get();
-                    f.buf.write(m.typarams.get(&id).as_bytes());
+                    f.buf.write(m.typarams.get(&id).as_bytes())
                 })
             }
             clean::ResolvedPath{id, typarams: ref tp, path: ref path} => {
-                resolved_path(f.buf, id, path, false);
-                typarams(f.buf, tp);
+                if_ok!(resolved_path(f.buf, id, path, false));
+                typarams(f.buf, tp)
             }
             clean::ExternalPath{path: ref path, typarams: ref tp,
                                 fqn: ref fqn, kind, crate} => {
-                external_path(f.buf, path, false, fqn.as_slice(), kind, crate);
-                typarams(f.buf, tp);
+                if_ok!(external_path(f.buf, path, false, fqn.as_slice(), kind,
+                                     crate))
+                typarams(f.buf, tp)
             }
             clean::Self(..) => f.buf.write("Self".as_bytes()),
             clean::Primitive(prim) => {
@@ -306,7 +334,7 @@ impl fmt::Show for clean::Type {
                     ast::TyBool => "bool",
                     ast::TyChar => "char",
                 };
-                f.buf.write(s.as_bytes());
+                f.buf.write(s.as_bytes())
             }
             clean::Closure(ref decl) => {
                 let region = match decl.region {
@@ -322,7 +350,7 @@ impl fmt::Show for clean::Type {
                            ast::ManagedSigil => format!("@{}fn({})", region, decl.decl.inputs),
                        },
                        arrow = match decl.decl.output { clean::Unit => "no", _ => "yes" },
-                       ret = decl.decl.output);
+                       ret = decl.decl.output)
                 // FIXME: where are bounds and lifetimes printed?!
             }
             clean::BareFunction(ref decl) => {
@@ -333,19 +361,21 @@ impl fmt::Show for clean::Type {
                            ref s => " " + *s + " ",
                        },
                        decl.generics,
-                       decl.decl);
+                       decl.decl)
             }
             clean::Tuple(ref typs) => {
-                f.buf.write("(".as_bytes());
+                if_ok!(f.buf.write("(".as_bytes()));
                 for (i, typ) in typs.iter().enumerate() {
-                    if i > 0 { f.buf.write(", ".as_bytes()) }
-                    write!(f.buf, "{}", *typ);
+                    if i > 0 {
+                        if_ok!(f.buf.write(", ".as_bytes()))
+                    }
+                    if_ok!(write!(f.buf, "{}", *typ));
                 }
-                f.buf.write(")".as_bytes());
+                f.buf.write(")".as_bytes())
             }
             clean::Vector(ref t) => write!(f.buf, "[{}]", **t),
             clean::FixedVector(ref t, ref s) => {
-                write!(f.buf, "[{}, ..{}]", **t, *s);
+                write!(f.buf, "[{}, ..{}]", **t, *s)
             }
             clean::String => f.buf.write("str".as_bytes()),
             clean::Bool => f.buf.write("bool".as_bytes()),
@@ -368,23 +398,23 @@ impl fmt::Show for clean::Type {
                            clean::Mutable => "mut ",
                            clean::Immutable => "",
                        },
-                       **ty);
+                       **ty)
             }
         }
     }
 }
 
 impl fmt::Show for clean::FnDecl {
-    fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) {
+    fn fmt(d: &clean::FnDecl, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f.buf, "({args}){arrow, select, yes{ -&gt; {ret}} other{}}",
                args = d.inputs,
                arrow = match d.output { clean::Unit => "no", _ => "yes" },
-               ret = d.output);
+               ret = d.output)
     }
 }
 
 impl fmt::Show for ~[clean::Argument] {
-    fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) {
+    fn fmt(inputs: &~[clean::Argument], f: &mut fmt::Formatter) -> fmt::Result {
         let mut args = ~"";
         for (i, input) in inputs.iter().enumerate() {
             if i > 0 { args.push_str(", "); }
@@ -393,12 +423,12 @@ impl fmt::Show for ~[clean::Argument] {
             }
             args.push_str(format!("{}", input.type_));
         }
-        f.buf.write(args.as_bytes());
+        f.buf.write(args.as_bytes())
     }
 }
 
 impl<'a> fmt::Show for Method<'a> {
-    fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) {
+    fn fmt(m: &Method<'a>, f: &mut fmt::Formatter) -> fmt::Result {
         let Method(selfty, d) = *m;
         let mut args = ~"";
         match *selfty {
@@ -429,74 +459,79 @@ impl<'a> fmt::Show for Method<'a> {
         write!(f.buf, "({args}){arrow, select, yes{ -&gt; {ret}} other{}}",
                args = args,
                arrow = match d.output { clean::Unit => "no", _ => "yes" },
-               ret = d.output);
+               ret = d.output)
     }
 }
 
 impl fmt::Show for VisSpace {
-    fn fmt(v: &VisSpace, f: &mut fmt::Formatter) {
+    fn fmt(v: &VisSpace, f: &mut fmt::Formatter) -> fmt::Result {
         match v.get() {
-            Some(ast::Public) => { write!(f.buf, "pub "); }
-            Some(ast::Private) => { write!(f.buf, "priv "); }
-            Some(ast::Inherited) | None => {}
+            Some(ast::Public) => write!(f.buf, "pub "),
+            Some(ast::Private) => write!(f.buf, "priv "),
+            Some(ast::Inherited) | None => Ok(())
         }
     }
 }
 
 impl fmt::Show for PuritySpace {
-    fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) {
+    fn fmt(p: &PuritySpace, f: &mut fmt::Formatter) -> fmt::Result {
         match p.get() {
             ast::UnsafeFn => write!(f.buf, "unsafe "),
             ast::ExternFn => write!(f.buf, "extern "),
-            ast::ImpureFn => {}
+            ast::ImpureFn => Ok(())
         }
     }
 }
 
 impl fmt::Show for clean::ViewPath {
-    fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) {
+    fn fmt(v: &clean::ViewPath, f: &mut fmt::Formatter) -> fmt::Result {
         match *v {
             clean::SimpleImport(ref name, ref src) => {
                 if *name == src.path.segments.last().unwrap().name {
-                    write!(f.buf, "use {};", *src);
+                    write!(f.buf, "use {};", *src)
                 } else {
-                    write!(f.buf, "use {} = {};", *name, *src);
+                    write!(f.buf, "use {} = {};", *name, *src)
                 }
             }
             clean::GlobImport(ref src) => {
-                write!(f.buf, "use {}::*;", *src);
+                write!(f.buf, "use {}::*;", *src)
             }
             clean::ImportList(ref src, ref names) => {
-                write!(f.buf, "use {}::\\{", *src);
+                if_ok!(write!(f.buf, "use {}::\\{", *src));
                 for (i, n) in names.iter().enumerate() {
-                    if i > 0 { write!(f.buf, ", "); }
-                    write!(f.buf, "{}", *n);
+                    if i > 0 {
+                        if_ok!(write!(f.buf, ", "));
+                    }
+                    if_ok!(write!(f.buf, "{}", *n));
                 }
-                write!(f.buf, "\\};");
+                write!(f.buf, "\\};")
             }
         }
     }
 }
 
 impl fmt::Show for clean::ImportSource {
-    fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) {
+    fn fmt(v: &clean::ImportSource, f: &mut fmt::Formatter) -> fmt::Result {
         match v.did {
             // FIXME: shouldn't be restricted to just local imports
             Some(did) if ast_util::is_local(did) => {
-                resolved_path(f.buf, did.node, &v.path, true);
+                resolved_path(f.buf, did.node, &v.path, true)
             }
             _ => {
                 for (i, seg) in v.path.segments.iter().enumerate() {
-                    if i > 0 { write!(f.buf, "::") }
-                    write!(f.buf, "{}", seg.name);
+                    if i > 0 {
+                        if_ok!(write!(f.buf, "::"))
+                    }
+                    if_ok!(write!(f.buf, "{}", seg.name));
                 }
+                Ok(())
             }
         }
     }
 }
 
 impl fmt::Show for clean::ViewListIdent {
-    fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) {
+    fn fmt(v: &clean::ViewListIdent, f: &mut fmt::Formatter) -> fmt::Result {
         match v.source {
             // FIXME: shouldn't be limited to just local imports
             Some(did) if ast_util::is_local(did) => {
@@ -508,7 +543,7 @@ impl fmt::Show for clean::ViewListIdent {
                         types: ~[],
                     }]
                 };
-                resolved_path(f.buf, did.node, &path, false);
+                resolved_path(f.buf, did.node, &path, false)
             }
             _ => write!(f.buf, "{}", v.name),
         }
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 4565facea02..db7c882ab42 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -26,6 +26,7 @@ pub struct Page<'a> {
 
 pub fn render<T: fmt::Show, S: fmt::Show>(
     dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
+    -> fmt::Result
 {
     write!(dst,
 "<!DOCTYPE html>
@@ -121,7 +122,7 @@ pub fn render<T: fmt::Show, S: fmt::Show>(
     favicon   = nonestr(layout.favicon),
     sidebar   = *sidebar,
     crate     = layout.crate,
-    );
+    )
 }
 
 fn nonestr<'a>(s: &'a str) -> &'a str {
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 254d65ae2f6..c2203a352c5 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -109,7 +109,7 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
     }
 }
 
-pub fn render(w: &mut io::Writer, s: &str) {
+pub fn render(w: &mut io::Writer, s: &str) -> fmt::Result {
     extern fn block(ob: *buf, text: *buf, lang: *buf, opaque: *libc::c_void) {
         unsafe {
             let my_opaque: &my_opaque = cast::transmute(opaque);
@@ -159,11 +159,12 @@ pub fn render(w: &mut io::Writer, s: &str) {
         sd_markdown_render(ob, s.as_ptr(), s.len() as libc::size_t, markdown);
         sd_markdown_free(markdown);
 
-        vec::raw::buf_as_slice((*ob).data, (*ob).size as uint, |buf| {
-            w.write(buf);
+        let ret = vec::raw::buf_as_slice((*ob).data, (*ob).size as uint, |buf| {
+            w.write(buf)
         });
 
         bufrelease(ob);
+        ret
     }
 }
 
@@ -210,10 +211,10 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
 }
 
 impl<'a> fmt::Show for Markdown<'a> {
-    fn fmt(md: &Markdown<'a>, fmt: &mut fmt::Formatter) {
+    fn fmt(md: &Markdown<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
         let Markdown(md) = *md;
         // This is actually common enough to special-case
-        if md.len() == 0 { return; }
-        render(fmt.buf, md.as_slice());
+        if md.len() == 0 { return Ok(()) }
+        render(fmt.buf, md.as_slice())
     }
 }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 0b2c568c723..65696528a6f 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -195,7 +195,7 @@ local_data_key!(pub cache_key: Arc<Cache>)
 local_data_key!(pub current_location_key: ~[~str])
 
 /// Generates the documentation for `crate` into the directory `dst`
-pub fn run(mut crate: clean::Crate, dst: Path) {
+pub fn run(mut crate: clean::Crate, dst: Path) -> io::IoResult<()> {
     let mut cx = Context {
         dst: dst,
         current: ~[],
@@ -208,7 +208,7 @@ pub fn run(mut crate: clean::Crate, dst: Path) {
         },
         include_sources: true,
     };
-    mkdir(&cx.dst);
+    if_ok!(mkdir(&cx.dst));
 
     match crate.module.as_ref().map(|m| m.doc_list().unwrap_or(&[])) {
         Some(attrs) => {
@@ -248,47 +248,55 @@ pub fn run(mut crate: clean::Crate, dst: Path) {
 
     // Add all the static files
     let mut dst = cx.dst.join(crate.name.as_slice());
-    mkdir(&dst);
-    write(dst.join("jquery.js"), include_str!("static/jquery-2.0.3.min.js"));
-    write(dst.join("main.js"), include_str!("static/main.js"));
-    write(dst.join("main.css"), include_str!("static/main.css"));
-    write(dst.join("normalize.css"), include_str!("static/normalize.css"));
+    if_ok!(mkdir(&dst));
+    if_ok!(write(dst.join("jquery.js"),
+                 include_str!("static/jquery-2.0.3.min.js")));
+    if_ok!(write(dst.join("main.js"), include_str!("static/main.js")));
+    if_ok!(write(dst.join("main.css"), include_str!("static/main.css")));
+    if_ok!(write(dst.join("normalize.css"),
+                 include_str!("static/normalize.css")));
 
     // Publish the search index
     {
         dst.push("search-index.js");
         let mut w = BufferedWriter::new(File::create(&dst).unwrap());
         let w = &mut w as &mut Writer;
-        write!(w, "var searchIndex = [");
+        if_ok!(write!(w, "var searchIndex = ["));
         for (i, item) in cache.search_index.iter().enumerate() {
-            if i > 0 { write!(w, ","); }
-            write!(w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}",
-                   item.ty, item.name, item.path,
-                   item.desc.to_json().to_str())
+            if i > 0 {
+                if_ok!(write!(w, ","));
+            }
+            if_ok!(write!(w, "\\{ty:\"{}\",name:\"{}\",path:\"{}\",desc:{}",
+                          item.ty, item.name, item.path,
+                          item.desc.to_json().to_str()));
             match item.parent {
-                Some(id) => { write!(w, ",parent:'{}'", id); }
+                Some(id) => {
+                    if_ok!(write!(w, ",parent:'{}'", id));
+                }
                 None => {}
             }
-            write!(w, "\\}");
+            if_ok!(write!(w, "\\}"));
         }
-        write!(w, "];");
-        write!(w, "var allPaths = \\{");
+        if_ok!(write!(w, "];"));
+        if_ok!(write!(w, "var allPaths = \\{"));
         for (i, (&id, &(ref fqp, short))) in cache.paths.iter().enumerate() {
-            if i > 0 { write!(w, ","); }
-            write!(w, "'{}':\\{type:'{}',name:'{}'\\}",
-                   id, short, *fqp.last().unwrap());
+            if i > 0 {
+                if_ok!(write!(w, ","));
+            }
+            if_ok!(write!(w, "'{}':\\{type:'{}',name:'{}'\\}",
+                          id, short, *fqp.last().unwrap()));
         }
-        write!(w, "\\};");
-        w.flush();
+        if_ok!(write!(w, "\\};"));
+        if_ok!(w.flush());
     }
 
     // Render all source files (this may turn into a giant no-op)
     {
         info!("emitting source files");
         let dst = cx.dst.join("src");
-        mkdir(&dst);
+        if_ok!(mkdir(&dst));
         let dst = dst.join(crate.name.as_slice());
-        mkdir(&dst);
+        if_ok!(mkdir(&dst));
         let mut folder = SourceCollector {
             dst: dst,
             seen: HashSet::new(),
@@ -302,27 +310,23 @@ pub fn run(mut crate: clean::Crate, dst: Path) {
     }
 
     // And finally render the whole crate's documentation
-    cx.crate(crate, cache);
+    cx.crate(crate, cache)
 }
 
 /// Writes the entire contents of a string to a destination, not attempting to
 /// catch any errors.
-fn write(dst: Path, contents: &str) {
-    File::create(&dst).write(contents.as_bytes());
+fn write(dst: Path, contents: &str) -> io::IoResult<()> {
+    File::create(&dst).write(contents.as_bytes())
 }
 
 /// Makes a directory on the filesystem, failing the task if an error occurs and
 /// skipping if the directory already exists.
-fn mkdir(path: &Path) {
-    io::io_error::cond.trap(|err| {
-        error!("Couldn't create directory `{}`: {}",
-                path.display(), err.desc);
-        fail!()
-    }).inside(|| {
-        if !path.is_dir() {
-            fs::mkdir(path, io::UserRWX);
-        }
-    })
+fn mkdir(path: &Path) -> io::IoResult<()> {
+    if !path.exists() {
+        fs::mkdir(path, io::UserRWX)
+    } else {
+        Ok(())
+    }
 }
 
 /// Takes a path to a source file and cleans the path to it. This canonicalizes
@@ -387,15 +391,17 @@ impl<'a> DocFolder for SourceCollector<'a> {
             // something like that), so just don't include sources for the
             // entire crate. The other option is maintaining this mapping on a
             // per-file basis, but that's probably not worth it...
-            self.cx.include_sources = self.emit_source(item.source.filename);
+            self.cx.include_sources = match self.emit_source(item.source.filename) {
+                Ok(()) => true,
+                Err(e) => {
+                    println!("warning: source code was requested to be rendered, \
+                              but processing `{}` had an error: {}",
+                             item.source.filename, e);
+                    println!("         skipping rendering of source code");
+                    false
+                }
+            };
             self.seen.insert(item.source.filename.clone());
-
-            if !self.cx.include_sources {
-                println!("warning: source code was requested to be rendered, \
-                          but `{}` is a missing source file.",
-                         item.source.filename);
-                println!("         skipping rendering of source code");
-            }
         }
 
         self.fold_item_recur(item)
@@ -404,30 +410,18 @@ impl<'a> DocFolder for SourceCollector<'a> {
 
 impl<'a> SourceCollector<'a> {
     /// Renders the given filename into its corresponding HTML source file.
-    fn emit_source(&mut self, filename: &str) -> bool {
+    fn emit_source(&mut self, filename: &str) -> io::IoResult<()> {
         let p = Path::new(filename);
 
-        // Read the contents of the file
-        let mut contents = ~[];
-        {
-            let mut buf = [0, ..1024];
-            // If we couldn't open this file, then just returns because it
-            // probably means that it's some standard library macro thing and we
-            // can't have the source to it anyway.
-            let mut r = match io::result(|| File::open(&p)) {
-                Ok(r) => r,
-                // eew macro hacks
-                Err(..) => return filename == "<std-macros>"
-            };
-
-            // read everything
-            loop {
-                match r.read(buf) {
-                    Some(n) => contents.push_all(buf.slice_to(n)),
-                    None => break
-                }
-            }
-        }
+        // If we couldn't open this file, then just returns because it
+        // probably means that it's some standard library macro thing and we
+        // can't have the source to it anyway.
+        let contents = match File::open(&p).read_to_end() {
+            Ok(r) => r,
+            // eew macro hacks
+            Err(..) if filename == "<std-macros>" => return Ok(()),
+            Err(e) => return Err(e)
+        };
         let contents = str::from_utf8_owned(contents).unwrap();
 
         // Create the intermediate directories
@@ -435,12 +429,12 @@ impl<'a> SourceCollector<'a> {
         let mut root_path = ~"../../";
         clean_srcpath(p.dirname(), |component| {
             cur.push(component);
-            mkdir(&cur);
+            mkdir(&cur).unwrap();
             root_path.push_str("../");
         });
 
         cur.push(p.filename().expect("source has no filename") + bytes!(".html"));
-        let mut w = BufferedWriter::new(File::create(&cur).unwrap());
+        let mut w = BufferedWriter::new(if_ok!(File::create(&cur)));
 
         let title = cur.filename_display().with_str(|s| format!("{} -- source", s));
         let page = layout::Page {
@@ -448,10 +442,10 @@ impl<'a> SourceCollector<'a> {
             ty: "source",
             root_path: root_path,
         };
-        layout::render(&mut w as &mut Writer, &self.cx.layout,
-                       &page, &(""), &Source(contents.as_slice()));
-        w.flush();
-        return true;
+        if_ok!(layout::render(&mut w as &mut Writer, &self.cx.layout,
+                              &page, &(""), &Source(contents.as_slice())));
+        if_ok!(w.flush());
+        return Ok(());
     }
 }
 
@@ -665,7 +659,7 @@ impl Context {
 
         info!("Recursing into {}", self.dst.display());
 
-        mkdir(&self.dst);
+        mkdir(&self.dst).unwrap();
         let ret = f(self);
 
         info!("Recursed; leaving {}", self.dst.display());
@@ -683,10 +677,10 @@ impl Context {
     ///
     /// This currently isn't parallelized, but it'd be pretty easy to add
     /// parallelization to this function.
-    fn crate(self, mut crate: clean::Crate, cache: Cache) {
+    fn crate(self, mut crate: clean::Crate, cache: Cache) -> io::IoResult<()> {
         let mut item = match crate.module.take() {
             Some(i) => i,
-            None => return
+            None => return Ok(())
         };
         item.name = Some(crate.name);
 
@@ -696,12 +690,13 @@ impl Context {
         let mut work = ~[(self, item)];
         loop {
             match work.pop() {
-                Some((mut cx, item)) => cx.item(item, |cx, item| {
+                Some((mut cx, item)) => if_ok!(cx.item(item, |cx, item| {
                     work.push((cx.clone(), item));
-                }),
+                })),
                 None => break,
             }
         }
+        Ok(())
     }
 
     /// Non-parellelized version of rendering an item. This will take the input
@@ -709,9 +704,10 @@ impl Context {
     /// all sub-items which need to be rendered.
     ///
     /// The rendering driver uses this closure to queue up more work.
-    fn item(&mut self, item: clean::Item, f: |&mut Context, clean::Item|) {
+    fn item(&mut self, item: clean::Item,
+            f: |&mut Context, clean::Item|) -> io::IoResult<()> {
         fn render(w: io::File, cx: &mut Context, it: &clean::Item,
-                  pushname: bool) {
+                  pushname: bool) -> io::IoResult<()> {
             info!("Rendering an item to {}", w.path().display());
             // A little unfortunate that this is done like this, but it sure
             // does make formatting *a lot* nicer.
@@ -733,10 +729,10 @@ impl Context {
             // of the pain by using a buffered writer instead of invoking the
             // write sycall all the time.
             let mut writer = BufferedWriter::new(w);
-            layout::render(&mut writer as &mut Writer, &cx.layout, &page,
-                           &Sidebar{ cx: cx, item: it },
-                           &Item{ cx: cx, item: it });
-            writer.flush();
+            if_ok!(layout::render(&mut writer as &mut Writer, &cx.layout, &page,
+                                  &Sidebar{ cx: cx, item: it },
+                                  &Item{ cx: cx, item: it }));
+            writer.flush()
         }
 
         match item.inner {
@@ -748,7 +744,8 @@ impl Context {
                 self.recurse(name, |this| {
                     let item = item.take_unwrap();
                     let dst = this.dst.join("index.html");
-                    render(File::create(&dst).unwrap(), this, &item, false);
+                    let dst = if_ok!(File::create(&dst));
+                    if_ok!(render(dst, this, &item, false));
 
                     let m = match item.inner {
                         clean::ModuleItem(m) => m,
@@ -758,6 +755,7 @@ impl Context {
                     for item in m.items.move_iter() {
                         f(this,item);
                     }
+                    Ok(())
                 })
             }
 
@@ -765,10 +763,11 @@ impl Context {
             // pages dedicated to them.
             _ if item.name.is_some() => {
                 let dst = self.dst.join(item_path(&item));
-                render(File::create(&dst).unwrap(), self, &item, true);
+                let dst = if_ok!(File::create(&dst));
+                render(dst, self, &item, true)
             }
 
-            _ => {}
+            _ => Ok(())
         }
     }
 }
@@ -802,16 +801,16 @@ impl<'a> Item<'a> {
 }
 
 impl<'a> fmt::Show for Item<'a> {
-    fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) {
+    fn fmt(it: &Item<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
         match attr::find_stability(it.item.attrs.iter()) {
             Some(ref stability) => {
-                write!(fmt.buf,
+                if_ok!(write!(fmt.buf,
                        "<a class='stability {lvl}' title='{reason}'>{lvl}</a>",
                        lvl = stability.level.to_str(),
                        reason = match stability.text {
                            Some(ref s) => (*s).clone(),
                            None => InternedString::new(""),
-                       });
+                       }));
             }
             None => {}
         }
@@ -826,23 +825,24 @@ impl<'a> fmt::Show for Item<'a> {
             } else {
                 format!("{}-{}", it.item.source.loline, it.item.source.hiline)
             };
-            write!(fmt.buf,
-                   "<a class='source'
-                       href='{root}src/{crate}/{path}.html\\#{href}'>[src]</a>",
-                   root = it.cx.root_path,
-                   crate = it.cx.layout.crate,
-                   path = path.connect("/"),
-                   href = href);
+            if_ok!(write!(fmt.buf,
+                          "<a class='source'
+                              href='{root}src/{crate}/{path}.html\\#{href}'>\
+                              [src]</a>",
+                          root = it.cx.root_path,
+                          crate = it.cx.layout.crate,
+                          path = path.connect("/"),
+                          href = href));
         }
 
         // Write the breadcrumb trail header for the top
-        write!(fmt.buf, "<h1 class='fqn'>");
+        if_ok!(write!(fmt.buf, "<h1 class='fqn'>"));
         match it.item.inner {
-            clean::ModuleItem(..) => write!(fmt.buf, "Module "),
-            clean::FunctionItem(..) => write!(fmt.buf, "Function "),
-            clean::TraitItem(..) => write!(fmt.buf, "Trait "),
-            clean::StructItem(..) => write!(fmt.buf, "Struct "),
-            clean::EnumItem(..) => write!(fmt.buf, "Enum "),
+            clean::ModuleItem(..) => if_ok!(write!(fmt.buf, "Module ")),
+            clean::FunctionItem(..) => if_ok!(write!(fmt.buf, "Function ")),
+            clean::TraitItem(..) => if_ok!(write!(fmt.buf, "Trait ")),
+            clean::StructItem(..) => if_ok!(write!(fmt.buf, "Struct ")),
+            clean::EnumItem(..) => if_ok!(write!(fmt.buf, "Enum ")),
             _ => {}
         }
         let cur = it.cx.current.as_slice();
@@ -852,11 +852,11 @@ impl<'a> fmt::Show for Item<'a> {
             for _ in range(0, cur.len() - i - 1) {
                 trail.push_str("../");
             }
-            write!(fmt.buf, "<a href='{}index.html'>{}</a>::",
-                   trail, component.as_slice());
+            if_ok!(write!(fmt.buf, "<a href='{}index.html'>{}</a>::",
+                          trail, component.as_slice()));
         }
-        write!(fmt.buf, "<a class='{}' href=''>{}</a></h1>",
-               shortty(it.item), it.item.name.get_ref().as_slice());
+        if_ok!(write!(fmt.buf, "<a class='{}' href=''>{}</a></h1>",
+                      shortty(it.item), it.item.name.get_ref().as_slice()));
 
         match it.item.inner {
             clean::ModuleItem(ref m) => item_module(fmt.buf, it.cx,
@@ -867,7 +867,7 @@ impl<'a> fmt::Show for Item<'a> {
             clean::StructItem(ref s) => item_struct(fmt.buf, it.item, s),
             clean::EnumItem(ref e) => item_enum(fmt.buf, it.item, e),
             clean::TypedefItem(ref t) => item_typedef(fmt.buf, it.item, t),
-            _ => {}
+            _ => Ok(())
         }
     }
 }
@@ -903,18 +903,19 @@ fn shorter<'a>(s: Option<&'a str>) -> &'a str {
     }
 }
 
-fn document(w: &mut Writer, item: &clean::Item) {
+fn document(w: &mut Writer, item: &clean::Item) -> fmt::Result {
     match item.doc_value() {
         Some(s) => {
-            write!(w, "<div class='docblock'>{}</div>", Markdown(s));
+            if_ok!(write!(w, "<div class='docblock'>{}</div>", Markdown(s)));
         }
         None => {}
     }
+    Ok(())
 }
 
 fn item_module(w: &mut Writer, cx: &Context,
-               item: &clean::Item, items: &[clean::Item]) {
-    document(w, item);
+               item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
+    if_ok!(document(w, item));
     debug!("{:?}", items);
     let mut indices = vec::from_fn(items.len(), |i| i);
 
@@ -965,10 +966,10 @@ fn item_module(w: &mut Writer, cx: &Context,
         let myty = shortty(myitem);
         if myty != curty {
             if curty != "" {
-                write!(w, "</table>");
+                if_ok!(write!(w, "</table>"));
             }
             curty = myty;
-            write!(w, "<h2>{}</h2>\n<table>", match myitem.inner {
+            if_ok!(write!(w, "<h2>{}</h2>\n<table>", match myitem.inner {
                 clean::ModuleItem(..)          => "Modules",
                 clean::StructItem(..)          => "Structs",
                 clean::EnumItem(..)            => "Enums",
@@ -984,24 +985,26 @@ fn item_module(w: &mut Writer, cx: &Context,
                 clean::VariantItem(..)         => "Variants",
                 clean::ForeignFunctionItem(..) => "Foreign Functions",
                 clean::ForeignStaticItem(..)   => "Foreign Statics",
-            });
+            }));
         }
 
         match myitem.inner {
             clean::StaticItem(ref s) | clean::ForeignStaticItem(ref s) => {
                 struct Initializer<'a>(&'a str);
                 impl<'a> fmt::Show for Initializer<'a> {
-                    fn fmt(s: &Initializer<'a>, f: &mut fmt::Formatter) {
+                    fn fmt(s: &Initializer<'a>,
+                           f: &mut fmt::Formatter) -> fmt::Result {
                         let Initializer(s) = *s;
-                        if s.len() == 0 { return; }
-                        write!(f.buf, "<code> = </code>");
+                        if s.len() == 0 { return Ok(()); }
+                        if_ok!(write!(f.buf, "<code> = </code>"));
                         let tag = if s.contains("\n") { "pre" } else { "code" };
-                        write!(f.buf, "<{tag}>{}</{tag}>",
-                               s.as_slice(), tag=tag);
+                        if_ok!(write!(f.buf, "<{tag}>{}</{tag}>",
+                                      s.as_slice(), tag=tag));
+                        Ok(())
                     }
                 }
 
-                write!(w, "
+                if_ok!(write!(w, "
                     <tr>
                         <td><code>{}static {}: {}</code>{}</td>
                         <td class='docblock'>{}&nbsp;</td>
@@ -1011,27 +1014,27 @@ fn item_module(w: &mut Writer, cx: &Context,
                 *myitem.name.get_ref(),
                 s.type_,
                 Initializer(s.expr),
-                Markdown(blank(myitem.doc_value())));
+                Markdown(blank(myitem.doc_value()))));
             }
 
             clean::ViewItemItem(ref item) => {
                 match item.inner {
                     clean::ExternMod(ref name, ref src, _) => {
-                        write!(w, "<tr><td><code>extern mod {}",
-                               name.as_slice());
+                        if_ok!(write!(w, "<tr><td><code>extern mod {}",
+                                      name.as_slice()));
                         match *src {
-                            Some(ref src) => write!(w, " = \"{}\"",
-                                                    src.as_slice()),
+                            Some(ref src) => if_ok!(write!(w, " = \"{}\"",
+                                                           src.as_slice())),
                             None => {}
                         }
-                        write!(w, ";</code></td></tr>");
+                        if_ok!(write!(w, ";</code></td></tr>"));
                     }
 
                     clean::Import(ref imports) => {
                         for import in imports.iter() {
-                            write!(w, "<tr><td><code>{}{}</code></td></tr>",
-                                   VisSpace(myitem.visibility),
-                                   *import);
+                            if_ok!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
+                                          VisSpace(myitem.visibility),
+                                          *import));
                         }
                     }
                 }
@@ -1040,7 +1043,7 @@ fn item_module(w: &mut Writer, cx: &Context,
 
             _ => {
                 if myitem.name.is_none() { continue }
-                write!(w, "
+                if_ok!(write!(w, "
                     <tr>
                         <td><a class='{class}' href='{href}'
                                title='{title}'>{}</a></td>
@@ -1051,24 +1054,26 @@ fn item_module(w: &mut Writer, cx: &Context,
                 Markdown(shorter(myitem.doc_value())),
                 class = shortty(myitem),
                 href = item_path(myitem),
-                title = full_path(cx, myitem));
+                title = full_path(cx, myitem)));
             }
         }
     }
-    write!(w, "</table>");
+    write!(w, "</table>")
 }
 
-fn item_function(w: &mut Writer, it: &clean::Item, f: &clean::Function) {
-    write!(w, "<pre class='fn'>{vis}{purity}fn {name}{generics}{decl}</pre>",
+fn item_function(w: &mut Writer, it: &clean::Item,
+                 f: &clean::Function) -> fmt::Result {
+    if_ok!(write!(w, "<pre class='fn'>{vis}{purity}fn {name}{generics}{decl}</pre>",
            vis = VisSpace(it.visibility),
            purity = PuritySpace(f.purity),
            name = it.name.get_ref().as_slice(),
            generics = f.generics,
-           decl = f.decl);
-    document(w, it);
+           decl = f.decl));
+    document(w, it)
 }
 
-fn item_trait(w: &mut Writer, it: &clean::Item, t: &clean::Trait) {
+fn item_trait(w: &mut Writer, it: &clean::Item,
+              t: &clean::Trait) -> fmt::Result {
     let mut parents = ~"";
     if t.parents.len() > 0 {
         parents.push_str(": ");
@@ -1079,99 +1084,102 @@ fn item_trait(w: &mut Writer, it: &clean::Item, t: &clean::Trait) {
     }
 
     // Output the trait definition
-    write!(w, "<pre class='trait'>{}trait {}{}{} ",
-           VisSpace(it.visibility),
-           it.name.get_ref().as_slice(),
-           t.generics,
-           parents);
+    if_ok!(write!(w, "<pre class='trait'>{}trait {}{}{} ",
+                  VisSpace(it.visibility),
+                  it.name.get_ref().as_slice(),
+                  t.generics,
+                  parents));
     let required = t.methods.iter().filter(|m| m.is_req()).to_owned_vec();
     let provided = t.methods.iter().filter(|m| !m.is_req()).to_owned_vec();
 
     if t.methods.len() == 0 {
-        write!(w, "\\{ \\}");
+        if_ok!(write!(w, "\\{ \\}"));
     } else {
-        write!(w, "\\{\n");
+        if_ok!(write!(w, "\\{\n"));
         for m in required.iter() {
-            write!(w, "    ");
-            render_method(w, m.item(), true);
-            write!(w, ";\n");
+            if_ok!(write!(w, "    "));
+            if_ok!(render_method(w, m.item(), true));
+            if_ok!(write!(w, ";\n"));
         }
         if required.len() > 0 && provided.len() > 0 {
-            w.write("\n".as_bytes());
+            if_ok!(w.write("\n".as_bytes()));
         }
         for m in provided.iter() {
-            write!(w, "    ");
-            render_method(w, m.item(), true);
-            write!(w, " \\{ ... \\}\n");
+            if_ok!(write!(w, "    "));
+            if_ok!(render_method(w, m.item(), true));
+            if_ok!(write!(w, " \\{ ... \\}\n"));
         }
-        write!(w, "\\}");
+        if_ok!(write!(w, "\\}"));
     }
-    write!(w, "</pre>");
+    if_ok!(write!(w, "</pre>"));
 
     // Trait documentation
-    document(w, it);
-
-    fn meth(w: &mut Writer, m: &clean::TraitMethod) {
-        write!(w, "<h3 id='{}.{}' class='method'><code>",
-               shortty(m.item()),
-               *m.item().name.get_ref());
-        render_method(w, m.item(), false);
-        write!(w, "</code></h3>");
-        document(w, m.item());
+    if_ok!(document(w, it));
+
+    fn meth(w: &mut Writer, m: &clean::TraitMethod) -> fmt::Result {
+        if_ok!(write!(w, "<h3 id='{}.{}' class='method'><code>",
+                      shortty(m.item()),
+                      *m.item().name.get_ref()));
+        if_ok!(render_method(w, m.item(), false));
+        if_ok!(write!(w, "</code></h3>"));
+        if_ok!(document(w, m.item()));
+        Ok(())
     }
 
     // Output the documentation for each function individually
     if required.len() > 0 {
-        write!(w, "
+        if_ok!(write!(w, "
             <h2 id='required-methods'>Required Methods</h2>
             <div class='methods'>
-        ");
+        "));
         for m in required.iter() {
-            meth(w, *m);
+            if_ok!(meth(w, *m));
         }
-        write!(w, "</div>");
+        if_ok!(write!(w, "</div>"));
     }
     if provided.len() > 0 {
-        write!(w, "
+        if_ok!(write!(w, "
             <h2 id='provided-methods'>Provided Methods</h2>
             <div class='methods'>
-        ");
+        "));
         for m in provided.iter() {
-            meth(w, *m);
+            if_ok!(meth(w, *m));
         }
-        write!(w, "</div>");
+        if_ok!(write!(w, "</div>"));
     }
 
     local_data::get(cache_key, |cache| {
         let cache = cache.unwrap().get();
         match cache.implementors.find(&it.id) {
             Some(implementors) => {
-                write!(w, "
+                if_ok!(write!(w, "
                     <h2 id='implementors'>Implementors</h2>
                     <ul class='item-list'>
-                ");
+                "));
                 for i in implementors.iter() {
                     match *i {
                         PathType(ref ty) => {
-                            write!(w, "<li><code>{}</code></li>", *ty);
+                            if_ok!(write!(w, "<li><code>{}</code></li>", *ty));
                         }
                         OtherType(ref generics, ref trait_, ref for_) => {
-                            write!(w, "<li><code>impl{} {} for {}</code></li>",
-                                   *generics, *trait_, *for_);
+                            if_ok!(write!(w, "<li><code>impl{} {} for {}</code></li>",
+                                          *generics, *trait_, *for_));
                         }
                     }
                 }
-                write!(w, "</ul>");
+                if_ok!(write!(w, "</ul>"));
             }
             None => {}
         }
+        Ok(())
     })
 }
 
-fn render_method(w: &mut Writer, meth: &clean::Item, withlink: bool) {
+fn render_method(w: &mut Writer, meth: &clean::Item,
+                 withlink: bool) -> fmt::Result {
     fn fun(w: &mut Writer, it: &clean::Item, purity: ast::Purity,
            g: &clean::Generics, selfty: &clean::SelfTy, d: &clean::FnDecl,
-           withlink: bool) {
+           withlink: bool) -> fmt::Result {
         write!(w, "{}fn {withlink, select,
                             true{<a href='\\#{ty}.{name}'
                                     class='fnname'>{name}</a>}
@@ -1185,118 +1193,125 @@ fn render_method(w: &mut Writer, meth: &clean::Item, withlink: bool) {
                name = it.name.get_ref().as_slice(),
                generics = *g,
                decl = Method(selfty, d),
-               withlink = if withlink {"true"} else {"false"});
+               withlink = if withlink {"true"} else {"false"})
     }
     match meth.inner {
         clean::TyMethodItem(ref m) => {
-            fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink);
+            fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink)
         }
         clean::MethodItem(ref m) => {
-            fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink);
+            fun(w, meth, m.purity, &m.generics, &m.self_, &m.decl, withlink)
         }
         _ => unreachable!()
     }
 }
 
-fn item_struct(w: &mut Writer, it: &clean::Item, s: &clean::Struct) {
-    write!(w, "<pre class='struct'>");
-    render_struct(w, it, Some(&s.generics), s.struct_type, s.fields,
-                  s.fields_stripped, "", true);
-    write!(w, "</pre>");
+fn item_struct(w: &mut Writer, it: &clean::Item,
+               s: &clean::Struct) -> fmt::Result {
+    if_ok!(write!(w, "<pre class='struct'>"));
+    if_ok!(render_struct(w, it, Some(&s.generics), s.struct_type, s.fields,
+                         s.fields_stripped, "", true));
+    if_ok!(write!(w, "</pre>"));
 
-    document(w, it);
+    if_ok!(document(w, it));
     match s.struct_type {
         doctree::Plain if s.fields.len() > 0 => {
-            write!(w, "<h2 class='fields'>Fields</h2>\n<table>");
+            if_ok!(write!(w, "<h2 class='fields'>Fields</h2>\n<table>"));
             for field in s.fields.iter() {
-                write!(w, "<tr><td id='structfield.{name}'>\
-                                <code>{name}</code></td><td>",
-                       name = field.name.get_ref().as_slice());
-                document(w, field);
-                write!(w, "</td></tr>");
+                if_ok!(write!(w, "<tr><td id='structfield.{name}'>\
+                                  <code>{name}</code></td><td>",
+                              name = field.name.get_ref().as_slice()));
+                if_ok!(document(w, field));
+                if_ok!(write!(w, "</td></tr>"));
             }
-            write!(w, "</table>");
+            if_ok!(write!(w, "</table>"));
         }
         _ => {}
     }
-    render_methods(w, it);
+    render_methods(w, it)
 }
 
-fn item_enum(w: &mut Writer, it: &clean::Item, e: &clean::Enum) {
-    write!(w, "<pre class='enum'>{}enum {}{}",
-           VisSpace(it.visibility),
-           it.name.get_ref().as_slice(),
-           e.generics);
+fn item_enum(w: &mut Writer, it: &clean::Item, e: &clean::Enum) -> fmt::Result {
+    if_ok!(write!(w, "<pre class='enum'>{}enum {}{}",
+                  VisSpace(it.visibility),
+                  it.name.get_ref().as_slice(),
+                  e.generics));
     if e.variants.len() == 0 && !e.variants_stripped {
-        write!(w, " \\{\\}");
+        if_ok!(write!(w, " \\{\\}"));
     } else {
-        write!(w, " \\{\n");
+        if_ok!(write!(w, " \\{\n"));
         for v in e.variants.iter() {
-            write!(w, "    ");
+            if_ok!(write!(w, "    "));
             let name = v.name.get_ref().as_slice();
             match v.inner {
                 clean::VariantItem(ref var) => {
                     match var.kind {
-                        clean::CLikeVariant => write!(w, "{}", name),
+                        clean::CLikeVariant => if_ok!(write!(w, "{}", name)),
                         clean::TupleVariant(ref tys) => {
-                            write!(w, "{}(", name);
+                            if_ok!(write!(w, "{}(", name));
                             for (i, ty) in tys.iter().enumerate() {
-                                if i > 0 { write!(w, ", ") }
-                                write!(w, "{}", *ty);
+                                if i > 0 {
+                                    if_ok!(write!(w, ", "))
+                                }
+                                if_ok!(write!(w, "{}", *ty));
                             }
-                            write!(w, ")");
+                            if_ok!(write!(w, ")"));
                         }
                         clean::StructVariant(ref s) => {
-                            render_struct(w, v, None, s.struct_type, s.fields,
-                                          s.fields_stripped, "    ", false);
+                            if_ok!(render_struct(w, v, None, s.struct_type,
+                                                 s.fields, s.fields_stripped,
+                                                 "    ", false));
                         }
                     }
                 }
                 _ => unreachable!()
             }
-            write!(w, ",\n");
+            if_ok!(write!(w, ",\n"));
         }
 
         if e.variants_stripped {
-            write!(w, "    // some variants omitted\n");
+            if_ok!(write!(w, "    // some variants omitted\n"));
         }
-        write!(w, "\\}");
+        if_ok!(write!(w, "\\}"));
     }
-    write!(w, "</pre>");
+    if_ok!(write!(w, "</pre>"));
 
-    document(w, it);
+    if_ok!(document(w, it));
     if e.variants.len() > 0 {
-        write!(w, "<h2 class='variants'>Variants</h2>\n<table>");
+        if_ok!(write!(w, "<h2 class='variants'>Variants</h2>\n<table>"));
         for variant in e.variants.iter() {
-            write!(w, "<tr><td id='variant.{name}'><code>{name}</code></td><td>",
-                   name = variant.name.get_ref().as_slice());
-            document(w, variant);
+            if_ok!(write!(w, "<tr><td id='variant.{name}'><code>{name}</code></td><td>",
+                          name = variant.name.get_ref().as_slice()));
+            if_ok!(document(w, variant));
             match variant.inner {
                 clean::VariantItem(ref var) => {
                     match var.kind {
                         clean::StructVariant(ref s) => {
-                            write!(w, "<h3 class='fields'>Fields</h3>\n<table>");
+                            if_ok!(write!(w, "<h3 class='fields'>Fields</h3>\n
+                                              <table>"));
                             for field in s.fields.iter() {
-                                write!(w, "<tr><td id='variant.{v}.field.{f}'>\
-                                           <code>{f}</code></td><td>",
-                                       v = variant.name.get_ref().as_slice(),
-                                       f = field.name.get_ref().as_slice());
-                                document(w, field);
-                                write!(w, "</td></tr>");
+                                if_ok!(write!(w, "<tr><td \
+                                                  id='variant.{v}.field.{f}'>\
+                                                  <code>{f}</code></td><td>",
+                                              v = variant.name.get_ref().as_slice(),
+                                              f = field.name.get_ref().as_slice()));
+                                if_ok!(document(w, field));
+                                if_ok!(write!(w, "</td></tr>"));
                             }
-                            write!(w, "</table>");
+                            if_ok!(write!(w, "</table>"));
                         }
                         _ => ()
                     }
                 }
                 _ => ()
             }
-            write!(w, "</td></tr>");
+            if_ok!(write!(w, "</td></tr>"));
         }
-        write!(w, "</table>");
+        if_ok!(write!(w, "</table>"));
 
     }
-    render_methods(w, it);
+    if_ok!(render_methods(w, it));
+    Ok(())
 }
 
 fn render_struct(w: &mut Writer, it: &clean::Item,
@@ -1305,54 +1320,59 @@ fn render_struct(w: &mut Writer, it: &clean::Item,
                  fields: &[clean::Item],
                  fields_stripped: bool,
                  tab: &str,
-                 structhead: bool) {
-    write!(w, "{}{}{}",
-           VisSpace(it.visibility),
-           if structhead {"struct "} else {""},
-           it.name.get_ref().as_slice());
+                 structhead: bool) -> fmt::Result {
+    if_ok!(write!(w, "{}{}{}",
+                  VisSpace(it.visibility),
+                  if structhead {"struct "} else {""},
+                  it.name.get_ref().as_slice()));
     match g {
-        Some(g) => write!(w, "{}", *g),
+        Some(g) => if_ok!(write!(w, "{}", *g)),
         None => {}
     }
     match ty {
         doctree::Plain => {
-            write!(w, " \\{\n{}", tab);
+            if_ok!(write!(w, " \\{\n{}", tab));
             for field in fields.iter() {
                 match field.inner {
                     clean::StructFieldItem(ref ty) => {
-                        write!(w, "    {}{}: {},\n{}",
-                               VisSpace(field.visibility),
-                               field.name.get_ref().as_slice(),
-                               ty.type_,
-                               tab);
+                        if_ok!(write!(w, "    {}{}: {},\n{}",
+                                      VisSpace(field.visibility),
+                                      field.name.get_ref().as_slice(),
+                                      ty.type_,
+                                      tab));
                     }
                     _ => unreachable!()
                 }
             }
 
             if fields_stripped {
-                write!(w, "    // some fields omitted\n{}", tab);
+                if_ok!(write!(w, "    // some fields omitted\n{}", tab));
             }
-            write!(w, "\\}");
+            if_ok!(write!(w, "\\}"));
         }
         doctree::Tuple | doctree::Newtype => {
-            write!(w, "(");
+            if_ok!(write!(w, "("));
             for (i, field) in fields.iter().enumerate() {
-                if i > 0 { write!(w, ", ") }
+                if i > 0 {
+                    if_ok!(write!(w, ", "));
+                }
                 match field.inner {
                     clean::StructFieldItem(ref field) => {
-                        write!(w, "{}", field.type_);
+                        if_ok!(write!(w, "{}", field.type_));
                     }
                     _ => unreachable!()
                 }
             }
-            write!(w, ");");
+            if_ok!(write!(w, ");"));
+        }
+        doctree::Unit => {
+            if_ok!(write!(w, ";"));
         }
-        doctree::Unit => { write!(w, ";"); }
     }
+    Ok(())
 }
 
-fn render_methods(w: &mut Writer, it: &clean::Item) {
+fn render_methods(w: &mut Writer, it: &clean::Item) -> fmt::Result {
     local_data::get(cache_key, |cache| {
         let c = cache.unwrap().get();
         match c.impls.find(&it.id) {
@@ -1367,29 +1387,31 @@ fn render_methods(w: &mut Writer, it: &clean::Item) {
                 let traits = traits.to_owned_vec();
 
                 if non_trait.len() > 0 {
-                    write!(w, "<h2 id='methods'>Methods</h2>");
+                    if_ok!(write!(w, "<h2 id='methods'>Methods</h2>"));
                     for &(ref i, ref dox) in non_trait.move_iter() {
-                        render_impl(w, i, dox);
+                        if_ok!(render_impl(w, i, dox));
                     }
                 }
                 if traits.len() > 0 {
-                    write!(w, "<h2 id='implementations'>Trait \
-                               Implementations</h2>");
+                    if_ok!(write!(w, "<h2 id='implementations'>Trait \
+                                      Implementations</h2>"));
                     for &(ref i, ref dox) in traits.move_iter() {
-                        render_impl(w, i, dox);
+                        if_ok!(render_impl(w, i, dox));
                     }
                 }
             }
             None => {}
         }
+        Ok(())
     })
 }
 
-fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
-    write!(w, "<h3 class='impl'><code>impl{} ", i.generics);
+fn render_impl(w: &mut Writer, i: &clean::Impl,
+               dox: &Option<~str>) -> fmt::Result {
+    if_ok!(write!(w, "<h3 class='impl'><code>impl{} ", i.generics));
     let trait_id = match i.trait_ {
         Some(ref ty) => {
-            write!(w, "{} for ", *ty);
+            if_ok!(write!(w, "{} for ", *ty));
             match *ty {
                 clean::ResolvedPath { id, .. } => Some(id),
                 _ => None,
@@ -1397,32 +1419,32 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
         }
         None => None
     };
-    write!(w, "{}</code></h3>", i.for_);
+    if_ok!(write!(w, "{}</code></h3>", i.for_));
     match *dox {
         Some(ref dox) => {
-            write!(w, "<div class='docblock'>{}</div>",
-                   Markdown(dox.as_slice()));
+            if_ok!(write!(w, "<div class='docblock'>{}</div>",
+                          Markdown(dox.as_slice())));
         }
         None => {}
     }
 
-    fn docmeth(w: &mut Writer, item: &clean::Item) -> bool {
-        write!(w, "<h4 id='method.{}' class='method'><code>",
-               *item.name.get_ref());
-        render_method(w, item, false);
-        write!(w, "</code></h4>\n");
+    fn docmeth(w: &mut Writer, item: &clean::Item) -> io::IoResult<bool> {
+        if_ok!(write!(w, "<h4 id='method.{}' class='method'><code>",
+                      *item.name.get_ref()));
+        if_ok!(render_method(w, item, false));
+        if_ok!(write!(w, "</code></h4>\n"));
         match item.doc_value() {
             Some(s) => {
-                write!(w, "<div class='docblock'>{}</div>", Markdown(s));
-                true
+                if_ok!(write!(w, "<div class='docblock'>{}</div>", Markdown(s)));
+                Ok(true)
             }
-            None => false
+            None => Ok(false)
         }
     }
 
-    write!(w, "<div class='methods'>");
+    if_ok!(write!(w, "<div class='methods'>"));
     for meth in i.methods.iter() {
-        if docmeth(w, meth) {
+        if if_ok!(docmeth(w, meth)) {
             continue
         }
 
@@ -1431,7 +1453,7 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
             None => continue,
             Some(id) => id,
         };
-        local_data::get(cache_key, |cache| {
+        if_ok!(local_data::get(cache_key, |cache| {
             let cache = cache.unwrap().get();
             match cache.traits.find(&trait_id) {
                 Some(t) => {
@@ -1440,9 +1462,9 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
                         Some(method) => {
                             match method.item().doc_value() {
                                 Some(s) => {
-                                    write!(w,
-                                           "<div class='docblock'>{}</div>",
-                                           Markdown(s));
+                                    if_ok!(write!(w,
+                                                  "<div class='docblock'>{}</div>",
+                                                  Markdown(s)));
                                 }
                                 None => {}
                             }
@@ -1452,7 +1474,8 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
                 }
                 None => {}
             }
-        })
+            Ok(())
+        }))
     }
 
     // If we've implemented a trait, then also emit documentation for all
@@ -1460,7 +1483,7 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
     match trait_id {
         None => {}
         Some(id) => {
-            local_data::get(cache_key, |cache| {
+            if_ok!(local_data::get(cache_key, |cache| {
                 let cache = cache.unwrap().get();
                 match cache.traits.find(&id) {
                     Some(t) => {
@@ -1471,50 +1494,56 @@ fn render_impl(w: &mut Writer, i: &clean::Impl, dox: &Option<~str>) {
                                 None => {}
                             }
 
-                            docmeth(w, method.item());
+                            if_ok!(docmeth(w, method.item()));
                         }
                     }
                     None => {}
                 }
-            })
+                Ok(())
+            }))
         }
     }
-    write!(w, "</div>");
+    if_ok!(write!(w, "</div>"));
+    Ok(())
 }
 
-fn item_typedef(w: &mut Writer, it: &clean::Item, t: &clean::Typedef) {
-    write!(w, "<pre class='typedef'>type {}{} = {};</pre>",
-           it.name.get_ref().as_slice(),
-           t.generics,
-           t.type_);
+fn item_typedef(w: &mut Writer, it: &clean::Item,
+                t: &clean::Typedef) -> fmt::Result {
+    if_ok!(write!(w, "<pre class='typedef'>type {}{} = {};</pre>",
+                  it.name.get_ref().as_slice(),
+                  t.generics,
+                  t.type_));
 
-    document(w, it);
+    document(w, it)
 }
 
 impl<'a> fmt::Show for Sidebar<'a> {
-    fn fmt(s: &Sidebar<'a>, fmt: &mut fmt::Formatter) {
+    fn fmt(s: &Sidebar<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
         let cx = s.cx;
         let it = s.item;
-        write!(fmt.buf, "<p class='location'>");
+        if_ok!(write!(fmt.buf, "<p class='location'>"));
         let len = cx.current.len() - if it.is_mod() {1} else {0};
         for (i, name) in cx.current.iter().take(len).enumerate() {
-            if i > 0 { write!(fmt.buf, "&\\#8203;::") }
-            write!(fmt.buf, "<a href='{}index.html'>{}</a>",
-                   cx.root_path.slice_to((cx.current.len() - i - 1) * 3), *name);
+            if i > 0 {
+                if_ok!(write!(fmt.buf, "&\\#8203;::"));
+            }
+            if_ok!(write!(fmt.buf, "<a href='{}index.html'>{}</a>",
+                          cx.root_path.slice_to((cx.current.len() - i - 1) * 3),
+                          *name));
         }
-        write!(fmt.buf, "</p>");
+        if_ok!(write!(fmt.buf, "</p>"));
 
         fn block(w: &mut Writer, short: &str, longty: &str,
-                 cur: &clean::Item, cx: &Context) {
+                 cur: &clean::Item, cx: &Context) -> fmt::Result {
             let items = match cx.sidebar.find_equiv(&short) {
                 Some(items) => items.as_slice(),
-                None => return
+                None => return Ok(())
             };
-            write!(w, "<div class='block {}'><h2>{}</h2>", short, longty);
+            if_ok!(write!(w, "<div class='block {}'><h2>{}</h2>", short, longty));
             for item in items.iter() {
                 let class = if cur.name.get_ref() == item &&
                                short == shortty(cur) { "current" } else { "" };
-                write!(w, "<a class='{ty} {class}' href='{curty, select,
+                if_ok!(write!(w, "<a class='{ty} {class}' href='{curty, select,
                                 mod{../}
                                 other{}
                            }{tysel, select,
@@ -1525,16 +1554,18 @@ impl<'a> fmt::Show for Sidebar<'a> {
                        tysel = short,
                        class = class,
                        curty = shortty(cur),
-                       name = item.as_slice());
+                       name = item.as_slice()));
             }
-            write!(w, "</div>");
+            if_ok!(write!(w, "</div>"));
+            Ok(())
         }
 
-        block(fmt.buf, "mod", "Modules", it, cx);
-        block(fmt.buf, "struct", "Structs", it, cx);
-        block(fmt.buf, "enum", "Enums", it, cx);
-        block(fmt.buf, "trait", "Traits", it, cx);
-        block(fmt.buf, "fn", "Functions", it, cx);
+        if_ok!(block(fmt.buf, "mod", "Modules", it, cx));
+        if_ok!(block(fmt.buf, "struct", "Structs", it, cx));
+        if_ok!(block(fmt.buf, "enum", "Enums", it, cx));
+        if_ok!(block(fmt.buf, "trait", "Traits", it, cx));
+        if_ok!(block(fmt.buf, "fn", "Functions", it, cx));
+        Ok(())
     }
 }
 
@@ -1557,7 +1588,7 @@ fn build_sidebar(m: &clean::Module) -> HashMap<~str, ~[~str]> {
 }
 
 impl<'a> fmt::Show for Source<'a> {
-    fn fmt(s: &Source<'a>, fmt: &mut fmt::Formatter) {
+    fn fmt(s: &Source<'a>, fmt: &mut fmt::Formatter) -> fmt::Result {
         let Source(s) = *s;
         let lines = s.lines().len();
         let mut cols = 0;
@@ -1566,13 +1597,14 @@ impl<'a> fmt::Show for Source<'a> {
             cols += 1;
             tmp /= 10;
         }
-        write!(fmt.buf, "<pre class='line-numbers'>");
+        if_ok!(write!(fmt.buf, "<pre class='line-numbers'>"));
         for i in range(1, lines + 1) {
-            write!(fmt.buf, "<span id='{0:u}'>{0:1$u}</span>\n", i, cols);
+            if_ok!(write!(fmt.buf, "<span id='{0:u}'>{0:1$u}</span>\n", i, cols));
         }
-        write!(fmt.buf, "</pre>");
-        write!(fmt.buf, "<pre class='rust'>");
-        write!(fmt.buf, "{}", Escape(s.as_slice()));
-        write!(fmt.buf, "</pre>");
+        if_ok!(write!(fmt.buf, "</pre>"));
+        if_ok!(write!(fmt.buf, "<pre class='rust'>"));
+        if_ok!(write!(fmt.buf, "{}", Escape(s.as_slice())));
+        if_ok!(write!(fmt.buf, "</pre>"));
+        Ok(())
     }
 }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index f7a484e3d3e..fe989279e71 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -162,10 +162,16 @@ pub fn main_args(args: &[~str]) -> int {
     let output = matches.opt_str("o").map(|s| Path::new(s));
     match matches.opt_str("w") {
         Some(~"html") | None => {
-            html::render::run(crate, output.unwrap_or(Path::new("doc")))
+            match html::render::run(crate, output.unwrap_or(Path::new("doc"))) {
+                Ok(()) => {}
+                Err(e) => fail!("failed to generate documentation: {}", e),
+            }
         }
         Some(~"json") => {
-            json_output(crate, res, output.unwrap_or(Path::new("doc.json")))
+            match json_output(crate, res, output.unwrap_or(Path::new("doc.json"))) {
+                Ok(()) => {}
+                Err(e) => fail!("failed to write json: {}", e),
+            }
         }
         Some(s) => {
             println!("unknown output format: {}", s);
@@ -276,8 +282,8 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output {
 /// run over the deserialized output.
 fn json_input(input: &str) -> Result<Output, ~str> {
     let mut input = match File::open(&Path::new(input)) {
-        Some(f) => f,
-        None => return Err(format!("couldn't open {} for reading", input)),
+        Ok(f) => f,
+        Err(e) => return Err(format!("couldn't open {}: {}", input, e)),
     };
     match json::from_reader(&mut input) {
         Err(s) => Err(s.to_str()),
@@ -312,7 +318,8 @@ fn json_input(input: &str) -> Result<Output, ~str> {
 
 /// Outputs the crate/plugin json as a giant json blob at the specified
 /// destination.
-fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
+fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson],
+               dst: Path) -> io::IoResult<()> {
     // {
     //   "schema": version,
     //   "crate": { parsed crate ... },
@@ -340,6 +347,7 @@ fn json_output(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
     json.insert(~"crate", crate_json);
     json.insert(~"plugins", json::Object(plugins_json));
 
-    let mut file = File::create(&dst).unwrap();
-    json::Object(json).to_writer(&mut file);
+    let mut file = if_ok!(File::create(&dst));
+    if_ok!(json::Object(json).to_writer(&mut file));
+    Ok(())
 }
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 12874d1b502..9e3b217f69f 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -127,8 +127,8 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>) {
     let exe = outdir.path().join("rust_out");
     let out = run::process_output(exe.as_str().unwrap(), []);
     match out {
-        None => fail!("couldn't run the test"),
-        Some(out) => {
+        Err(e) => fail!("couldn't run the test: {}", e),
+        Ok(out) => {
             if !out.status.success() {
                 fail!("test executable failed:\n{}",
                       str::from_utf8(out.error));
diff --git a/src/librustuv/file.rs b/src/librustuv/file.rs
index 31afa7b5c7c..2cef2664c2f 100644
--- a/src/librustuv/file.rs
+++ b/src/librustuv/file.rs
@@ -140,9 +140,9 @@ impl FsRequest {
             let mut paths = ~[];
             let path = CString::new(path.with_ref(|p| p), false);
             let parent = Path::new(path);
-            c_str::from_c_multistring(req.get_ptr() as *libc::c_char,
-                                      Some(req.get_result() as uint),
-                                      |rel| {
+            let _ = c_str::from_c_multistring(req.get_ptr() as *libc::c_char,
+                                              Some(req.get_result() as uint),
+                                              |rel| {
                 let p = rel.as_bytes();
                 paths.push(parent.join(p.slice_to(rel.len())));
             });
@@ -378,7 +378,8 @@ impl Drop for FileWatcher {
             rtio::CloseAsynchronously => {
                 unsafe {
                     let req = uvll::malloc_req(uvll::UV_FS);
-                    uvll::uv_fs_close(self.loop_.handle, req, self.fd, close_cb);
+                    assert_eq!(uvll::uv_fs_close(self.loop_.handle, req,
+                                                 self.fd, close_cb), 0);
                 }
 
                 extern fn close_cb(req: *uvll::uv_fs_t) {
diff --git a/src/librustuv/homing.rs b/src/librustuv/homing.rs
index 8d3e71312cd..a2f3457a943 100644
--- a/src/librustuv/homing.rs
+++ b/src/librustuv/homing.rs
@@ -176,7 +176,7 @@ mod test {
         });
 
         let task = pool.task(TaskOpts::new(), proc() {
-            port.recv();
+            drop(port.recv());
         });
         pool.spawn_sched().send(sched::TaskFromFriend(task));
 
@@ -197,7 +197,7 @@ mod test {
             let listener = UdpWatcher::bind(local_loop(), addr2);
             chan.send((listener.unwrap(), addr1));
             let mut listener = UdpWatcher::bind(local_loop(), addr1).unwrap();
-            listener.sendto([1, 2, 3, 4], addr2);
+            listener.sendto([1, 2, 3, 4], addr2).unwrap();
         });
 
         let task = pool.task(TaskOpts::new(), proc() {
diff --git a/src/librustuv/idle.rs b/src/librustuv/idle.rs
index 3d6e81d0d6f..dafd3dbe1bc 100644
--- a/src/librustuv/idle.rs
+++ b/src/librustuv/idle.rs
@@ -52,7 +52,7 @@ impl IdleWatcher {
                 let data = uvll::get_data_for_uv_handle(handle);
                 let f: ~proc() = cast::transmute(data);
                 (*f)();
-                uvll::uv_idle_stop(handle);
+                assert_eq!(uvll::uv_idle_stop(handle), 0);
                 uvll::uv_close(handle, close_cb);
             }
         }
@@ -122,7 +122,7 @@ mod test {
                     }
                 }
             };
-            task.wake().map(|t| t.reawaken(true));
+            let _ = task.wake().map(|t| t.reawaken(true));
         }
     }
 
diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs
index 0b889e17a44..f945c0972ca 100644
--- a/src/librustuv/lib.rs
+++ b/src/librustuv/lib.rs
@@ -40,6 +40,7 @@ via `close` and `delete` methods.
 #[crate_type = "dylib"];
 
 #[feature(macro_rules)];
+#[deny(unused_result, unused_must_use)];
 
 #[cfg(test)] extern mod green;
 
@@ -207,7 +208,7 @@ fn wait_until_woken_after(slot: *mut Option<BlockedTask>, f: ||) {
 
 fn wakeup(slot: &mut Option<BlockedTask>) {
     assert!(slot.is_some());
-    slot.take_unwrap().wake().map(|t| t.reawaken(true));
+    let _ = slot.take_unwrap().wake().map(|t| t.reawaken(true));
 }
 
 pub struct Request {
@@ -276,7 +277,7 @@ impl Loop {
     pub fn wrap(handle: *uvll::uv_loop_t) -> Loop { Loop { handle: handle } }
 
     pub fn run(&mut self) {
-        unsafe { uvll::uv_run(self.handle, uvll::RUN_DEFAULT) };
+        assert_eq!(unsafe { uvll::uv_run(self.handle, uvll::RUN_DEFAULT) }, 0);
     }
 
     pub fn close(&mut self) {
diff --git a/src/librustuv/macros.rs b/src/librustuv/macros.rs
index 6c8c16784a1..75b68e3a528 100644
--- a/src/librustuv/macros.rs
+++ b/src/librustuv/macros.rs
@@ -33,14 +33,15 @@ pub fn dumb_println(args: &fmt::Arguments) {
 
     struct Stderr;
     impl io::Writer for Stderr {
-        fn write(&mut self, data: &[u8]) {
-            unsafe {
+        fn write(&mut self, data: &[u8]) -> io::IoResult<()> {
+            let _ = unsafe {
                 libc::write(libc::STDERR_FILENO,
                             data.as_ptr() as *libc::c_void,
-                            data.len() as libc::size_t);
-            }
+                            data.len() as libc::size_t)
+            };
+            Ok(()) // just ignore the errors
         }
     }
     let mut w = Stderr;
-    fmt::writeln(&mut w as &mut io::Writer, args);
+    let _ = fmt::writeln(&mut w as &mut io::Writer, args);
 }
diff --git a/src/librustuv/net.rs b/src/librustuv/net.rs
index 8919ecfa97e..5461fc6272d 100644
--- a/src/librustuv/net.rs
+++ b/src/librustuv/net.rs
@@ -953,11 +953,11 @@ mod test {
         spawn(proc() {
             let port2 = port.recv();
             let mut stream = TcpWatcher::connect(local_loop(), addr).unwrap();
-            stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
-            stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
+            stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
+            stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
             port2.recv();
-            stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
-            stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
+            stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
+            stream.write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
             port2.recv();
         });
 
@@ -1008,7 +1008,7 @@ mod test {
         while stream.is_err() {
             stream = TcpWatcher::connect(local_loop(), addr);
         }
-        stream.unwrap().write([0, 1, 2, 3, 4, 5, 6, 7]);
+        stream.unwrap().write([0, 1, 2, 3, 4, 5, 6, 7]).unwrap();
     }
 
     #[should_fail] #[test]
@@ -1028,7 +1028,7 @@ mod test {
             let w = TcpListener::bind(local_loop(), addr).unwrap();
             let mut w = w.listen().unwrap();
             chan.send(());
-            w.accept();
+            drop(w.accept().unwrap());
         });
         port.recv();
         let _w = TcpWatcher::connect(local_loop(), addr).unwrap();
diff --git a/src/librustuv/pipe.rs b/src/librustuv/pipe.rs
index cfe86d739ab..a021a13e2d9 100644
--- a/src/librustuv/pipe.rs
+++ b/src/librustuv/pipe.rs
@@ -306,7 +306,7 @@ mod tests {
             let p = PipeListener::bind(local_loop(), &path2.to_c_str()).unwrap();
             let mut p = p.listen().unwrap();
             chan.send(());
-            p.accept();
+            drop(p.accept().unwrap());
         });
         port.recv();
         let _c = PipeWatcher::connect(local_loop(), &path.to_c_str()).unwrap();
diff --git a/src/librustuv/queue.rs b/src/librustuv/queue.rs
index 32f8d8532a2..0e1c4225caa 100644
--- a/src/librustuv/queue.rs
+++ b/src/librustuv/queue.rs
@@ -67,7 +67,7 @@ extern fn async_cb(handle: *uvll::uv_async_t, status: c_int) {
     loop {
         match state.consumer.pop() {
             mpsc::Data(Task(task)) => {
-                task.wake().map(|t| t.reawaken(true));
+                let _ = task.wake().map(|t| t.reawaken(true));
             }
             mpsc::Data(Increment) => unsafe {
                 if state.refcnt == 0 {
diff --git a/src/librustuv/signal.rs b/src/librustuv/signal.rs
index 8cb0c1f0a52..2fcc61be79b 100644
--- a/src/librustuv/signal.rs
+++ b/src/librustuv/signal.rs
@@ -86,7 +86,7 @@ mod test {
                                          chan);
 
         spawn(proc() {
-            port.try_recv();
+            let _ = port.recv_opt();
         });
 
         // when we drop the SignalWatcher we're going to destroy the channel,
diff --git a/src/librustuv/timer.rs b/src/librustuv/timer.rs
index aeda1a45175..792414238fd 100644
--- a/src/librustuv/timer.rs
+++ b/src/librustuv/timer.rs
@@ -138,11 +138,11 @@ extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
 
     match timer.action.take_unwrap() {
         WakeTask(task) => {
-            task.wake().map(|t| t.reawaken(true));
+            let _ = task.wake().map(|t| t.reawaken(true));
         }
-        SendOnce(chan) => { chan.try_send(()); }
+        SendOnce(chan) => { let _ = chan.try_send(()); }
         SendMany(chan, id) => {
-            chan.try_send(());
+            let _ = chan.try_send(());
 
             // Note that the above operation could have performed some form of
             // scheduling. This means that the timer may have decided to insert
@@ -246,7 +246,7 @@ mod test {
         let timer_port = timer.period(1000);
 
         spawn(proc() {
-            timer_port.recv_opt();
+            let _ = timer_port.recv_opt();
         });
 
         // when we drop the TimerWatcher we're going to destroy the channel,
@@ -260,10 +260,10 @@ mod test {
         let timer_port = timer.period(1000);
 
         spawn(proc() {
-            timer_port.recv_opt();
+            let _ = timer_port.recv_opt();
         });
 
-        timer.oneshot(1);
+        drop(timer.oneshot(1));
     }
     #[test]
     fn reset_doesnt_switch_tasks2() {
@@ -272,7 +272,7 @@ mod test {
         let timer_port = timer.period(1000);
 
         spawn(proc() {
-            timer_port.recv_opt();
+            let _ = timer_port.recv_opt();
         });
 
         timer.sleep(1);
@@ -299,7 +299,7 @@ mod test {
     #[test]
     fn receiver_goes_away_oneshot() {
         let mut timer1 = TimerWatcher::new(local_loop());
-        timer1.oneshot(1);
+        drop(timer1.oneshot(1));
         let mut timer2 = TimerWatcher::new(local_loop());
         // while sleeping, the prevous timer should fire and not have its
         // callback do something terrible.
@@ -309,7 +309,7 @@ mod test {
     #[test]
     fn receiver_goes_away_period() {
         let mut timer1 = TimerWatcher::new(local_loop());
-        timer1.period(1);
+        drop(timer1.period(1));
         let mut timer2 = TimerWatcher::new(local_loop());
         // while sleeping, the prevous timer should fire and not have its
         // callback do something terrible.
diff --git a/src/librustuv/uvio.rs b/src/librustuv/uvio.rs
index e0bff059b0c..8a8ef4a41ec 100644
--- a/src/librustuv/uvio.rs
+++ b/src/librustuv/uvio.rs
@@ -71,7 +71,7 @@ impl Drop for UvEventLoop {
         // after the loop has been closed because during the closing of the loop
         // the handle is required to be used apparently.
         let handle = self.uvio.handle_pool.get_ref().handle();
-        self.uvio.handle_pool.take();
+        drop(self.uvio.handle_pool.take());
         self.uvio.loop_.close();
         unsafe { uvll::free_handle(handle) }
     }
diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs
index 7b1a6055542..bccebeaa79f 100644
--- a/src/libstd/comm/mod.rs
+++ b/src/libstd/comm/mod.rs
@@ -1252,7 +1252,7 @@ mod test {
             spawn(proc() {
                 let _p = port;
             });
-            task::try(proc() {
+            let _ = task::try(proc() {
                 chan.send(1);
             });
         }
diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs
index a17a030f4f7..06737e22007 100644
--- a/src/libstd/fmt/mod.rs
+++ b/src/libstd/fmt/mod.rs
@@ -163,9 +163,10 @@ method of the signature:
 
 ```rust
 # use std;
+# mod fmt { pub type Result = (); }
 # struct T;
 # trait SomeName<T> {
-fn fmt(value: &T, f: &mut std::fmt::Formatter);
+fn fmt(value: &T, f: &mut std::fmt::Formatter) -> fmt::Result;
 # }
 ```
 
@@ -174,7 +175,14 @@ emit output into the `f.buf` stream. It is up to each format trait
 implementation to correctly adhere to the requested formatting parameters. The
 values of these parameters will be listed in the fields of the `Formatter`
 struct. In order to help with this, the `Formatter` struct also provides some
-helper methods. An example of implementing the formatting traits would look
+helper methods.
+
+Additionally, the return value of this function is `fmt::Result` which is a
+typedef to `Result<(), IoError>` (also known as `IoError<()>`). Formatting
+implementations should ensure that they return errors from `write!` correctly
+(propagating errors upward).
+
+An example of implementing the formatting traits would look
 like:
 
 ```rust
@@ -187,7 +195,7 @@ struct Vector2D {
 }
 
 impl fmt::Show for Vector2D {
-    fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) {
+    fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) -> fmt::Result {
         // The `f.buf` value is of the type `&mut io::Writer`, which is what th
         // write! macro is expecting. Note that this formatting ignores the
         // various flags provided to format strings.
@@ -198,7 +206,7 @@ impl fmt::Show for Vector2D {
 // Different traits allow different forms of output of a type. The meaning of
 // this format is to print the magnitude of a vector.
 impl fmt::Binary for Vector2D {
-    fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) {
+    fn fmt(obj: &Vector2D, f: &mut fmt::Formatter) -> fmt::Result {
         let magnitude = (obj.x * obj.x + obj.y * obj.y) as f64;
         let magnitude = magnitude.sqrt();
 
@@ -207,7 +215,7 @@ impl fmt::Binary for Vector2D {
         // for details, and the function `pad` can be used to pad strings.
         let decimals = f.precision.unwrap_or(3);
         let string = f64::to_str_exact(magnitude, decimals);
-        f.pad_integral(string.as_bytes(), "", true);
+        f.pad_integral(string.as_bytes(), "", true)
     }
 }
 
@@ -242,6 +250,7 @@ strings and instead directly write the output. Under the hood, this function is
 actually invoking the `write` function defined in this module. Example usage is:
 
 ```rust
+# #[allow(unused_must_use)];
 use std::io;
 
 let mut w = io::MemWriter::new();
@@ -468,16 +477,20 @@ will look like `"\\{"`.
 
 */
 
-#[cfg(not(stage0))]
-use prelude::*;
-
 use cast;
 use char::Char;
+use container::Container;
 use io::MemWriter;
 use io;
-use str;
+use iter::{Iterator, range};
+use num::Signed;
+use option::{Option,Some,None};
 use repr;
+use result::{Ok, Err};
+use str::StrSlice;
+use str;
 use util;
+use vec::ImmutableVector;
 use vec;
 
 // NOTE this is just because the `prelude::*` import above includes
@@ -485,22 +498,11 @@ use vec;
 #[cfg(stage0)]
 pub use Default = fmt::Show; // export required for `format!()` etc.
 
-#[cfg(stage0)]
-use container::Container;
-#[cfg(stage0)]
-use iter::{Iterator, range};
-#[cfg(stage0)]
-use option::{Option,Some,None};
-#[cfg(stage0)]
-use vec::ImmutableVector;
-#[cfg(stage0)]
-use str::StrSlice;
-#[cfg(stage0)]
-use num::Signed;
-
 pub mod parse;
 pub mod rt;
 
+pub type Result = io::IoResult<()>;
+
 /// A struct to represent both where to emit formatting strings to and how they
 /// should be formatted. A mutable version of this is passed to all formatting
 /// traits.
@@ -527,7 +529,7 @@ pub struct Formatter<'a> {
 /// compile time it is ensured that the function and the value have the correct
 /// types, and then this struct is used to canonicalize arguments to one type.
 pub struct Argument<'a> {
-    priv formatter: extern "Rust" fn(&util::Void, &mut Formatter),
+    priv formatter: extern "Rust" fn(&util::Void, &mut Formatter) -> Result,
     priv value: &'a util::Void,
 }
 
@@ -561,50 +563,50 @@ pub struct Arguments<'a> {
 /// to this trait. There is not an explicit way of selecting this trait to be
 /// used for formatting, it is only if no other format is specified.
 #[allow(missing_doc)]
-pub trait Show { fn fmt(&Self, &mut Formatter); }
+pub trait Show { fn fmt(&Self, &mut Formatter) -> Result; }
 
 /// Format trait for the `b` character
 #[allow(missing_doc)]
-pub trait Bool { fn fmt(&Self, &mut Formatter); }
+pub trait Bool { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `c` character
 #[allow(missing_doc)]
-pub trait Char { fn fmt(&Self, &mut Formatter); }
+pub trait Char { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `i` and `d` characters
 #[allow(missing_doc)]
-pub trait Signed { fn fmt(&Self, &mut Formatter); }
+pub trait Signed { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `u` character
 #[allow(missing_doc)]
-pub trait Unsigned { fn fmt(&Self, &mut Formatter); }
+pub trait Unsigned { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `o` character
 #[allow(missing_doc)]
-pub trait Octal { fn fmt(&Self, &mut Formatter); }
+pub trait Octal { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `b` character
 #[allow(missing_doc)]
-pub trait Binary { fn fmt(&Self, &mut Formatter); }
+pub trait Binary { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `x` character
 #[allow(missing_doc)]
-pub trait LowerHex { fn fmt(&Self, &mut Formatter); }
+pub trait LowerHex { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `X` character
 #[allow(missing_doc)]
-pub trait UpperHex { fn fmt(&Self, &mut Formatter); }
+pub trait UpperHex { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `s` character
 #[allow(missing_doc)]
-pub trait String { fn fmt(&Self, &mut Formatter); }
+pub trait String { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `?` character
 #[allow(missing_doc)]
-pub trait Poly { fn fmt(&Self, &mut Formatter); }
+pub trait Poly { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `p` character
 #[allow(missing_doc)]
-pub trait Pointer { fn fmt(&Self, &mut Formatter); }
+pub trait Pointer { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `f` character
 #[allow(missing_doc)]
-pub trait Float { fn fmt(&Self, &mut Formatter); }
+pub trait Float { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `e` character
 #[allow(missing_doc)]
-pub trait LowerExp { fn fmt(&Self, &mut Formatter); }
+pub trait LowerExp { fn fmt(&Self, &mut Formatter) -> Result; }
 /// Format trait for the `E` character
 #[allow(missing_doc)]
-pub trait UpperExp { fn fmt(&Self, &mut Formatter); }
+pub trait UpperExp { fn fmt(&Self, &mut Formatter) -> Result; }
 
 // FIXME #11938 - UFCS would make us able call the above methods
 // directly Show::show(x, fmt).
@@ -617,7 +619,7 @@ macro_rules! uniform_fn_call_workaround {
     ($( $name: ident, $trait_: ident; )*) => {
         $(
             #[doc(hidden)]
-            pub fn $name<T: $trait_>(x: &T, fmt: &mut Formatter) {
+            pub fn $name<T: $trait_>(x: &T, fmt: &mut Formatter) -> Result {
                 $trait_::fmt(x, fmt)
             }
             )*
@@ -653,21 +655,22 @@ uniform_fn_call_workaround! {
 /// # Example
 ///
 /// ```rust
+/// # #[allow(unused_must_use)];
 /// use std::fmt;
 /// use std::io;
 ///
 /// let w = &mut io::stdout() as &mut io::Writer;
-/// format_args!(|args| { fmt::write(w, args) }, "Hello, {}!", "world");
+/// format_args!(|args| { fmt::write(w, args); }, "Hello, {}!", "world");
 /// ```
-pub fn write(output: &mut io::Writer, args: &Arguments) {
+pub fn write(output: &mut io::Writer, args: &Arguments) -> Result {
     unsafe { write_unsafe(output, args.fmt, args.args) }
 }
 
 /// The `writeln` function takes the same arguments as `write`, except that it
 /// will also write a newline (`\n`) character at the end of the format string.
-pub fn writeln(output: &mut io::Writer, args: &Arguments) {
-    unsafe { write_unsafe(output, args.fmt, args.args) }
-    output.write(['\n' as u8]);
+pub fn writeln(output: &mut io::Writer, args: &Arguments) -> Result {
+    let first = unsafe { write_unsafe(output, args.fmt, args.args) };
+    first.and_then(|()| output.write(['\n' as u8]))
 }
 
 /// The `write_unsafe` function takes an output stream, a precompiled format
@@ -692,7 +695,7 @@ pub fn writeln(output: &mut io::Writer, args: &Arguments) {
 /// format string.
 pub unsafe fn write_unsafe(output: &mut io::Writer,
                            fmt: &[rt::Piece],
-                           args: &[Argument]) {
+                           args: &[Argument]) -> Result {
     let mut formatter = Formatter {
         flags: 0,
         width: None,
@@ -704,8 +707,9 @@ pub unsafe fn write_unsafe(output: &mut io::Writer,
         curarg: args.iter(),
     };
     for piece in fmt.iter() {
-        formatter.run(piece, None);
+        if_ok!(formatter.run(piece, None));
     }
+    Ok(())
 }
 
 /// The format function takes a precompiled format string and a list of
@@ -752,7 +756,7 @@ pub fn format(args: &Arguments) -> ~str {
 /// format string.
 pub unsafe fn format_unsafe(fmt: &[rt::Piece], args: &[Argument]) -> ~str {
     let mut output = MemWriter::new();
-    write_unsafe(&mut output as &mut io::Writer, fmt, args);
+    write_unsafe(&mut output as &mut io::Writer, fmt, args).unwrap();
     return str::from_utf8_owned(output.unwrap()).unwrap();
 }
 
@@ -762,10 +766,10 @@ impl<'a> Formatter<'a> {
     // at runtime. This consumes all of the compile-time statics generated by
     // the format! syntax extension.
 
-    fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) {
+    fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) -> Result {
         match *piece {
-            rt::String(s) => { self.buf.write(s.as_bytes()); }
-            rt::CurrentArgument(()) => { self.buf.write(cur.unwrap().as_bytes()); }
+            rt::String(s) => self.buf.write(s.as_bytes()),
+            rt::CurrentArgument(()) => self.buf.write(cur.unwrap().as_bytes()),
             rt::Argument(ref arg) => {
                 // Fill in the format parameters into the formatter
                 self.fill = arg.format.fill;
@@ -782,8 +786,8 @@ impl<'a> Formatter<'a> {
 
                 // Then actually do some printing
                 match arg.method {
-                    None => { (value.formatter)(value.value, self); }
-                    Some(ref method) => { self.execute(*method, value); }
+                    None => (value.formatter)(value.value, self),
+                    Some(ref method) => self.execute(*method, value)
                 }
             }
         }
@@ -804,7 +808,7 @@ impl<'a> Formatter<'a> {
         }
     }
 
-    fn execute(&mut self, method: &rt::Method, arg: Argument) {
+    fn execute(&mut self, method: &rt::Method, arg: Argument) -> Result {
         match *method {
             // Pluralization is selection upon a numeric value specified as the
             // parameter.
@@ -847,7 +851,7 @@ impl<'a> Formatter<'a> {
                     }
                 }
 
-                self.runplural(value, *default);
+                self.runplural(value, *default)
             }
 
             // Select is just a matching against the string specified.
@@ -860,24 +864,26 @@ impl<'a> Formatter<'a> {
                 for s in selectors.iter() {
                     if s.selector == value {
                         for piece in s.result.iter() {
-                            self.run(piece, Some(value));
+                            if_ok!(self.run(piece, Some(value)));
                         }
-                        return;
+                        return Ok(());
                     }
                 }
                 for piece in default.iter() {
-                    self.run(piece, Some(value));
+                    if_ok!(self.run(piece, Some(value)));
                 }
+                Ok(())
             }
         }
     }
 
-    fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) {
+    fn runplural(&mut self, value: uint, pieces: &[rt::Piece]) -> Result {
         ::uint::to_str_bytes(value, 10, |buf| {
             let valuestr = str::from_utf8(buf).unwrap();
             for piece in pieces.iter() {
-                self.run(piece, Some(valuestr));
+                if_ok!(self.run(piece, Some(valuestr)));
             }
+            Ok(())
         })
     }
 
@@ -899,7 +905,7 @@ impl<'a> Formatter<'a> {
     /// This function will correctly account for the flags provided as well as
     /// the minimum width. It will not take precision into account.
     pub fn pad_integral(&mut self, s: &[u8], alternate_prefix: &str,
-                        positive: bool) {
+                        positive: bool) -> Result {
         use fmt::parse::{FlagAlternate, FlagSignPlus, FlagSignAwareZeroPad};
 
         let mut actual_len = s.len();
@@ -916,32 +922,32 @@ impl<'a> Formatter<'a> {
         let sign = |this: &mut Formatter| {
             if !signprinted {
                 if this.flags & 1 << (FlagSignPlus as uint) != 0 && positive {
-                    this.buf.write(['+' as u8]);
+                    if_ok!(this.buf.write(['+' as u8]));
                 } else if !positive {
-                    this.buf.write(['-' as u8]);
+                    if_ok!(this.buf.write(['-' as u8]));
                 }
                 if this.flags & 1 << (FlagAlternate as uint) != 0 {
-                    this.buf.write(alternate_prefix.as_bytes());
+                    if_ok!(this.buf.write(alternate_prefix.as_bytes()));
                 }
                 signprinted = true;
             }
+            Ok(())
         };
 
         let emit = |this: &mut Formatter| {
-            sign(this);
-            this.buf.write(s);
+            sign(this).and_then(|()| this.buf.write(s))
         };
 
         match self.width {
-            None => { emit(self) }
-            Some(min) if actual_len >= min => { emit(self) }
+            None => emit(self),
+            Some(min) if actual_len >= min => emit(self),
             Some(min) => {
                 if self.flags & 1 << (FlagSignAwareZeroPad as uint) != 0 {
                     self.fill = '0';
-                    sign(self);
+                    if_ok!(sign(self));
                 }
                 self.with_padding(min - actual_len, parse::AlignRight, |me| {
-                    emit(me);
+                    emit(me)
                 })
             }
         }
@@ -958,11 +964,10 @@ impl<'a> Formatter<'a> {
     ///               is longer than this length
     ///
     /// Notably this function ignored the `flag` parameters
-    pub fn pad(&mut self, s: &str) {
+    pub fn pad(&mut self, s: &str) -> Result {
         // Make sure there's a fast path up front
         if self.width.is_none() && self.precision.is_none() {
-            self.buf.write(s.as_bytes());
-            return
+            return self.buf.write(s.as_bytes());
         }
         // The `precision` field can be interpreted as a `max-width` for the
         // string being formatted
@@ -974,8 +979,7 @@ impl<'a> Formatter<'a> {
                 let char_len = s.char_len();
                 if char_len >= max {
                     let nchars = ::cmp::min(max, char_len);
-                    self.buf.write(s.slice_chars(0, nchars).as_bytes());
-                    return
+                    return self.buf.write(s.slice_chars(0, nchars).as_bytes());
                 }
             }
             None => {}
@@ -985,7 +989,7 @@ impl<'a> Formatter<'a> {
         match self.width {
             // If we're under the maximum length, and there's no minimum length
             // requirements, then we can just emit the string
-            None => { self.buf.write(s.as_bytes()) }
+            None => self.buf.write(s.as_bytes()),
 
             // If we're under the maximum width, check if we're over the minimum
             // width, if so it's as easy as just emitting the string.
@@ -997,7 +1001,7 @@ impl<'a> Formatter<'a> {
             // up the minimum width with the specified string + some alignment.
             Some(width) => {
                 self.with_padding(width - s.len(), parse::AlignLeft, |me| {
-                    me.buf.write(s.as_bytes());
+                    me.buf.write(s.as_bytes())
                 })
             }
         }
@@ -1006,29 +1010,30 @@ impl<'a> Formatter<'a> {
     fn with_padding(&mut self,
                     padding: uint,
                     default: parse::Alignment,
-                    f: |&mut Formatter|) {
+                    f: |&mut Formatter| -> Result) -> Result {
         let align = match self.align {
             parse::AlignUnknown => default,
             parse::AlignLeft | parse::AlignRight => self.align
         };
         if align == parse::AlignLeft {
-            f(self);
+            if_ok!(f(self));
         }
         let mut fill = [0u8, ..4];
         let len = self.fill.encode_utf8(fill);
         for _ in range(0, padding) {
-            self.buf.write(fill.slice_to(len));
+            if_ok!(self.buf.write(fill.slice_to(len)));
         }
         if align == parse::AlignRight {
-            f(self);
+            if_ok!(f(self));
         }
+        Ok(())
     }
 }
 
 /// This is a function which calls are emitted to by the compiler itself to
 /// create the Argument structures that are passed into the `format` function.
 #[doc(hidden)] #[inline]
-pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter),
+pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter) -> Result,
                        t: &'a T) -> Argument<'a> {
     unsafe {
         Argument {
@@ -1055,41 +1060,41 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
 // Implementations of the core formatting traits
 
 impl Bool for bool {
-    fn fmt(b: &bool, f: &mut Formatter) {
-        String::fmt(&(if *b {"true"} else {"false"}), f);
+    fn fmt(b: &bool, f: &mut Formatter) -> Result {
+        String::fmt(&(if *b {"true"} else {"false"}), f)
     }
 }
 
 impl<'a, T: str::Str> String for T {
-    fn fmt(s: &T, f: &mut Formatter) {
-        f.pad(s.as_slice());
+    fn fmt(s: &T, f: &mut Formatter) -> Result {
+        f.pad(s.as_slice())
     }
 }
 
 impl Char for char {
-    fn fmt(c: &char, f: &mut Formatter) {
+    fn fmt(c: &char, f: &mut Formatter) -> Result {
         let mut utf8 = [0u8, ..4];
         let amt = c.encode_utf8(utf8);
         let s: &str = unsafe { cast::transmute(utf8.slice_to(amt)) };
-        String::fmt(&s, f);
+        String::fmt(&s, f)
     }
 }
 
 macro_rules! int_base(($ty:ident, $into:ident, $base:expr,
                        $name:ident, $prefix:expr) => {
     impl $name for $ty {
-        fn fmt(c: &$ty, f: &mut Formatter) {
+        fn fmt(c: &$ty, f: &mut Formatter) -> Result {
             ::$into::to_str_bytes(*c as $into, $base, |buf| {
-                f.pad_integral(buf, $prefix, true);
+                f.pad_integral(buf, $prefix, true)
             })
         }
     }
 })
 macro_rules! upper_hex(($ty:ident, $into:ident) => {
     impl UpperHex for $ty {
-        fn fmt(c: &$ty, f: &mut Formatter) {
+        fn fmt(c: &$ty, f: &mut Formatter) -> Result {
             ::$into::to_str_bytes(*c as $into, 16, |buf| {
-                upperhex(buf, f);
+                upperhex(buf, f)
             })
         }
     }
@@ -1097,7 +1102,7 @@ macro_rules! upper_hex(($ty:ident, $into:ident) => {
 // Not sure why, but this causes an "unresolved enum variant, struct or const"
 // when inlined into the above macro...
 #[doc(hidden)]
-pub fn upperhex(buf: &[u8], f: &mut Formatter) {
+pub fn upperhex(buf: &[u8], f: &mut Formatter) -> Result {
     let mut local = [0u8, ..16];
     for i in ::iter::range(0, buf.len()) {
         local[i] = match buf[i] as char {
@@ -1105,16 +1110,16 @@ pub fn upperhex(buf: &[u8], f: &mut Formatter) {
             c => c as u8,
         }
     }
-    f.pad_integral(local.slice_to(buf.len()), "0x", true);
+    f.pad_integral(local.slice_to(buf.len()), "0x", true)
 }
 
 macro_rules! integer(($signed:ident, $unsigned:ident) => {
     // Signed is special because it actuall emits the negative sign,
     // nothing else should do that, however.
     impl Signed for $signed {
-        fn fmt(c: &$signed, f: &mut Formatter) {
+        fn fmt(c: &$signed, f: &mut Formatter) -> Result {
             ::$unsigned::to_str_bytes(c.abs() as $unsigned, 10, |buf| {
-                f.pad_integral(buf, "", *c >= 0);
+                f.pad_integral(buf, "", *c >= 0)
             })
         }
     }
@@ -1138,35 +1143,35 @@ integer!(i64, u64)
 
 macro_rules! floating(($ty:ident) => {
     impl Float for $ty {
-        fn fmt(f: &$ty, fmt: &mut Formatter) {
+        fn fmt(f: &$ty, fmt: &mut Formatter) -> Result {
             // FIXME: this shouldn't perform an allocation
             let s = match fmt.precision {
                 Some(i) => ::$ty::to_str_exact(f.abs(), i),
                 None => ::$ty::to_str_digits(f.abs(), 6)
             };
-            fmt.pad_integral(s.as_bytes(), "", *f >= 0.0);
+            fmt.pad_integral(s.as_bytes(), "", *f >= 0.0)
         }
     }
 
     impl LowerExp for $ty {
-        fn fmt(f: &$ty, fmt: &mut Formatter) {
+        fn fmt(f: &$ty, fmt: &mut Formatter) -> Result {
             // FIXME: this shouldn't perform an allocation
             let s = match fmt.precision {
                 Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, false),
                 None => ::$ty::to_str_exp_digits(f.abs(), 6, false)
             };
-            fmt.pad_integral(s.as_bytes(), "", *f >= 0.0);
+            fmt.pad_integral(s.as_bytes(), "", *f >= 0.0)
         }
     }
 
     impl UpperExp for $ty {
-        fn fmt(f: &$ty, fmt: &mut Formatter) {
+        fn fmt(f: &$ty, fmt: &mut Formatter) -> Result {
             // FIXME: this shouldn't perform an allocation
             let s = match fmt.precision {
                 Some(i) => ::$ty::to_str_exp_exact(f.abs(), i, true),
                 None => ::$ty::to_str_exp_digits(f.abs(), 6, true)
             };
-            fmt.pad_integral(s.as_bytes(), "", *f >= 0.0);
+            fmt.pad_integral(s.as_bytes(), "", *f >= 0.0)
         }
     }
 })
@@ -1174,39 +1179,41 @@ floating!(f32)
 floating!(f64)
 
 impl<T> Poly for T {
-    fn fmt(t: &T, f: &mut Formatter) {
+    fn fmt(t: &T, f: &mut Formatter) -> Result {
         match (f.width, f.precision) {
             (None, None) => {
-                repr::write_repr(f.buf, t);
+                repr::write_repr(f.buf, t)
             }
 
             // If we have a specified width for formatting, then we have to make
             // this allocation of a new string
             _ => {
                 let s = repr::repr_to_str(t);
-                f.pad(s);
+                f.pad(s)
             }
         }
     }
 }
 
 impl<T> Pointer for *T {
-    fn fmt(t: &*T, f: &mut Formatter) {
+    fn fmt(t: &*T, f: &mut Formatter) -> Result {
         f.flags |= 1 << (parse::FlagAlternate as uint);
         ::uint::to_str_bytes(*t as uint, 16, |buf| {
-            f.pad_integral(buf, "0x", true);
+            f.pad_integral(buf, "0x", true)
         })
     }
 }
 impl<T> Pointer for *mut T {
-    fn fmt(t: &*mut T, f: &mut Formatter) { Pointer::fmt(&(*t as *T), f) }
+    fn fmt(t: &*mut T, f: &mut Formatter) -> Result {
+        Pointer::fmt(&(*t as *T), f)
+    }
 }
 
 // Implementation of Show for various core types
 
 macro_rules! delegate(($ty:ty to $other:ident) => {
     impl<'a> Show for $ty {
-        fn fmt(me: &$ty, f: &mut Formatter) {
+        fn fmt(me: &$ty, f: &mut Formatter) -> Result {
             $other::fmt(me, f)
         }
     }
@@ -1229,10 +1236,10 @@ delegate!(f32 to Float)
 delegate!(f64 to Float)
 
 impl<T> Show for *T {
-    fn fmt(me: &*T, f: &mut Formatter) { Pointer::fmt(me, f) }
+    fn fmt(me: &*T, f: &mut Formatter) -> Result { Pointer::fmt(me, f) }
 }
 impl<T> Show for *mut T {
-    fn fmt(me: &*mut T, f: &mut Formatter) { Pointer::fmt(me, f) }
+    fn fmt(me: &*mut T, f: &mut Formatter) -> Result { Pointer::fmt(me, f) }
 }
 
 // If you expected tests to be here, look instead at the run-pass/ifmt.rs test,
diff --git a/src/libstd/hash.rs b/src/libstd/hash.rs
index 1444f9b4129..4163d1e0c96 100644
--- a/src/libstd/hash.rs
+++ b/src/libstd/hash.rs
@@ -27,13 +27,14 @@
 #[allow(missing_doc)];
 
 use container::Container;
+use io::{Writer, IoResult};
 use iter::Iterator;
+use num::ToStrRadix;
 use option::{Some, None};
-use io::Writer;
+use result::Ok;
 use str::OwnedStr;
 use to_bytes::IterBytes;
 use vec::ImmutableVector;
-use num::ToStrRadix;
 
 // Alias `SipState` to `State`.
 pub use State = hash::SipState;
@@ -164,7 +165,7 @@ macro_rules! compress (
 impl Writer for SipState {
     // Methods for io::writer
     #[inline]
-    fn write(&mut self, msg: &[u8]) {
+    fn write(&mut self, msg: &[u8]) -> IoResult<()> {
         let length = msg.len();
         self.length += length;
 
@@ -180,7 +181,7 @@ impl Writer for SipState {
                     t += 1;
                 }
                 self.ntail += length;
-                return;
+                return Ok(())
             }
 
             let mut t = 0;
@@ -222,17 +223,14 @@ impl Writer for SipState {
             t += 1
         }
         self.ntail = left;
-    }
-
-    fn flush(&mut self) {
-        // No-op
+        Ok(())
     }
 }
 
 impl Streaming for SipState {
     #[inline]
     fn input(&mut self, buf: &[u8]) {
-        self.write(buf);
+        self.write(buf).unwrap();
     }
 
     #[inline]
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 64e42c5480f..256f9d325f3 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -11,10 +11,11 @@
 //! Buffering wrappers for I/O traits
 
 use container::Container;
-use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE};
+use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
 use iter::ExactSize;
 use num;
-use option::{Option, Some, None};
+use option::{Some, None};
+use result::{Ok, Err};
 use vec::{OwnedVector, ImmutableVector, MutableVector};
 use vec;
 
@@ -30,14 +31,13 @@ use vec;
 /// ```rust
 /// use std::io::{BufferedReader, File};
 ///
-/// # let _g = ::std::io::ignore_io_error();
 /// let file = File::open(&Path::new("message.txt"));
 /// let mut reader = BufferedReader::new(file);
 ///
 /// let mut buf = [0, ..100];
 /// match reader.read(buf) {
-///     Some(nread) => println!("Read {} bytes", nread),
-///     None => println!("At the end of the file!")
+///     Ok(nread) => println!("Read {} bytes", nread),
+///     Err(e) => println!("error reading: {}", e)
 /// }
 /// ```
 pub struct BufferedReader<R> {
@@ -86,17 +86,12 @@ impl<R: Reader> BufferedReader<R> {
 }
 
 impl<R: Reader> Buffer for BufferedReader<R> {
-    fn fill<'a>(&'a mut self) -> &'a [u8] {
+    fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
         if self.pos == self.cap {
-            match self.inner.read(self.buf) {
-                Some(cap) => {
-                    self.pos = 0;
-                    self.cap = cap;
-                }
-                None => { self.eof = true; }
-            }
+            self.cap = if_ok!(self.inner.read(self.buf));
+            self.pos = 0;
         }
-        return self.buf.slice(self.pos, self.cap);
+        Ok(self.buf.slice(self.pos, self.cap))
     }
 
     fn consume(&mut self, amt: uint) {
@@ -106,18 +101,15 @@ impl<R: Reader> Buffer for BufferedReader<R> {
 }
 
 impl<R: Reader> Reader for BufferedReader<R> {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let nread = {
-            let available = self.fill();
+            let available = if_ok!(self.fill());
             let nread = num::min(available.len(), buf.len());
             vec::bytes::copy_memory(buf, available.slice_to(nread));
             nread
         };
         self.pos += nread;
-        if nread == 0 && buf.len() != 0 && self.eof {
-            return None;
-        }
-        Some(nread)
+        Ok(nread)
     }
 }
 
@@ -128,9 +120,9 @@ impl<R: Reader> Reader for BufferedReader<R> {
 /// # Example
 ///
 /// ```rust
+/// # #[allow(unused_must_use)];
 /// use std::io::{BufferedWriter, File};
 ///
-/// # let _g = ::std::io::ignore_io_error();
 /// let file = File::open(&Path::new("message.txt"));
 /// let mut writer = BufferedWriter::new(file);
 ///
@@ -161,10 +153,13 @@ impl<W: Writer> BufferedWriter<W> {
         BufferedWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
     }
 
-    fn flush_buf(&mut self) {
+    fn flush_buf(&mut self) -> IoResult<()> {
         if self.pos != 0 {
-            self.inner.write(self.buf.slice_to(self.pos));
+            let ret = self.inner.write(self.buf.slice_to(self.pos));
             self.pos = 0;
+            ret
+        } else {
+            Ok(())
         }
     }
 
@@ -178,29 +173,30 @@ impl<W: Writer> BufferedWriter<W> {
     ///
     /// The buffer is flushed before returning the writer.
     pub fn unwrap(mut self) -> W {
-        self.flush_buf();
+        // FIXME: is failing the right thing to do if flushing fails?
+        self.flush_buf().unwrap();
         self.inner
     }
 }
 
 impl<W: Writer> Writer for BufferedWriter<W> {
-    fn write(&mut self, buf: &[u8]) {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         if self.pos + buf.len() > self.buf.len() {
-            self.flush_buf();
+            if_ok!(self.flush_buf());
         }
 
         if buf.len() > self.buf.len() {
-            self.inner.write(buf);
+            self.inner.write(buf)
         } else {
             let dst = self.buf.mut_slice_from(self.pos);
             vec::bytes::copy_memory(dst, buf);
             self.pos += buf.len();
+            Ok(())
         }
     }
 
-    fn flush(&mut self) {
-        self.flush_buf();
-        self.inner.flush();
+    fn flush(&mut self) -> IoResult<()> {
+        self.flush_buf().and_then(|()| self.inner.flush())
     }
 }
 
@@ -234,18 +230,19 @@ impl<W: Writer> LineBufferedWriter<W> {
 }
 
 impl<W: Writer> Writer for LineBufferedWriter<W> {
-    fn write(&mut self, buf: &[u8]) {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         match buf.iter().rposition(|&b| b == '\n' as u8) {
             Some(i) => {
-                self.inner.write(buf.slice_to(i + 1));
-                self.inner.flush();
-                self.inner.write(buf.slice_from(i + 1));
+                if_ok!(self.inner.write(buf.slice_to(i + 1)));
+                if_ok!(self.inner.flush());
+                if_ok!(self.inner.write(buf.slice_from(i + 1)));
+                Ok(())
             }
             None => self.inner.write(buf),
         }
     }
 
-    fn flush(&mut self) { self.inner.flush() }
+    fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
 }
 
 struct InternalBufferedWriter<W>(BufferedWriter<W>);
@@ -258,7 +255,9 @@ impl<W> InternalBufferedWriter<W> {
 }
 
 impl<W: Reader> Reader for InternalBufferedWriter<W> {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.get_mut_ref().inner.read(buf) }
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+        self.get_mut_ref().inner.read(buf)
+    }
 }
 
 /// Wraps a Stream and buffers input and output to and from it
@@ -268,9 +267,9 @@ impl<W: Reader> Reader for InternalBufferedWriter<W> {
 /// # Example
 ///
 /// ```rust
+/// # #[allow(unused_must_use)];
 /// use std::io::{BufferedStream, File};
 ///
-/// # let _g = ::std::io::ignore_io_error();
 /// let file = File::open(&Path::new("message.txt"));
 /// let mut stream = BufferedStream::new(file);
 ///
@@ -279,8 +278,8 @@ impl<W: Reader> Reader for InternalBufferedWriter<W> {
 ///
 /// let mut buf = [0, ..100];
 /// match stream.read(buf) {
-///     Some(nread) => println!("Read {} bytes", nread),
-///     None => println!("At the end of the stream!")
+///     Ok(nread) => println!("Read {} bytes", nread),
+///     Err(e) => println!("error reading: {}", e)
 /// }
 /// ```
 pub struct BufferedStream<S> {
@@ -326,17 +325,23 @@ impl<S: Stream> BufferedStream<S> {
 }
 
 impl<S: Stream> Buffer for BufferedStream<S> {
-    fn fill<'a>(&'a mut self) -> &'a [u8] { self.inner.fill() }
+    fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill() }
     fn consume(&mut self, amt: uint) { self.inner.consume(amt) }
 }
 
 impl<S: Stream> Reader for BufferedStream<S> {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.inner.read(buf) }
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+        self.inner.read(buf)
+    }
 }
 
 impl<S: Stream> Writer for BufferedStream<S> {
-    fn write(&mut self, buf: &[u8]) { self.inner.inner.get_mut_ref().write(buf) }
-    fn flush(&mut self) { self.inner.inner.get_mut_ref().flush() }
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
+        self.inner.inner.get_mut_ref().write(buf)
+    }
+    fn flush(&mut self) -> IoResult<()> {
+        self.inner.inner.get_mut_ref().flush()
+    }
 }
 
 #[cfg(test)]
@@ -354,13 +359,13 @@ mod test {
     pub struct NullStream;
 
     impl Reader for NullStream {
-        fn read(&mut self, _: &mut [u8]) -> Option<uint> {
-            None
+        fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
+            Err(io::standard_error(io::EndOfFile))
         }
     }
 
     impl Writer for NullStream {
-        fn write(&mut self, _: &[u8]) { }
+        fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) }
     }
 
     /// A dummy reader intended at testing short-reads propagation.
@@ -369,8 +374,11 @@ mod test {
     }
 
     impl Reader for ShortReader {
-        fn read(&mut self, _: &mut [u8]) -> Option<uint> {
-            self.lengths.shift()
+        fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
+            match self.lengths.shift() {
+                Some(i) => Ok(i),
+                None => Err(io::standard_error(io::EndOfFile))
+            }
         }
     }
 
@@ -381,24 +389,24 @@ mod test {
 
         let mut buf = [0, 0, 0];
         let nread = reader.read(buf);
-        assert_eq!(Some(2), nread);
+        assert_eq!(Ok(2), nread);
         assert_eq!([0, 1, 0], buf);
 
         let mut buf = [0];
         let nread = reader.read(buf);
-        assert_eq!(Some(1), nread);
+        assert_eq!(Ok(1), nread);
         assert_eq!([2], buf);
 
         let mut buf = [0, 0, 0];
         let nread = reader.read(buf);
-        assert_eq!(Some(1), nread);
+        assert_eq!(Ok(1), nread);
         assert_eq!([3, 0, 0], buf);
 
         let nread = reader.read(buf);
-        assert_eq!(Some(1), nread);
+        assert_eq!(Ok(1), nread);
         assert_eq!([4, 0, 0], buf);
 
-        assert_eq!(None, reader.read(buf));
+        assert!(reader.read(buf).is_err());
     }
 
     #[test]
@@ -406,35 +414,35 @@ mod test {
         let inner = MemWriter::new();
         let mut writer = BufferedWriter::with_capacity(2, inner);
 
-        writer.write([0, 1]);
+        writer.write([0, 1]).unwrap();
         assert_eq!([], writer.get_ref().get_ref());
 
-        writer.write([2]);
+        writer.write([2]).unwrap();
         assert_eq!([0, 1], writer.get_ref().get_ref());
 
-        writer.write([3]);
+        writer.write([3]).unwrap();
         assert_eq!([0, 1], writer.get_ref().get_ref());
 
-        writer.flush();
+        writer.flush().unwrap();
         assert_eq!([0, 1, 2, 3], writer.get_ref().get_ref());
 
-        writer.write([4]);
-        writer.write([5]);
+        writer.write([4]).unwrap();
+        writer.write([5]).unwrap();
         assert_eq!([0, 1, 2, 3], writer.get_ref().get_ref());
 
-        writer.write([6]);
+        writer.write([6]).unwrap();
         assert_eq!([0, 1, 2, 3, 4, 5],
                    writer.get_ref().get_ref());
 
-        writer.write([7, 8]);
+        writer.write([7, 8]).unwrap();
         assert_eq!([0, 1, 2, 3, 4, 5, 6],
                    writer.get_ref().get_ref());
 
-        writer.write([9, 10, 11]);
+        writer.write([9, 10, 11]).unwrap();
         assert_eq!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
                    writer.get_ref().get_ref());
 
-        writer.flush();
+        writer.flush().unwrap();
         assert_eq!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
                    writer.get_ref().get_ref());
     }
@@ -442,7 +450,7 @@ mod test {
     #[test]
     fn test_buffered_writer_inner_flushes() {
         let mut w = BufferedWriter::with_capacity(3, MemWriter::new());
-        w.write([0, 1]);
+        w.write([0, 1]).unwrap();
         assert_eq!([], w.get_ref().get_ref());
         let w = w.unwrap();
         assert_eq!([0, 1], w.get_ref());
@@ -455,47 +463,49 @@ mod test {
         struct S;
 
         impl io::Writer for S {
-            fn write(&mut self, _: &[u8]) {}
+            fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) }
         }
 
         impl io::Reader for S {
-            fn read(&mut self, _: &mut [u8]) -> Option<uint> { None }
+            fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
+                Err(io::standard_error(io::EndOfFile))
+            }
         }
 
         let mut stream = BufferedStream::new(S);
         let mut buf = [];
-        stream.read(buf);
-        stream.write(buf);
-        stream.flush();
+        assert!(stream.read(buf).is_err());
+        stream.write(buf).unwrap();
+        stream.flush().unwrap();
     }
 
     #[test]
     fn test_read_until() {
         let inner = MemReader::new(~[0, 1, 2, 1, 0]);
         let mut reader = BufferedReader::with_capacity(2, inner);
-        assert_eq!(reader.read_until(0), Some(~[0]));
-        assert_eq!(reader.read_until(2), Some(~[1, 2]));
-        assert_eq!(reader.read_until(1), Some(~[1]));
-        assert_eq!(reader.read_until(8), Some(~[0]));
-        assert_eq!(reader.read_until(9), None);
+        assert_eq!(reader.read_until(0), Ok(~[0]));
+        assert_eq!(reader.read_until(2), Ok(~[1, 2]));
+        assert_eq!(reader.read_until(1), Ok(~[1]));
+        assert_eq!(reader.read_until(8), Ok(~[0]));
+        assert!(reader.read_until(9).is_err());
     }
 
     #[test]
     fn test_line_buffer() {
         let mut writer = LineBufferedWriter::new(MemWriter::new());
-        writer.write([0]);
+        writer.write([0]).unwrap();
         assert_eq!(writer.get_ref().get_ref(), []);
-        writer.write([1]);
+        writer.write([1]).unwrap();
         assert_eq!(writer.get_ref().get_ref(), []);
-        writer.flush();
+        writer.flush().unwrap();
         assert_eq!(writer.get_ref().get_ref(), [0, 1]);
-        writer.write([0, '\n' as u8, 1, '\n' as u8, 2]);
+        writer.write([0, '\n' as u8, 1, '\n' as u8, 2]).unwrap();
         assert_eq!(writer.get_ref().get_ref(),
             [0, 1, 0, '\n' as u8, 1, '\n' as u8]);
-        writer.flush();
+        writer.flush().unwrap();
         assert_eq!(writer.get_ref().get_ref(),
             [0, 1, 0, '\n' as u8, 1, '\n' as u8, 2]);
-        writer.write([3, '\n' as u8]);
+        writer.write([3, '\n' as u8]).unwrap();
         assert_eq!(writer.get_ref().get_ref(),
             [0, 1, 0, '\n' as u8, 1, '\n' as u8, 2, 3, '\n' as u8]);
     }
@@ -504,10 +514,10 @@ mod test {
     fn test_read_line() {
         let in_buf = MemReader::new(bytes!("a\nb\nc").to_owned());
         let mut reader = BufferedReader::with_capacity(2, in_buf);
-        assert_eq!(reader.read_line(), Some(~"a\n"));
-        assert_eq!(reader.read_line(), Some(~"b\n"));
-        assert_eq!(reader.read_line(), Some(~"c"));
-        assert_eq!(reader.read_line(), None);
+        assert_eq!(reader.read_line(), Ok(~"a\n"));
+        assert_eq!(reader.read_line(), Ok(~"b\n"));
+        assert_eq!(reader.read_line(), Ok(~"c"));
+        assert!(reader.read_line().is_err());
     }
 
     #[test]
@@ -526,20 +536,20 @@ mod test {
         let inner = ShortReader{lengths: ~[0, 1, 2, 0, 1, 0]};
         let mut reader = BufferedReader::new(inner);
         let mut buf = [0, 0];
-        assert_eq!(reader.read(buf), Some(0));
-        assert_eq!(reader.read(buf), Some(1));
-        assert_eq!(reader.read(buf), Some(2));
-        assert_eq!(reader.read(buf), Some(0));
-        assert_eq!(reader.read(buf), Some(1));
-        assert_eq!(reader.read(buf), Some(0));
-        assert_eq!(reader.read(buf), None);
+        assert_eq!(reader.read(buf), Ok(0));
+        assert_eq!(reader.read(buf), Ok(1));
+        assert_eq!(reader.read(buf), Ok(2));
+        assert_eq!(reader.read(buf), Ok(0));
+        assert_eq!(reader.read(buf), Ok(1));
+        assert_eq!(reader.read(buf), Ok(0));
+        assert!(reader.read(buf).is_err());
     }
 
     #[test]
     fn read_char_buffered() {
         let buf = [195u8, 159u8];
         let mut reader = BufferedReader::with_capacity(1, BufReader::new(buf));
-        assert_eq!(reader.read_char(), Some('ß'));
+        assert_eq!(reader.read_char(), Ok('ß'));
     }
 
     #[bench]
diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs
index 1eaa752d2a3..6ed588ac69f 100644
--- a/src/libstd/io/comm_adapters.rs
+++ b/src/libstd/io/comm_adapters.rs
@@ -14,7 +14,7 @@ use comm::{Port, Chan};
 use cmp;
 use io;
 use option::{None, Option, Some};
-use super::{Reader, Writer};
+use super::{Reader, Writer, IoResult};
 use vec::{bytes, CloneableVector, MutableVector, ImmutableVector};
 
 /// Allows reading from a port.
@@ -49,7 +49,7 @@ impl PortReader {
 }
 
 impl Reader for PortReader {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let mut num_read = 0;
         loop {
             match self.buf {
@@ -71,10 +71,9 @@ impl Reader for PortReader {
             self.closed = self.buf.is_none();
         }
         if self.closed && num_read == 0 {
-            io::io_error::cond.raise(io::standard_error(io::EndOfFile));
-            None
+            Err(io::standard_error(io::EndOfFile))
         } else {
-            Some(num_read)
+            Ok(num_read)
         }
     }
 }
@@ -98,13 +97,15 @@ impl ChanWriter {
 }
 
 impl Writer for ChanWriter {
-    fn write(&mut self, buf: &[u8]) {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         if !self.chan.try_send(buf.to_owned()) {
-            io::io_error::cond.raise(io::IoError {
+            Err(io::IoError {
                 kind: io::BrokenPipe,
                 desc: "Pipe closed",
                 detail: None
-            });
+            })
+        } else {
+            Ok(())
         }
     }
 }
@@ -132,36 +133,28 @@ mod test {
         let mut buf = ~[0u8, ..3];
 
 
-        assert_eq!(Some(0), reader.read([]));
+        assert_eq!(Ok(0), reader.read([]));
 
-        assert_eq!(Some(3), reader.read(buf));
+        assert_eq!(Ok(3), reader.read(buf));
         assert_eq!(~[1,2,3], buf);
 
-        assert_eq!(Some(3), reader.read(buf));
+        assert_eq!(Ok(3), reader.read(buf));
         assert_eq!(~[4,5,6], buf);
 
-        assert_eq!(Some(2), reader.read(buf));
+        assert_eq!(Ok(2), reader.read(buf));
         assert_eq!(~[7,8,6], buf);
 
-        let mut err = None;
-        let result = io::io_error::cond.trap(|io::standard_error(k, _, _)| {
-            err = Some(k)
-        }).inside(|| {
-            reader.read(buf)
-        });
-        assert_eq!(Some(io::EndOfFile), err);
-        assert_eq!(None, result);
+        match reader.read(buf) {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind, io::EndOfFile),
+        }
         assert_eq!(~[7,8,6], buf);
 
         // Ensure it continues to fail in the same way.
-        err = None;
-        let result = io::io_error::cond.trap(|io::standard_error(k, _, _)| {
-            err = Some(k)
-        }).inside(|| {
-            reader.read(buf)
-        });
-        assert_eq!(Some(io::EndOfFile), err);
-        assert_eq!(None, result);
+        match reader.read(buf) {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind, io::EndOfFile),
+        }
         assert_eq!(~[7,8,6], buf);
     }
 
@@ -169,18 +162,15 @@ mod test {
     fn test_chan_writer() {
         let (port, chan) = Chan::new();
         let mut writer = ChanWriter::new(chan);
-        writer.write_be_u32(42);
+        writer.write_be_u32(42).unwrap();
 
         let wanted = ~[0u8, 0u8, 0u8, 42u8];
         let got = task::try(proc() { port.recv() }).unwrap();
         assert_eq!(wanted, got);
 
-        let mut err = None;
-        io::io_error::cond.trap(|io::IoError { kind, .. } | {
-            err = Some(kind)
-        }).inside(|| {
-            writer.write_u8(1)
-        });
-        assert_eq!(Some(io::BrokenPipe), err);
+        match writer.write_u8(1) {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind, io::BrokenPipe),
+        }
     }
 }
diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs
index 548dc3efe92..49d51cbb26f 100644
--- a/src/libstd/io/extensions.rs
+++ b/src/libstd/io/extensions.rs
@@ -46,7 +46,7 @@ impl<'r, R: Reader> Bytes<'r, R> {
 impl<'r, R: Reader> Iterator<u8> for Bytes<'r, R> {
     #[inline]
     fn next(&mut self) -> Option<u8> {
-        self.reader.read_byte()
+        self.reader.read_byte().ok()
     }
 }
 
@@ -125,23 +125,22 @@ pub fn u64_from_be_bytes(data: &[u8],
 
 #[cfg(test)]
 mod test {
-    use unstable::finally::Finally;
     use prelude::*;
+    use io;
     use io::{MemReader, MemWriter};
-    use io::{io_error, placeholder_error};
 
     struct InitialZeroByteReader {
         count: int,
     }
 
     impl Reader for InitialZeroByteReader {
-        fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+        fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
             if self.count == 0 {
                 self.count = 1;
-                Some(0)
+                Ok(0)
             } else {
                 buf[0] = 10;
-                Some(1)
+                Ok(1)
             }
         }
     }
@@ -149,17 +148,16 @@ mod test {
     struct EofReader;
 
     impl Reader for EofReader {
-        fn read(&mut self, _: &mut [u8]) -> Option<uint> {
-            None
+        fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
+            Err(io::standard_error(io::EndOfFile))
         }
     }
 
     struct ErroringReader;
 
     impl Reader for ErroringReader {
-        fn read(&mut self, _: &mut [u8]) -> Option<uint> {
-            io_error::cond.raise(placeholder_error());
-            None
+        fn read(&mut self, _: &mut [u8]) -> io::IoResult<uint> {
+            Err(io::standard_error(io::InvalidInput))
         }
     }
 
@@ -168,16 +166,16 @@ mod test {
     }
 
     impl Reader for PartialReader {
-        fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+        fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
             if self.count == 0 {
                 self.count = 1;
                 buf[0] = 10;
                 buf[1] = 11;
-                Some(2)
+                Ok(2)
             } else {
                 buf[0] = 12;
                 buf[1] = 13;
-                Some(2)
+                Ok(2)
             }
         }
     }
@@ -187,14 +185,13 @@ mod test {
     }
 
     impl Reader for ErroringLaterReader {
-        fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+        fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
             if self.count == 0 {
                 self.count = 1;
                 buf[0] = 10;
-                Some(1)
+                Ok(1)
             } else {
-                io_error::cond.raise(placeholder_error());
-                None
+                Err(io::standard_error(io::InvalidInput))
             }
         }
     }
@@ -204,19 +201,19 @@ mod test {
     }
 
     impl Reader for ThreeChunkReader {
-        fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+        fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
             if self.count == 0 {
                 self.count = 1;
                 buf[0] = 10;
                 buf[1] = 11;
-                Some(2)
+                Ok(2)
             } else if self.count == 1 {
                 self.count = 2;
                 buf[0] = 12;
                 buf[1] = 13;
-                Some(2)
+                Ok(2)
             } else {
-                None
+                Err(io::standard_error(io::EndOfFile))
             }
         }
     }
@@ -225,7 +222,7 @@ mod test {
     fn read_byte() {
         let mut reader = MemReader::new(~[10]);
         let byte = reader.read_byte();
-        assert!(byte == Some(10));
+        assert!(byte == Ok(10));
     }
 
     #[test]
@@ -234,24 +231,21 @@ mod test {
             count: 0,
         };
         let byte = reader.read_byte();
-        assert!(byte == Some(10));
+        assert!(byte == Ok(10));
     }
 
     #[test]
     fn read_byte_eof() {
         let mut reader = EofReader;
         let byte = reader.read_byte();
-        assert!(byte == None);
+        assert!(byte.is_err());
     }
 
     #[test]
     fn read_byte_error() {
         let mut reader = ErroringReader;
-        io_error::cond.trap(|_| {
-        }).inside(|| {
-            let byte = reader.read_byte();
-            assert!(byte == None);
-        });
+        let byte = reader.read_byte();
+        assert!(byte.is_err());
     }
 
     #[test]
@@ -267,23 +261,21 @@ mod test {
     fn bytes_eof() {
         let mut reader = EofReader;
         let byte = reader.bytes().next();
-        assert!(byte == None);
+        assert!(byte.is_none());
     }
 
     #[test]
     fn bytes_error() {
         let mut reader = ErroringReader;
         let mut it = reader.bytes();
-        io_error::cond.trap(|_| ()).inside(|| {
-            let byte = it.next();
-            assert!(byte == None);
-        })
+        let byte = it.next();
+        assert!(byte.is_none());
     }
 
     #[test]
     fn read_bytes() {
         let mut reader = MemReader::new(~[10, 11, 12, 13]);
-        let bytes = reader.read_bytes(4);
+        let bytes = reader.read_bytes(4).unwrap();
         assert!(bytes == ~[10, 11, 12, 13]);
     }
 
@@ -292,24 +284,21 @@ mod test {
         let mut reader = PartialReader {
             count: 0,
         };
-        let bytes = reader.read_bytes(4);
+        let bytes = reader.read_bytes(4).unwrap();
         assert!(bytes == ~[10, 11, 12, 13]);
     }
 
     #[test]
     fn read_bytes_eof() {
         let mut reader = MemReader::new(~[10, 11]);
-        io_error::cond.trap(|_| {
-        }).inside(|| {
-            assert!(reader.read_bytes(4) == ~[10, 11]);
-        })
+        assert!(reader.read_bytes(4).is_err());
     }
 
     #[test]
     fn push_bytes() {
         let mut reader = MemReader::new(~[10, 11, 12, 13]);
         let mut buf = ~[8, 9];
-        reader.push_bytes(&mut buf, 4);
+        reader.push_bytes(&mut buf, 4).unwrap();
         assert!(buf == ~[8, 9, 10, 11, 12, 13]);
     }
 
@@ -319,7 +308,7 @@ mod test {
             count: 0,
         };
         let mut buf = ~[8, 9];
-        reader.push_bytes(&mut buf, 4);
+        reader.push_bytes(&mut buf, 4).unwrap();
         assert!(buf == ~[8, 9, 10, 11, 12, 13]);
     }
 
@@ -327,11 +316,8 @@ mod test {
     fn push_bytes_eof() {
         let mut reader = MemReader::new(~[10, 11]);
         let mut buf = ~[8, 9];
-        io_error::cond.trap(|_| {
-        }).inside(|| {
-            reader.push_bytes(&mut buf, 4);
-            assert!(buf == ~[8, 9, 10, 11]);
-        })
+        assert!(reader.push_bytes(&mut buf, 4).is_err());
+        assert!(buf == ~[8, 9, 10, 11]);
     }
 
     #[test]
@@ -340,38 +326,16 @@ mod test {
             count: 0,
         };
         let mut buf = ~[8, 9];
-        io_error::cond.trap(|_| { } ).inside(|| {
-            reader.push_bytes(&mut buf, 4);
-        });
+        assert!(reader.push_bytes(&mut buf, 4).is_err());
         assert!(buf == ~[8, 9, 10]);
     }
 
     #[test]
-    #[should_fail]
-    #[ignore] // borrow issues with RefCell
-    fn push_bytes_fail_reset_len() {
-        // push_bytes unsafely sets the vector length. This is testing that
-        // upon failure the length is reset correctly.
-        let _reader = ErroringLaterReader {
-            count: 0,
-        };
-        // FIXME (#7049): Figure out some other way to do this.
-        //let buf = RefCell::new(~[8, 9]);
-        (|| {
-            //reader.push_bytes(buf.borrow_mut().get(), 4);
-        }).finally(|| {
-            // NB: Using rtassert here to trigger abort on failure since this is a should_fail test
-            // FIXME: #7049 This fails because buf is still borrowed
-            //rtassert!(buf.borrow().get() == ~[8, 9, 10]);
-        })
-    }
-
-    #[test]
     fn read_to_end() {
         let mut reader = ThreeChunkReader {
             count: 0,
         };
-        let buf = reader.read_to_end();
+        let buf = reader.read_to_end().unwrap();
         assert!(buf == ~[10, 11, 12, 13]);
     }
 
@@ -381,7 +345,7 @@ mod test {
         let mut reader = ThreeChunkReader {
             count: 0,
         };
-        let buf = reader.read_to_end();
+        let buf = reader.read_to_end().unwrap();
         assert!(buf == ~[10, 11]);
     }
 
@@ -391,12 +355,12 @@ mod test {
 
         let mut writer = MemWriter::new();
         for i in uints.iter() {
-            writer.write_le_u64(*i);
+            writer.write_le_u64(*i).unwrap();
         }
 
         let mut reader = MemReader::new(writer.unwrap());
         for i in uints.iter() {
-            assert!(reader.read_le_u64() == *i);
+            assert!(reader.read_le_u64().unwrap() == *i);
         }
     }
 
@@ -407,12 +371,12 @@ mod test {
 
         let mut writer = MemWriter::new();
         for i in uints.iter() {
-            writer.write_be_u64(*i);
+            writer.write_be_u64(*i).unwrap();
         }
 
         let mut reader = MemReader::new(writer.unwrap());
         for i in uints.iter() {
-            assert!(reader.read_be_u64() == *i);
+            assert!(reader.read_be_u64().unwrap() == *i);
         }
     }
 
@@ -422,14 +386,14 @@ mod test {
 
         let mut writer = MemWriter::new();
         for i in ints.iter() {
-            writer.write_be_i32(*i);
+            writer.write_be_i32(*i).unwrap();
         }
 
         let mut reader = MemReader::new(writer.unwrap());
         for i in ints.iter() {
             // this tests that the sign extension is working
             // (comparing the values as i32 would not test this)
-            assert!(reader.read_be_int_n(4) == *i as i64);
+            assert!(reader.read_be_int_n(4).unwrap() == *i as i64);
         }
     }
 
@@ -439,10 +403,10 @@ mod test {
         let buf = ~[0x41, 0x02, 0x00, 0x00];
 
         let mut writer = MemWriter::new();
-        writer.write(buf);
+        writer.write(buf).unwrap();
 
         let mut reader = MemReader::new(writer.unwrap());
-        let f = reader.read_be_f32();
+        let f = reader.read_be_f32().unwrap();
         assert!(f == 8.1250);
     }
 
@@ -451,12 +415,12 @@ mod test {
         let f:f32 = 8.1250;
 
         let mut writer = MemWriter::new();
-        writer.write_be_f32(f);
-        writer.write_le_f32(f);
+        writer.write_be_f32(f).unwrap();
+        writer.write_le_f32(f).unwrap();
 
         let mut reader = MemReader::new(writer.unwrap());
-        assert!(reader.read_be_f32() == 8.1250);
-        assert!(reader.read_le_f32() == 8.1250);
+        assert!(reader.read_be_f32().unwrap() == 8.1250);
+        assert!(reader.read_le_f32().unwrap() == 8.1250);
     }
 
     #[test]
diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs
index 8904101dd05..ef1b1a56ec0 100644
--- a/src/libstd/io/fs.rs
+++ b/src/libstd/io/fs.rs
@@ -14,11 +14,11 @@ This module provides a set of functions and traits for working
 with regular files & directories on a filesystem.
 
 At the top-level of the module are a set of freestanding functions, associated
-with various filesystem operations. They all operate on a `Path` object.
+with various filesystem operations. They all operate on `Path` objects.
 
 All operations in this module, including those as part of `File` et al
-block the task during execution. Most will raise `std::io::io_error`
-conditions in the event of failure.
+block the task during execution. In the event of failure, all functions/methods
+will return an `IoResult` type with an `Err` value.
 
 Also included in this module is an implementation block on the `Path` object
 defined in `std::path::Path`. The impl adds useful methods about inspecting the
@@ -27,21 +27,25 @@ particular bits of it, etc.
 
 # Example
 
-    use std::io::{File, fs};
+```rust
+# #[allow(unused_must_use)];
+use std::io::{File, fs};
 
-    let path = Path::new("foo.txt");
+let path = Path::new("foo.txt");
 
-    // create the file, whether it exists or not
-    let mut file = File::create(&path);
-    file.write(bytes!("foobar"));
+// create the file, whether it exists or not
+let mut file = File::create(&path);
+file.write(bytes!("foobar"));
+# drop(file);
 
-    // open the file in read-only mode
-    let mut file = File::open(&path);
-    file.read_to_end();
+// open the file in read-only mode
+let mut file = File::open(&path);
+file.read_to_end();
 
-    println!("{}", path.stat().size);
-    fs::symlink(&path, &Path::new("bar.txt"));
-    fs::unlink(&path);
+println!("{}", path.stat().unwrap().size);
+# drop(file);
+fs::unlink(&path);
+```
 
 */
 
@@ -50,7 +54,7 @@ use clone::Clone;
 use iter::Iterator;
 use super::{Reader, Writer, Seek};
 use super::{SeekStyle, Read, Write, Open, IoError, Truncate,
-            FileMode, FileAccess, FileStat, io_error, FilePermission};
+            FileMode, FileAccess, FileStat, IoResult, FilePermission};
 use rt::rtio::{RtioFileStream, IoFactory, LocalIo};
 use io;
 use option::{Some, None, Option};
@@ -64,11 +68,12 @@ use vec::{OwnedVector, ImmutableVector};
 /// Can be constructed via `File::open()`, `File::create()`, and
 /// `File::open_mode()`.
 ///
-/// # Errors
+/// # Error
 ///
-/// This type will raise an io_error condition if operations are attempted against
-/// it for which its underlying file descriptor was not configured at creation
-/// time, via the `FileAccess` parameter to `File::open_mode()`.
+/// This type will return errors as an `IoResult<T>` if operations are
+/// attempted against it for which its underlying file descriptor was not
+/// configured at creation time, via the `FileAccess` parameter to
+/// `File::open_mode()`.
 pub struct File {
     priv fd: ~RtioFileStream,
     priv path: Path,
@@ -81,22 +86,19 @@ impl File {
     ///
     /// # Example
     ///
-    ///     use std::io::{File, io_error, Open, ReadWrite};
+    /// ```rust,should_fail
+    /// use std::io::{File, Open, ReadWrite};
     ///
-    ///     let p = Path::new("/some/file/path.txt");
+    /// let p = Path::new("/some/file/path.txt");
     ///
-    ///     io_error::cond.trap(|_| {
-    ///         // hoo-boy...
-    ///     }).inside(|| {
-    ///         let file = match File::open_mode(&p, Open, ReadWrite) {
-    ///             Some(s) => s,
-    ///             None => fail!("whoops! I'm sure this raised, anyways..")
-    ///         };
-    ///         // do some stuff with that file
+    /// let file = match File::open_mode(&p, Open, ReadWrite) {
+    ///     Ok(f) => f,
+    ///     Err(e) => fail!("file error: {}", e),
+    /// };
+    /// // do some stuff with that file
     ///
-    ///         // the file will be closed at the end of this block
-    ///     })
-    ///     // ..
+    /// // the file will be closed at the end of this block
+    /// ```
     ///
     /// `FileMode` and `FileAccess` provide information about the permissions
     /// context in which a given stream is created. More information about them
@@ -106,12 +108,12 @@ impl File {
     ///
     /// Note that, with this function, a `File` is returned regardless of the
     /// access-limitations indicated by `FileAccess` (e.g. calling `write` on a
-    /// `File` opened as `Read` will raise an `io_error` condition at runtime).
+    /// `File` opened as `Read` will return an error at runtime).
     ///
-    /// # Errors
+    /// # Error
     ///
-    /// This function will raise an `io_error` condition under a number of
-    /// different circumstances, to include but not limited to:
+    /// This function will return an error under a number of different
+    /// circumstances, to include but not limited to:
     ///
     /// * Opening a file that does not exist with `Read` access.
     /// * Attempting to open a file with a `FileAccess` that the user lacks
@@ -119,7 +121,7 @@ impl File {
     /// * Filesystem-level errors (full disk, etc)
     pub fn open_mode(path: &Path,
                      mode: FileMode,
-                     access: FileAccess) -> Option<File> {
+                     access: FileAccess) -> IoResult<File> {
         LocalIo::maybe_raise(|io| {
             io.fs_open(&path.to_c_str(), mode, access).map(|fd| {
                 File {
@@ -139,10 +141,12 @@ impl File {
     ///
     /// # Example
     ///
-    ///     use std::io::File;
+    /// ```rust
+    /// use std::io::File;
     ///
-    ///     let contents = File::open(&Path::new("foo.txt")).read_to_end();
-    pub fn open(path: &Path) -> Option<File> {
+    /// let contents = File::open(&Path::new("foo.txt")).read_to_end();
+    /// ```
+    pub fn open(path: &Path) -> IoResult<File> {
         File::open_mode(path, Open, Read)
     }
 
@@ -154,11 +158,16 @@ impl File {
     ///
     /// # Example
     ///
-    ///     use std::io::File;
+    /// ```rust
+    /// # #[allow(unused_must_use)];
+    /// use std::io::File;
     ///
-    ///     let mut f = File::create(&Path::new("foo.txt"));
-    ///     f.write(bytes!("This is a sample file"));
-    pub fn create(path: &Path) -> Option<File> {
+    /// let mut f = File::create(&Path::new("foo.txt"));
+    /// f.write(bytes!("This is a sample file"));
+    /// # drop(f);
+    /// # ::std::io::fs::unlink(&Path::new("foo.txt"));
+    /// ```
+    pub fn create(path: &Path) -> IoResult<File> {
         File::open_mode(path, Truncate, Write)
     }
 
@@ -170,24 +179,16 @@ impl File {
     /// Synchronizes all modifications to this file to its permanent storage
     /// device. This will flush any internal buffers necessary to perform this
     /// operation.
-    ///
-    /// # Errors
-    ///
-    /// This function will raise on the `io_error` condition on failure.
-    pub fn fsync(&mut self) {
-        let _ = self.fd.fsync().map_err(|e| io_error::cond.raise(e));
+    pub fn fsync(&mut self) -> IoResult<()> {
+        self.fd.fsync()
     }
 
     /// This function is similar to `fsync`, except that it may not synchronize
     /// file metadata to the filesystem. This is intended for use case which
     /// must synchronize content, but don't need the metadata on disk. The goal
     /// of this method is to reduce disk operations.
-    ///
-    /// # Errors
-    ///
-    /// This function will raise on the `io_error` condition on failure.
-    pub fn datasync(&mut self) {
-        let _ = self.fd.datasync().map_err(|e| io_error::cond.raise(e));
+    pub fn datasync(&mut self) -> IoResult<()> {
+        self.fd.datasync()
     }
 
     /// Either truncates or extends the underlying file, updating the size of
@@ -198,12 +199,8 @@ impl File {
     /// be shrunk. If it is greater than the current file's size, then the file
     /// will be extended to `size` and have all of the intermediate data filled
     /// in with 0s.
-    ///
-    /// # Errors
-    ///
-    /// On error, this function will raise on the `io_error` condition.
-    pub fn truncate(&mut self, size: i64) {
-        let _ = self.fd.truncate(size).map_err(|e| io_error::cond.raise(e));
+    pub fn truncate(&mut self, size: i64) -> IoResult<()> {
+        self.fd.truncate(size)
     }
 
     /// Tests whether this stream has reached EOF.
@@ -219,24 +216,25 @@ impl File {
 ///
 /// # Example
 ///
-///     use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io::fs;
 ///
-///     let p = Path::new("/some/file/path.txt");
-///     fs::unlink(&p);
-///     // if we made it here without failing, then the
-///     // unlink operation was successful
+/// let p = Path::new("/some/file/path.txt");
+/// fs::unlink(&p);
+/// ```
 ///
 /// Note that, just because an unlink call was successful, it is not
 /// guaranteed that a file is immediately deleted (e.g. depending on
 /// platform, other open file descriptors may prevent immediate removal)
 ///
-/// # Errors
+/// # Error
 ///
-/// This function will raise an `io_error` condition if the path points to a
-/// directory, the user lacks permissions to remove the file, or if some
-/// other filesystem-level error occurs.
-pub fn unlink(path: &Path) {
-    LocalIo::maybe_raise(|io| io.fs_unlink(&path.to_c_str()));
+/// This function will return an error if the path points to a directory, the
+/// user lacks permissions to remove the file, or if some other filesystem-level
+/// error occurs.
+pub fn unlink(path: &Path) -> IoResult<()> {
+    LocalIo::maybe_raise(|io| io.fs_unlink(&path.to_c_str()))
 }
 
 /// Given a path, query the file system to get information about a file,
@@ -249,48 +247,25 @@ pub fn unlink(path: &Path) {
 ///
 /// # Example
 ///
-///     use std::io;
-///     use std::io::fs;
+/// ```rust
+/// use std::io::fs;
 ///
-///     let p = Path::new("/some/file/path.txt");
-///     match io::result(|| fs::stat(&p)) {
-///         Ok(stat) => { /* ... */ }
-///         Err(e) => { /* handle error */ }
-///     }
+/// let p = Path::new("/some/file/path.txt");
+/// match fs::stat(&p) {
+///     Ok(stat) => { /* ... */ }
+///     Err(e) => { /* handle error */ }
+/// }
+/// ```
 ///
-/// # Errors
+/// # Error
 ///
-/// This call will raise an `io_error` condition if the user lacks the
-/// requisite permissions to perform a `stat` call on the given path or if
-/// there is no entry in the filesystem at the provided path.
-pub fn stat(path: &Path) -> FileStat {
+/// This call will return an error if the user lacks the requisite permissions
+/// to perform a `stat` call on the given path or if there is no entry in the
+/// filesystem at the provided path.
+pub fn stat(path: &Path) -> IoResult<FileStat> {
     LocalIo::maybe_raise(|io| {
         io.fs_stat(&path.to_c_str())
-    }).unwrap_or_else(dummystat)
-}
-
-fn dummystat() -> FileStat {
-    FileStat {
-        path: Path::new(""),
-        size: 0,
-        kind: io::TypeFile,
-        perm: 0,
-        created: 0,
-        modified: 0,
-        accessed: 0,
-        unstable: io::UnstableFileStat {
-            device: 0,
-            inode: 0,
-            rdev: 0,
-            nlink: 0,
-            uid: 0,
-            gid: 0,
-            blksize: 0,
-            blocks: 0,
-            flags: 0,
-            gen: 0,
-        }
-    }
+    })
 }
 
 /// Perform the same operation as the `stat` function, except that this
@@ -298,31 +273,33 @@ fn dummystat() -> FileStat {
 /// information about the symlink file instead of the file that it points
 /// to.
 ///
-/// # Errors
+/// # Error
 ///
 /// See `stat`
-pub fn lstat(path: &Path) -> FileStat {
+pub fn lstat(path: &Path) -> IoResult<FileStat> {
     LocalIo::maybe_raise(|io| {
         io.fs_lstat(&path.to_c_str())
-    }).unwrap_or_else(dummystat)
+    })
 }
 
 /// Rename a file or directory to a new name.
 ///
 /// # Example
 ///
-///     use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io::fs;
 ///
-///     fs::rename(&Path::new("foo"), &Path::new("bar"));
-///     // Oh boy, nothing was raised!
+/// fs::rename(&Path::new("foo"), &Path::new("bar"));
+/// ```
 ///
-/// # Errors
+/// # Error
 ///
-/// Will raise an `io_error` condition if the provided `path` doesn't exist,
-/// the process lacks permissions to view the contents, or if some other
-/// intermittent I/O error occurs.
-pub fn rename(from: &Path, to: &Path) {
-    LocalIo::maybe_raise(|io| io.fs_rename(&from.to_c_str(), &to.to_c_str()));
+/// Will return an error if the provided `path` doesn't exist, the process lacks
+/// permissions to view the contents, or if some other intermittent I/O error
+/// occurs.
+pub fn rename(from: &Path, to: &Path) -> IoResult<()> {
+    LocalIo::maybe_raise(|io| io.fs_rename(&from.to_c_str(), &to.to_c_str()))
 }
 
 /// Copies the contents of one file to another. This function will also
@@ -333,15 +310,17 @@ pub fn rename(from: &Path, to: &Path) {
 ///
 /// # Example
 ///
-///     use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io::fs;
 ///
-///     fs::copy(&Path::new("foo.txt"), &Path::new("bar.txt"));
-///     // Oh boy, nothing was raised!
+/// fs::copy(&Path::new("foo.txt"), &Path::new("bar.txt"));
+/// ```
 ///
-/// # Errors
+/// # Error
 ///
-/// Will raise an `io_error` condition is the following situations, but is
-/// not limited to just these cases:
+/// Will return an error in the following situations, but is not limited to
+/// just these cases:
 ///
 /// * The `from` path is not a file
 /// * The `from` file does not exist
@@ -351,27 +330,29 @@ pub fn rename(from: &Path, to: &Path) {
 /// Note that this copy is not atomic in that once the destination is
 /// ensured to not exist, there is nothing preventing the destination from
 /// being created and then destroyed by this operation.
-pub fn copy(from: &Path, to: &Path) {
+pub fn copy(from: &Path, to: &Path) -> IoResult<()> {
     if !from.is_file() {
-        return io_error::cond.raise(IoError {
+        return Err(IoError {
             kind: io::MismatchedFileTypeForOperation,
             desc: "the source path is not an existing file",
             detail: None,
-        });
+        })
     }
 
-    let mut reader = match File::open(from) { Some(f) => f, None => return };
-    let mut writer = match File::create(to) { Some(f) => f, None => return };
+    let mut reader = if_ok!(File::open(from));
+    let mut writer = if_ok!(File::create(to));
     let mut buf = [0, ..io::DEFAULT_BUF_SIZE];
 
     loop {
-        match reader.read(buf) {
-            Some(amt) => writer.write(buf.slice_to(amt)),
-            None => break
-        }
+        let amt = match reader.read(buf) {
+            Ok(n) => n,
+            Err(ref e) if e.kind == io::EndOfFile => { break }
+            Err(e) => return Err(e)
+        };
+        if_ok!(writer.write(buf.slice_to(amt)));
     }
 
-    chmod(to, from.stat().perm)
+    chmod(to, if_ok!(from.stat()).perm)
 }
 
 /// Changes the permission mode bits found on a file or a directory. This
@@ -379,61 +360,51 @@ pub fn copy(from: &Path, to: &Path) {
 ///
 /// # Example
 ///
-///     use std::io;
-///     use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io;
+/// use std::io::fs;
 ///
-///     fs::chmod(&Path::new("file.txt"), io::UserFile);
-///     fs::chmod(&Path::new("file.txt"), io::UserRead | io::UserWrite);
-///     fs::chmod(&Path::new("dir"),      io::UserDir);
-///     fs::chmod(&Path::new("file.exe"), io::UserExec);
+/// fs::chmod(&Path::new("file.txt"), io::UserFile);
+/// fs::chmod(&Path::new("file.txt"), io::UserRead | io::UserWrite);
+/// fs::chmod(&Path::new("dir"),      io::UserDir);
+/// fs::chmod(&Path::new("file.exe"), io::UserExec);
+/// ```
 ///
-/// # Errors
+/// # Error
 ///
-/// If this function encounters an I/O error, it will raise on the `io_error`
-/// condition. Some possible error situations are not having the permission to
+/// If this function encounters an I/O error, it will return an `Err` value.
+/// Some possible error situations are not having the permission to
 /// change the attributes of a file or the file not existing.
-pub fn chmod(path: &Path, mode: io::FilePermission) {
-    LocalIo::maybe_raise(|io| io.fs_chmod(&path.to_c_str(), mode));
+pub fn chmod(path: &Path, mode: io::FilePermission) -> IoResult<()> {
+    LocalIo::maybe_raise(|io| io.fs_chmod(&path.to_c_str(), mode))
 }
 
 /// Change the user and group owners of a file at the specified path.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition on failure.
-pub fn chown(path: &Path, uid: int, gid: int) {
-    LocalIo::maybe_raise(|io| io.fs_chown(&path.to_c_str(), uid, gid));
+pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> {
+    LocalIo::maybe_raise(|io| io.fs_chown(&path.to_c_str(), uid, gid))
 }
 
 /// Creates a new hard link on the filesystem. The `dst` path will be a
 /// link pointing to the `src` path. Note that systems often require these
 /// two paths to both be located on the same filesystem.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition on failure.
-pub fn link(src: &Path, dst: &Path) {
-    LocalIo::maybe_raise(|io| io.fs_link(&src.to_c_str(), &dst.to_c_str()));
+pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
+    LocalIo::maybe_raise(|io| io.fs_link(&src.to_c_str(), &dst.to_c_str()))
 }
 
 /// Creates a new symbolic link on the filesystem. The `dst` path will be a
 /// symlink pointing to the `src` path.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition on failure.
-pub fn symlink(src: &Path, dst: &Path) {
-    LocalIo::maybe_raise(|io| io.fs_symlink(&src.to_c_str(), &dst.to_c_str()));
+pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
+    LocalIo::maybe_raise(|io| io.fs_symlink(&src.to_c_str(), &dst.to_c_str()))
 }
 
 /// Reads a symlink, returning the file that the symlink points to.
 ///
-/// # Errors
+/// # Error
 ///
-/// This function will raise on the `io_error` condition on failure. Failure
-/// conditions include reading a file that does not exist or reading a file
-/// which is not a symlink.
-pub fn readlink(path: &Path) -> Option<Path> {
+/// This function will return an error on failure. Failure conditions include
+/// reading a file that does not exist or reading a file which is not a symlink.
+pub fn readlink(path: &Path) -> IoResult<Path> {
     LocalIo::maybe_raise(|io| io.fs_readlink(&path.to_c_str()))
 }
 
@@ -441,75 +412,85 @@ pub fn readlink(path: &Path) -> Option<Path> {
 ///
 /// # Example
 ///
-///     use std::libc::S_IRWXU;
-///     use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io;
+/// use std::io::fs;
 ///
-///     let p = Path::new("/some/dir");
-///     fs::mkdir(&p, S_IRWXU as int);
-///     // If we got here, our directory exists! Hooray!
+/// let p = Path::new("/some/dir");
+/// fs::mkdir(&p, io::UserRWX);
+/// ```
 ///
-/// # Errors
+/// # Error
 ///
-/// This call will raise an `io_error` condition if the user lacks permissions
-/// to make a new directory at the provided path, or if the directory already
-/// exists.
-pub fn mkdir(path: &Path, mode: FilePermission) {
-    LocalIo::maybe_raise(|io| io.fs_mkdir(&path.to_c_str(), mode));
+/// This call will return an error if the user lacks permissions to make a new
+/// directory at the provided path, or if the directory already exists.
+pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> {
+    LocalIo::maybe_raise(|io| io.fs_mkdir(&path.to_c_str(), mode))
 }
 
 /// Remove an existing, empty directory
 ///
 /// # Example
 ///
-///     use std::io::fs;
+/// ```rust
+/// # #[allow(unused_must_use)];
+/// use std::io::fs;
 ///
-///     let p = Path::new("/some/dir");
-///     fs::rmdir(&p);
-///     // good riddance, you mean ol' directory
+/// let p = Path::new("/some/dir");
+/// fs::rmdir(&p);
+/// ```
 ///
-/// # Errors
+/// # Error
 ///
-/// This call will raise an `io_error` condition if the user lacks permissions
-/// to remove the directory at the provided path, or if the directory isn't
-/// empty.
-pub fn rmdir(path: &Path) {
-    LocalIo::maybe_raise(|io| io.fs_rmdir(&path.to_c_str()));
+/// This call will return an error if the user lacks permissions to remove the
+/// directory at the provided path, or if the directory isn't empty.
+pub fn rmdir(path: &Path) -> IoResult<()> {
+    LocalIo::maybe_raise(|io| io.fs_rmdir(&path.to_c_str()))
 }
 
 /// Retrieve a vector containing all entries within a provided directory
 ///
 /// # Example
 ///
-///     use std::io::fs;
-///
-///     // one possible implementation of fs::walk_dir only visiting files
-///     fn visit_dirs(dir: &Path, cb: |&Path|) {
-///         if dir.is_dir() {
-///             let contents = fs::readdir(dir).unwrap();
-///             for entry in contents.iter() {
-///                 if entry.is_dir() { visit_dirs(entry, cb); }
-///                 else { cb(entry); }
+/// ```rust
+/// use std::io;
+/// use std::io::fs;
+///
+/// // one possible implementation of fs::walk_dir only visiting files
+/// fn visit_dirs(dir: &Path, cb: |&Path|) -> io::IoResult<()> {
+///     if dir.is_dir() {
+///         let contents = if_ok!(fs::readdir(dir));
+///         for entry in contents.iter() {
+///             if entry.is_dir() {
+///                 if_ok!(visit_dirs(entry, |p| cb(p)));
+///             } else {
+///                 cb(entry);
 ///             }
 ///         }
-///         else { fail!("nope"); }
+///         Ok(())
+///     } else {
+///         Err(io::standard_error(io::InvalidInput))
 ///     }
+/// }
+/// ```
 ///
-/// # Errors
+/// # Error
 ///
-/// Will raise an `io_error` condition if the provided `from` doesn't exist,
-/// the process lacks permissions to view the contents or if the `path` points
-/// at a non-directory file
-pub fn readdir(path: &Path) -> ~[Path] {
+/// Will return an error if the provided `from` doesn't exist, the process lacks
+/// permissions to view the contents or if the `path` points at a non-directory
+/// file
+pub fn readdir(path: &Path) -> IoResult<~[Path]> {
     LocalIo::maybe_raise(|io| {
         io.fs_readdir(&path.to_c_str(), 0)
-    }).unwrap_or_else(|| ~[])
+    })
 }
 
 /// Returns an iterator which will recursively walk the directory structure
 /// rooted at `path`. The path given will not be iterated over, and this will
 /// perform iteration in a top-down order.
-pub fn walk_dir(path: &Path) -> Directories {
-    Directories { stack: readdir(path) }
+pub fn walk_dir(path: &Path) -> IoResult<Directories> {
+    Ok(Directories { stack: if_ok!(readdir(path)) })
 }
 
 /// An iterator which walks over a directory
@@ -522,7 +503,10 @@ impl Iterator<Path> for Directories {
         match self.stack.shift() {
             Some(path) => {
                 if path.is_dir() {
-                    self.stack.push_all_move(readdir(&path));
+                    match readdir(&path) {
+                        Ok(dirs) => { self.stack.push_all_move(dirs); }
+                        Err(..) => {}
+                    }
                 }
                 Some(path)
             }
@@ -534,19 +518,18 @@ impl Iterator<Path> for Directories {
 /// Recursively create a directory and all of its parent components if they
 /// are missing.
 ///
-/// # Errors
+/// # Error
 ///
-/// This function will raise on the `io_error` condition if an error
-/// happens, see `fs::mkdir` for more information about error conditions
-/// and performance.
-pub fn mkdir_recursive(path: &Path, mode: FilePermission) {
+/// This function will return an `Err` value if an error happens, see
+/// `fs::mkdir` for more information about error conditions and performance.
+pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> {
     // tjc: if directory exists but with different permissions,
     // should we return false?
     if path.is_dir() {
-        return
+        return Ok(())
     }
     if path.filename().is_some() {
-        mkdir_recursive(&path.dir_path(), mode);
+        if_ok!(mkdir_recursive(&path.dir_path(), mode));
     }
     mkdir(path, mode)
 }
@@ -554,92 +537,64 @@ pub fn mkdir_recursive(path: &Path, mode: FilePermission) {
 /// Removes a directory at this path, after removing all its contents. Use
 /// carefully!
 ///
-/// # Errors
+/// # Error
 ///
-/// This function will raise on the `io_error` condition if an error
-/// happens. See `file::unlink` and `fs::readdir` for possible error
-/// conditions.
-pub fn rmdir_recursive(path: &Path) {
-    let children = readdir(path);
+/// This function will return an `Err` value if an error happens. See
+/// `file::unlink` and `fs::readdir` for possible error conditions.
+pub fn rmdir_recursive(path: &Path) -> IoResult<()> {
+    let children = if_ok!(readdir(path));
     for child in children.iter() {
         if child.is_dir() {
-            rmdir_recursive(child);
+            if_ok!(rmdir_recursive(child));
         } else {
-            unlink(child);
+            if_ok!(unlink(child));
         }
     }
     // Directory should now be empty
-    rmdir(path);
+    rmdir(path)
 }
 
 /// Changes the timestamps for a file's last modification and access time.
 /// The file at the path specified will have its last access time set to
 /// `atime` and its modification time set to `mtime`. The times specified should
 /// be in milliseconds.
-///
-/// # Errors
-///
-/// This function will raise on the `io_error` condition if an error
-/// happens.
 // FIXME(#10301) these arguments should not be u64
-pub fn change_file_times(path: &Path, atime: u64, mtime: u64) {
-    LocalIo::maybe_raise(|io| io.fs_utime(&path.to_c_str(), atime, mtime));
+pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> {
+    LocalIo::maybe_raise(|io| io.fs_utime(&path.to_c_str(), atime, mtime))
 }
 
 impl Reader for File {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         match self.fd.read(buf) {
             Ok(read) => {
                 self.last_nread = read;
                 match read {
-                    0 => None,
-                    _ => Some(read as uint)
+                    0 => Err(io::standard_error(io::EndOfFile)),
+                    _ => Ok(read as uint)
                 }
             },
-            Err(ioerr) => {
-                // EOF is indicated by returning None
-                if ioerr.kind != io::EndOfFile {
-                    io_error::cond.raise(ioerr);
-                }
-                return None;
-            }
+            Err(e) => Err(e),
         }
     }
 }
 
 impl Writer for File {
-    fn write(&mut self, buf: &[u8]) {
-        match self.fd.write(buf) {
-            Ok(()) => (),
-            Err(ioerr) => {
-                io_error::cond.raise(ioerr);
-            }
-        }
-    }
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.fd.write(buf) }
 }
 
 impl Seek for File {
-    fn tell(&self) -> u64 {
-        let res = self.fd.tell();
-        match res {
-            Ok(cursor) => cursor,
-            Err(ioerr) => {
-                io_error::cond.raise(ioerr);
-                return -1;
-            }
-        }
+    fn tell(&self) -> IoResult<u64> {
+        self.fd.tell()
     }
 
-    fn seek(&mut self, pos: i64, style: SeekStyle) {
+    fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
         match self.fd.seek(pos, style) {
             Ok(_) => {
                 // successful seek resets EOF indicator
                 self.last_nread = -1;
-                ()
-            },
-            Err(ioerr) => {
-                io_error::cond.raise(ioerr);
+                Ok(())
             }
+            Err(e) => Err(e),
         }
     }
 }
@@ -650,17 +605,17 @@ impl path::Path {
     /// Consult the `file::stat` documentation for more info.
     ///
     /// This call preserves identical runtime/error semantics with `file::stat`.
-    pub fn stat(&self) -> FileStat { stat(self) }
+    pub fn stat(&self) -> IoResult<FileStat> { stat(self) }
 
     /// Boolean value indicator whether the underlying file exists on the local
     /// filesystem. This will return true if the path points to either a
     /// directory or a file.
     ///
-    /// # Errors
+    /// # Error
     ///
     /// Will not raise a condition
     pub fn exists(&self) -> bool {
-        io::result(|| self.stat()).is_ok()
+        self.stat().is_ok()
     }
 
     /// Whether the underlying implementation (be it a file path, or something
@@ -668,11 +623,11 @@ impl path::Path {
     /// to non-existent locations or directories or other non-regular files
     /// (named pipes, etc).
     ///
-    /// # Errors
+    /// # Error
     ///
     /// Will not raise a condition
     pub fn is_file(&self) -> bool {
-        match io::result(|| self.stat()) {
+        match self.stat() {
             Ok(s) => s.kind == io::TypeFile,
             Err(..) => false
         }
@@ -683,11 +638,11 @@ impl path::Path {
     /// Will return false for paths to non-existent locations or if the item is
     /// not a directory (eg files, named pipes, links, etc)
     ///
-    /// # Errors
+    /// # Error
     ///
     /// Will not raise a condition
     pub fn is_dir(&self) -> bool {
-        match io::result(|| self.stat()) {
+        match self.stat() {
             Ok(s) => s.kind == io::TypeDirectory,
             Err(..) => false
         }
@@ -698,8 +653,7 @@ impl path::Path {
 #[allow(unused_imports)]
 mod test {
     use prelude::*;
-    use io::{SeekSet, SeekCur, SeekEnd, io_error, Read, Open,
-             ReadWrite};
+    use io::{SeekSet, SeekCur, SeekEnd, Read, Open, ReadWrite};
     use io;
     use str;
     use io::fs::{File, rmdir, mkdir, readdir, rmdir_recursive,
@@ -729,7 +683,7 @@ mod test {
             // Gee, seeing how we're testing the fs module I sure hope that we
             // at least implement this correctly!
             let TempDir(ref p) = *self;
-            io::fs::rmdir_recursive(p);
+            io::fs::rmdir_recursive(p).unwrap();
         }
     }
 
@@ -737,7 +691,7 @@ mod test {
         use os;
         use rand;
         let ret = os::tmpdir().join(format!("rust-{}", rand::random::<u32>()));
-        io::fs::mkdir(&ret, io::UserRWX);
+        io::fs::mkdir(&ret, io::UserRWX).unwrap();
         TempDir(ret)
     }
 
@@ -747,7 +701,7 @@ mod test {
         let filename = &tmpdir.join("file_rt_io_file_test.txt");
         {
             let mut write_stream = File::open_mode(filename, Open, ReadWrite);
-            write_stream.write(message.as_bytes());
+            write_stream.write(message.as_bytes()).unwrap();
         }
         {
             let mut read_stream = File::open_mode(filename, Open, Read);
@@ -758,30 +712,20 @@ mod test {
             };
             assert_eq!(read_str, message.to_owned());
         }
-        unlink(filename);
+        unlink(filename).unwrap();
     })
 
     iotest!(fn invalid_path_raises() {
         let tmpdir = tmpdir();
         let filename = &tmpdir.join("file_that_does_not_exist.txt");
-        let mut called = false;
-        io_error::cond.trap(|_| {
-            called = true;
-        }).inside(|| {
-            let result = File::open_mode(filename, Open, Read);
-            assert!(result.is_none());
-        });
-        assert!(called);
+        let result = File::open_mode(filename, Open, Read);
+        assert!(result.is_err());
     })
 
     iotest!(fn file_test_iounlinking_invalid_path_should_raise_condition() {
         let tmpdir = tmpdir();
         let filename = &tmpdir.join("file_another_file_that_does_not_exist.txt");
-        let mut called = false;
-        io_error::cond.trap(|_| {
-            called = true;
-        }).inside(|| unlink(filename));
-        assert!(called);
+        assert!(unlink(filename).is_err());
     })
 
     iotest!(fn file_test_io_non_positional_read() {
@@ -791,20 +735,20 @@ mod test {
         let filename = &tmpdir.join("file_rt_io_file_test_positional.txt");
         {
             let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
-            rw_stream.write(message.as_bytes());
+            rw_stream.write(message.as_bytes()).unwrap();
         }
         {
             let mut read_stream = File::open_mode(filename, Open, Read);
             {
                 let read_buf = read_mem.mut_slice(0, 4);
-                read_stream.read(read_buf);
+                read_stream.read(read_buf).unwrap();
             }
             {
                 let read_buf = read_mem.mut_slice(4, 8);
-                read_stream.read(read_buf);
+                read_stream.read(read_buf).unwrap();
             }
         }
-        unlink(filename);
+        unlink(filename).unwrap();
         let read_str = str::from_utf8(read_mem).unwrap();
         assert_eq!(read_str, message);
     })
@@ -819,16 +763,16 @@ mod test {
         let filename = &tmpdir.join("file_rt_io_file_test_seeking.txt");
         {
             let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
-            rw_stream.write(message.as_bytes());
+            rw_stream.write(message.as_bytes()).unwrap();
         }
         {
             let mut read_stream = File::open_mode(filename, Open, Read);
-            read_stream.seek(set_cursor as i64, SeekSet);
-            tell_pos_pre_read = read_stream.tell();
-            read_stream.read(read_mem);
-            tell_pos_post_read = read_stream.tell();
+            read_stream.seek(set_cursor as i64, SeekSet).unwrap();
+            tell_pos_pre_read = read_stream.tell().unwrap();
+            read_stream.read(read_mem).unwrap();
+            tell_pos_post_read = read_stream.tell().unwrap();
         }
-        unlink(filename);
+        unlink(filename).unwrap();
         let read_str = str::from_utf8(read_mem).unwrap();
         assert_eq!(read_str, message.slice(4, 8));
         assert_eq!(tell_pos_pre_read, set_cursor);
@@ -845,15 +789,15 @@ mod test {
         let filename = &tmpdir.join("file_rt_io_file_test_seek_and_write.txt");
         {
             let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
-            rw_stream.write(initial_msg.as_bytes());
-            rw_stream.seek(seek_idx as i64, SeekSet);
-            rw_stream.write(overwrite_msg.as_bytes());
+            rw_stream.write(initial_msg.as_bytes()).unwrap();
+            rw_stream.seek(seek_idx as i64, SeekSet).unwrap();
+            rw_stream.write(overwrite_msg.as_bytes()).unwrap();
         }
         {
             let mut read_stream = File::open_mode(filename, Open, Read);
-            read_stream.read(read_mem);
+            read_stream.read(read_mem).unwrap();
         }
-        unlink(filename);
+        unlink(filename).unwrap();
         let read_str = str::from_utf8(read_mem).unwrap();
         assert!(read_str == final_msg.to_owned());
     })
@@ -869,24 +813,24 @@ mod test {
         let filename = &tmpdir.join("file_rt_io_file_test_seek_shakedown.txt");
         {
             let mut rw_stream = File::open_mode(filename, Open, ReadWrite);
-            rw_stream.write(initial_msg.as_bytes());
+            rw_stream.write(initial_msg.as_bytes()).unwrap();
         }
         {
             let mut read_stream = File::open_mode(filename, Open, Read);
 
-            read_stream.seek(-4, SeekEnd);
-            read_stream.read(read_mem);
+            read_stream.seek(-4, SeekEnd).unwrap();
+            read_stream.read(read_mem).unwrap();
             assert_eq!(str::from_utf8(read_mem).unwrap(), chunk_three);
 
-            read_stream.seek(-9, SeekCur);
-            read_stream.read(read_mem);
+            read_stream.seek(-9, SeekCur).unwrap();
+            read_stream.read(read_mem).unwrap();
             assert_eq!(str::from_utf8(read_mem).unwrap(), chunk_two);
 
-            read_stream.seek(0, SeekSet);
-            read_stream.read(read_mem);
+            read_stream.seek(0, SeekSet).unwrap();
+            read_stream.read(read_mem).unwrap();
             assert_eq!(str::from_utf8(read_mem).unwrap(), chunk_one);
         }
-        unlink(filename);
+        unlink(filename).unwrap();
     })
 
     iotest!(fn file_test_stat_is_correct_on_is_file() {
@@ -895,36 +839,36 @@ mod test {
         {
             let mut fs = File::open_mode(filename, Open, ReadWrite);
             let msg = "hw";
-            fs.write(msg.as_bytes());
+            fs.write(msg.as_bytes()).unwrap();
         }
-        let stat_res = stat(filename);
+        let stat_res = stat(filename).unwrap();
         assert_eq!(stat_res.kind, io::TypeFile);
-        unlink(filename);
+        unlink(filename).unwrap();
     })
 
     iotest!(fn file_test_stat_is_correct_on_is_dir() {
         let tmpdir = tmpdir();
         let filename = &tmpdir.join("file_stat_correct_on_is_dir");
-        mkdir(filename, io::UserRWX);
-        let stat_res = filename.stat();
+        mkdir(filename, io::UserRWX).unwrap();
+        let stat_res = filename.stat().unwrap();
         assert!(stat_res.kind == io::TypeDirectory);
-        rmdir(filename);
+        rmdir(filename).unwrap();
     })
 
     iotest!(fn file_test_fileinfo_false_when_checking_is_file_on_a_directory() {
         let tmpdir = tmpdir();
         let dir = &tmpdir.join("fileinfo_false_on_dir");
-        mkdir(dir, io::UserRWX);
+        mkdir(dir, io::UserRWX).unwrap();
         assert!(dir.is_file() == false);
-        rmdir(dir);
+        rmdir(dir).unwrap();
     })
 
     iotest!(fn file_test_fileinfo_check_exists_before_and_after_file_creation() {
         let tmpdir = tmpdir();
         let file = &tmpdir.join("fileinfo_check_exists_b_and_a.txt");
-        File::create(file).write(bytes!("foo"));
+        File::create(file).write(bytes!("foo")).unwrap();
         assert!(file.exists());
-        unlink(file);
+        unlink(file).unwrap();
         assert!(!file.exists());
     })
 
@@ -932,10 +876,10 @@ mod test {
         let tmpdir = tmpdir();
         let dir = &tmpdir.join("before_and_after_dir");
         assert!(!dir.exists());
-        mkdir(dir, io::UserRWX);
+        mkdir(dir, io::UserRWX).unwrap();
         assert!(dir.exists());
         assert!(dir.is_dir());
-        rmdir(dir);
+        rmdir(dir).unwrap();
         assert!(!dir.exists());
     })
 
@@ -943,21 +887,21 @@ mod test {
         use std::str;
         let tmpdir = tmpdir();
         let dir = &tmpdir.join("di_readdir");
-        mkdir(dir, io::UserRWX);
+        mkdir(dir, io::UserRWX).unwrap();
         let prefix = "foo";
         for n in range(0,3) {
             let f = dir.join(format!("{}.txt", n));
-            let mut w = File::create(&f);
+            let mut w = File::create(&f).unwrap();
             let msg_str = (prefix + n.to_str().to_owned()).to_owned();
             let msg = msg_str.as_bytes();
-            w.write(msg);
+            w.write(msg).unwrap();
         }
-        let files = readdir(dir);
+        let files = readdir(dir).unwrap();
         let mut mem = [0u8, .. 4];
         for f in files.iter() {
             {
                 let n = f.filestem_str();
-                File::open(f).read(mem);
+                File::open(f).read(mem).unwrap();
                 let read_str = str::from_utf8(mem).unwrap();
                 let expected = match n {
                     None|Some("") => fail!("really shouldn't happen.."),
@@ -965,13 +909,13 @@ mod test {
                 };
                 assert_eq!(expected.as_slice(), read_str);
             }
-            unlink(f);
+            unlink(f).unwrap();
         }
-        rmdir(dir);
+        rmdir(dir).unwrap();
     })
 
     iotest!(fn recursive_mkdir_slash() {
-        mkdir_recursive(&Path::new("/"), io::UserRWX);
+        mkdir_recursive(&Path::new("/"), io::UserRWX).unwrap();
     })
 
     iotest!(fn unicode_path_is_dir() {
@@ -982,12 +926,12 @@ mod test {
 
         let mut dirpath = tmpdir.path().clone();
         dirpath.push(format!("test-가一ー你好"));
-        mkdir(&dirpath, io::UserRWX);
+        mkdir(&dirpath, io::UserRWX).unwrap();
         assert!(dirpath.is_dir());
 
         let mut filepath = dirpath;
         filepath.push("unicode-file-\uac00\u4e00\u30fc\u4f60\u597d.rs");
-        File::create(&filepath); // ignore return; touch only
+        File::create(&filepath).unwrap(); // ignore return; touch only
         assert!(!filepath.is_dir());
         assert!(filepath.exists());
     })
@@ -999,7 +943,7 @@ mod test {
         let tmpdir = tmpdir();
         let unicode = tmpdir.path();
         let unicode = unicode.join(format!("test-각丁ー再见"));
-        mkdir(&unicode, io::UserRWX);
+        mkdir(&unicode, io::UserRWX).unwrap();
         assert!(unicode.exists());
         assert!(!Path::new("test/unicode-bogus-path-각丁ー再见").exists());
     })
@@ -1007,7 +951,7 @@ mod test {
     iotest!(fn copy_file_does_not_exist() {
         let from = Path::new("test/nonexistent-bogus-path");
         let to = Path::new("test/other-bogus-path");
-        match io::result(|| copy(&from, &to)) {
+        match copy(&from, &to) {
             Ok(..) => fail!(),
             Err(..) => {
                 assert!(!from.exists());
@@ -1021,20 +965,20 @@ mod test {
         let input = tmpdir.join("in.txt");
         let out = tmpdir.join("out.txt");
 
-        File::create(&input).write(bytes!("hello"));
-        copy(&input, &out);
-        let contents = File::open(&out).read_to_end();
+        File::create(&input).write(bytes!("hello")).unwrap();
+        copy(&input, &out).unwrap();
+        let contents = File::open(&out).read_to_end().unwrap();
         assert_eq!(contents.as_slice(), bytes!("hello"));
 
-        assert_eq!(input.stat().perm, out.stat().perm);
+        assert_eq!(input.stat().unwrap().perm, out.stat().unwrap().perm);
     })
 
     iotest!(fn copy_file_dst_dir() {
         let tmpdir = tmpdir();
         let out = tmpdir.join("out");
 
-        File::create(&out);
-        match io::result(|| copy(&out, tmpdir.path())) {
+        File::create(&out).unwrap();
+        match copy(&out, tmpdir.path()) {
             Ok(..) => fail!(), Err(..) => {}
         }
     })
@@ -1044,11 +988,11 @@ mod test {
         let input = tmpdir.join("in");
         let output = tmpdir.join("out");
 
-        File::create(&input).write("foo".as_bytes());
-        File::create(&output).write("bar".as_bytes());
-        copy(&input, &output);
+        File::create(&input).write("foo".as_bytes()).unwrap();
+        File::create(&output).write("bar".as_bytes()).unwrap();
+        copy(&input, &output).unwrap();
 
-        assert_eq!(File::open(&output).read_to_end(),
+        assert_eq!(File::open(&output).read_to_end().unwrap(),
                    (bytes!("foo")).to_owned());
     })
 
@@ -1056,7 +1000,7 @@ mod test {
         let tmpdir = tmpdir();
         let out = tmpdir.join("out");
 
-        match io::result(|| copy(tmpdir.path(), &out)) {
+        match copy(tmpdir.path(), &out) {
             Ok(..) => fail!(), Err(..) => {}
         }
         assert!(!out.exists());
@@ -1067,13 +1011,13 @@ mod test {
         let input = tmpdir.join("in.txt");
         let out = tmpdir.join("out.txt");
 
-        File::create(&input);
-        chmod(&input, io::UserRead);
-        copy(&input, &out);
-        assert!(out.stat().perm & io::UserWrite == 0);
+        File::create(&input).unwrap();
+        chmod(&input, io::UserRead).unwrap();
+        copy(&input, &out).unwrap();
+        assert!(out.stat().unwrap().perm & io::UserWrite == 0);
 
-        chmod(&input, io::UserFile);
-        chmod(&out, io::UserFile);
+        chmod(&input, io::UserFile).unwrap();
+        chmod(&out, io::UserFile).unwrap();
     })
 
     #[cfg(not(windows))] // FIXME(#10264) operation not permitted?
@@ -1082,26 +1026,27 @@ mod test {
         let input = tmpdir.join("in.txt");
         let out = tmpdir.join("out.txt");
 
-        File::create(&input).write("foobar".as_bytes());
-        symlink(&input, &out);
+        File::create(&input).write("foobar".as_bytes()).unwrap();
+        symlink(&input, &out).unwrap();
         if cfg!(not(windows)) {
-            assert_eq!(lstat(&out).kind, io::TypeSymlink);
+            assert_eq!(lstat(&out).unwrap().kind, io::TypeSymlink);
         }
-        assert_eq!(stat(&out).size, stat(&input).size);
-        assert_eq!(File::open(&out).read_to_end(), (bytes!("foobar")).to_owned());
+        assert_eq!(stat(&out).unwrap().size, stat(&input).unwrap().size);
+        assert_eq!(File::open(&out).read_to_end().unwrap(),
+                   (bytes!("foobar")).to_owned());
     })
 
     #[cfg(not(windows))] // apparently windows doesn't like symlinks
     iotest!(fn symlink_noexist() {
         let tmpdir = tmpdir();
         // symlinks can point to things that don't exist
-        symlink(&tmpdir.join("foo"), &tmpdir.join("bar"));
+        symlink(&tmpdir.join("foo"), &tmpdir.join("bar")).unwrap();
         assert!(readlink(&tmpdir.join("bar")).unwrap() == tmpdir.join("foo"));
     })
 
     iotest!(fn readlink_not_symlink() {
         let tmpdir = tmpdir();
-        match io::result(|| readlink(tmpdir.path())) {
+        match readlink(tmpdir.path()) {
             Ok(..) => fail!("wanted a failure"),
             Err(..) => {}
         }
@@ -1112,22 +1057,23 @@ mod test {
         let input = tmpdir.join("in.txt");
         let out = tmpdir.join("out.txt");
 
-        File::create(&input).write("foobar".as_bytes());
-        link(&input, &out);
+        File::create(&input).write("foobar".as_bytes()).unwrap();
+        link(&input, &out).unwrap();
         if cfg!(not(windows)) {
-            assert_eq!(lstat(&out).kind, io::TypeFile);
-            assert_eq!(stat(&out).unstable.nlink, 2);
+            assert_eq!(lstat(&out).unwrap().kind, io::TypeFile);
+            assert_eq!(stat(&out).unwrap().unstable.nlink, 2);
         }
-        assert_eq!(stat(&out).size, stat(&input).size);
-        assert_eq!(File::open(&out).read_to_end(), (bytes!("foobar")).to_owned());
+        assert_eq!(stat(&out).unwrap().size, stat(&input).unwrap().size);
+        assert_eq!(File::open(&out).read_to_end().unwrap(),
+                   (bytes!("foobar")).to_owned());
 
         // can't link to yourself
-        match io::result(|| link(&input, &input)) {
+        match link(&input, &input) {
             Ok(..) => fail!("wanted a failure"),
             Err(..) => {}
         }
         // can't link to something that doesn't exist
-        match io::result(|| link(&tmpdir.join("foo"), &tmpdir.join("bar"))) {
+        match link(&tmpdir.join("foo"), &tmpdir.join("bar")) {
             Ok(..) => fail!("wanted a failure"),
             Err(..) => {}
         }
@@ -1137,17 +1083,17 @@ mod test {
         let tmpdir = tmpdir();
         let file = tmpdir.join("in.txt");
 
-        File::create(&file);
-        assert!(stat(&file).perm & io::UserWrite == io::UserWrite);
-        chmod(&file, io::UserRead);
-        assert!(stat(&file).perm & io::UserWrite == 0);
+        File::create(&file).unwrap();
+        assert!(stat(&file).unwrap().perm & io::UserWrite == io::UserWrite);
+        chmod(&file, io::UserRead).unwrap();
+        assert!(stat(&file).unwrap().perm & io::UserWrite == 0);
 
-        match io::result(|| chmod(&tmpdir.join("foo"), io::UserRWX)) {
+        match chmod(&tmpdir.join("foo"), io::UserRWX) {
             Ok(..) => fail!("wanted a failure"),
             Err(..) => {}
         }
 
-        chmod(&file, io::UserFile);
+        chmod(&file, io::UserFile).unwrap();
     })
 
     iotest!(fn sync_doesnt_kill_anything() {
@@ -1155,11 +1101,11 @@ mod test {
         let path = tmpdir.join("in.txt");
 
         let mut file = File::open_mode(&path, io::Open, io::ReadWrite).unwrap();
-        file.fsync();
-        file.datasync();
-        file.write(bytes!("foo"));
-        file.fsync();
-        file.datasync();
+        file.fsync().unwrap();
+        file.datasync().unwrap();
+        file.write(bytes!("foo")).unwrap();
+        file.fsync().unwrap();
+        file.datasync().unwrap();
         drop(file);
     })
 
@@ -1168,28 +1114,28 @@ mod test {
         let path = tmpdir.join("in.txt");
 
         let mut file = File::open_mode(&path, io::Open, io::ReadWrite).unwrap();
-        file.write(bytes!("foo"));
-        file.fsync();
+        file.write(bytes!("foo")).unwrap();
+        file.fsync().unwrap();
 
         // Do some simple things with truncation
-        assert_eq!(stat(&path).size, 3);
-        file.truncate(10);
-        assert_eq!(stat(&path).size, 10);
-        file.write(bytes!("bar"));
-        file.fsync();
-        assert_eq!(stat(&path).size, 10);
-        assert_eq!(File::open(&path).read_to_end(),
+        assert_eq!(stat(&path).unwrap().size, 3);
+        file.truncate(10).unwrap();
+        assert_eq!(stat(&path).unwrap().size, 10);
+        file.write(bytes!("bar")).unwrap();
+        file.fsync().unwrap();
+        assert_eq!(stat(&path).unwrap().size, 10);
+        assert_eq!(File::open(&path).read_to_end().unwrap(),
                    (bytes!("foobar", 0, 0, 0, 0)).to_owned());
 
         // Truncate to a smaller length, don't seek, and then write something.
         // Ensure that the intermediate zeroes are all filled in (we're seeked
         // past the end of the file).
-        file.truncate(2);
-        assert_eq!(stat(&path).size, 2);
-        file.write(bytes!("wut"));
-        file.fsync();
-        assert_eq!(stat(&path).size, 9);
-        assert_eq!(File::open(&path).read_to_end(),
+        file.truncate(2).unwrap();
+        assert_eq!(stat(&path).unwrap().size, 2);
+        file.write(bytes!("wut")).unwrap();
+        file.fsync().unwrap();
+        assert_eq!(stat(&path).unwrap().size, 9);
+        assert_eq!(File::open(&path).read_to_end().unwrap(),
                    (bytes!("fo", 0, 0, 0, 0, "wut")).to_owned());
         drop(file);
     })
@@ -1197,8 +1143,7 @@ mod test {
     iotest!(fn open_flavors() {
         let tmpdir = tmpdir();
 
-        match io::result(|| File::open_mode(&tmpdir.join("a"), io::Open,
-                                            io::Read)) {
+        match File::open_mode(&tmpdir.join("a"), io::Open, io::Read) {
             Ok(..) => fail!(), Err(..) => {}
         }
         File::open_mode(&tmpdir.join("b"), io::Open, io::Write).unwrap();
@@ -1208,46 +1153,46 @@ mod test {
         File::open_mode(&tmpdir.join("f"), io::Truncate, io::Write).unwrap();
         File::open_mode(&tmpdir.join("g"), io::Truncate, io::ReadWrite).unwrap();
 
-        File::create(&tmpdir.join("h")).write("foo".as_bytes());
+        File::create(&tmpdir.join("h")).write("foo".as_bytes()).unwrap();
         File::open_mode(&tmpdir.join("h"), io::Open, io::Read).unwrap();
         {
             let mut f = File::open_mode(&tmpdir.join("h"), io::Open,
                                         io::Read).unwrap();
-            match io::result(|| f.write("wut".as_bytes())) {
+            match f.write("wut".as_bytes()) {
                 Ok(..) => fail!(), Err(..) => {}
             }
         }
-        assert_eq!(stat(&tmpdir.join("h")).size, 3);
+        assert_eq!(stat(&tmpdir.join("h")).unwrap().size, 3);
         {
             let mut f = File::open_mode(&tmpdir.join("h"), io::Append,
                                         io::Write).unwrap();
-            f.write("bar".as_bytes());
+            f.write("bar".as_bytes()).unwrap();
         }
-        assert_eq!(stat(&tmpdir.join("h")).size, 6);
+        assert_eq!(stat(&tmpdir.join("h")).unwrap().size, 6);
         {
             let mut f = File::open_mode(&tmpdir.join("h"), io::Truncate,
                                         io::Write).unwrap();
-            f.write("bar".as_bytes());
+            f.write("bar".as_bytes()).unwrap();
         }
-        assert_eq!(stat(&tmpdir.join("h")).size, 3);
+        assert_eq!(stat(&tmpdir.join("h")).unwrap().size, 3);
     })
 
     #[test]
     fn utime() {
         let tmpdir = tmpdir();
         let path = tmpdir.join("a");
-        File::create(&path);
+        File::create(&path).unwrap();
 
-        change_file_times(&path, 1000, 2000);
-        assert_eq!(path.stat().accessed, 1000);
-        assert_eq!(path.stat().modified, 2000);
+        change_file_times(&path, 1000, 2000).unwrap();
+        assert_eq!(path.stat().unwrap().accessed, 1000);
+        assert_eq!(path.stat().unwrap().modified, 2000);
     }
 
     #[test]
     fn utime_noexist() {
         let tmpdir = tmpdir();
 
-        match io::result(|| change_file_times(&tmpdir.join("a"), 100, 200)) {
+        match change_file_times(&tmpdir.join("a"), 100, 200) {
             Ok(..) => fail!(),
             Err(..) => {}
         }
diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs
index c185951feca..395ece17ede 100644
--- a/src/libstd/io/mem.rs
+++ b/src/libstd/io/mem.rs
@@ -13,9 +13,10 @@
 use cmp::max;
 use cmp::min;
 use container::Container;
-use option::{Option, Some, None};
-use super::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, io_error,
-            OtherIoError};
+use option::None;
+use result::{Err, Ok};
+use io;
+use io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
 use vec;
 use vec::{Vector, ImmutableVector, MutableVector, OwnedCloneableVector};
 
@@ -24,6 +25,7 @@ use vec::{Vector, ImmutableVector, MutableVector, OwnedCloneableVector};
 /// # Example
 ///
 /// ```rust
+/// # #[allow(unused_must_use)];
 /// use std::io::MemWriter;
 ///
 /// let mut w = MemWriter::new();
@@ -59,7 +61,7 @@ impl MemWriter {
 }
 
 impl Writer for MemWriter {
-    fn write(&mut self, buf: &[u8]) {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         // Make sure the internal buffer is as least as big as where we
         // currently are
         let difference = self.pos as i64 - self.buf.len() as i64;
@@ -86,14 +88,15 @@ impl Writer for MemWriter {
 
         // Bump us forward
         self.pos += buf.len();
+        Ok(())
     }
 }
 
 // FIXME(#10432)
 impl Seek for MemWriter {
-    fn tell(&self) -> u64 { self.pos as u64 }
+    fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
 
-    fn seek(&mut self, pos: i64, style: SeekStyle) {
+    fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
         // compute offset as signed and clamp to prevent overflow
         let offset = match style {
             SeekSet => { 0 }
@@ -102,6 +105,7 @@ impl Seek for MemWriter {
         } as i64;
 
         self.pos = max(0, offset+pos) as uint;
+        Ok(())
     }
 }
 
@@ -110,11 +114,12 @@ impl Seek for MemWriter {
 /// # Example
 ///
 /// ```rust
+/// # #[allow(unused_must_use)];
 /// use std::io::MemReader;
 ///
 /// let mut r = MemReader::new(~[0, 1, 2]);
 ///
-/// assert_eq!(r.read_to_end(), ~[0, 1, 2]);
+/// assert_eq!(r.read_to_end().unwrap(), ~[0, 1, 2]);
 /// ```
 pub struct MemReader {
     priv buf: ~[u8],
@@ -148,8 +153,8 @@ impl MemReader {
 }
 
 impl Reader for MemReader {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
-        if self.eof() { return None }
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+        if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
 
         let write_len = min(buf.len(), self.buf.len() - self.pos);
         {
@@ -161,28 +166,31 @@ impl Reader for MemReader {
         self.pos += write_len;
         assert!(self.pos <= self.buf.len());
 
-        return Some(write_len);
+        return Ok(write_len);
     }
 }
 
 impl Seek for MemReader {
-    fn tell(&self) -> u64 { self.pos as u64 }
-    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
+    fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
+    fn seek(&mut self, _pos: i64, _style: SeekStyle) -> IoResult<()> { fail!() }
 }
 
 impl Buffer for MemReader {
-    fn fill<'a>(&'a mut self) -> &'a [u8] { self.buf.slice_from(self.pos) }
+    fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
+        Ok(self.buf.slice_from(self.pos))
+    }
     fn consume(&mut self, amt: uint) { self.pos += amt; }
 }
 
 /// Writes to a fixed-size byte slice
 ///
-/// If a write will not fit in the buffer, it raises the `io_error`
-/// condition and does not write any data.
+/// If a write will not fit in the buffer, it returns an error and does not
+/// write any data.
 ///
 /// # Example
 ///
 /// ```rust
+/// # #[allow(unused_must_use)];
 /// use std::io::BufWriter;
 ///
 /// let mut buf = [0, ..4];
@@ -207,28 +215,28 @@ impl<'a> BufWriter<'a> {
 }
 
 impl<'a> Writer for BufWriter<'a> {
-    fn write(&mut self, buf: &[u8]) {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
         // raises a condition if the entire write does not fit in the buffer
         let max_size = self.buf.len();
         if self.pos >= max_size || (self.pos + buf.len()) > max_size {
-            io_error::cond.raise(IoError {
-                kind: OtherIoError,
+            return Err(IoError {
+                kind: io::OtherIoError,
                 desc: "Trying to write past end of buffer",
                 detail: None
-            });
-            return;
+            })
         }
 
         vec::bytes::copy_memory(self.buf.mut_slice_from(self.pos), buf);
         self.pos += buf.len();
+        Ok(())
     }
 }
 
 // FIXME(#10432)
 impl<'a> Seek for BufWriter<'a> {
-    fn tell(&self) -> u64 { self.pos as u64 }
+    fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
 
-    fn seek(&mut self, pos: i64, style: SeekStyle) {
+    fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
         // compute offset as signed and clamp to prevent overflow
         let offset = match style {
             SeekSet => { 0 }
@@ -237,6 +245,7 @@ impl<'a> Seek for BufWriter<'a> {
         } as i64;
 
         self.pos = max(0, offset+pos) as uint;
+        Ok(())
     }
 }
 
@@ -246,12 +255,13 @@ impl<'a> Seek for BufWriter<'a> {
 /// # Example
 ///
 /// ```rust
+/// # #[allow(unused_must_use)];
 /// use std::io::BufReader;
 ///
 /// let mut buf = [0, 1, 2, 3];
 /// let mut r = BufReader::new(buf);
 ///
-/// assert_eq!(r.read_to_end(), ~[0, 1, 2, 3]);
+/// assert_eq!(r.read_to_end().unwrap(), ~[0, 1, 2, 3]);
 /// ```
 pub struct BufReader<'a> {
     priv buf: &'a [u8],
@@ -274,8 +284,8 @@ impl<'a> BufReader<'a> {
 }
 
 impl<'a> Reader for BufReader<'a> {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
-        if self.eof() { return None }
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+        if self.eof() { return Err(io::standard_error(io::EndOfFile)) }
 
         let write_len = min(buf.len(), self.buf.len() - self.pos);
         {
@@ -287,18 +297,19 @@ impl<'a> Reader for BufReader<'a> {
         self.pos += write_len;
         assert!(self.pos <= self.buf.len());
 
-        return Some(write_len);
+        return Ok(write_len);
      }
 }
 
 impl<'a> Seek for BufReader<'a> {
-    fn tell(&self) -> u64 { self.pos as u64 }
-
-    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
+    fn tell(&self) -> IoResult<u64> { Ok(self.pos as u64) }
+    fn seek(&mut self, _pos: i64, _style: SeekStyle) -> IoResult<()> { fail!() }
 }
 
 impl<'a> Buffer for BufReader<'a> {
-    fn fill<'a>(&'a mut self) -> &'a [u8] { self.buf.slice_from(self.pos) }
+    fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]> {
+        Ok(self.buf.slice_from(self.pos))
+    }
     fn consume(&mut self, amt: uint) { self.pos += amt; }
 }
 
@@ -307,33 +318,34 @@ mod test {
     use prelude::*;
     use super::*;
     use io::*;
+    use io;
 
     #[test]
     fn test_mem_writer() {
         let mut writer = MemWriter::new();
-        assert_eq!(writer.tell(), 0);
-        writer.write([0]);
-        assert_eq!(writer.tell(), 1);
-        writer.write([1, 2, 3]);
-        writer.write([4, 5, 6, 7]);
-        assert_eq!(writer.tell(), 8);
+        assert_eq!(writer.tell(), Ok(0));
+        writer.write([0]).unwrap();
+        assert_eq!(writer.tell(), Ok(1));
+        writer.write([1, 2, 3]).unwrap();
+        writer.write([4, 5, 6, 7]).unwrap();
+        assert_eq!(writer.tell(), Ok(8));
         assert_eq!(writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7]);
 
-        writer.seek(0, SeekSet);
-        assert_eq!(writer.tell(), 0);
-        writer.write([3, 4]);
+        writer.seek(0, SeekSet).unwrap();
+        assert_eq!(writer.tell(), Ok(0));
+        writer.write([3, 4]).unwrap();
         assert_eq!(writer.get_ref(), [3, 4, 2, 3, 4, 5, 6, 7]);
 
-        writer.seek(1, SeekCur);
-        writer.write([0, 1]);
+        writer.seek(1, SeekCur).unwrap();
+        writer.write([0, 1]).unwrap();
         assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 7]);
 
-        writer.seek(-1, SeekEnd);
-        writer.write([1, 2]);
+        writer.seek(-1, SeekEnd).unwrap();
+        writer.write([1, 2]).unwrap();
         assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 1, 2]);
 
-        writer.seek(1, SeekEnd);
-        writer.write([1]);
+        writer.seek(1, SeekEnd).unwrap();
+        writer.write([1]).unwrap();
         assert_eq!(writer.get_ref(), [3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1]);
     }
 
@@ -342,12 +354,12 @@ mod test {
         let mut buf = [0 as u8, ..8];
         {
             let mut writer = BufWriter::new(buf);
-            assert_eq!(writer.tell(), 0);
-            writer.write([0]);
-            assert_eq!(writer.tell(), 1);
-            writer.write([1, 2, 3]);
-            writer.write([4, 5, 6, 7]);
-            assert_eq!(writer.tell(), 8);
+            assert_eq!(writer.tell(), Ok(0));
+            writer.write([0]).unwrap();
+            assert_eq!(writer.tell(), Ok(1));
+            writer.write([1, 2, 3]).unwrap();
+            writer.write([4, 5, 6, 7]).unwrap();
+            assert_eq!(writer.tell(), Ok(8));
         }
         assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7]);
     }
@@ -357,24 +369,24 @@ mod test {
         let mut buf = [0 as u8, ..8];
         {
             let mut writer = BufWriter::new(buf);
-            assert_eq!(writer.tell(), 0);
-            writer.write([1]);
-            assert_eq!(writer.tell(), 1);
+            assert_eq!(writer.tell(), Ok(0));
+            writer.write([1]).unwrap();
+            assert_eq!(writer.tell(), Ok(1));
 
-            writer.seek(2, SeekSet);
-            assert_eq!(writer.tell(), 2);
-            writer.write([2]);
-            assert_eq!(writer.tell(), 3);
+            writer.seek(2, SeekSet).unwrap();
+            assert_eq!(writer.tell(), Ok(2));
+            writer.write([2]).unwrap();
+            assert_eq!(writer.tell(), Ok(3));
 
-            writer.seek(-2, SeekCur);
-            assert_eq!(writer.tell(), 1);
-            writer.write([3]);
-            assert_eq!(writer.tell(), 2);
+            writer.seek(-2, SeekCur).unwrap();
+            assert_eq!(writer.tell(), Ok(1));
+            writer.write([3]).unwrap();
+            assert_eq!(writer.tell(), Ok(2));
 
-            writer.seek(-1, SeekEnd);
-            assert_eq!(writer.tell(), 7);
-            writer.write([4]);
-            assert_eq!(writer.tell(), 8);
+            writer.seek(-1, SeekEnd).unwrap();
+            assert_eq!(writer.tell(), Ok(7));
+            writer.write([4]).unwrap();
+            assert_eq!(writer.tell(), Ok(8));
 
         }
         assert_eq!(buf, [1, 3, 2, 0, 0, 0, 0, 4]);
@@ -384,35 +396,31 @@ mod test {
     fn test_buf_writer_error() {
         let mut buf = [0 as u8, ..2];
         let mut writer = BufWriter::new(buf);
-        writer.write([0]);
-
-        let mut called = false;
-        io_error::cond.trap(|err| {
-            assert_eq!(err.kind, OtherIoError);
-            called = true;
-        }).inside(|| {
-            writer.write([0, 0]);
-        });
-        assert!(called);
+        writer.write([0]).unwrap();
+
+        match writer.write([0, 0]) {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind, io::OtherIoError),
+        }
     }
 
     #[test]
     fn test_mem_reader() {
         let mut reader = MemReader::new(~[0, 1, 2, 3, 4, 5, 6, 7]);
         let mut buf = [];
-        assert_eq!(reader.read(buf), Some(0));
-        assert_eq!(reader.tell(), 0);
+        assert_eq!(reader.read(buf), Ok(0));
+        assert_eq!(reader.tell(), Ok(0));
         let mut buf = [0];
-        assert_eq!(reader.read(buf), Some(1));
-        assert_eq!(reader.tell(), 1);
+        assert_eq!(reader.read(buf), Ok(1));
+        assert_eq!(reader.tell(), Ok(1));
         assert_eq!(buf, [0]);
         let mut buf = [0, ..4];
-        assert_eq!(reader.read(buf), Some(4));
-        assert_eq!(reader.tell(), 5);
+        assert_eq!(reader.read(buf), Ok(4));
+        assert_eq!(reader.tell(), Ok(5));
         assert_eq!(buf, [1, 2, 3, 4]);
-        assert_eq!(reader.read(buf), Some(3));
+        assert_eq!(reader.read(buf), Ok(3));
         assert_eq!(buf.slice(0, 3), [5, 6, 7]);
-        assert_eq!(reader.read(buf), None);
+        assert!(reader.read(buf).is_err());
     }
 
     #[test]
@@ -420,64 +428,64 @@ mod test {
         let in_buf = ~[0, 1, 2, 3, 4, 5, 6, 7];
         let mut reader = BufReader::new(in_buf);
         let mut buf = [];
-        assert_eq!(reader.read(buf), Some(0));
-        assert_eq!(reader.tell(), 0);
+        assert_eq!(reader.read(buf), Ok(0));
+        assert_eq!(reader.tell(), Ok(0));
         let mut buf = [0];
-        assert_eq!(reader.read(buf), Some(1));
-        assert_eq!(reader.tell(), 1);
+        assert_eq!(reader.read(buf), Ok(1));
+        assert_eq!(reader.tell(), Ok(1));
         assert_eq!(buf, [0]);
         let mut buf = [0, ..4];
-        assert_eq!(reader.read(buf), Some(4));
-        assert_eq!(reader.tell(), 5);
+        assert_eq!(reader.read(buf), Ok(4));
+        assert_eq!(reader.tell(), Ok(5));
         assert_eq!(buf, [1, 2, 3, 4]);
-        assert_eq!(reader.read(buf), Some(3));
+        assert_eq!(reader.read(buf), Ok(3));
         assert_eq!(buf.slice(0, 3), [5, 6, 7]);
-        assert_eq!(reader.read(buf), None);
+        assert!(reader.read(buf).is_err());
     }
 
     #[test]
     fn test_read_char() {
         let b = bytes!("Việt");
         let mut r = BufReader::new(b);
-        assert_eq!(r.read_char(), Some('V'));
-        assert_eq!(r.read_char(), Some('i'));
-        assert_eq!(r.read_char(), Some('ệ'));
-        assert_eq!(r.read_char(), Some('t'));
-        assert_eq!(r.read_char(), None);
+        assert_eq!(r.read_char(), Ok('V'));
+        assert_eq!(r.read_char(), Ok('i'));
+        assert_eq!(r.read_char(), Ok('ệ'));
+        assert_eq!(r.read_char(), Ok('t'));
+        assert!(r.read_char().is_err());
     }
 
     #[test]
     fn test_read_bad_char() {
         let b = bytes!(0x80);
         let mut r = BufReader::new(b);
-        assert_eq!(r.read_char(), None);
+        assert!(r.read_char().is_err());
     }
 
     #[test]
     fn test_write_strings() {
         let mut writer = MemWriter::new();
-        writer.write_str("testing");
-        writer.write_line("testing");
-        writer.write_str("testing");
+        writer.write_str("testing").unwrap();
+        writer.write_line("testing").unwrap();
+        writer.write_str("testing").unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        assert_eq!(r.read_to_str(), ~"testingtesting\ntesting");
+        assert_eq!(r.read_to_str().unwrap(), ~"testingtesting\ntesting");
     }
 
     #[test]
     fn test_write_char() {
         let mut writer = MemWriter::new();
-        writer.write_char('a');
-        writer.write_char('\n');
-        writer.write_char('ệ');
+        writer.write_char('a').unwrap();
+        writer.write_char('\n').unwrap();
+        writer.write_char('ệ').unwrap();
         let mut r = BufReader::new(writer.get_ref());
-        assert_eq!(r.read_to_str(), ~"a\nệ");
+        assert_eq!(r.read_to_str().unwrap(), ~"a\nệ");
     }
 
     #[test]
     fn test_read_whole_string_bad() {
         let buf = [0xff];
         let mut r = BufReader::new(buf);
-        match result(|| r.read_to_str()) {
+        match r.read_to_str() {
             Ok(..) => fail!(),
             Err(..) => {}
         }
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 69f0cf96ffc..7690c88478f 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -29,7 +29,6 @@ Some examples of obvious things you might want to do
     use std::io::BufferedReader;
     use std::io::stdin;
 
-    # let _g = ::std::io::ignore_io_error();
     let mut stdin = BufferedReader::new(stdin());
     for line in stdin.lines() {
         print!("{}", line);
@@ -41,16 +40,15 @@ Some examples of obvious things you might want to do
     ```rust
     use std::io::File;
 
-    # let _g = ::std::io::ignore_io_error();
     let contents = File::open(&Path::new("message.txt")).read_to_end();
     ```
 
 * Write a line to a file
 
     ```rust
+    # #[allow(unused_must_use)];
     use std::io::File;
 
-    # let _g = ::std::io::ignore_io_error();
     let mut file = File::create(&Path::new("message.txt"));
     file.write(bytes!("hello, file!\n"));
     # drop(file);
@@ -63,7 +61,6 @@ Some examples of obvious things you might want to do
     use std::io::BufferedReader;
     use std::io::File;
 
-    # let _g = ::std::io::ignore_io_error();
     let path = Path::new("message.txt");
     let mut file = BufferedReader::new(File::open(&path));
     for line in file.lines() {
@@ -77,7 +74,6 @@ Some examples of obvious things you might want to do
     use std::io::BufferedReader;
     use std::io::File;
 
-    # let _g = ::std::io::ignore_io_error();
     let path = Path::new("message.txt");
     let mut file = BufferedReader::new(File::open(&path));
     let lines: ~[~str] = file.lines().collect();
@@ -88,10 +84,10 @@ Some examples of obvious things you might want to do
   `write_str` and `write_line` methods.
 
     ```rust,should_fail
+    # #[allow(unused_must_use)];
     use std::io::net::ip::SocketAddr;
     use std::io::net::tcp::TcpStream;
 
-    # let _g = ::std::io::ignore_io_error();
     let addr = from_str::<SocketAddr>("127.0.0.1:8080").unwrap();
     let mut socket = TcpStream::connect(addr).unwrap();
     socket.write(bytes!("GET / HTTP/1.0\n\n"));
@@ -168,72 +164,51 @@ asynchronous request completes.
 # Error Handling
 
 I/O is an area where nearly every operation can result in unexpected
-errors. It should allow errors to be handled efficiently.
-It needs to be convenient to use I/O when you don't care
-about dealing with specific errors.
+errors. Errors should be painfully visible when they happen, and handling them
+should be easy to work with. It should be convenient to handle specific I/O
+errors, and it should also be convenient to not deal with I/O errors.
 
 Rust's I/O employs a combination of techniques to reduce boilerplate
 while still providing feedback about errors. The basic strategy:
 
-* Errors are fatal by default, resulting in task failure
-* Errors raise the `io_error` condition which provides an opportunity to inspect
-  an IoError object containing details.
-* Return values must have a sensible null or zero value which is returned
-  if a condition is handled successfully. This may be an `Option`, an empty
-  vector, or other designated error value.
-* Common traits are implemented for `Option`, e.g. `impl<R: Reader> Reader for Option<R>`,
-  so that nullable values do not have to be 'unwrapped' before use.
+* All I/O operations return `IoResult<T>` which is equivalent to
+  `Result<T, IoError>`. The core `Result` type is defined in the `std::result`
+  module.
+* If the `Result` type goes unused, then the compiler will by default emit a
+  warning about the unused result.
+* Common traits are implemented for `IoResult`, e.g.
+  `impl<R: Reader> Reader for IoResult<R>`, so that error values do not have
+  to be 'unwrapped' before use.
 
 These features combine in the API to allow for expressions like
 `File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n"))`
 without having to worry about whether "diary.txt" exists or whether
 the write succeeds. As written, if either `new` or `write_line`
-encounters an error the task will fail.
+encounters an error then the result of the entire expression will
+be an error.
 
 If you wanted to handle the error though you might write:
 
 ```rust
+# #[allow(unused_must_use)];
 use std::io::File;
-use std::io::{IoError, io_error};
 
-let mut error = None;
-io_error::cond.trap(|e: IoError| {
-    error = Some(e);
-}).inside(|| {
-    File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n"));
-});
-
-if error.is_some() {
-    println!("failed to write my diary");
+match File::create(&Path::new("diary.txt")).write(bytes!("Met a girl.\n")) {
+    Ok(()) => { /* succeeded */ }
+    Err(e) => println!("failed to write to my diary: {}", e),
 }
+
 # ::std::io::fs::unlink(&Path::new("diary.txt"));
 ```
 
-FIXME: Need better condition handling syntax
-
-In this case the condition handler will have the opportunity to
-inspect the IoError raised by either the call to `new` or the call to
-`write_line`, but then execution will continue.
-
-So what actually happens if `new` encounters an error? To understand
-that it's important to know that what `new` returns is not a `File`
-but an `Option<File>`.  If the file does not open, and the condition
-is handled, then `new` will simply return `None`. Because there is an
-implementation of `Writer` (the trait required ultimately required for
-types to implement `write_line`) there is no need to inspect or unwrap
-the `Option<File>` and we simply call `write_line` on it.  If `new`
-returned a `None` then the followup call to `write_line` will also
-raise an error.
-
-## Concerns about this strategy
-
-This structure will encourage a programming style that is prone
-to errors similar to null pointer dereferences.
-In particular code written to ignore errors and expect conditions to be unhandled
-will start passing around null or zero objects when wrapped in a condition handler.
-
-* FIXME: How should we use condition handlers that return values?
-* FIXME: Should EOF raise default conditions when EOF is not an error?
+So what actually happens if `create` encounters an error?
+It's important to know that what `new` returns is not a `File`
+but an `IoResult<File>`.  If the file does not open, then `new` will simply
+return `Err(..)`. Because there is an implementation of `Writer` (the trait
+required ultimately required for types to implement `write_line`) there is no
+need to inspect or unwrap the `IoResult<File>` and we simply call `write_line`
+on it. If `new` returned an `Err(..)` then the followup call to `write_line`
+will also return an error.
 
 # Issues with i/o scheduler affinity, work stealing, task pinning
 
@@ -287,18 +262,19 @@ Out of scope
 */
 
 #[allow(missing_doc)];
+#[deny(unused_must_use)];
 
 use cast;
 use char::Char;
-use condition::Guard;
 use container::Container;
+use fmt;
 use int;
 use iter::Iterator;
 use option::{Option, Some, None};
 use path::Path;
 use result::{Ok, Err, Result};
-use str;
 use str::{StrSlice, OwnedStr};
+use str;
 use to_str::ToStr;
 use uint;
 use unstable::finally::Finally;
@@ -347,8 +323,8 @@ mod mem;
 /// Non-blocking access to stdin, stdout, stderr
 pub mod stdio;
 
-/// Implementations for Option
-mod option;
+/// Implementations for Result
+mod result;
 
 /// Extension traits
 pub mod extensions;
@@ -373,17 +349,30 @@ mod comm_adapters;
 // https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
 static DEFAULT_BUF_SIZE: uint = 1024 * 64;
 
+pub type IoResult<T> = Result<T, IoError>;
+
 /// The type passed to I/O condition handlers to indicate error
 ///
 /// # FIXME
 ///
 /// Is something like this sufficient? It's kind of archaic
+#[deriving(Eq, Clone)]
 pub struct IoError {
     kind: IoErrorKind,
     desc: &'static str,
     detail: Option<~str>
 }
 
+impl fmt::Show for IoError {
+    fn fmt(err: &IoError, fmt: &mut fmt::Formatter) -> fmt::Result {
+        if_ok!(fmt.buf.write_str(err.desc));
+        match err.detail {
+            Some(ref s) => write!(fmt.buf, " ({})", *s),
+            None => Ok(())
+        }
+    }
+}
+
 // FIXME: #8242 implementing manually because deriving doesn't work for some reason
 impl ToStr for IoError {
     fn to_str(&self) -> ~str {
@@ -398,9 +387,8 @@ impl ToStr for IoError {
     }
 }
 
-#[deriving(Eq)]
+#[deriving(Eq, Clone)]
 pub enum IoErrorKind {
-    PreviousIoError,
     OtherIoError,
     EndOfFile,
     FileNotFound,
@@ -424,7 +412,6 @@ pub enum IoErrorKind {
 impl ToStr for IoErrorKind {
     fn to_str(&self) -> ~str {
         match *self {
-            PreviousIoError => ~"PreviousIoError",
             OtherIoError => ~"OtherIoError",
             EndOfFile => ~"EndOfFile",
             FileNotFound => ~"FileNotFound",
@@ -446,184 +433,130 @@ impl ToStr for IoErrorKind {
     }
 }
 
-// FIXME: Can't put doc comments on macros
-// Raised by `I/O` operations on error.
-condition! {
-    pub io_error: IoError -> ();
-}
-
-/// Helper for wrapper calls where you want to
-/// ignore any io_errors that might be raised
-pub fn ignore_io_error() -> Guard<'static,IoError,()> {
-    io_error::cond.trap(|_| {
-        // just swallow the error.. downstream users
-        // who can make a decision based on a None result
-        // won't care
-    }).guard()
-}
-
-/// Helper for catching an I/O error and wrapping it in a Result object. The
-/// return result will be the last I/O error that happened or the result of the
-/// closure if no error occurred.
-pub fn result<T>(cb: || -> T) -> Result<T, IoError> {
-    let mut err = None;
-    let ret = io_error::cond.trap(|e| {
-        if err.is_none() {
-            err = Some(e);
-        }
-    }).inside(cb);
-    match err {
-        Some(e) => Err(e),
-        None => Ok(ret),
-    }
-}
-
 pub trait Reader {
 
-    // Only two methods which need to get implemented for this trait
+    // Only method which need to get implemented for this trait
 
     /// Read bytes, up to the length of `buf` and place them in `buf`.
     /// Returns the number of bytes read. The number of bytes read my
-    /// be less than the number requested, even 0. Returns `None` on EOF.
-    ///
-    /// # Failure
+    /// be less than the number requested, even 0. Returns `Err` on EOF.
     ///
-    /// Raises the `io_error` condition on error. If the condition
-    /// is handled then no guarantee is made about the number of bytes
-    /// read and the contents of `buf`. If the condition is handled
-    /// returns `None` (FIXME see below).
+    /// # Error
     ///
-    /// # FIXME
-    ///
-    /// * Should raise_default error on eof?
-    /// * If the condition is handled it should still return the bytes read,
-    ///   in which case there's no need to return Option - but then you *have*
-    ///   to install a handler to detect eof.
-    ///
-    /// This doesn't take a `len` argument like the old `read`.
-    /// Will people often need to slice their vectors to call this
-    /// and will that be annoying?
-    /// Is it actually possible for 0 bytes to be read successfully?
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint>;
+    /// If an error occurs during this I/O operation, then it is returned as
+    /// `Err(IoError)`. Note that end-of-file is considered an error, and can be
+    /// inspected for in the error's `kind` field. Also note that reading 0
+    /// bytes is not considered an error in all circumstances
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
 
     // Convenient helper methods based on the above methods
 
-    /// Reads a single byte. Returns `None` on EOF.
-    ///
-    /// # Failure
-    ///
-    /// Raises the same conditions as the `read` method. Returns
-    /// `None` if the condition is handled.
-    fn read_byte(&mut self) -> Option<u8> {
+    /// Reads a single byte. Returns `Err` on EOF.
+    fn read_byte(&mut self) -> IoResult<u8> {
         let mut buf = [0];
-        match self.read(buf) {
-            Some(0) => {
-                debug!("read 0 bytes. trying again");
-                self.read_byte()
+        loop {
+            match self.read(buf) {
+                Ok(0) => {
+                    debug!("read 0 bytes. trying again");
+                }
+                Ok(1) => return Ok(buf[0]),
+                Ok(_) => unreachable!(),
+                Err(e) => return Err(e)
             }
-            Some(1) => Some(buf[0]),
-            Some(_) => unreachable!(),
-            None => None
         }
     }
 
     /// Reads `len` bytes and appends them to a vector.
     ///
     /// May push fewer than the requested number of bytes on error
-    /// or EOF. Returns true on success, false on EOF or error.
-    ///
-    /// # Failure
-    ///
-    /// Raises the same conditions as `read`. Additionally raises `io_error`
-    /// on EOF. If `io_error` is handled then `push_bytes` may push less
-    /// than the requested number of bytes.
-    fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) {
-        unsafe {
-            let start_len = buf.len();
-            let mut total_read = 0;
-
-            buf.reserve_additional(len);
-            buf.set_len(start_len + len);
-
-            (|| {
-                while total_read < len {
-                    let len = buf.len();
-                    let slice = buf.mut_slice(start_len + total_read, len);
-                    match self.read(slice) {
-                        Some(nread) => {
-                            total_read += nread;
-                        }
-                        None => {
-                            io_error::cond.raise(standard_error(EndOfFile));
-                            break;
-                        }
+    /// or EOF. If `Ok(())` is returned, then all of the requested bytes were
+    /// pushed on to the vector, otherwise the amount `len` bytes couldn't be
+    /// read (an error was encountered), and the error is returned.
+    fn push_bytes(&mut self, buf: &mut ~[u8], len: uint) -> IoResult<()> {
+        let start_len = buf.len();
+        let mut total_read = 0;
+
+        buf.reserve_additional(len);
+        unsafe { buf.set_len(start_len + len); }
+
+        (|| {
+            while total_read < len {
+                let len = buf.len();
+                let slice = buf.mut_slice(start_len + total_read, len);
+                match self.read(slice) {
+                    Ok(nread) => {
+                        total_read += nread;
                     }
+                    Err(e) => return Err(e)
                 }
-            }).finally(|| buf.set_len(start_len + total_read))
-        }
+            }
+            Ok(())
+        }).finally(|| unsafe { buf.set_len(start_len + total_read) })
     }
 
     /// Reads `len` bytes and gives you back a new vector of length `len`
     ///
-    /// # Failure
+    /// # Error
     ///
-    /// Raises the same conditions as `read`. Additionally raises `io_error`
-    /// on EOF. If `io_error` is handled then the returned vector may
-    /// contain less than the requested number of bytes.
-    fn read_bytes(&mut self, len: uint) -> ~[u8] {
+    /// Fails with the same conditions as `read`. Additionally returns error on
+    /// on EOF. Note that if an error is returned, then some number of bytes may
+    /// have already been consumed from the underlying reader, and they are lost
+    /// (not returned as part of the error). If this is unacceptable, then it is
+    /// recommended to use the `push_bytes` or `read` methods.
+    fn read_bytes(&mut self, len: uint) -> IoResult<~[u8]> {
         let mut buf = vec::with_capacity(len);
-        self.push_bytes(&mut buf, len);
-        return buf;
+        match self.push_bytes(&mut buf, len) {
+            Ok(()) => Ok(buf),
+            Err(e) => Err(e),
+        }
     }
 
     /// Reads all remaining bytes from the stream.
     ///
-    /// # Failure
+    /// # Error
     ///
-    /// Raises the same conditions as the `read` method except for
-    /// `EndOfFile` which is swallowed.
-    fn read_to_end(&mut self) -> ~[u8] {
+    /// Returns any non-EOF error immediately. Previously read bytes are
+    /// discarded when an error is returned.
+    ///
+    /// When EOF is encountered, all bytes read up to that point are returned.
+    fn read_to_end(&mut self) -> IoResult<~[u8]> {
         let mut buf = vec::with_capacity(DEFAULT_BUF_SIZE);
-        let mut keep_reading = true;
-        io_error::cond.trap(|e| {
-            if e.kind == EndOfFile {
-                keep_reading = false;
-            } else {
-                io_error::cond.raise(e)
-            }
-        }).inside(|| {
-            while keep_reading {
-                self.push_bytes(&mut buf, DEFAULT_BUF_SIZE)
+        loop {
+            match self.push_bytes(&mut buf, DEFAULT_BUF_SIZE) {
+                Ok(()) => {}
+                Err(ref e) if e.kind == EndOfFile => break,
+                Err(e) => return Err(e)
             }
-        });
-        return buf;
+        }
+        return Ok(buf);
     }
 
     /// Reads all of the remaining bytes of this stream, interpreting them as a
     /// UTF-8 encoded stream. The corresponding string is returned.
     ///
-    /// # Failure
+    /// # Error
     ///
-    /// This function will raise all the same conditions as the `read` method,
-    /// along with raising a condition if the input is not valid UTF-8.
-    fn read_to_str(&mut self) -> ~str {
-        match str::from_utf8_owned(self.read_to_end()) {
-            Some(s) => s,
-            None => {
-                io_error::cond.raise(standard_error(InvalidInput));
-                ~""
+    /// This function returns all of the same errors as `read_to_end` with an
+    /// additional error if the reader's contents are not a valid sequence of
+    /// UTF-8 bytes.
+    fn read_to_str(&mut self) -> IoResult<~str> {
+        self.read_to_end().and_then(|s| {
+            match str::from_utf8_owned(s) {
+                Some(s) => Ok(s),
+                None => Err(standard_error(InvalidInput)),
             }
-        }
+        })
     }
 
     /// Create an iterator that reads a single byte on
     /// each iteration, until EOF.
     ///
-    /// # Failure
+    /// # Error
     ///
-    /// Raises the same conditions as the `read` method, for
-    /// each call to its `.next()` method.
-    /// Ends the iteration if the condition is handled.
+    /// The iterator protocol causes all specifics about errors encountered to
+    /// be swallowed. All errors will be signified by returning `None` from the
+    /// iterator. If this is undesirable, it is recommended to use the
+    /// `read_byte` method.
     fn bytes<'r>(&'r mut self) -> extensions::Bytes<'r, Self> {
         extensions::Bytes::new(self)
     }
@@ -633,225 +566,219 @@ pub trait Reader {
     /// Reads `n` little-endian unsigned integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_le_uint_n(&mut self, nbytes: uint) -> u64 {
+    fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
         assert!(nbytes > 0 && nbytes <= 8);
 
         let mut val = 0u64;
         let mut pos = 0;
         let mut i = nbytes;
         while i > 0 {
-            val += (self.read_u8() as u64) << pos;
+            val += (if_ok!(self.read_u8()) as u64) << pos;
             pos += 8;
             i -= 1;
         }
-        val
+        Ok(val)
     }
 
     /// Reads `n` little-endian signed integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_le_int_n(&mut self, nbytes: uint) -> i64 {
-        extend_sign(self.read_le_uint_n(nbytes), nbytes)
+    fn read_le_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
+        self.read_le_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
     }
 
     /// Reads `n` big-endian unsigned integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_be_uint_n(&mut self, nbytes: uint) -> u64 {
+    fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
         assert!(nbytes > 0 && nbytes <= 8);
 
         let mut val = 0u64;
         let mut i = nbytes;
         while i > 0 {
             i -= 1;
-            val += (self.read_u8() as u64) << i * 8;
+            val += (if_ok!(self.read_u8()) as u64) << i * 8;
         }
-        val
+        Ok(val)
     }
 
     /// Reads `n` big-endian signed integer bytes.
     ///
     /// `n` must be between 1 and 8, inclusive.
-    fn read_be_int_n(&mut self, nbytes: uint) -> i64 {
-        extend_sign(self.read_be_uint_n(nbytes), nbytes)
+    fn read_be_int_n(&mut self, nbytes: uint) -> IoResult<i64> {
+        self.read_be_uint_n(nbytes).map(|i| extend_sign(i, nbytes))
     }
 
     /// Reads a little-endian unsigned integer.
     ///
     /// The number of bytes returned is system-dependant.
-    fn read_le_uint(&mut self) -> uint {
-        self.read_le_uint_n(uint::BYTES) as uint
+    fn read_le_uint(&mut self) -> IoResult<uint> {
+        self.read_le_uint_n(uint::BYTES).map(|i| i as uint)
     }
 
     /// Reads a little-endian integer.
     ///
     /// The number of bytes returned is system-dependant.
-    fn read_le_int(&mut self) -> int {
-        self.read_le_int_n(int::BYTES) as int
+    fn read_le_int(&mut self) -> IoResult<int> {
+        self.read_le_int_n(int::BYTES).map(|i| i as int)
     }
 
     /// Reads a big-endian unsigned integer.
     ///
     /// The number of bytes returned is system-dependant.
-    fn read_be_uint(&mut self) -> uint {
-        self.read_be_uint_n(uint::BYTES) as uint
+    fn read_be_uint(&mut self) -> IoResult<uint> {
+        self.read_be_uint_n(uint::BYTES).map(|i| i as uint)
     }
 
     /// Reads a big-endian integer.
     ///
     /// The number of bytes returned is system-dependant.
-    fn read_be_int(&mut self) -> int {
-        self.read_be_int_n(int::BYTES) as int
+    fn read_be_int(&mut self) -> IoResult<int> {
+        self.read_be_int_n(int::BYTES).map(|i| i as int)
     }
 
     /// Reads a big-endian `u64`.
     ///
     /// `u64`s are 8 bytes long.
-    fn read_be_u64(&mut self) -> u64 {
+    fn read_be_u64(&mut self) -> IoResult<u64> {
         self.read_be_uint_n(8)
     }
 
     /// Reads a big-endian `u32`.
     ///
     /// `u32`s are 4 bytes long.
-    fn read_be_u32(&mut self) -> u32 {
-        self.read_be_uint_n(4) as u32
+    fn read_be_u32(&mut self) -> IoResult<u32> {
+        self.read_be_uint_n(4).map(|i| i as u32)
     }
 
     /// Reads a big-endian `u16`.
     ///
     /// `u16`s are 2 bytes long.
-    fn read_be_u16(&mut self) -> u16 {
-        self.read_be_uint_n(2) as u16
+    fn read_be_u16(&mut self) -> IoResult<u16> {
+        self.read_be_uint_n(2).map(|i| i as u16)
     }
 
     /// Reads a big-endian `i64`.
     ///
     /// `i64`s are 8 bytes long.
-    fn read_be_i64(&mut self) -> i64 {
+    fn read_be_i64(&mut self) -> IoResult<i64> {
         self.read_be_int_n(8)
     }
 
     /// Reads a big-endian `i32`.
     ///
     /// `i32`s are 4 bytes long.
-    fn read_be_i32(&mut self) -> i32 {
-        self.read_be_int_n(4) as i32
+    fn read_be_i32(&mut self) -> IoResult<i32> {
+        self.read_be_int_n(4).map(|i| i as i32)
     }
 
     /// Reads a big-endian `i16`.
     ///
     /// `i16`s are 2 bytes long.
-    fn read_be_i16(&mut self) -> i16 {
-        self.read_be_int_n(2) as i16
+    fn read_be_i16(&mut self) -> IoResult<i16> {
+        self.read_be_int_n(2).map(|i| i as i16)
     }
 
     /// Reads a big-endian `f64`.
     ///
     /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
-    fn read_be_f64(&mut self) -> f64 {
-        unsafe {
-            cast::transmute::<u64, f64>(self.read_be_u64())
-        }
+    fn read_be_f64(&mut self) -> IoResult<f64> {
+        self.read_be_u64().map(|i| unsafe {
+            cast::transmute::<u64, f64>(i)
+        })
     }
 
     /// Reads a big-endian `f32`.
     ///
     /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
-    fn read_be_f32(&mut self) -> f32 {
-        unsafe {
-            cast::transmute::<u32, f32>(self.read_be_u32())
-        }
+    fn read_be_f32(&mut self) -> IoResult<f32> {
+        self.read_be_u32().map(|i| unsafe {
+            cast::transmute::<u32, f32>(i)
+        })
     }
 
     /// Reads a little-endian `u64`.
     ///
     /// `u64`s are 8 bytes long.
-    fn read_le_u64(&mut self) -> u64 {
+    fn read_le_u64(&mut self) -> IoResult<u64> {
         self.read_le_uint_n(8)
     }
 
     /// Reads a little-endian `u32`.
     ///
     /// `u32`s are 4 bytes long.
-    fn read_le_u32(&mut self) -> u32 {
-        self.read_le_uint_n(4) as u32
+    fn read_le_u32(&mut self) -> IoResult<u32> {
+        self.read_le_uint_n(4).map(|i| i as u32)
     }
 
     /// Reads a little-endian `u16`.
     ///
     /// `u16`s are 2 bytes long.
-    fn read_le_u16(&mut self) -> u16 {
-        self.read_le_uint_n(2) as u16
+    fn read_le_u16(&mut self) -> IoResult<u16> {
+        self.read_le_uint_n(2).map(|i| i as u16)
     }
 
     /// Reads a little-endian `i64`.
     ///
     /// `i64`s are 8 bytes long.
-    fn read_le_i64(&mut self) -> i64 {
+    fn read_le_i64(&mut self) -> IoResult<i64> {
         self.read_le_int_n(8)
     }
 
     /// Reads a little-endian `i32`.
     ///
     /// `i32`s are 4 bytes long.
-    fn read_le_i32(&mut self) -> i32 {
-        self.read_le_int_n(4) as i32
+    fn read_le_i32(&mut self) -> IoResult<i32> {
+        self.read_le_int_n(4).map(|i| i as i32)
     }
 
     /// Reads a little-endian `i16`.
     ///
     /// `i16`s are 2 bytes long.
-    fn read_le_i16(&mut self) -> i16 {
-        self.read_le_int_n(2) as i16
+    fn read_le_i16(&mut self) -> IoResult<i16> {
+        self.read_le_int_n(2).map(|i| i as i16)
     }
 
     /// Reads a little-endian `f64`.
     ///
     /// `f64`s are 8 byte, IEEE754 double-precision floating point numbers.
-    fn read_le_f64(&mut self) -> f64 {
-        unsafe {
-            cast::transmute::<u64, f64>(self.read_le_u64())
-        }
+    fn read_le_f64(&mut self) -> IoResult<f64> {
+        self.read_le_u64().map(|i| unsafe {
+            cast::transmute::<u64, f64>(i)
+        })
     }
 
     /// Reads a little-endian `f32`.
     ///
     /// `f32`s are 4 byte, IEEE754 single-precision floating point numbers.
-    fn read_le_f32(&mut self) -> f32 {
-        unsafe {
-            cast::transmute::<u32, f32>(self.read_le_u32())
-        }
+    fn read_le_f32(&mut self) -> IoResult<f32> {
+        self.read_le_u32().map(|i| unsafe {
+            cast::transmute::<u32, f32>(i)
+        })
     }
 
     /// Read a u8.
     ///
     /// `u8`s are 1 byte.
-    fn read_u8(&mut self) -> u8 {
-        match self.read_byte() {
-            Some(b) => b,
-            None => 0
-        }
+    fn read_u8(&mut self) -> IoResult<u8> {
+        self.read_byte()
     }
 
     /// Read an i8.
     ///
     /// `i8`s are 1 byte.
-    fn read_i8(&mut self) -> i8 {
-        match self.read_byte() {
-            Some(b) => b as i8,
-            None => 0
-        }
+    fn read_i8(&mut self) -> IoResult<i8> {
+        self.read_byte().map(|i| i as i8)
     }
 
 }
 
 impl Reader for ~Reader {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.read(buf) }
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
 }
 
 impl<'a> Reader for &'a mut Reader {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.read(buf) }
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
 }
 
 fn extend_sign(val: u64, nbytes: uint) -> i64 {
@@ -860,19 +787,22 @@ fn extend_sign(val: u64, nbytes: uint) -> i64 {
 }
 
 pub trait Writer {
-    /// Write the given buffer
+    /// Write the entirety of a given buffer
     ///
-    /// # Failure
+    /// # Errors
     ///
-    /// Raises the `io_error` condition on error
-    fn write(&mut self, buf: &[u8]);
+    /// If an error happens during the I/O operation, the error is returned as
+    /// `Err`. Note that it is considered an error if the entire buffer could
+    /// not be written, and if an error is returned then it is unknown how much
+    /// data (if any) was actually written.
+    fn write(&mut self, buf: &[u8]) -> IoResult<()>;
 
     /// Flush this output stream, ensuring that all intermediately buffered
     /// contents reach their destination.
     ///
     /// This is by default a no-op and implementers of the `Writer` trait should
     /// decide whether their stream needs to be buffered or not.
-    fn flush(&mut self) {}
+    fn flush(&mut self) -> IoResult<()> { Ok(()) }
 
     /// Write a rust string into this sink.
     ///
@@ -880,8 +810,8 @@ pub trait Writer {
     /// If other encodings are desired, it is recommended to compose this stream
     /// with another performing the conversion, or to use `write` with a
     /// converted byte-array instead.
-    fn write_str(&mut self, s: &str) {
-        self.write(s.as_bytes());
+    fn write_str(&mut self, s: &str) -> IoResult<()> {
+        self.write(s.as_bytes())
     }
 
     /// Writes a string into this sink, and then writes a literal newline (`\n`)
@@ -891,125 +821,124 @@ pub trait Writer {
     ///
     /// If other encodings or line ending flavors are desired, it is recommended
     /// that the `write` method is used specifically instead.
-    fn write_line(&mut self, s: &str) {
-        self.write_str(s);
-        self.write(['\n' as u8]);
+    fn write_line(&mut self, s: &str) -> IoResult<()> {
+        self.write_str(s).and_then(|()| self.write(['\n' as u8]))
     }
 
     /// Write a single char, encoded as UTF-8.
-    fn write_char(&mut self, c: char) {
+    fn write_char(&mut self, c: char) -> IoResult<()> {
         let mut buf = [0u8, ..4];
         let n = c.encode_utf8(buf.as_mut_slice());
-        self.write(buf.slice_to(n));
+        self.write(buf.slice_to(n))
     }
 
     /// Write the result of passing n through `int::to_str_bytes`.
-    fn write_int(&mut self, n: int) {
+    fn write_int(&mut self, n: int) -> IoResult<()> {
         int::to_str_bytes(n, 10u, |bytes| self.write(bytes))
     }
 
     /// Write the result of passing n through `uint::to_str_bytes`.
-    fn write_uint(&mut self, n: uint) {
+    fn write_uint(&mut self, n: uint) -> IoResult<()> {
         uint::to_str_bytes(n, 10u, |bytes| self.write(bytes))
     }
 
     /// Write a little-endian uint (number of bytes depends on system).
-    fn write_le_uint(&mut self, n: uint) {
+    fn write_le_uint(&mut self, n: uint) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, uint::BYTES, |v| self.write(v))
     }
 
     /// Write a little-endian int (number of bytes depends on system).
-    fn write_le_int(&mut self, n: int) {
+    fn write_le_int(&mut self, n: int) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, int::BYTES, |v| self.write(v))
     }
 
     /// Write a big-endian uint (number of bytes depends on system).
-    fn write_be_uint(&mut self, n: uint) {
+    fn write_be_uint(&mut self, n: uint) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, uint::BYTES, |v| self.write(v))
     }
 
     /// Write a big-endian int (number of bytes depends on system).
-    fn write_be_int(&mut self, n: int) {
+    fn write_be_int(&mut self, n: int) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, int::BYTES, |v| self.write(v))
     }
 
     /// Write a big-endian u64 (8 bytes).
-    fn write_be_u64(&mut self, n: u64) {
+    fn write_be_u64(&mut self, n: u64) -> IoResult<()> {
         extensions::u64_to_be_bytes(n, 8u, |v| self.write(v))
     }
 
     /// Write a big-endian u32 (4 bytes).
-    fn write_be_u32(&mut self, n: u32) {
+    fn write_be_u32(&mut self, n: u32) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
     }
 
     /// Write a big-endian u16 (2 bytes).
-    fn write_be_u16(&mut self, n: u16) {
+    fn write_be_u16(&mut self, n: u16) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
     }
 
     /// Write a big-endian i64 (8 bytes).
-    fn write_be_i64(&mut self, n: i64) {
+    fn write_be_i64(&mut self, n: i64) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, 8u, |v| self.write(v))
     }
 
     /// Write a big-endian i32 (4 bytes).
-    fn write_be_i32(&mut self, n: i32) {
+    fn write_be_i32(&mut self, n: i32) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, 4u, |v| self.write(v))
     }
 
     /// Write a big-endian i16 (2 bytes).
-    fn write_be_i16(&mut self, n: i16) {
+    fn write_be_i16(&mut self, n: i16) -> IoResult<()> {
         extensions::u64_to_be_bytes(n as u64, 2u, |v| self.write(v))
     }
 
     /// Write a big-endian IEEE754 double-precision floating-point (8 bytes).
-    fn write_be_f64(&mut self, f: f64) {
+    fn write_be_f64(&mut self, f: f64) -> IoResult<()> {
         unsafe {
             self.write_be_u64(cast::transmute(f))
         }
     }
 
     /// Write a big-endian IEEE754 single-precision floating-point (4 bytes).
-    fn write_be_f32(&mut self, f: f32) {
+    fn write_be_f32(&mut self, f: f32) -> IoResult<()> {
         unsafe {
             self.write_be_u32(cast::transmute(f))
         }
     }
 
     /// Write a little-endian u64 (8 bytes).
-    fn write_le_u64(&mut self, n: u64) {
+    fn write_le_u64(&mut self, n: u64) -> IoResult<()> {
         extensions::u64_to_le_bytes(n, 8u, |v| self.write(v))
     }
 
     /// Write a little-endian u32 (4 bytes).
-    fn write_le_u32(&mut self, n: u32) {
+    fn write_le_u32(&mut self, n: u32) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
     }
 
     /// Write a little-endian u16 (2 bytes).
-    fn write_le_u16(&mut self, n: u16) {
+    fn write_le_u16(&mut self, n: u16) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
     }
 
     /// Write a little-endian i64 (8 bytes).
-    fn write_le_i64(&mut self, n: i64) {
+    fn write_le_i64(&mut self, n: i64) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, 8u, |v| self.write(v))
     }
 
     /// Write a little-endian i32 (4 bytes).
-    fn write_le_i32(&mut self, n: i32) {
+    fn write_le_i32(&mut self, n: i32) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, 4u, |v| self.write(v))
     }
 
     /// Write a little-endian i16 (2 bytes).
-    fn write_le_i16(&mut self, n: i16) {
+    fn write_le_i16(&mut self, n: i16) -> IoResult<()> {
         extensions::u64_to_le_bytes(n as u64, 2u, |v| self.write(v))
     }
 
     /// Write a little-endian IEEE754 double-precision floating-point
     /// (8 bytes).
-    fn write_le_f64(&mut self, f: f64) {
+    fn write_le_f64(&mut self, f: f64) -> IoResult<()> {
         unsafe {
             self.write_le_u64(cast::transmute(f))
         }
@@ -1017,31 +946,31 @@ pub trait Writer {
 
     /// Write a little-endian IEEE754 single-precision floating-point
     /// (4 bytes).
-    fn write_le_f32(&mut self, f: f32) {
+    fn write_le_f32(&mut self, f: f32) -> IoResult<()> {
         unsafe {
             self.write_le_u32(cast::transmute(f))
         }
     }
 
     /// Write a u8 (1 byte).
-    fn write_u8(&mut self, n: u8) {
+    fn write_u8(&mut self, n: u8) -> IoResult<()> {
         self.write([n])
     }
 
     /// Write a i8 (1 byte).
-    fn write_i8(&mut self, n: i8) {
+    fn write_i8(&mut self, n: i8) -> IoResult<()> {
         self.write([n as u8])
     }
 }
 
 impl Writer for ~Writer {
-    fn write(&mut self, buf: &[u8]) { self.write(buf) }
-    fn flush(&mut self) { self.flush() }
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
+    fn flush(&mut self) -> IoResult<()> { self.flush() }
 }
 
 impl<'a> Writer for &'a mut Writer {
-    fn write(&mut self, buf: &[u8]) { self.write(buf) }
-    fn flush(&mut self) { self.flush() }
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.write(buf) }
+    fn flush(&mut self) -> IoResult<()> { self.flush() }
 }
 
 pub trait Stream: Reader + Writer { }
@@ -1057,18 +986,18 @@ impl<T: Reader + Writer> Stream for T {}
 /// an iteration, but continue to yield elements if iteration
 /// is attempted again.
 ///
-/// # Failure
+/// # Error
 ///
-/// Raises the same conditions as the `read` method except for `EndOfFile`
-/// which is swallowed.
-/// Iteration yields `None` if the condition is handled.
+/// This iterator will swallow all I/O errors, transforming `Err` values to
+/// `None`. If errors need to be handled, it is recommended to use the
+/// `read_line` method directly.
 pub struct Lines<'r, T> {
     priv buffer: &'r mut T,
 }
 
 impl<'r, T: Buffer> Iterator<~str> for Lines<'r, T> {
     fn next(&mut self) -> Option<~str> {
-        self.buffer.read_line()
+        self.buffer.read_line().ok()
     }
 }
 
@@ -1085,11 +1014,12 @@ pub trait Buffer: Reader {
     /// consumed from this buffer returned to ensure that the bytes are never
     /// returned twice.
     ///
-    /// # Failure
+    /// # Error
     ///
-    /// This function will raise on the `io_error` condition if a read error is
-    /// encountered.
-    fn fill<'a>(&'a mut self) -> &'a [u8];
+    /// This function will return an I/O error if the underlying reader was
+    /// read, but returned an error. Note that it is not an error to return a
+    /// 0-length buffer.
+    fn fill<'a>(&'a mut self) -> IoResult<&'a [u8]>;
 
     /// Tells this buffer that `amt` bytes have been consumed from the buffer,
     /// so they should no longer be returned in calls to `fill` or `read`.
@@ -1103,108 +1033,117 @@ pub trait Buffer: Reader {
     ///
     /// ```rust
     /// use std::io::{BufferedReader, stdin};
-    /// # let _g = ::std::io::ignore_io_error();
     ///
     /// let mut reader = BufferedReader::new(stdin());
     ///
-    /// let input = reader.read_line().unwrap_or(~"nothing");
+    /// let input = reader.read_line().ok().unwrap_or(~"nothing");
     /// ```
     ///
-    /// # Failure
+    /// # Error
+    ///
+    /// This function has the same error semantics as `read_until`:
+    ///
+    /// * All non-EOF errors will be returned immediately
+    /// * If an error is returned previously consumed bytes are lost
+    /// * EOF is only returned if no bytes have been read
+    /// * Reach EOF may mean that the delimiter is not present in the return
+    ///   value
     ///
-    /// This function will raise on the `io_error` condition (except for
-    /// `EndOfFile` which is swallowed) if a read error is encountered.
-    /// The task will also fail if sequence of bytes leading up to
-    /// the newline character are not valid UTF-8.
-    fn read_line(&mut self) -> Option<~str> {
-        self.read_until('\n' as u8).map(|line| str::from_utf8_owned(line).unwrap())
+    /// Additionally, this function can fail if the line of input read is not a
+    /// valid UTF-8 sequence of bytes.
+    fn read_line(&mut self) -> IoResult<~str> {
+        self.read_until('\n' as u8).and_then(|line|
+            match str::from_utf8_owned(line) {
+                Some(s) => Ok(s),
+                None => Err(standard_error(InvalidInput)),
+            }
+        )
     }
 
     /// Create an iterator that reads a line on each iteration until EOF.
     ///
-    /// # Failure
+    /// # Error
     ///
-    /// Iterator raises the same conditions as the `read` method
-    /// except for `EndOfFile`.
+    /// This iterator will transform all error values to `None`, discarding the
+    /// cause of the error. If this is undesirable, it is recommended to call
+    /// `read_line` directly.
     fn lines<'r>(&'r mut self) -> Lines<'r, Self> {
-        Lines {
-            buffer: self,
-        }
+        Lines { buffer: self }
     }
 
     /// Reads a sequence of bytes leading up to a specified delimiter. Once the
     /// specified byte is encountered, reading ceases and the bytes up to and
     /// including the delimiter are returned.
     ///
-    /// # Failure
+    /// # Error
     ///
-    /// This function will raise on the `io_error` condition if a read error is
-    /// encountered, except that `EndOfFile` is swallowed.
-    fn read_until(&mut self, byte: u8) -> Option<~[u8]> {
+    /// If any I/O error is encountered other than EOF, the error is immediately
+    /// returned. Note that this may discard bytes which have already been read,
+    /// and those bytes will *not* be returned. It is recommended to use other
+    /// methods if this case is worrying.
+    ///
+    /// If EOF is encountered, then this function will return EOF if 0 bytes
+    /// have been read, otherwise the pending byte buffer is returned. This
+    /// is the reason that the byte buffer returned may not always contain the
+    /// delimiter.
+    fn read_until(&mut self, byte: u8) -> IoResult<~[u8]> {
         let mut res = ~[];
 
-        io_error::cond.trap(|e| {
-            if e.kind != EndOfFile {
-                io_error::cond.raise(e);
-            }
-        }).inside(|| {
-            let mut used;
-            loop {
-                {
-                    let available = self.fill();
-                    match available.iter().position(|&b| b == byte) {
-                        Some(i) => {
-                            res.push_all(available.slice_to(i + 1));
-                            used = i + 1;
-                            break
-                        }
-                        None => {
-                            res.push_all(available);
-                            used = available.len();
-                        }
+        let mut used;
+        loop {
+            {
+                let available = match self.fill() {
+                    Ok(n) => n,
+                    Err(ref e) if res.len() > 0 && e.kind == EndOfFile => {
+                        used = 0;
+                        break
+                    }
+                    Err(e) => return Err(e)
+                };
+                match available.iter().position(|&b| b == byte) {
+                    Some(i) => {
+                        res.push_all(available.slice_to(i + 1));
+                        used = i + 1;
+                        break
+                    }
+                    None => {
+                        res.push_all(available);
+                        used = available.len();
                     }
                 }
-                if used == 0 {
-                    break
-                }
-                self.consume(used);
             }
             self.consume(used);
-        });
-        return if res.len() == 0 {None} else {Some(res)};
-
+        }
+        self.consume(used);
+        Ok(res)
     }
 
     /// Reads the next utf8-encoded character from the underlying stream.
     ///
-    /// This will return `None` if the following sequence of bytes in the
-    /// stream are not a valid utf8-sequence, or if an I/O error is encountered.
-    ///
-    /// # Failure
-    ///
-    /// This function will raise on the `io_error` condition if a read error is
-    /// encountered.
-    fn read_char(&mut self) -> Option<char> {
-        let width = {
-            let available = self.fill();
-            if available.len() == 0 { return None } // read error
-            str::utf8_char_width(available[0])
-        };
-        if width == 0 { return None } // not uf8
-        let mut buf = [0, ..4];
+    /// # Error
+    ///
+    /// If an I/O error occurs, or EOF, then this function will return `Err`.
+    /// This function will also return error if the stream does not contain a
+    /// valid utf-8 encoded codepoint as the next few bytes in the stream.
+    fn read_char(&mut self) -> IoResult<char> {
+        let first_byte = if_ok!(self.read_byte());
+        let width = str::utf8_char_width(first_byte);
+        if width == 1 { return Ok(first_byte as char) }
+        if width == 0 { return Err(standard_error(InvalidInput)) } // not utf8
+        let mut buf = [first_byte, 0, 0, 0];
         {
-            let mut start = 0;
-            loop {
-                match self.read(buf.mut_slice(start, width)) {
-                    Some(n) if n == width - start => break,
-                    Some(n) if n < width - start => { start += n; }
-                    Some(..) | None => return None // read error
+            let mut start = 1;
+            while start < width {
+                match if_ok!(self.read(buf.mut_slice(start, width))) {
+                    n if n == width - start => break,
+                    n if n < width - start => { start += n; }
+                    _ => return Err(standard_error(InvalidInput)),
                 }
             }
         }
         match str::from_utf8(buf.slice_to(width)) {
-            Some(s) => Some(s.char_at(0)),
-            None => None
+            Some(s) => Ok(s.char_at(0)),
+            None => Err(standard_error(InvalidInput))
         }
     }
 }
@@ -1222,7 +1161,7 @@ pub enum SeekStyle {
 /// * Are `u64` and `i64` the right choices?
 pub trait Seek {
     /// Return position of file cursor in the stream
-    fn tell(&self) -> u64;
+    fn tell(&self) -> IoResult<u64>;
 
     /// Seek to an offset in a stream
     ///
@@ -1231,31 +1170,35 @@ pub trait Seek {
     /// # FIXME
     ///
     /// * What is the behavior when seeking past the end of a stream?
-    fn seek(&mut self, pos: i64, style: SeekStyle);
+    fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()>;
 }
 
-/// A listener is a value that can consume itself to start listening for connections.
+/// A listener is a value that can consume itself to start listening for
+/// connections.
+///
 /// Doing so produces some sort of Acceptor.
 pub trait Listener<T, A: Acceptor<T>> {
     /// Spin up the listener and start queuing incoming connections
     ///
-    /// # Failure
+    /// # Error
     ///
-    /// Raises `io_error` condition. If the condition is handled,
-    /// then `listen` returns `None`.
-    fn listen(self) -> Option<A>;
+    /// Returns `Err` if this listener could not be bound to listen for
+    /// connections. In all cases, this listener is consumed.
+    fn listen(self) -> IoResult<A>;
 }
 
 /// An acceptor is a value that presents incoming connections
 pub trait Acceptor<T> {
     /// Wait for and accept an incoming connection
     ///
-    /// # Failure
-    /// Raise `io_error` condition. If the condition is handled,
-    /// then `accept` returns `None`.
-    fn accept(&mut self) -> Option<T>;
+    /// # Error
+    ///
+    /// Returns `Err` if an I/O error is encountered.
+    fn accept(&mut self) -> IoResult<T>;
 
-    /// Create an iterator over incoming connection attempts
+    /// Create an iterator over incoming connection attempts.
+    ///
+    /// Note that I/O errors will be yielded by the iterator itself.
     fn incoming<'r>(&'r mut self) -> IncomingConnections<'r, Self> {
         IncomingConnections { inc: self }
     }
@@ -1264,23 +1207,22 @@ pub trait Acceptor<T> {
 /// An infinite iterator over incoming connection attempts.
 /// Calling `next` will block the task until a connection is attempted.
 ///
-/// Since connection attempts can continue forever, this iterator always returns Some.
-/// The Some contains another Option representing whether the connection attempt was succesful.
-/// A successful connection will be wrapped in Some.
-/// A failed connection is represented as a None and raises a condition.
+/// Since connection attempts can continue forever, this iterator always returns
+/// `Some`. The `Some` contains the `IoResult` representing whether the
+/// connection attempt was succesful.  A successful connection will be wrapped
+/// in `Ok`. A failed connection is represented as an `Err`.
 pub struct IncomingConnections<'a, A> {
     priv inc: &'a mut A,
 }
 
-impl<'a, T, A: Acceptor<T>> Iterator<Option<T>> for IncomingConnections<'a, A> {
-    fn next(&mut self) -> Option<Option<T>> {
+impl<'a, T, A: Acceptor<T>> Iterator<IoResult<T>> for IncomingConnections<'a, A> {
+    fn next(&mut self) -> Option<IoResult<T>> {
         Some(self.inc.accept())
     }
 }
 
 pub fn standard_error(kind: IoErrorKind) -> IoError {
     let desc = match kind {
-        PreviousIoError => "failing due to previous I/O error",
         EndOfFile => "end of file",
         IoUnavailable => "I/O is unavailable",
         InvalidInput => "invalid input",
@@ -1314,7 +1256,7 @@ pub enum FileMode {
 }
 
 /// Access permissions with which the file should be opened. `File`s
-/// opened with `Read` will raise an `io_error` condition if written to.
+/// opened with `Read` will return an error if written to.
 pub enum FileAccess {
     Read,
     Write,
diff --git a/src/libstd/io/net/addrinfo.rs b/src/libstd/io/net/addrinfo.rs
index 29bf6261a07..e9ffe97f1c3 100644
--- a/src/libstd/io/net/addrinfo.rs
+++ b/src/libstd/io/net/addrinfo.rs
@@ -17,8 +17,9 @@ getaddrinfo()
 
 */
 
-use option::{Option, Some, None};
+use io::IoResult;
 use io::net::ip::{SocketAddr, IpAddr};
+use option::{Option, Some, None};
 use rt::rtio::{IoFactory, LocalIo};
 use vec::ImmutableVector;
 
@@ -69,11 +70,7 @@ pub struct Info {
 
 /// Easy name resolution. Given a hostname, returns the list of IP addresses for
 /// that hostname.
-///
-/// # Failure
-///
-/// On failure, this will raise on the `io_error` condition.
-pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
+pub fn get_host_addresses(host: &str) -> IoResult<~[IpAddr]> {
     lookup(Some(host), None, None).map(|a| a.map(|i| i.address.ip))
 }
 
@@ -87,14 +84,10 @@ pub fn get_host_addresses(host: &str) -> Option<~[IpAddr]> {
 /// * hint - see the hint structure, and "man -s 3 getaddrinfo", for how this
 ///          controls lookup
 ///
-/// # Failure
-///
-/// On failure, this will raise on the `io_error` condition.
-///
 /// FIXME: this is not public because the `Hint` structure is not ready for public
 ///      consumption just yet.
 fn lookup(hostname: Option<&str>, servname: Option<&str>, hint: Option<Hint>)
-          -> Option<~[Info]> {
+          -> IoResult<~[Info]> {
     LocalIo::maybe_raise(|io| io.get_host_addresses(hostname, servname, hint))
 }
 
@@ -115,6 +108,6 @@ mod test {
     iotest!(fn issue_10663() {
         // Something should happen here, but this certainly shouldn't cause
         // everything to die. The actual outcome we don't care too much about.
-        get_host_addresses("example.com");
+        get_host_addresses("example.com").unwrap();
     } #[ignore])
 }
diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs
index 475e3b206f2..a0bdc193d98 100644
--- a/src/libstd/io/net/tcp.rs
+++ b/src/libstd/io/net/tcp.rs
@@ -8,11 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use option::{Option, Some, None};
-use result::{Ok, Err};
 use io::net::ip::SocketAddr;
-use io::{Reader, Writer, Listener, Acceptor};
-use io::{io_error, EndOfFile};
+use io::{Reader, Writer, Listener, Acceptor, IoResult};
 use rt::rtio::{IoFactory, LocalIo, RtioSocket, RtioTcpListener};
 use rt::rtio::{RtioTcpAcceptor, RtioTcpStream};
 
@@ -25,57 +22,27 @@ impl TcpStream {
         TcpStream { obj: s }
     }
 
-    pub fn connect(addr: SocketAddr) -> Option<TcpStream> {
+    pub fn connect(addr: SocketAddr) -> IoResult<TcpStream> {
         LocalIo::maybe_raise(|io| {
             io.tcp_connect(addr).map(TcpStream::new)
         })
     }
 
-    pub fn peer_name(&mut self) -> Option<SocketAddr> {
-        match self.obj.peer_name() {
-            Ok(pn) => Some(pn),
-            Err(ioerr) => {
-                debug!("failed to get peer name: {:?}", ioerr);
-                io_error::cond.raise(ioerr);
-                None
-            }
-        }
+    pub fn peer_name(&mut self) -> IoResult<SocketAddr> {
+        self.obj.peer_name()
     }
 
-    pub fn socket_name(&mut self) -> Option<SocketAddr> {
-        match self.obj.socket_name() {
-            Ok(sn) => Some(sn),
-            Err(ioerr) => {
-                debug!("failed to get socket name: {:?}", ioerr);
-                io_error::cond.raise(ioerr);
-                None
-            }
-        }
+    pub fn socket_name(&mut self) -> IoResult<SocketAddr> {
+        self.obj.socket_name()
     }
 }
 
 impl Reader for TcpStream {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
-        match self.obj.read(buf) {
-            Ok(read) => Some(read),
-            Err(ioerr) => {
-                // EOF is indicated by returning None
-                if ioerr.kind != EndOfFile {
-                    io_error::cond.raise(ioerr);
-                }
-                return None;
-            }
-        }
-    }
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.obj.read(buf) }
 }
 
 impl Writer for TcpStream {
-    fn write(&mut self, buf: &[u8]) {
-        match self.obj.write(buf) {
-            Ok(_) => (),
-            Err(ioerr) => io_error::cond.raise(ioerr),
-        }
-    }
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.obj.write(buf) }
 }
 
 pub struct TcpListener {
@@ -83,33 +50,20 @@ pub struct TcpListener {
 }
 
 impl TcpListener {
-    pub fn bind(addr: SocketAddr) -> Option<TcpListener> {
+    pub fn bind(addr: SocketAddr) -> IoResult<TcpListener> {
         LocalIo::maybe_raise(|io| {
             io.tcp_bind(addr).map(|l| TcpListener { obj: l })
         })
     }
 
-    pub fn socket_name(&mut self) -> Option<SocketAddr> {
-        match self.obj.socket_name() {
-            Ok(sn) => Some(sn),
-            Err(ioerr) => {
-                debug!("failed to get socket name: {:?}", ioerr);
-                io_error::cond.raise(ioerr);
-                None
-            }
-        }
+    pub fn socket_name(&mut self) -> IoResult<SocketAddr> {
+        self.obj.socket_name()
     }
 }
 
 impl Listener<TcpStream, TcpAcceptor> for TcpListener {
-    fn listen(self) -> Option<TcpAcceptor> {
-        match self.obj.listen() {
-            Ok(acceptor) => Some(TcpAcceptor { obj: acceptor }),
-            Err(ioerr) => {
-                io_error::cond.raise(ioerr);
-                None
-            }
-        }
+    fn listen(self) -> IoResult<TcpAcceptor> {
+        self.obj.listen().map(|acceptor| TcpAcceptor { obj: acceptor })
     }
 }
 
@@ -118,14 +72,8 @@ pub struct TcpAcceptor {
 }
 
 impl Acceptor<TcpStream> for TcpAcceptor {
-    fn accept(&mut self) -> Option<TcpStream> {
-        match self.obj.accept() {
-            Ok(s) => Some(TcpStream::new(s)),
-            Err(ioerr) => {
-                io_error::cond.raise(ioerr);
-                None
-            }
-        }
+    fn accept(&mut self) -> IoResult<TcpStream> {
+        self.obj.accept().map(TcpStream::new)
     }
 }
 
@@ -138,29 +86,19 @@ mod test {
 
     // FIXME #11530 this fails on android because tests are run as root
     iotest!(fn bind_error() {
-        let mut called = false;
-        io_error::cond.trap(|e| {
-            assert!(e.kind == PermissionDenied);
-            called = true;
-        }).inside(|| {
-            let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
-            let listener = TcpListener::bind(addr);
-            assert!(listener.is_none());
-        });
-        assert!(called);
+        let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
+        match TcpListener::bind(addr) {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind, PermissionDenied),
+        }
     } #[ignore(cfg(windows))] #[ignore(cfg(target_os = "android"))])
 
     iotest!(fn connect_error() {
-        let mut called = false;
-        io_error::cond.trap(|e| {
-            assert_eq!(e.kind, ConnectionRefused);
-            called = true;
-        }).inside(|| {
-            let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
-            let stream = TcpStream::connect(addr);
-            assert!(stream.is_none());
-        });
-        assert!(called);
+        let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
+        match TcpStream::connect(addr) {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind, ConnectionRefused),
+        }
     })
 
     iotest!(fn smoke_test_ip4() {
@@ -170,14 +108,14 @@ mod test {
         spawn(proc() {
             port.recv();
             let mut stream = TcpStream::connect(addr);
-            stream.write([99]);
+            stream.write([99]).unwrap();
         });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
         let mut stream = acceptor.accept();
         let mut buf = [0];
-        stream.read(buf);
+        stream.read(buf).unwrap();
         assert!(buf[0] == 99);
     })
 
@@ -188,14 +126,14 @@ mod test {
         spawn(proc() {
             port.recv();
             let mut stream = TcpStream::connect(addr);
-            stream.write([99]);
+            stream.write([99]).unwrap();
         });
 
         let mut acceptor = TcpListener::bind(addr).listen();
         chan.send(());
         let mut stream = acceptor.accept();
         let mut buf = [0];
-        stream.read(buf);
+        stream.read(buf).unwrap();
         assert!(buf[0] == 99);
     })
 
@@ -214,7 +152,7 @@ mod test {
         let mut stream = acceptor.accept();
         let mut buf = [0];
         let nread = stream.read(buf);
-        assert!(nread.is_none());
+        assert!(nread.is_err());
     })
 
     iotest!(fn read_eof_ip6() {
@@ -232,7 +170,7 @@ mod test {
         let mut stream = acceptor.accept();
         let mut buf = [0];
         let nread = stream.read(buf);
-        assert!(nread.is_none());
+        assert!(nread.is_err());
     })
 
     iotest!(fn read_eof_twice_ip4() {
@@ -250,17 +188,15 @@ mod test {
         let mut stream = acceptor.accept();
         let mut buf = [0];
         let nread = stream.read(buf);
-        assert!(nread.is_none());
-        io_error::cond.trap(|e| {
-            if cfg!(windows) {
-                assert_eq!(e.kind, NotConnected);
-            } else {
-                fail!();
+        assert!(nread.is_err());
+
+        match stream.read(buf) {
+            Ok(..) => fail!(),
+            Err(ref e) => {
+                assert!(e.kind == NotConnected || e.kind == EndOfFile,
+                        "unknown kind: {:?}", e.kind);
             }
-        }).inside(|| {
-            let nread = stream.read(buf);
-            assert!(nread.is_none());
-        })
+        }
     })
 
     iotest!(fn read_eof_twice_ip6() {
@@ -278,17 +214,15 @@ mod test {
         let mut stream = acceptor.accept();
         let mut buf = [0];
         let nread = stream.read(buf);
-        assert!(nread.is_none());
-        io_error::cond.trap(|e| {
-            if cfg!(windows) {
-                assert_eq!(e.kind, NotConnected);
-            } else {
-                fail!();
+        assert!(nread.is_err());
+
+        match stream.read(buf) {
+            Ok(..) => fail!(),
+            Err(ref e) => {
+                assert!(e.kind == NotConnected || e.kind == EndOfFile,
+                        "unknown kind: {:?}", e.kind);
             }
-        }).inside(|| {
-            let nread = stream.read(buf);
-            assert!(nread.is_none());
-        })
+        }
     })
 
     iotest!(fn write_close_ip4() {
@@ -306,19 +240,16 @@ mod test {
         let mut stream = acceptor.accept();
         let buf = [0];
         loop {
-            let mut stop = false;
-            io_error::cond.trap(|e| {
-                // NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED
-                //     on windows
-                assert!(e.kind == ConnectionReset ||
-                        e.kind == BrokenPipe ||
-                        e.kind == ConnectionAborted,
-                        "unknown error: {:?}", e);
-                stop = true;
-            }).inside(|| {
-                stream.write(buf);
-            });
-            if stop { break }
+            match stream.write(buf) {
+                Ok(..) => {}
+                Err(e) => {
+                    assert!(e.kind == ConnectionReset ||
+                            e.kind == BrokenPipe ||
+                            e.kind == ConnectionAborted,
+                            "unknown error: {:?}", e);
+                    break;
+                }
+            }
         }
     })
 
@@ -337,19 +268,16 @@ mod test {
         let mut stream = acceptor.accept();
         let buf = [0];
         loop {
-            let mut stop = false;
-            io_error::cond.trap(|e| {
-                // NB: ECONNRESET on linux, EPIPE on mac, ECONNABORTED
-                //     on windows
-                assert!(e.kind == ConnectionReset ||
-                        e.kind == BrokenPipe ||
-                        e.kind == ConnectionAborted,
-                        "unknown error: {:?}", e);
-                stop = true;
-            }).inside(|| {
-                stream.write(buf);
-            });
-            if stop { break }
+            match stream.write(buf) {
+                Ok(..) => {}
+                Err(e) => {
+                    assert!(e.kind == ConnectionReset ||
+                            e.kind == BrokenPipe ||
+                            e.kind == ConnectionAborted,
+                            "unknown error: {:?}", e);
+                    break;
+                }
+            }
         }
     })
 
@@ -362,7 +290,7 @@ mod test {
             port.recv();
             for _ in range(0, max) {
                 let mut stream = TcpStream::connect(addr);
-                stream.write([99]);
+                stream.write([99]).unwrap();
             }
         });
 
@@ -370,7 +298,7 @@ mod test {
         chan.send(());
         for ref mut stream in acceptor.incoming().take(max) {
             let mut buf = [0];
-            stream.read(buf);
+            stream.read(buf).unwrap();
             assert_eq!(buf[0], 99);
         }
     })
@@ -384,7 +312,7 @@ mod test {
             port.recv();
             for _ in range(0, max) {
                 let mut stream = TcpStream::connect(addr);
-                stream.write([99]);
+                stream.write([99]).unwrap();
             }
         });
 
@@ -392,7 +320,7 @@ mod test {
         chan.send(());
         for ref mut stream in acceptor.incoming().take(max) {
             let mut buf = [0];
-            stream.read(buf);
+            stream.read(buf).unwrap();
             assert_eq!(buf[0], 99);
         }
     })
@@ -410,7 +338,7 @@ mod test {
                 spawn(proc() {
                     let mut stream = stream;
                     let mut buf = [0];
-                    stream.read(buf);
+                    stream.read(buf).unwrap();
                     assert!(buf[0] == i as u8);
                     debug!("read");
                 });
@@ -429,7 +357,7 @@ mod test {
                 // Connect again before writing
                 connect(i + 1, addr);
                 debug!("writing");
-                stream.write([i as u8]);
+                stream.write([i as u8]).unwrap();
             });
         }
     })
@@ -447,7 +375,7 @@ mod test {
                 spawn(proc() {
                     let mut stream = stream;
                     let mut buf = [0];
-                    stream.read(buf);
+                    stream.read(buf).unwrap();
                     assert!(buf[0] == i as u8);
                     debug!("read");
                 });
@@ -466,7 +394,7 @@ mod test {
                 // Connect again before writing
                 connect(i + 1, addr);
                 debug!("writing");
-                stream.write([i as u8]);
+                stream.write([i as u8]).unwrap();
             });
         }
     })
@@ -484,7 +412,7 @@ mod test {
                 spawn(proc() {
                     let mut stream = stream;
                     let mut buf = [0];
-                    stream.read(buf);
+                    stream.read(buf).unwrap();
                     assert!(buf[0] == 99);
                     debug!("read");
                 });
@@ -503,7 +431,7 @@ mod test {
                 // Connect again before writing
                 connect(i + 1, addr);
                 debug!("writing");
-                stream.write([99]);
+                stream.write([99]).unwrap();
             });
         }
     })
@@ -521,7 +449,7 @@ mod test {
                 spawn(proc() {
                     let mut stream = stream;
                     let mut buf = [0];
-                    stream.read(buf);
+                    stream.read(buf).unwrap();
                     assert!(buf[0] == 99);
                     debug!("read");
                 });
@@ -540,7 +468,7 @@ mod test {
                 // Connect again before writing
                 connect(i + 1, addr);
                 debug!("writing");
-                stream.write([99]);
+                stream.write([99]).unwrap();
             });
         }
     })
@@ -551,7 +479,7 @@ mod test {
         // Make sure socket_name gives
         // us the socket we binded to.
         let so_name = listener.socket_name();
-        assert!(so_name.is_some());
+        assert!(so_name.is_ok());
         assert_eq!(addr, so_name.unwrap());
     }
 
@@ -561,20 +489,20 @@ mod test {
         spawn(proc() {
             let mut acceptor = TcpListener::bind(addr).listen();
             chan.send(());
-            acceptor.accept();
+            acceptor.accept().unwrap();
         });
 
         port.recv();
         let stream = TcpStream::connect(addr);
 
-        assert!(stream.is_some());
+        assert!(stream.is_ok());
         let mut stream = stream.unwrap();
 
         // Make sure peer_name gives us the
         // address/port of the peer we've
         // connected to.
         let peer_name = stream.peer_name();
-        assert!(peer_name.is_some());
+        assert!(peer_name.is_ok());
         assert_eq!(addr, peer_name.unwrap());
     }
 
@@ -593,37 +521,33 @@ mod test {
         let addr = next_test_ip4();
         let (p, c) = Chan::new();
         spawn(proc() {
-            let mut srv = TcpListener::bind(addr).listen();
+            let mut srv = TcpListener::bind(addr).listen().unwrap();
             c.send(());
             let mut cl = srv.accept().unwrap();
-            cl.write([10]);
+            cl.write([10]).unwrap();
             let mut b = [0];
-            cl.read(b);
+            cl.read(b).unwrap();
             c.send(());
         });
 
         p.recv();
         let mut c = TcpStream::connect(addr).unwrap();
         let mut b = [0, ..10];
-        assert_eq!(c.read(b), Some(1));
-        c.write([1]);
+        assert_eq!(c.read(b), Ok(1));
+        c.write([1]).unwrap();
         p.recv();
     })
 
     iotest!(fn double_bind() {
-        let mut called = false;
-        io_error::cond.trap(|e| {
-            assert!(e.kind == ConnectionRefused || e.kind == OtherIoError);
-            called = true;
-        }).inside(|| {
-            let addr = next_test_ip4();
-            let listener = TcpListener::bind(addr).unwrap().listen();
-            assert!(listener.is_some());
-            let listener2 = TcpListener::bind(addr).and_then(|l|
-                                                    l.listen());
-            assert!(listener2.is_none());
-        });
-        assert!(called);
+        let addr = next_test_ip4();
+        let listener = TcpListener::bind(addr).unwrap().listen();
+        assert!(listener.is_ok());
+        match TcpListener::bind(addr).listen() {
+            Ok(..) => fail!(),
+            Err(e) => {
+                assert!(e.kind == ConnectionRefused || e.kind == OtherIoError);
+            }
+        }
     })
 
     iotest!(fn fast_rebind() {
@@ -632,7 +556,7 @@ mod test {
 
         spawn(proc() {
             port.recv();
-            let _stream = TcpStream::connect(addr);
+            let _stream = TcpStream::connect(addr).unwrap();
             // Close
             port.recv();
         });
@@ -641,7 +565,7 @@ mod test {
             let mut acceptor = TcpListener::bind(addr).listen();
             chan.send(());
             {
-                let _stream = acceptor.accept();
+                let _stream = acceptor.accept().unwrap();
                 // Close client
                 chan.send(());
             }
diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs
index 1cf30d469f7..0ef62648afc 100644
--- a/src/libstd/io/net/udp.rs
+++ b/src/libstd/io/net/udp.rs
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use option::{Option, Some, None};
 use result::{Ok, Err};
 use io::net::ip::SocketAddr;
-use io::{Reader, Writer};
-use io::{io_error, EndOfFile};
+use io::{Reader, Writer, IoResult};
 use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, LocalIo};
 
 pub struct UdpSocket {
@@ -20,45 +18,26 @@ pub struct UdpSocket {
 }
 
 impl UdpSocket {
-    pub fn bind(addr: SocketAddr) -> Option<UdpSocket> {
+    pub fn bind(addr: SocketAddr) -> IoResult<UdpSocket> {
         LocalIo::maybe_raise(|io| {
             io.udp_bind(addr).map(|s| UdpSocket { obj: s })
         })
     }
 
-    pub fn recvfrom(&mut self, buf: &mut [u8]) -> Option<(uint, SocketAddr)> {
-        match self.obj.recvfrom(buf) {
-            Ok((nread, src)) => Some((nread, src)),
-            Err(ioerr) => {
-                // EOF is indicated by returning None
-                if ioerr.kind != EndOfFile {
-                    io_error::cond.raise(ioerr);
-                }
-                None
-            }
-        }
+    pub fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)> {
+        self.obj.recvfrom(buf)
     }
 
-    pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) {
-        match self.obj.sendto(buf, dst) {
-            Ok(_) => (),
-            Err(ioerr) => io_error::cond.raise(ioerr),
-        }
+    pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()> {
+        self.obj.sendto(buf, dst)
     }
 
     pub fn connect(self, other: SocketAddr) -> UdpStream {
         UdpStream { socket: self, connectedTo: other }
     }
 
-    pub fn socket_name(&mut self) -> Option<SocketAddr> {
-        match self.obj.socket_name() {
-            Ok(sn) => Some(sn),
-            Err(ioerr) => {
-                debug!("failed to get socket name: {:?}", ioerr);
-                io_error::cond.raise(ioerr);
-                None
-            }
-        }
+    pub fn socket_name(&mut self) -> IoResult<SocketAddr> {
+        self.obj.socket_name()
     }
 }
 
@@ -76,21 +55,21 @@ impl UdpStream {
 }
 
 impl Reader for UdpStream {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let peer = self.connectedTo;
         self.as_socket(|sock| {
             match sock.recvfrom(buf) {
-                Some((_nread, src)) if src != peer => Some(0),
-                Some((nread, _src)) => Some(nread),
-                None => None,
+                Ok((_nread, src)) if src != peer => Ok(0),
+                Ok((nread, _src)) => Ok(nread),
+                Err(e) => Err(e),
             }
         })
     }
 }
 
 impl Writer for UdpStream {
-    fn write(&mut self, buf: &[u8]) {
-        self.as_socket(|sock| sock.sendto(buf, self.connectedTo));
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
+        self.as_socket(|sock| sock.sendto(buf, self.connectedTo))
     }
 }
 
@@ -101,16 +80,11 @@ mod test {
 
     // FIXME #11530 this fails on android because tests are run as root
     iotest!(fn bind_error() {
-        let mut called = false;
-        io_error::cond.trap(|e| {
-            assert_eq!(e.kind, PermissionDenied);
-            called = true;
-        }).inside(|| {
-            let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
-            let socket = UdpSocket::bind(addr);
-            assert!(socket.is_none());
-        });
-        assert!(called);
+        let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
+        match UdpSocket::bind(addr) {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind, PermissionDenied),
+        }
     } #[ignore(cfg(windows))] #[ignore(cfg(target_os = "android"))])
 
     iotest!(fn socket_smoke_test_ip4() {
@@ -121,29 +95,29 @@ mod test {
 
         spawn(proc() {
             match UdpSocket::bind(client_ip) {
-                Some(ref mut client) => {
+                Ok(ref mut client) => {
                     port.recv();
-                    client.sendto([99], server_ip)
+                    client.sendto([99], server_ip).unwrap()
                 }
-                None => fail!()
+                Err(..) => fail!()
             }
             chan2.send(());
         });
 
         match UdpSocket::bind(server_ip) {
-            Some(ref mut server) => {
+            Ok(ref mut server) => {
                 chan.send(());
                 let mut buf = [0];
                 match server.recvfrom(buf) {
-                    Some((nread, src)) => {
+                    Ok((nread, src)) => {
                         assert_eq!(nread, 1);
                         assert_eq!(buf[0], 99);
                         assert_eq!(src, client_ip);
                     }
-                    None => fail!()
+                    Err(..) => fail!()
                 }
             }
-            None => fail!()
+            Err(..) => fail!()
         }
         port2.recv();
     })
@@ -155,28 +129,28 @@ mod test {
 
         spawn(proc() {
             match UdpSocket::bind(client_ip) {
-                Some(ref mut client) => {
+                Ok(ref mut client) => {
                     port.recv();
-                    client.sendto([99], server_ip)
+                    client.sendto([99], server_ip).unwrap()
                 }
-                None => fail!()
+                Err(..) => fail!()
             }
         });
 
         match UdpSocket::bind(server_ip) {
-            Some(ref mut server) => {
+            Ok(ref mut server) => {
                 chan.send(());
                 let mut buf = [0];
                 match server.recvfrom(buf) {
-                    Some((nread, src)) => {
+                    Ok((nread, src)) => {
                         assert_eq!(nread, 1);
                         assert_eq!(buf[0], 99);
                         assert_eq!(src, client_ip);
                     }
-                    None => fail!()
+                    Err(..) => fail!()
                 }
             }
-            None => fail!()
+            Err(..) => fail!()
         }
     })
 
@@ -188,32 +162,32 @@ mod test {
 
         spawn(proc() {
             match UdpSocket::bind(client_ip) {
-                Some(client) => {
+                Ok(client) => {
                     let client = ~client;
                     let mut stream = client.connect(server_ip);
                     port.recv();
-                    stream.write([99]);
+                    stream.write([99]).unwrap();
                 }
-                None => fail!()
+                Err(..) => fail!()
             }
             chan2.send(());
         });
 
         match UdpSocket::bind(server_ip) {
-            Some(server) => {
+            Ok(server) => {
                 let server = ~server;
                 let mut stream = server.connect(client_ip);
                 chan.send(());
                 let mut buf = [0];
                 match stream.read(buf) {
-                    Some(nread) => {
+                    Ok(nread) => {
                         assert_eq!(nread, 1);
                         assert_eq!(buf[0], 99);
                     }
-                    None => fail!()
+                    Err(..) => fail!()
                 }
             }
-            None => fail!()
+            Err(..) => fail!()
         }
         port2.recv();
     })
@@ -226,32 +200,32 @@ mod test {
 
         spawn(proc() {
             match UdpSocket::bind(client_ip) {
-                Some(client) => {
+                Ok(client) => {
                     let client = ~client;
                     let mut stream = client.connect(server_ip);
                     port.recv();
-                    stream.write([99]);
+                    stream.write([99]).unwrap();
                 }
-                None => fail!()
+                Err(..) => fail!()
             }
             chan2.send(());
         });
 
         match UdpSocket::bind(server_ip) {
-            Some(server) => {
+            Ok(server) => {
                 let server = ~server;
                 let mut stream = server.connect(client_ip);
                 chan.send(());
                 let mut buf = [0];
                 match stream.read(buf) {
-                    Some(nread) => {
+                    Ok(nread) => {
                         assert_eq!(nread, 1);
                         assert_eq!(buf[0], 99);
                     }
-                    None => fail!()
+                    Err(..) => fail!()
                 }
             }
-            None => fail!()
+            Err(..) => fail!()
         }
         port2.recv();
     })
@@ -259,13 +233,13 @@ mod test {
     pub fn socket_name(addr: SocketAddr) {
         let server = UdpSocket::bind(addr);
 
-        assert!(server.is_some());
+        assert!(server.is_ok());
         let mut server = server.unwrap();
 
         // Make sure socket_name gives
         // us the socket we binded to.
         let so_name = server.socket_name();
-        assert!(so_name.is_some());
+        assert!(so_name.is_ok());
         assert_eq!(addr, so_name.unwrap());
     }
 
diff --git a/src/libstd/io/net/unix.rs b/src/libstd/io/net/unix.rs
index d470e9bfda1..ce95b987663 100644
--- a/src/libstd/io/net/unix.rs
+++ b/src/libstd/io/net/unix.rs
@@ -28,7 +28,7 @@ use c_str::ToCStr;
 use rt::rtio::{IoFactory, LocalIo, RtioUnixListener};
 use rt::rtio::{RtioUnixAcceptor, RtioPipe};
 use io::pipe::PipeStream;
-use io::{io_error, Listener, Acceptor, Reader, Writer};
+use io::{Listener, Acceptor, Reader, Writer, IoResult};
 
 /// A stream which communicates over a named pipe.
 pub struct UnixStream {
@@ -45,20 +45,17 @@ impl UnixStream {
     ///
     /// The returned stream will be closed when the object falls out of scope.
     ///
-    /// # Failure
-    ///
-    /// This function will raise on the `io_error` condition if the connection
-    /// could not be made.
-    ///
     /// # Example
     ///
-    ///     use std::io::net::unix::UnixStream;
+    /// ```rust
+    /// # #[allow(unused_must_use)];
+    /// use std::io::net::unix::UnixStream;
     ///
-    ///     let server = Path("path/to/my/socket");
-    ///     let mut stream = UnixStream::connect(&server);
-    ///     stream.write([1, 2, 3]);
-    ///
-    pub fn connect<P: ToCStr>(path: &P) -> Option<UnixStream> {
+    /// let server = Path::new("path/to/my/socket");
+    /// let mut stream = UnixStream::connect(&server);
+    /// stream.write([1, 2, 3]);
+    /// ```
+    pub fn connect<P: ToCStr>(path: &P) -> IoResult<UnixStream> {
         LocalIo::maybe_raise(|io| {
             io.unix_connect(&path.to_c_str()).map(UnixStream::new)
         })
@@ -66,11 +63,11 @@ impl UnixStream {
 }
 
 impl Reader for UnixStream {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> { self.obj.read(buf) }
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.obj.read(buf) }
 }
 
 impl Writer for UnixStream {
-    fn write(&mut self, buf: &[u8]) { self.obj.write(buf) }
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.obj.write(buf) }
 }
 
 pub struct UnixListener {
@@ -84,23 +81,20 @@ impl UnixListener {
     ///
     /// This listener will be closed when it falls out of scope.
     ///
-    /// # Failure
-    ///
-    /// This function will raise on the `io_error` condition if the specified
-    /// path could not be bound.
-    ///
     /// # Example
     ///
-    ///     use std::io::net::unix::UnixListener;
-    ///
-    ///     let server = Path("path/to/my/socket");
-    ///     let mut stream = UnixListener::bind(&server);
-    ///     for client in stream.incoming() {
-    ///         let mut client = client;
-    ///         client.write([1, 2, 3, 4]);
-    ///     }
+    /// ```
+    /// use std::io::net::unix::UnixListener;
+    /// use std::io::Listener;
     ///
-    pub fn bind<P: ToCStr>(path: &P) -> Option<UnixListener> {
+    /// let server = Path::new("path/to/my/socket");
+    /// let mut stream = UnixListener::bind(&server);
+    /// for client in stream.incoming() {
+    ///     let mut client = client;
+    ///     client.write([1, 2, 3, 4]);
+    /// }
+    /// ```
+    pub fn bind<P: ToCStr>(path: &P) -> IoResult<UnixListener> {
         LocalIo::maybe_raise(|io| {
             io.unix_bind(&path.to_c_str()).map(|s| UnixListener { obj: s })
         })
@@ -108,14 +102,8 @@ impl UnixListener {
 }
 
 impl Listener<UnixStream, UnixAcceptor> for UnixListener {
-    fn listen(self) -> Option<UnixAcceptor> {
-        match self.obj.listen() {
-            Ok(acceptor) => Some(UnixAcceptor { obj: acceptor }),
-            Err(ioerr) => {
-                io_error::cond.raise(ioerr);
-                None
-            }
-        }
+    fn listen(self) -> IoResult<UnixAcceptor> {
+        self.obj.listen().map(|obj| UnixAcceptor { obj: obj })
     }
 }
 
@@ -124,14 +112,8 @@ pub struct UnixAcceptor {
 }
 
 impl Acceptor<UnixStream> for UnixAcceptor {
-    fn accept(&mut self) -> Option<UnixStream> {
-        match self.obj.accept() {
-            Ok(s) => Some(UnixStream::new(s)),
-            Err(ioerr) => {
-                io_error::cond.raise(ioerr);
-                None
-            }
-        }
+    fn accept(&mut self) -> IoResult<UnixStream> {
+        self.obj.accept().map(UnixStream::new)
     }
 }
 
@@ -159,39 +141,29 @@ mod tests {
 
     #[test]
     fn bind_error() {
-        let mut called = false;
-        io_error::cond.trap(|e| {
-            assert!(e.kind == PermissionDenied);
-            called = true;
-        }).inside(|| {
-            let listener = UnixListener::bind(&("path/to/nowhere"));
-            assert!(listener.is_none());
-        });
-        assert!(called);
+        match UnixListener::bind(&("path/to/nowhere")) {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind, PermissionDenied),
+        }
     }
 
     #[test]
     fn connect_error() {
-        let mut called = false;
-        io_error::cond.trap(|e| {
-            assert_eq!(e.kind,
-                       if cfg!(windows) {OtherIoError} else {FileNotFound});
-            called = true;
-        }).inside(|| {
-            let stream = UnixStream::connect(&("path/to/nowhere"));
-            assert!(stream.is_none());
-        });
-        assert!(called);
+        match UnixStream::connect(&("path/to/nowhere")) {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind,
+                        if cfg!(windows) {OtherIoError} else {FileNotFound})
+        }
     }
 
     #[test]
     fn smoke() {
         smalltest(proc(mut server) {
             let mut buf = [0];
-            server.read(buf);
+            server.read(buf).unwrap();
             assert!(buf[0] == 99);
         }, proc(mut client) {
-            client.write([99]);
+            client.write([99]).unwrap();
         })
     }
 
@@ -199,8 +171,8 @@ mod tests {
     fn read_eof() {
         smalltest(proc(mut server) {
             let mut buf = [0];
-            assert!(server.read(buf).is_none());
-            assert!(server.read(buf).is_none());
+            assert!(server.read(buf).is_err());
+            assert!(server.read(buf).is_err());
         }, proc(_client) {
             // drop the client
         })
@@ -210,15 +182,15 @@ mod tests {
     fn write_begone() {
         smalltest(proc(mut server) {
             let buf = [0];
-            let mut stop = false;
-            while !stop{
-                io_error::cond.trap(|e| {
-                    assert!(e.kind == BrokenPipe || e.kind == NotConnected,
-                            "unknown error {:?}", e);
-                    stop = true;
-                }).inside(|| {
-                    server.write(buf);
-                })
+            loop {
+                match server.write(buf) {
+                    Ok(..) => {}
+                    Err(e) => {
+                        assert!(e.kind == BrokenPipe || e.kind == NotConnected,
+                                "unknown error {:?}", e);
+                        break;
+                    }
+                }
             }
         }, proc(_client) {
             // drop the client
@@ -236,7 +208,7 @@ mod tests {
             port.recv();
             for _ in range(0, times) {
                 let mut stream = UnixStream::connect(&path2);
-                stream.write([100]);
+                stream.write([100]).unwrap();
             }
         });
 
@@ -245,7 +217,7 @@ mod tests {
         for _ in range(0, times) {
             let mut client = acceptor.accept();
             let mut buf = [0];
-            client.read(buf);
+            client.read(buf).unwrap();
             assert_eq!(buf[0], 100);
         }
     }
diff --git a/src/libstd/io/option.rs b/src/libstd/io/option.rs
deleted file mode 100644
index e2eec652d9d..00000000000
--- a/src/libstd/io/option.rs
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Implementations of I/O traits for the Option type
-//!
-//! I/O constructors return option types to allow errors to be handled.
-//! These implementations allow e.g. `Option<File>` to be used
-//! as a `Reader` without unwrapping the option first.
-
-use option::*;
-use super::{Reader, Writer, Listener, Acceptor, Seek, SeekStyle};
-use super::{standard_error, PreviousIoError, io_error, IoError};
-
-fn prev_io_error() -> IoError {
-    standard_error(PreviousIoError)
-}
-
-impl<W: Writer> Writer for Option<W> {
-    fn write(&mut self, buf: &[u8]) {
-        match *self {
-            Some(ref mut writer) => writer.write(buf),
-            None => io_error::cond.raise(prev_io_error())
-        }
-    }
-
-    fn flush(&mut self) {
-        match *self {
-            Some(ref mut writer) => writer.flush(),
-            None => io_error::cond.raise(prev_io_error())
-        }
-    }
-}
-
-impl<R: Reader> Reader for Option<R> {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
-        match *self {
-            Some(ref mut reader) => reader.read(buf),
-            None => {
-                io_error::cond.raise(prev_io_error());
-                None
-            }
-        }
-    }
-}
-
-impl<S: Seek> Seek for Option<S> {
-    fn tell(&self) -> u64 {
-        match *self {
-            Some(ref seeker) => seeker.tell(),
-            None => {
-                io_error::cond.raise(prev_io_error());
-                0
-            }
-        }
-    }
-    fn seek(&mut self, pos: i64, style: SeekStyle) {
-        match *self {
-            Some(ref mut seeker) => seeker.seek(pos, style),
-            None => io_error::cond.raise(prev_io_error())
-        }
-    }
-}
-
-impl<T, A: Acceptor<T>, L: Listener<T, A>> Listener<T, A> for Option<L> {
-    fn listen(self) -> Option<A> {
-        match self {
-            Some(listener) => listener.listen(),
-            None => {
-                io_error::cond.raise(prev_io_error());
-                None
-            }
-        }
-    }
-}
-
-impl<T, A: Acceptor<T>> Acceptor<T> for Option<A> {
-    fn accept(&mut self) -> Option<T> {
-        match *self {
-            Some(ref mut acceptor) => acceptor.accept(),
-            None => {
-                io_error::cond.raise(prev_io_error());
-                None
-            }
-        }
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use prelude::*;
-    use super::super::mem::*;
-    use super::super::{PreviousIoError, io_error};
-
-    #[test]
-    fn test_option_writer() {
-        let mut writer: Option<MemWriter> = Some(MemWriter::new());
-        writer.write([0, 1, 2]);
-        writer.flush();
-        assert_eq!(writer.unwrap().unwrap(), ~[0, 1, 2]);
-    }
-
-    #[test]
-    fn test_option_writer_error() {
-        let mut writer: Option<MemWriter> = None;
-
-        let mut called = false;
-        io_error::cond.trap(|err| {
-            assert_eq!(err.kind, PreviousIoError);
-            called = true;
-        }).inside(|| {
-            writer.write([0, 0, 0]);
-        });
-        assert!(called);
-
-        let mut called = false;
-        io_error::cond.trap(|err| {
-            assert_eq!(err.kind, PreviousIoError);
-            called = true;
-        }).inside(|| {
-            writer.flush();
-        });
-        assert!(called);
-    }
-
-    #[test]
-    fn test_option_reader() {
-        let mut reader: Option<MemReader> = Some(MemReader::new(~[0, 1, 2, 3]));
-        let mut buf = [0, 0];
-        reader.read(buf);
-        assert_eq!(buf, [0, 1]);
-    }
-
-    #[test]
-    fn test_option_reader_error() {
-        let mut reader: Option<MemReader> = None;
-        let mut buf = [];
-
-        let mut called = false;
-        io_error::cond.trap(|err| {
-            assert_eq!(err.kind, PreviousIoError);
-            called = true;
-        }).inside(|| {
-            reader.read(buf);
-        });
-        assert!(called);
-    }
-}
diff --git a/src/libstd/io/pipe.rs b/src/libstd/io/pipe.rs
index 9919d333f41..ca85707149b 100644
--- a/src/libstd/io/pipe.rs
+++ b/src/libstd/io/pipe.rs
@@ -14,7 +14,7 @@
 //! enough so that pipes can be created to child processes.
 
 use prelude::*;
-use io::{io_error, EndOfFile};
+use io::IoResult;
 use libc;
 use rt::rtio::{RtioPipe, LocalIo};
 
@@ -32,17 +32,15 @@ impl PipeStream {
     ///
     /// # Example
     ///
-    ///     use std::libc;
-    ///     use std::io::pipe;
+    /// ```rust
+    /// # #[allow(unused_must_use)];
+    /// use std::libc;
+    /// use std::io::pipe::PipeStream;
     ///
-    ///     let mut pipe = PipeStream::open(libc::STDERR_FILENO);
-    ///     pipe.write(bytes!("Hello, stderr!"));
-    ///
-    /// # Failure
-    ///
-    /// If the pipe cannot be created, an error will be raised on the
-    /// `io_error` condition.
-    pub fn open(fd: libc::c_int) -> Option<PipeStream> {
+    /// let mut pipe = PipeStream::open(libc::STDERR_FILENO);
+    /// pipe.write(bytes!("Hello, stderr!"));
+    /// ```
+    pub fn open(fd: libc::c_int) -> IoResult<PipeStream> {
         LocalIo::maybe_raise(|io| {
             io.pipe_open(fd).map(|obj| PipeStream { obj: obj })
         })
@@ -54,29 +52,11 @@ impl PipeStream {
 }
 
 impl Reader for PipeStream {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
-        match self.obj.read(buf) {
-            Ok(read) => Some(read),
-            Err(ioerr) => {
-                // EOF is indicated by returning None
-                if ioerr.kind != EndOfFile {
-                    io_error::cond.raise(ioerr);
-                }
-                return None;
-            }
-        }
-    }
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.obj.read(buf) }
 }
 
 impl Writer for PipeStream {
-    fn write(&mut self, buf: &[u8]) {
-        match self.obj.write(buf) {
-            Ok(_) => (),
-            Err(ioerr) => {
-                io_error::cond.raise(ioerr);
-            }
-        }
-    }
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> { self.obj.write(buf) }
 }
 
 #[cfg(test)]
@@ -91,12 +71,12 @@ mod test {
         let (p, c) = Chan::new();
         spawn(proc() {
             let mut out = out;
-            out.write([10]);
+            out.write([10]).unwrap();
             p.recv(); // don't close the pipe until the other read has finished
         });
 
         let mut buf = [0, ..10];
-        input.read(buf);
+        input.read(buf).unwrap();
         c.send(());
     })
 }
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index 6a10f24916f..ccf3d4582de 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -14,7 +14,7 @@ use prelude::*;
 
 use libc;
 use io;
-use io::io_error;
+use io::IoResult;
 use rt::rtio::{RtioProcess, IoFactory, LocalIo};
 
 use fmt;
@@ -93,7 +93,7 @@ pub enum ProcessExit {
 
 impl fmt::Show for ProcessExit {
     /// Format a ProcessExit enum, to nicely present the information.
-    fn fmt(obj: &ProcessExit, f: &mut fmt::Formatter) {
+    fn fmt(obj: &ProcessExit, f: &mut fmt::Formatter) -> fmt::Result {
         match *obj {
             ExitStatus(code) =>  write!(f.buf, "exit code: {}", code),
             ExitSignal(code) =>  write!(f.buf, "signal: {}", code),
@@ -118,7 +118,7 @@ impl ProcessExit {
 impl Process {
     /// Creates a new pipe initialized, but not bound to any particular
     /// source/destination
-    pub fn new(config: ProcessConfig) -> Option<Process> {
+    pub fn new(config: ProcessConfig) -> IoResult<Process> {
         let mut config = Some(config);
         LocalIo::maybe_raise(|io| {
             io.spawn(config.take_unwrap()).map(|(p, io)| {
@@ -141,14 +141,9 @@ impl Process {
     /// Note that this is purely a wrapper around libuv's `uv_process_kill`
     /// function.
     ///
-    /// If the signal delivery fails, then the `io_error` condition is raised on
-    pub fn signal(&mut self, signal: int) {
-        match self.handle.kill(signal) {
-            Ok(()) => {}
-            Err(err) => {
-                io_error::cond.raise(err)
-            }
-        }
+    /// If the signal delivery fails, the corresponding error is returned.
+    pub fn signal(&mut self, signal: int) -> IoResult<()> {
+        self.handle.kill(signal)
     }
 
     /// Wait for the child to exit completely, returning the status that it
@@ -176,7 +171,6 @@ impl Drop for Process {
 mod tests {
     use io::process::{ProcessConfig, Process};
     use prelude::*;
-    use str;
 
     // FIXME(#10380)
     #[cfg(unix, not(target_os="android"))]
@@ -190,7 +184,7 @@ mod tests {
             io: io,
         };
         let p = Process::new(args);
-        assert!(p.is_some());
+        assert!(p.is_ok());
         let mut p = p.unwrap();
         assert!(p.wait().success());
     })
@@ -206,7 +200,7 @@ mod tests {
             cwd: None,
             io: io,
         };
-        match io::result(|| Process::new(args)) {
+        match Process::new(args) {
             Ok(..) => fail!(),
             Err(..) => {}
         }
@@ -224,7 +218,7 @@ mod tests {
             io: io,
         };
         let p = Process::new(args);
-        assert!(p.is_some());
+        assert!(p.is_ok());
         let mut p = p.unwrap();
         assert!(p.wait().matches_exit_status(1));
     })
@@ -240,7 +234,7 @@ mod tests {
             io: io,
         };
         let p = Process::new(args);
-        assert!(p.is_some());
+        assert!(p.is_ok());
         let mut p = p.unwrap();
         match p.wait() {
             process::ExitSignal(1) => {},
@@ -249,20 +243,12 @@ mod tests {
     })
 
     pub fn read_all(input: &mut Reader) -> ~str {
-        let mut ret = ~"";
-        let mut buf = [0, ..1024];
-        loop {
-            match input.read(buf) {
-                None => { break }
-                Some(n) => { ret.push_str(str::from_utf8(buf.slice_to(n)).unwrap()); }
-            }
-        }
-        return ret;
+        input.read_to_str().unwrap()
     }
 
     pub fn run_output(args: ProcessConfig) -> ~str {
         let p = Process::new(args);
-        assert!(p.is_some());
+        assert!(p.is_ok());
         let mut p = p.unwrap();
         assert!(p.io[0].is_none());
         assert!(p.io[1].is_some());
@@ -312,8 +298,8 @@ mod tests {
             cwd: None,
             io: io,
         };
-        let mut p = Process::new(args).expect("didn't create a proces?!");
-        p.io[0].get_mut_ref().write("foobar".as_bytes());
+        let mut p = Process::new(args).unwrap();
+        p.io[0].get_mut_ref().write("foobar".as_bytes()).unwrap();
         p.io[0] = None; // close stdin;
         let out = read_all(p.io[1].get_mut_ref() as &mut Reader);
         assert!(p.wait().success());
diff --git a/src/libstd/io/result.rs b/src/libstd/io/result.rs
new file mode 100644
index 00000000000..8e03cffd0fb
--- /dev/null
+++ b/src/libstd/io/result.rs
@@ -0,0 +1,128 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Implementations of I/O traits for the IoResult type
+//!
+//! I/O constructors return option types to allow errors to be handled.
+//! These implementations allow e.g. `IoResult<File>` to be used
+//! as a `Reader` without unwrapping the result first.
+
+use clone::Clone;
+use result::{Ok, Err};
+use super::{Reader, Writer, Listener, Acceptor, Seek, SeekStyle, IoResult};
+
+impl<W: Writer> Writer for IoResult<W> {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
+        match *self {
+            Ok(ref mut writer) => writer.write(buf),
+            Err(ref e) => Err((*e).clone())
+        }
+    }
+
+    fn flush(&mut self) -> IoResult<()> {
+        match *self {
+            Ok(ref mut writer) => writer.flush(),
+            Err(ref e) => Err(e.clone()),
+        }
+    }
+}
+
+impl<R: Reader> Reader for IoResult<R> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
+        match *self {
+            Ok(ref mut reader) => reader.read(buf),
+            Err(ref e) => Err(e.clone()),
+        }
+    }
+}
+
+impl<S: Seek> Seek for IoResult<S> {
+    fn tell(&self) -> IoResult<u64> {
+        match *self {
+            Ok(ref seeker) => seeker.tell(),
+            Err(ref e) => Err(e.clone()),
+        }
+    }
+    fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
+        match *self {
+            Ok(ref mut seeker) => seeker.seek(pos, style),
+            Err(ref e) => Err(e.clone())
+        }
+    }
+}
+
+impl<T, A: Acceptor<T>, L: Listener<T, A>> Listener<T, A> for IoResult<L> {
+    fn listen(self) -> IoResult<A> {
+        match self {
+            Ok(listener) => listener.listen(),
+            Err(e) => Err(e),
+        }
+    }
+}
+
+impl<T, A: Acceptor<T>> Acceptor<T> for IoResult<A> {
+    fn accept(&mut self) -> IoResult<T> {
+        match *self {
+            Ok(ref mut acceptor) => acceptor.accept(),
+            Err(ref e) => Err(e.clone()),
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use prelude::*;
+    use super::super::mem::*;
+    use io;
+
+    #[test]
+    fn test_option_writer() {
+        let mut writer: io::IoResult<MemWriter> = Ok(MemWriter::new());
+        writer.write([0, 1, 2]).unwrap();
+        writer.flush().unwrap();
+        assert_eq!(writer.unwrap().unwrap(), ~[0, 1, 2]);
+    }
+
+    #[test]
+    fn test_option_writer_error() {
+        let mut writer: io::IoResult<MemWriter> =
+            Err(io::standard_error(io::EndOfFile));
+
+        match writer.write([0, 0, 0]) {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind, io::EndOfFile),
+        }
+        match writer.flush() {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind, io::EndOfFile),
+        }
+    }
+
+    #[test]
+    fn test_option_reader() {
+        let mut reader: io::IoResult<MemReader> =
+            Ok(MemReader::new(~[0, 1, 2, 3]));
+        let mut buf = [0, 0];
+        reader.read(buf).unwrap();
+        assert_eq!(buf, [0, 1]);
+    }
+
+    #[test]
+    fn test_option_reader_error() {
+        let mut reader: io::IoResult<MemReader> =
+            Err(io::standard_error(io::EndOfFile));
+        let mut buf = [];
+
+        match reader.read(buf) {
+            Ok(..) => fail!(),
+            Err(e) => assert_eq!(e.kind, io::EndOfFile),
+        }
+    }
+}
diff --git a/src/libstd/io/signal.rs b/src/libstd/io/signal.rs
index 5575e289b59..75804c40c58 100644
--- a/src/libstd/io/signal.rs
+++ b/src/libstd/io/signal.rs
@@ -20,10 +20,11 @@ definitions for a number of signals.
 */
 
 use clone::Clone;
+use result::{Ok, Err};
 use comm::{Port, SharedChan};
 use container::{Map, MutableMap};
 use hashmap;
-use option::{Some, None};
+use io;
 use rt::rtio::{IoFactory, LocalIo, RtioSignal};
 
 #[repr(int)]
@@ -112,23 +113,22 @@ impl Listener {
     /// a signal, and a later call to `recv` will return the signal that was
     /// received while no task was waiting on it.
     ///
-    /// # Failure
+    /// # Error
     ///
     /// If this function fails to register a signal handler, then an error will
-    /// be raised on the `io_error` condition and the function will return
-    /// false.
-    pub fn register(&mut self, signum: Signum) -> bool {
+    /// be returned.
+    pub fn register(&mut self, signum: Signum) -> io::IoResult<()> {
         if self.handles.contains_key(&signum) {
-            return true; // self is already listening to signum, so succeed
+            return Ok(()); // self is already listening to signum, so succeed
         }
         match LocalIo::maybe_raise(|io| {
             io.signal(signum, self.chan.clone())
         }) {
-            Some(handle) => {
+            Ok(handle) => {
                 self.handles.insert(signum, handle);
-                true
+                Ok(())
             }
-            None => false
+            Err(e) => Err(e)
         }
     }
 
@@ -159,7 +159,7 @@ mod test {
     #[test] #[cfg(unix, not(target_os="android"))] // FIXME(#10378)
     fn test_io_signal_smoketest() {
         let mut signal = Listener::new();
-        signal.register(Interrupt);
+        signal.register(Interrupt).unwrap();
         sigint();
         timer::sleep(10);
         match signal.port.recv() {
@@ -172,8 +172,8 @@ mod test {
     fn test_io_signal_two_signal_one_signum() {
         let mut s1 = Listener::new();
         let mut s2 = Listener::new();
-        s1.register(Interrupt);
-        s2.register(Interrupt);
+        s1.register(Interrupt).unwrap();
+        s2.register(Interrupt).unwrap();
         sigint();
         timer::sleep(10);
         match s1.port.recv() {
@@ -190,8 +190,8 @@ mod test {
     fn test_io_signal_unregister() {
         let mut s1 = Listener::new();
         let mut s2 = Listener::new();
-        s1.register(Interrupt);
-        s2.register(Interrupt);
+        s1.register(Interrupt).unwrap();
+        s2.register(Interrupt).unwrap();
         s2.unregister(Interrupt);
         sigint();
         timer::sleep(10);
@@ -203,15 +203,14 @@ mod test {
     fn test_io_signal_invalid_signum() {
         use io;
         use super::User1;
+        use result::{Ok, Err};
         let mut s = Listener::new();
         let mut called = false;
-        io::io_error::cond.trap(|_| {
-            called = true;
-        }).inside(|| {
-            if s.register(User1) {
+        match s.register(User1) {
+            Ok(..) => {
                 fail!("Unexpected successful registry of signum {:?}", User1);
             }
-        });
-        assert!(called);
+            Err(..) => {}
+        }
     }
 }
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index d9fa2a4fc33..937ad0783e9 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -18,6 +18,7 @@ about the stream or terminal that it is attached to.
 # Example
 
 ```rust
+# #[allow(unused_must_use)];
 use std::io;
 
 let mut out = io::stdout();
@@ -28,7 +29,7 @@ out.write(bytes!("Hello, world!"));
 
 use container::Container;
 use fmt;
-use io::{Reader, Writer, io_error, IoError, OtherIoError,
+use io::{Reader, Writer, IoResult, IoError, OtherIoError,
          standard_error, EndOfFile, LineBufferedWriter};
 use libc;
 use option::{Option, Some, None};
@@ -114,7 +115,8 @@ fn reset_helper(w: ~Writer,
     match f(t.get(), w) {
         Some(mut w) => {
             drop(t);
-            w.flush();
+            // FIXME: is failing right here?
+            w.flush().unwrap();
             Some(w)
         }
         None => None
@@ -155,9 +157,9 @@ pub fn set_stderr(stderr: ~Writer) -> Option<~Writer> {
 //          // io1 aliases io2
 //      })
 //  })
-fn with_task_stdout(f: |&mut Writer|) {
+fn with_task_stdout(f: |&mut Writer| -> IoResult<()> ) {
     let task: Option<~Task> = Local::try_take();
-    match task {
+    let result = match task {
         Some(mut task) => {
             // Printing may run arbitrary code, so ensure that the task is in
             // TLS to allow all std services. Note that this means a print while
@@ -169,7 +171,7 @@ fn with_task_stdout(f: |&mut Writer|) {
             if my_stdout.is_none() {
                 my_stdout = Some(~LineBufferedWriter::new(stdout()) as ~Writer);
             }
-            f(*my_stdout.get_mut_ref());
+            let ret = f(*my_stdout.get_mut_ref());
 
             // Note that we need to be careful when putting the stdout handle
             // back into the task. If the handle was set to `Some` while
@@ -184,22 +186,29 @@ fn with_task_stdout(f: |&mut Writer|) {
             let prev = util::replace(&mut t.get().stdout, my_stdout);
             drop(t);
             drop(prev);
+            ret
         }
 
         None => {
             struct Stdout;
             impl Writer for Stdout {
-                fn write(&mut self, data: &[u8]) {
+                fn write(&mut self, data: &[u8]) -> IoResult<()> {
                     unsafe {
                         libc::write(libc::STDOUT_FILENO,
                                     data.as_ptr() as *libc::c_void,
                                     data.len() as libc::size_t);
                     }
+                    Ok(()) // just ignore the results
                 }
             }
             let mut io = Stdout;
-            f(&mut io as &mut Writer);
+            f(&mut io as &mut Writer)
         }
+    };
+
+    match result {
+        Ok(()) => {}
+        Err(e) => fail!("failed printing to stdout: {}", e),
     }
 }
 
@@ -226,8 +235,7 @@ pub fn print(s: &str) {
 /// `\n` character is printed to the console after the string.
 pub fn println(s: &str) {
     with_task_stdout(|io| {
-        io.write(s.as_bytes());
-        io.write(['\n' as u8]);
+        io.write(s.as_bytes()).and_then(|()| io.write(['\n' as u8]))
     })
 }
 
@@ -249,7 +257,7 @@ pub struct StdReader {
 }
 
 impl Reader for StdReader {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
         let ret = match self.inner {
             TTY(ref mut tty) => tty.read(buf),
             File(ref mut file) => file.read(buf).map(|i| i as uint),
@@ -260,15 +268,8 @@ impl Reader for StdReader {
             // return an actual EOF error, but apparently for stdin it's a
             // little different. Hence, here we convert a 0 length read to an
             // end-of-file indicator so the caller knows to stop reading.
-            Ok(0) => {
-                io_error::cond.raise(standard_error(EndOfFile));
-                None
-            }
-            Ok(amt) => Some(amt),
-            Err(e) => {
-                io_error::cond.raise(e);
-                None
-            }
+            Ok(0) => { Err(standard_error(EndOfFile)) }
+            ret @ Ok(..) | ret @ Err(..) => ret,
         }
     }
 }
@@ -283,30 +284,21 @@ impl StdWriter {
     /// when the writer is attached to something like a terminal, this is used
     /// to fetch the dimensions of the terminal.
     ///
-    /// If successful, returns Some((width, height)).
+    /// If successful, returns `Ok((width, height))`.
     ///
-    /// # Failure
+    /// # Error
     ///
-    /// This function will raise on the `io_error` condition if an error
-    /// happens.
-    pub fn winsize(&mut self) -> Option<(int, int)> {
+    /// This function will return an error if the output stream is not actually
+    /// connected to a TTY instance, or if querying the TTY instance fails.
+    pub fn winsize(&mut self) -> IoResult<(int, int)> {
         match self.inner {
-            TTY(ref mut tty) => {
-                match tty.get_winsize() {
-                    Ok(p) => Some(p),
-                    Err(e) => {
-                        io_error::cond.raise(e);
-                        None
-                    }
-                }
-            }
+            TTY(ref mut tty) => tty.get_winsize(),
             File(..) => {
-                io_error::cond.raise(IoError {
+                Err(IoError {
                     kind: OtherIoError,
                     desc: "stream is not a tty",
                     detail: None,
-                });
-                None
+                })
             }
         }
     }
@@ -314,24 +306,19 @@ impl StdWriter {
     /// Controls whether this output stream is a "raw stream" or simply a normal
     /// stream.
     ///
-    /// # Failure
+    /// # Error
     ///
-    /// This function will raise on the `io_error` condition if an error
-    /// happens.
-    pub fn set_raw(&mut self, raw: bool) {
+    /// This function will return an error if the output stream is not actually
+    /// connected to a TTY instance, or if querying the TTY instance fails.
+    pub fn set_raw(&mut self, raw: bool) -> IoResult<()> {
         match self.inner {
-            TTY(ref mut tty) => {
-                match tty.set_raw(raw) {
-                    Ok(()) => {},
-                    Err(e) => io_error::cond.raise(e),
-                }
-            }
+            TTY(ref mut tty) => tty.set_raw(raw),
             File(..) => {
-                io_error::cond.raise(IoError {
+                Err(IoError {
                     kind: OtherIoError,
                     desc: "stream is not a tty",
                     detail: None,
-                });
+                })
             }
         }
     }
@@ -346,14 +333,10 @@ impl StdWriter {
 }
 
 impl Writer for StdWriter {
-    fn write(&mut self, buf: &[u8]) {
-        let ret = match self.inner {
+    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
+        match self.inner {
             TTY(ref mut tty) => tty.write(buf),
             File(ref mut file) => file.write(buf),
-        };
-        match ret {
-            Ok(()) => {}
-            Err(e) => io_error::cond.raise(e)
         }
     }
 }
@@ -376,7 +359,7 @@ mod tests {
             set_stdout(~w as ~Writer);
             println!("hello!");
         });
-        assert_eq!(r.read_to_str(), ~"hello!\n");
+        assert_eq!(r.read_to_str().unwrap(), ~"hello!\n");
     })
 
     iotest!(fn capture_stderr() {
@@ -388,7 +371,7 @@ mod tests {
             set_stderr(~w as ~Writer);
             fail!("my special message");
         });
-        let s = r.read_to_str();
+        let s = r.read_to_str().unwrap();
         assert!(s.contains("my special message"));
     })
 }
diff --git a/src/libstd/io/timer.rs b/src/libstd/io/timer.rs
index 24eaf6adf3f..692aaa7afd0 100644
--- a/src/libstd/io/timer.rs
+++ b/src/libstd/io/timer.rs
@@ -39,8 +39,8 @@ loop {
 */
 
 use comm::Port;
-use option::Option;
 use rt::rtio::{IoFactory, LocalIo, RtioTimer};
+use io::IoResult;
 
 pub struct Timer {
     priv obj: ~RtioTimer
@@ -48,7 +48,8 @@ pub struct Timer {
 
 /// Sleep the current task for `msecs` milliseconds.
 pub fn sleep(msecs: u64) {
-    let mut timer = Timer::new().expect("timer::sleep: could not create a Timer");
+    let timer = Timer::new();
+    let mut timer = timer.ok().expect("timer::sleep: could not create a Timer");
 
     timer.sleep(msecs)
 }
@@ -57,7 +58,7 @@ impl Timer {
     /// Creates a new timer which can be used to put the current task to sleep
     /// for a number of milliseconds, or to possibly create channels which will
     /// get notified after an amount of time has passed.
-    pub fn new() -> Option<Timer> {
+    pub fn new() -> IoResult<Timer> {
         LocalIo::maybe_raise(|io| io.timer_init().map(|t| Timer { obj: t }))
     }
 
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index a1794d24fc9..c4d92b36ecf 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -7,8 +7,10 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
+
 use prelude::*;
 use cmp;
+use io;
 use vec::bytes::MutableByteVector;
 
 /// Wraps a `Reader`, limiting the number of bytes that can be read from it.
@@ -25,9 +27,9 @@ impl<'a, R: Reader> LimitReader<'a, R> {
 }
 
 impl<'a, R: Reader> Reader for LimitReader<'a, R> {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
         if self.limit == 0 {
-            return None;
+            return Err(io::standard_error(io::EndOfFile));
         }
 
         let len = cmp::min(self.limit, buf.len());
@@ -43,7 +45,7 @@ pub struct NullWriter;
 
 impl Writer for NullWriter {
     #[inline]
-    fn write(&mut self, _buf: &[u8]) { }
+    fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) }
 }
 
 /// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
@@ -51,9 +53,9 @@ pub struct ZeroReader;
 
 impl Reader for ZeroReader {
     #[inline]
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
         buf.set_memory(0);
-        Some(buf.len())
+        Ok(buf.len())
     }
 }
 
@@ -62,8 +64,8 @@ pub struct NullReader;
 
 impl Reader for NullReader {
     #[inline]
-    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> {
-        None
+    fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
+        Err(io::standard_error(io::EndOfFile))
     }
 }
 
@@ -81,17 +83,21 @@ impl MultiWriter {
 
 impl Writer for MultiWriter {
     #[inline]
-    fn write(&mut self, buf: &[u8]) {
+    fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
+        let mut ret = Ok(());
         for writer in self.writers.mut_iter() {
-            writer.write(buf);
+            ret = ret.and(writer.write(buf));
         }
+        return ret;
     }
 
     #[inline]
-    fn flush(&mut self) {
+    fn flush(&mut self) -> io::IoResult<()> {
+        let mut ret = Ok(());
         for writer in self.writers.mut_iter() {
-            writer.flush();
+            ret = ret.and(writer.flush());
         }
+        return ret;
     }
 }
 
@@ -111,20 +117,25 @@ impl<R: Reader, I: Iterator<R>> ChainedReader<I, R> {
 }
 
 impl<R: Reader, I: Iterator<R>> Reader for ChainedReader<I, R> {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
+    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
         loop {
-            match self.cur_reader {
+            let err = match self.cur_reader {
                 Some(ref mut r) => {
                     match r.read(buf) {
-                        Some(len) => return Some(len),
-                        None => {}
+                        Ok(len) => return Ok(len),
+                        Err(ref e) if e.kind == io::EndOfFile => None,
+                        Err(e) => Some(e),
                     }
                 }
                 None => break
+            };
+            self.cur_reader = self.readers.next();
+            match err {
+                Some(e) => return Err(e),
+                None => {}
             }
-            self.cur_reader = self.readers.next()
         }
-        None
+        Err(io::standard_error(io::EndOfFile))
     }
 }
 
@@ -150,27 +161,29 @@ impl<R: Reader, W: Writer> TeeReader<R, W> {
 }
 
 impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
-    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
-        self.reader.read(buf).map(|len| {
-            self.writer.write(buf.slice_to(len));
-            len
+    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
+        self.reader.read(buf).and_then(|len| {
+            self.writer.write(buf.slice_to(len)).map(|()| len)
         })
     }
 }
 
 /// Copies all data from a `Reader` to a `Writer`.
-pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) {
+pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
     let mut buf = [0, ..super::DEFAULT_BUF_SIZE];
     loop {
-        match r.read(buf) {
-            Some(len) => w.write(buf.slice_to(len)),
-            None => break
-        }
+        let len = match r.read(buf) {
+            Ok(len) => len,
+            Err(ref e) if e.kind == io::EndOfFile => return Ok(()),
+            Err(e) => return Err(e),
+        };
+        if_ok!(w.write(buf.slice_to(len)));
     }
 }
 
 #[cfg(test)]
 mod test {
+    use io;
     use io::{MemReader, MemWriter};
     use super::*;
     use prelude::*;
@@ -180,7 +193,7 @@ mod test {
         let mut r = MemReader::new(~[0, 1, 2]);
         {
             let mut r = LimitReader::new(&mut r, 4);
-            assert_eq!(~[0, 1, 2], r.read_to_end());
+            assert_eq!(~[0, 1, 2], r.read_to_end().unwrap());
         }
     }
 
@@ -189,24 +202,24 @@ mod test {
         let mut r = MemReader::new(~[0, 1, 2]);
         {
             let mut r = LimitReader::new(&mut r, 2);
-            assert_eq!(~[0, 1], r.read_to_end());
+            assert_eq!(~[0, 1], r.read_to_end().unwrap());
         }
-        assert_eq!(~[2], r.read_to_end());
+        assert_eq!(~[2], r.read_to_end().unwrap());
     }
 
     #[test]
     fn test_null_writer() {
         let mut s = NullWriter;
         let buf = ~[0, 0, 0];
-        s.write(buf);
-        s.flush();
+        s.write(buf).unwrap();
+        s.flush().unwrap();
     }
 
     #[test]
     fn test_zero_reader() {
         let mut s = ZeroReader;
         let mut buf = ~[1, 2, 3];
-        assert_eq!(s.read(buf), Some(3));
+        assert_eq!(s.read(buf), Ok(3));
         assert_eq!(~[0, 0, 0], buf);
     }
 
@@ -214,7 +227,7 @@ mod test {
     fn test_null_reader() {
         let mut r = NullReader;
         let mut buf = ~[0];
-        assert_eq!(r.read(buf), None);
+        assert!(r.read(buf).is_err());
     }
 
     #[test]
@@ -224,21 +237,23 @@ mod test {
 
         struct TestWriter;
         impl Writer for TestWriter {
-            fn write(&mut self, _buf: &[u8]) {
+            fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> {
                 unsafe { writes += 1 }
+                Ok(())
             }
 
-            fn flush(&mut self) {
+            fn flush(&mut self) -> io::IoResult<()> {
                 unsafe { flushes += 1 }
+                Ok(())
             }
         }
 
         let mut multi = MultiWriter::new(~[~TestWriter as ~Writer,
                                            ~TestWriter as ~Writer]);
-        multi.write([1, 2, 3]);
+        multi.write([1, 2, 3]).unwrap();
         assert_eq!(2, unsafe { writes });
         assert_eq!(0, unsafe { flushes });
-        multi.flush();
+        multi.flush().unwrap();
         assert_eq!(2, unsafe { writes });
         assert_eq!(2, unsafe { flushes });
     }
@@ -248,14 +263,14 @@ mod test {
         let rs = ~[MemReader::new(~[0, 1]), MemReader::new(~[]),
                    MemReader::new(~[2, 3])];
         let mut r = ChainedReader::new(rs.move_iter());
-        assert_eq!(~[0, 1, 2, 3], r.read_to_end());
+        assert_eq!(~[0, 1, 2, 3], r.read_to_end().unwrap());
     }
 
     #[test]
     fn test_tee_reader() {
         let mut r = TeeReader::new(MemReader::new(~[0, 1, 2]),
                                    MemWriter::new());
-        assert_eq!(~[0, 1, 2], r.read_to_end());
+        assert_eq!(~[0, 1, 2], r.read_to_end().unwrap());
         let (_, w) = r.unwrap();
         assert_eq!(~[0, 1, 2], w.unwrap());
     }
@@ -264,7 +279,7 @@ mod test {
     fn test_copy() {
         let mut r = MemReader::new(~[0, 1, 2, 3, 4]);
         let mut w = MemWriter::new();
-        copy(&mut r, &mut w);
+        copy(&mut r, &mut w).unwrap();
         assert_eq!(~[0, 1, 2, 3, 4], w.unwrap());
     }
 }
diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs
index 636d3ffd90a..c5e66ffc7be 100644
--- a/src/libstd/logging.rs
+++ b/src/libstd/logging.rs
@@ -102,6 +102,7 @@ use io::Writer;
 use ops::Drop;
 use option::{Some, None, Option};
 use prelude::drop;
+use result::{Ok, Err};
 use rt::local::Local;
 use rt::task::Task;
 use util;
@@ -131,13 +132,19 @@ struct DefaultLogger {
 impl Logger for DefaultLogger {
     // by default, just ignore the level
     fn log(&mut self, _level: u32, args: &fmt::Arguments) {
-        fmt::writeln(&mut self.handle, args);
+        match fmt::writeln(&mut self.handle, args) {
+            Err(e) => fail!("failed to log: {}", e),
+            Ok(()) => {}
+        }
     }
 }
 
 impl Drop for DefaultLogger {
     fn drop(&mut self) {
-        self.handle.flush();
+        match self.handle.flush() {
+            Err(e) => fail!("failed to flush a logger: {}", e),
+            Ok(()) => {}
+        }
     }
 }
 
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 4032b63790b..b31ae92d742 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -197,3 +197,8 @@ macro_rules! local_data_key (
         pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
     )
 )
+
+#[macro_export]
+macro_rules! if_ok (
+    ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
+)
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index 83cedd92a3f..19478e3dbb3 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -382,7 +382,7 @@ impl<T: Default> Option<T> {
 
 impl<T: fmt::Show> fmt::Show for Option<T> {
     #[inline]
-    fn fmt(s: &Option<T>, f: &mut fmt::Formatter) {
+    fn fmt(s: &Option<T>, f: &mut fmt::Formatter) -> fmt::Result {
         match *s {
             Some(ref t) => write!(f.buf, "Some({})", *t),
             None        => write!(f.buf, "None")
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 0ea1c7510a1..541db01f148 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -372,9 +372,9 @@ pub fn self_exe_name() -> Option<Path> {
     fn load_self() -> Option<~[u8]> {
         use std::io;
 
-        match io::result(|| io::fs::readlink(&Path::new("/proc/self/exe"))) {
-            Ok(Some(path)) => Some(path.as_vec().to_owned()),
-            Ok(None) | Err(..) => None
+        match io::fs::readlink(&Path::new("/proc/self/exe")) {
+            Ok(path) => Some(path.as_vec().to_owned()),
+            Err(..) => None
         }
     }
 
@@ -929,7 +929,7 @@ pub enum MapError {
 }
 
 impl fmt::Show for MapError {
-    fn fmt(val: &MapError, out: &mut fmt::Formatter) {
+    fn fmt(val: &MapError, out: &mut fmt::Formatter) -> fmt::Result {
         let str = match *val {
             ErrFdNotAvail => "fd not available for reading or writing",
             ErrInvalidFd => "Invalid fd",
@@ -944,23 +944,19 @@ impl fmt::Show for MapError {
             ErrAlreadyExists => "File mapping for specified file already exists",
             ErrZeroLength => "Zero-length mapping not allowed",
             ErrUnknown(code) => {
-                write!(out.buf, "Unknown error = {}", code);
-                return
+                return write!(out.buf, "Unknown error = {}", code)
             },
             ErrVirtualAlloc(code) => {
-                write!(out.buf, "VirtualAlloc failure = {}", code);
-                return
+                return write!(out.buf, "VirtualAlloc failure = {}", code)
             },
             ErrCreateFileMappingW(code) => {
-                format!("CreateFileMappingW failure = {}", code);
-                return
+                return write!(out.buf, "CreateFileMappingW failure = {}", code)
             },
             ErrMapViewOfFile(code) => {
-                write!(out.buf, "MapViewOfFile failure = {}", code);
-                return
+                return write!(out.buf, "MapViewOfFile failure = {}", code)
             }
         };
-        write!(out.buf, "{}", str);
+        write!(out.buf, "{}", str)
     }
 }
 
@@ -1496,7 +1492,6 @@ mod tests {
         use result::{Ok, Err};
         use os::*;
         use libc::*;
-        use io;
         use io::fs;
 
         #[cfg(unix)]
@@ -1540,9 +1535,9 @@ mod tests {
             assert!(*chunk.data == 0xbe);
             close(fd);
         }
+        drop(chunk);
 
-        let _guard = io::ignore_io_error();
-        fs::unlink(&path);
+        fs::unlink(&path).unwrap();
     }
 
     // More recursive_mkdir tests are in extra::tempfile
diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs
index 86f96a1075b..4aa4a3feab1 100644
--- a/src/libstd/path/mod.rs
+++ b/src/libstd/path/mod.rs
@@ -533,7 +533,7 @@ pub struct Display<'a, P> {
 }
 
 impl<'a, P: GenericPath> fmt::Show for Display<'a, P> {
-    fn fmt(d: &Display<P>, f: &mut fmt::Formatter) {
+    fn fmt(d: &Display<P>, f: &mut fmt::Formatter) -> fmt::Result {
         d.with_str(|s| f.pad(s))
     }
 }
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index c359d79d275..e9068c6b0c8 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -62,7 +62,7 @@ impl OSRng {
     pub fn new() -> OSRng {
         use path::Path;
         let reader = File::open(&Path::new("/dev/urandom"));
-        let reader = reader.expect("Error opening /dev/urandom");
+        let reader = reader.ok().expect("Error opening /dev/urandom");
         let reader_rng = ReaderRng::new(reader);
 
         OSRng { inner: reader_rng }
diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs
index e19fbd9aaf8..621d70970f0 100644
--- a/src/libstd/rand/reader.rs
+++ b/src/libstd/rand/reader.rs
@@ -11,7 +11,7 @@
 //! A wrapper around any Reader to treat it as an RNG.
 
 use container::Container;
-use option::{Some, None};
+use result::{Ok, Err};
 use io::Reader;
 
 use rand::Rng;
@@ -49,26 +49,26 @@ impl<R: Reader> Rng for ReaderRng<R> {
         // platform just involves blitting the bytes into the memory
         // of the u32, similarly for BE on BE; avoiding byteswapping.
         if cfg!(target_endian="little") {
-            self.reader.read_le_u32()
+            self.reader.read_le_u32().unwrap()
         } else {
-            self.reader.read_be_u32()
+            self.reader.read_be_u32().unwrap()
         }
     }
     fn next_u64(&mut self) -> u64 {
         // see above for explanation.
         if cfg!(target_endian="little") {
-            self.reader.read_le_u64()
+            self.reader.read_le_u64().unwrap()
         } else {
-            self.reader.read_be_u64()
+            self.reader.read_be_u64().unwrap()
         }
     }
     fn fill_bytes(&mut self, v: &mut [u8]) {
         if v.len() == 0 { return }
         match self.reader.read(v) {
-            Some(n) if n == v.len() => return,
-            Some(n) => fail!("ReaderRng.fill_bytes could not fill buffer: \
-                              read {} out of {} bytes.", n, v.len()),
-            None => fail!("ReaderRng.fill_bytes reached eof.")
+            Ok(n) if n == v.len() => return,
+            Ok(n) => fail!("ReaderRng.fill_bytes could not fill buffer: \
+                            read {} out of {} bytes.", n, v.len()),
+            Err(e) => fail!("ReaderRng.fill_bytes error: {}", e)
         }
     }
 }
diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs
index d6b4d3f5656..44ee5de7ac3 100644
--- a/src/libstd/reflect.rs
+++ b/src/libstd/reflect.rs
@@ -66,6 +66,8 @@ impl<V:TyVisitor + MovePtr> MovePtrAdaptor<V> {
     pub fn bump_past<T>(&mut self) {
         self.bump(mem::size_of::<T>());
     }
+
+    pub fn unwrap(self) -> V { self.inner }
 }
 
 /// Abstract type-directed pointer-movement using the MovePtr trait
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index 41ddf027787..f71649602b2 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -21,48 +21,57 @@ use char;
 use container::Container;
 use io;
 use iter::Iterator;
-use option::{Some, None};
+use option::{Some, None, Option};
 use ptr;
 use reflect;
 use reflect::{MovePtr, align};
+use result::{Ok, Err};
 use str::StrSlice;
 use to_str::ToStr;
 use vec::OwnedVector;
 use unstable::intrinsics::{Disr, Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
 use unstable::raw;
 
+macro_rules! if_ok( ($me:expr, $e:expr) => (
+    match $e {
+        Ok(()) => {},
+        Err(e) => { $me.last_err = Some(e); return false; }
+    }
+) )
+
 /// Representations
 
 trait Repr {
-    fn write_repr(&self, writer: &mut io::Writer);
+    fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()>;
 }
 
 impl Repr for () {
-    fn write_repr(&self, writer: &mut io::Writer) {
-        writer.write("()".as_bytes());
+    fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
+        writer.write("()".as_bytes())
     }
 }
 
 impl Repr for bool {
-    fn write_repr(&self, writer: &mut io::Writer) {
+    fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
         let s = if *self { "true" } else { "false" };
         writer.write(s.as_bytes())
     }
 }
 
 impl Repr for int {
-    fn write_repr(&self, writer: &mut io::Writer) {
+    fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
         ::int::to_str_bytes(*self, 10u, |bits| {
-            writer.write(bits);
+            writer.write(bits)
         })
     }
 }
 
 macro_rules! int_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
-    fn write_repr(&self, writer: &mut io::Writer) {
+    fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
         ::$ty::to_str_bytes(*self, 10u, |bits| {
-            writer.write(bits);
-            writer.write(bytes!($suffix));
+            writer.write(bits).and_then(|()| {
+                writer.write(bytes!($suffix))
+            })
         })
     }
 }))
@@ -78,10 +87,11 @@ int_repr!(u32, "u32")
 int_repr!(u64, "u64")
 
 macro_rules! num_repr(($ty:ident, $suffix:expr) => (impl Repr for $ty {
-    fn write_repr(&self, writer: &mut io::Writer) {
+    fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()> {
         let s = self.to_str();
-        writer.write(s.as_bytes());
-        writer.write(bytes!($suffix));
+        writer.write(s.as_bytes()).and_then(|()| {
+            writer.write(bytes!($suffix))
+        })
     }
 }))
 
@@ -100,7 +110,8 @@ pub struct ReprVisitor<'a> {
     priv ptr: *u8,
     priv ptr_stk: ~[*u8],
     priv var_stk: ~[VariantState],
-    priv writer: &'a mut io::Writer
+    priv writer: &'a mut io::Writer,
+    priv last_err: Option<io::IoError>,
 }
 
 pub fn ReprVisitor<'a>(ptr: *u8,
@@ -110,6 +121,7 @@ pub fn ReprVisitor<'a>(ptr: *u8,
         ptr_stk: ~[],
         var_stk: ~[],
         writer: writer,
+        last_err: None,
     }
 }
 
@@ -130,11 +142,10 @@ impl<'a> ReprVisitor<'a> {
     // Various helpers for the TyVisitor impl
 
     #[inline]
-    pub fn get<T>(&mut self, f: |&mut ReprVisitor, &T|) -> bool {
+    pub fn get<T>(&mut self, f: |&mut ReprVisitor, &T| -> bool) -> bool {
         unsafe {
-            f(self, transmute::<*u8,&T>(self.ptr));
+            f(self, transmute::<*u8,&T>(self.ptr))
         }
-        true
     }
 
     #[inline]
@@ -152,43 +163,53 @@ impl<'a> ReprVisitor<'a> {
                 ptr_stk: ~[],
                 var_stk: ~[],
                 writer: ::cast::transmute_copy(&self.writer),
+                last_err: None,
             };
             let mut v = reflect::MovePtrAdaptor(u);
             // Obviously this should not be a thing, but blame #8401 for now
             visit_tydesc(inner, &mut v as &mut TyVisitor);
-            true
+            match v.unwrap().last_err {
+                Some(e) => {
+                    self.last_err = Some(e);
+                    false
+                }
+                None => true,
+            }
         }
     }
 
     #[inline]
     pub fn write<T:Repr>(&mut self) -> bool {
         self.get(|this, v:&T| {
-            v.write_repr(unsafe { ::cast::transmute_copy(&this.writer) });
+            if_ok!(this, v.write_repr(this.writer));
+            true
         })
     }
 
-    pub fn write_escaped_slice(&mut self, slice: &str) {
-        self.writer.write(['"' as u8]);
+    pub fn write_escaped_slice(&mut self, slice: &str) -> bool {
+        if_ok!(self, self.writer.write(['"' as u8]));
         for ch in slice.chars() {
-            self.write_escaped_char(ch, true);
+            if !self.write_escaped_char(ch, true) { return false }
         }
-        self.writer.write(['"' as u8]);
+        if_ok!(self, self.writer.write(['"' as u8]));
+        true
     }
 
-    pub fn write_mut_qualifier(&mut self, mtbl: uint) {
+    pub fn write_mut_qualifier(&mut self, mtbl: uint) -> bool {
         if mtbl == 0 {
-            self.writer.write("mut ".as_bytes());
+            if_ok!(self, self.writer.write("mut ".as_bytes()));
         } else if mtbl == 1 {
             // skip, this is ast::m_imm
         } else {
             fail!("invalid mutability value");
         }
+        true
     }
 
     pub fn write_vec_range(&mut self, ptr: *(), len: uint, inner: *TyDesc) -> bool {
         let mut p = ptr as *u8;
         let (sz, al) = unsafe { ((*inner).size, (*inner).align) };
-        self.writer.write(['[' as u8]);
+        if_ok!(self, self.writer.write(['[' as u8]));
         let mut first = true;
         let mut left = len;
         // unit structs have 0 size, and don't loop forever.
@@ -197,13 +218,13 @@ impl<'a> ReprVisitor<'a> {
             if first {
                 first = false;
             } else {
-                self.writer.write(", ".as_bytes());
+                if_ok!(self, self.writer.write(", ".as_bytes()));
             }
             self.visit_ptr_inner(p as *u8, inner);
             p = align(unsafe { ptr::offset(p, sz as int) as uint }, al) as *u8;
             left -= dec;
         }
-        self.writer.write([']' as u8]);
+        if_ok!(self, self.writer.write([']' as u8]));
         true
     }
 
@@ -211,8 +232,8 @@ impl<'a> ReprVisitor<'a> {
         self.write_vec_range(ptr::to_unsafe_ptr(&v.data), v.fill, inner)
     }
 
-    fn write_escaped_char(&mut self, ch: char, is_str: bool) {
-        match ch {
+    fn write_escaped_char(&mut self, ch: char, is_str: bool) -> bool {
+        if_ok!(self, match ch {
             '\t' => self.writer.write("\\t".as_bytes()),
             '\r' => self.writer.write("\\r".as_bytes()),
             '\n' => self.writer.write("\\n".as_bytes()),
@@ -234,16 +255,18 @@ impl<'a> ReprVisitor<'a> {
             '\x20'..'\x7e' => self.writer.write([ch as u8]),
             _ => {
                 char::escape_unicode(ch, |c| {
-                    self.writer.write([c as u8]);
-                })
+                    let _ = self.writer.write([c as u8]);
+                });
+                Ok(())
             }
-        }
+        });
+        return true;
     }
 }
 
 impl<'a> TyVisitor for ReprVisitor<'a> {
     fn visit_bot(&mut self) -> bool {
-        self.writer.write("!".as_bytes());
+        if_ok!(self, self.writer.write("!".as_bytes()));
         true
     }
     fn visit_nil(&mut self) -> bool { self.write::<()>() }
@@ -265,9 +288,10 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
 
     fn visit_char(&mut self) -> bool {
         self.get::<char>(|this, &ch| {
-            this.writer.write(['\'' as u8]);
-            this.write_escaped_char(ch, false);
-            this.writer.write(['\'' as u8]);
+            if_ok!(this, this.writer.write(['\'' as u8]));
+            if !this.write_escaped_char(ch, false) { return false }
+            if_ok!(this, this.writer.write(['\'' as u8]));
+            true
         })
     }
 
@@ -277,8 +301,8 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
 
     fn visit_estr_uniq(&mut self) -> bool {
         self.get::<~str>(|this, s| {
-            this.writer.write(['~' as u8]);
-            this.write_escaped_slice(*s);
+            if_ok!(this, this.writer.write(['~' as u8]));
+            this.write_escaped_slice(*s)
         })
     }
 
@@ -291,34 +315,35 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
                         _align: uint) -> bool { fail!(); }
 
     fn visit_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
-        self.writer.write(['@' as u8]);
+        if_ok!(self, self.writer.write(['@' as u8]));
         self.write_mut_qualifier(mtbl);
         self.get::<&raw::Box<()>>(|this, b| {
             let p = ptr::to_unsafe_ptr(&b.data) as *u8;
-            this.visit_ptr_inner(p, inner);
+            this.visit_ptr_inner(p, inner)
         })
     }
 
     fn visit_uniq(&mut self, _mtbl: uint, inner: *TyDesc) -> bool {
-        self.writer.write(['~' as u8]);
+        if_ok!(self, self.writer.write(['~' as u8]));
         self.get::<*u8>(|this, b| {
-            this.visit_ptr_inner(*b, inner);
+            this.visit_ptr_inner(*b, inner)
         })
     }
 
     fn visit_ptr(&mut self, mtbl: uint, _inner: *TyDesc) -> bool {
         self.get::<*u8>(|this, p| {
-            write!(this.writer, "({} as *", *p);
+            if_ok!(this, write!(this.writer, "({} as *", *p));
             this.write_mut_qualifier(mtbl);
-            this.writer.write("())".as_bytes());
+            if_ok!(this, this.writer.write("())".as_bytes()));
+            true
         })
     }
 
     fn visit_rptr(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
-        self.writer.write(['&' as u8]);
+        if_ok!(self, self.writer.write(['&' as u8]));
         self.write_mut_qualifier(mtbl);
         self.get::<*u8>(|this, p| {
-            this.visit_ptr_inner(*p, inner);
+            this.visit_ptr_inner(*p, inner)
         })
     }
 
@@ -327,33 +352,33 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
 
     fn visit_unboxed_vec(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
         self.get::<raw::Vec<()>>(|this, b| {
-            this.write_unboxed_vec_repr(mtbl, b, inner);
+            this.write_unboxed_vec_repr(mtbl, b, inner)
         })
     }
 
     fn visit_evec_box(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
         self.get::<&raw::Box<raw::Vec<()>>>(|this, b| {
-            this.writer.write(['@' as u8]);
+            if_ok!(this, this.writer.write(['@' as u8]));
             this.write_mut_qualifier(mtbl);
-            this.write_unboxed_vec_repr(mtbl, &b.data, inner);
+            this.write_unboxed_vec_repr(mtbl, &b.data, inner)
         })
     }
 
     fn visit_evec_uniq(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
         self.get::<&raw::Vec<()>>(|this, b| {
-            this.writer.write(['~' as u8]);
-            this.write_unboxed_vec_repr(mtbl, *b, inner);
+            if_ok!(this, this.writer.write(['~' as u8]));
+            this.write_unboxed_vec_repr(mtbl, *b, inner)
         })
     }
 
     fn visit_evec_slice(&mut self, mtbl: uint, inner: *TyDesc) -> bool {
         self.get::<raw::Slice<()>>(|this, s| {
-            this.writer.write(['&' as u8]);
+            if_ok!(this, this.writer.write(['&' as u8]));
             this.write_mut_qualifier(mtbl);
             let size = unsafe {
                 if (*inner).size == 0 { 1 } else { (*inner).size }
             };
-            this.write_vec_range(s.data, s.len * size, inner);
+            this.write_vec_range(s.data, s.len * size, inner)
         })
     }
 
@@ -361,42 +386,42 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
                         _: uint, inner: *TyDesc) -> bool {
         let assumed_size = if sz == 0 { n } else { sz };
         self.get::<()>(|this, b| {
-            this.write_vec_range(ptr::to_unsafe_ptr(b), assumed_size, inner);
+            this.write_vec_range(ptr::to_unsafe_ptr(b), assumed_size, inner)
         })
     }
 
     fn visit_enter_rec(&mut self, _n_fields: uint,
                        _sz: uint, _align: uint) -> bool {
-        self.writer.write(['{' as u8]);
+        if_ok!(self, self.writer.write(['{' as u8]));
         true
     }
 
     fn visit_rec_field(&mut self, i: uint, name: &str,
                        mtbl: uint, inner: *TyDesc) -> bool {
         if i != 0 {
-            self.writer.write(", ".as_bytes());
+            if_ok!(self, self.writer.write(", ".as_bytes()));
         }
         self.write_mut_qualifier(mtbl);
-        self.writer.write(name.as_bytes());
-        self.writer.write(": ".as_bytes());
+        if_ok!(self, self.writer.write(name.as_bytes()));
+        if_ok!(self, self.writer.write(": ".as_bytes()));
         self.visit_inner(inner);
         true
     }
 
     fn visit_leave_rec(&mut self, _n_fields: uint,
                        _sz: uint, _align: uint) -> bool {
-        self.writer.write(['}' as u8]);
+        if_ok!(self, self.writer.write(['}' as u8]));
         true
     }
 
     fn visit_enter_class(&mut self, name: &str, named_fields: bool, n_fields: uint,
                          _sz: uint, _align: uint) -> bool {
-        self.writer.write(name.as_bytes());
+        if_ok!(self, self.writer.write(name.as_bytes()));
         if n_fields != 0 {
             if named_fields {
-                self.writer.write(['{' as u8]);
+                if_ok!(self, self.writer.write(['{' as u8]));
             } else {
-                self.writer.write(['(' as u8]);
+                if_ok!(self, self.writer.write(['(' as u8]));
             }
         }
         true
@@ -405,11 +430,11 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
     fn visit_class_field(&mut self, i: uint, name: &str, named: bool,
                          _mtbl: uint, inner: *TyDesc) -> bool {
         if i != 0 {
-            self.writer.write(", ".as_bytes());
+            if_ok!(self, self.writer.write(", ".as_bytes()));
         }
         if named {
-            self.writer.write(name.as_bytes());
-            self.writer.write(": ".as_bytes());
+            if_ok!(self, self.writer.write(name.as_bytes()));
+            if_ok!(self, self.writer.write(": ".as_bytes()));
         }
         self.visit_inner(inner);
         true
@@ -419,9 +444,9 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
                          _sz: uint, _align: uint) -> bool {
         if n_fields != 0 {
             if named_fields {
-                self.writer.write(['}' as u8]);
+                if_ok!(self, self.writer.write(['}' as u8]));
             } else {
-                self.writer.write([')' as u8]);
+                if_ok!(self, self.writer.write([')' as u8]));
             }
         }
         true
@@ -429,13 +454,13 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
 
     fn visit_enter_tup(&mut self, _n_fields: uint,
                        _sz: uint, _align: uint) -> bool {
-        self.writer.write(['(' as u8]);
+        if_ok!(self, self.writer.write(['(' as u8]));
         true
     }
 
     fn visit_tup_field(&mut self, i: uint, inner: *TyDesc) -> bool {
         if i != 0 {
-            self.writer.write(", ".as_bytes());
+            if_ok!(self, self.writer.write(", ".as_bytes()));
         }
         self.visit_inner(inner);
         true
@@ -444,9 +469,9 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
     fn visit_leave_tup(&mut self, _n_fields: uint,
                        _sz: uint, _align: uint) -> bool {
         if _n_fields == 1 {
-            self.writer.write([',' as u8]);
+            if_ok!(self, self.writer.write([',' as u8]));
         }
-        self.writer.write([')' as u8]);
+        if_ok!(self, self.writer.write([')' as u8]));
         true
     }
 
@@ -482,9 +507,9 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
         }
 
         if write {
-            self.writer.write(name.as_bytes());
+            if_ok!(self, self.writer.write(name.as_bytes()));
             if n_fields > 0 {
-                self.writer.write(['(' as u8]);
+                if_ok!(self, self.writer.write(['(' as u8]));
             }
         }
         true
@@ -498,7 +523,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
         match self.var_stk[self.var_stk.len() - 1] {
             Matched => {
                 if i != 0 {
-                    self.writer.write(", ".as_bytes());
+                    if_ok!(self, self.writer.write(", ".as_bytes()));
                 }
                 if ! self.visit_inner(inner) {
                     return false;
@@ -516,7 +541,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
         match self.var_stk[self.var_stk.len() - 1] {
             Matched => {
                 if n_fields > 0 {
-                    self.writer.write([')' as u8]);
+                    if_ok!(self, self.writer.write([')' as u8]));
                 }
             }
             _ => ()
@@ -538,28 +563,29 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
 
     fn visit_enter_fn(&mut self, _purity: uint, _proto: uint,
                       _n_inputs: uint, _retstyle: uint) -> bool {
-        self.writer.write("fn(".as_bytes());
+        if_ok!(self, self.writer.write("fn(".as_bytes()));
         true
     }
 
     fn visit_fn_input(&mut self, i: uint, _mode: uint, inner: *TyDesc) -> bool {
         if i != 0 {
-            self.writer.write(", ".as_bytes());
+            if_ok!(self, self.writer.write(", ".as_bytes()));
         }
         let name = unsafe { (*inner).name };
-        self.writer.write(name.as_bytes());
+        if_ok!(self, self.writer.write(name.as_bytes()));
         true
     }
 
-    fn visit_fn_output(&mut self, _retstyle: uint, variadic: bool, inner: *TyDesc) -> bool {
+    fn visit_fn_output(&mut self, _retstyle: uint, variadic: bool,
+                       inner: *TyDesc) -> bool {
         if variadic {
-            self.writer.write(", ...".as_bytes());
+            if_ok!(self, self.writer.write(", ...".as_bytes()));
         }
-        self.writer.write(")".as_bytes());
+        if_ok!(self, self.writer.write(")".as_bytes()));
         let name = unsafe { (*inner).name };
         if name != "()" {
-            self.writer.write(" -> ".as_bytes());
-            self.writer.write(name.as_bytes());
+            if_ok!(self, self.writer.write(" -> ".as_bytes()));
+            if_ok!(self, self.writer.write(name.as_bytes()));
         }
         true
     }
@@ -569,7 +595,7 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
 
 
     fn visit_trait(&mut self, name: &str) -> bool {
-        self.writer.write(name.as_bytes());
+        if_ok!(self, self.writer.write(name.as_bytes()));
         true
     }
 
@@ -582,13 +608,17 @@ impl<'a> TyVisitor for ReprVisitor<'a> {
     fn visit_closure_ptr(&mut self, _ck: uint) -> bool { true }
 }
 
-pub fn write_repr<T>(writer: &mut io::Writer, object: &T) {
+pub fn write_repr<T>(writer: &mut io::Writer, object: &T) -> io::IoResult<()> {
     unsafe {
         let ptr = ptr::to_unsafe_ptr(object) as *u8;
         let tydesc = get_tydesc::<T>();
         let u = ReprVisitor(ptr, writer);
         let mut v = reflect::MovePtrAdaptor(u);
         visit_tydesc(tydesc, &mut v as &mut TyVisitor);
+        match v.unwrap().last_err {
+            Some(e) => Err(e),
+            None => Ok(()),
+        }
     }
 }
 
@@ -597,7 +627,7 @@ pub fn repr_to_str<T>(t: &T) -> ~str {
     use io;
 
     let mut result = io::MemWriter::new();
-    write_repr(&mut result as &mut io::Writer, t);
+    write_repr(&mut result as &mut io::Writer, t).unwrap();
     str::from_utf8_owned(result.unwrap()).unwrap()
 }
 
@@ -615,7 +645,7 @@ fn test_repr() {
 
     fn exact_test<T>(t: &T, e:&str) {
         let mut m = io::MemWriter::new();
-        write_repr(&mut m as &mut io::Writer, t);
+        write_repr(&mut m as &mut io::Writer, t).unwrap();
         let s = str::from_utf8_owned(m.unwrap()).unwrap();
         assert_eq!(s.as_slice(), e);
     }
diff --git a/src/libstd/result.rs b/src/libstd/result.rs
index cc8fdeaccfe..846bba7533f 100644
--- a/src/libstd/result.rs
+++ b/src/libstd/result.rs
@@ -208,7 +208,7 @@ impl<T, E> Result<T, E> {
 
 impl<T: fmt::Show, E: fmt::Show> fmt::Show for Result<T, E> {
     #[inline]
-    fn fmt(s: &Result<T, E>, f: &mut fmt::Formatter) {
+    fn fmt(s: &Result<T, E>, f: &mut fmt::Formatter) -> fmt::Result {
         match *s {
             Ok(ref t) => write!(f.buf, "Ok({})", *t),
             Err(ref e) => write!(f.buf, "Err({})", *e)
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
index 455a84b4ce3..35b1e21df06 100644
--- a/src/libstd/rt/rtio.rs
+++ b/src/libstd/rt/rtio.rs
@@ -16,13 +16,13 @@ use libc;
 use ops::Drop;
 use option::{Option, Some, None};
 use path::Path;
-use result::{Result, Ok, Err};
+use result::{Result, Err};
 use rt::task::Task;
 use rt::local::Local;
 
 use ai = io::net::addrinfo;
 use io;
-use io::IoError;
+use io::{IoError, IoResult};
 use io::net::ip::{IpAddr, SocketAddr};
 use io::process::{ProcessConfig, ProcessExit};
 use io::signal::Signum;
@@ -116,23 +116,12 @@ impl<'a> LocalIo<'a> {
         return ret;
     }
 
-    pub fn maybe_raise<T>(f: |io: &mut IoFactory| -> Result<T, IoError>)
-        -> Option<T>
+    pub fn maybe_raise<T>(f: |io: &mut IoFactory| -> IoResult<T>)
+        -> IoResult<T>
     {
         match LocalIo::borrow() {
-            None => {
-                io::io_error::cond.raise(io::standard_error(io::IoUnavailable));
-                None
-            }
-            Some(mut io) => {
-                match f(io.get()) {
-                    Ok(t) => Some(t),
-                    Err(ioerr) => {
-                        io::io_error::cond.raise(ioerr);
-                        None
-                    }
-                }
-            }
+            None => Err(io::standard_error(io::IoUnavailable)),
+            Some(mut io) => f(io.get()),
         }
     }
 
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 7c43e64f17b..515eb93001a 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -119,6 +119,7 @@ impl Task {
 
             // Run the task main function, then do some cleanup.
             f.finally(|| {
+                #[allow(unused_must_use)]
                 fn close_outputs() {
                     let mut task = Local::borrow(None::<Task>);
                     let logger = task.get().logger.take();
@@ -126,8 +127,8 @@ impl Task {
                     let stdout = task.get().stdout.take();
                     drop(task);
                     drop(logger); // loggers are responsible for flushing
-                    match stdout { Some(mut w) => w.flush(), None => {} }
-                    match stderr { Some(mut w) => w.flush(), None => {} }
+                    match stdout { Some(mut w) => { w.flush(); }, None => {} }
+                    match stderr { Some(mut w) => { w.flush(); }, None => {} }
                 }
 
                 // First, flush/destroy the user stdout/logger because these
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 4d2dcb6c51c..9aece13b84c 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -464,9 +464,10 @@ fn begin_unwind_inner(msg: ~Any, file: &'static str, line: uint) -> ! {
             match task.stderr.take() {
                 Some(mut stderr) => {
                     Local::put(task);
-                    format_args!(|args| ::fmt::writeln(stderr, args),
-                                 "task '{}' failed at '{}', {}:{}",
-                                 n, msg_s, file, line);
+                    // FIXME: what to do when the task printing fails?
+                    let _err = format_args!(|args| ::fmt::writeln(stderr, args),
+                                            "task '{}' failed at '{}', {}:{}",
+                                            n, msg_s, file, line);
                     task = Local::take();
 
                     match util::replace(&mut task.stderr, Some(stderr)) {
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 9c17c624987..69e240f30bc 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -11,10 +11,12 @@
 use container::Container;
 use fmt;
 use from_str::FromStr;
+use io::IoResult;
 use iter::Iterator;
 use libc;
 use option::{Some, None, Option};
 use os;
+use result::Ok;
 use str::StrSlice;
 use unstable::running_on_valgrind;
 use vec::ImmutableVector;
@@ -73,16 +75,17 @@ pub fn dumb_println(args: &fmt::Arguments) {
 
     struct Stderr;
     impl io::Writer for Stderr {
-        fn write(&mut self, data: &[u8]) {
+        fn write(&mut self, data: &[u8]) -> IoResult<()> {
             unsafe {
                 libc::write(libc::STDERR_FILENO,
                             data.as_ptr() as *libc::c_void,
                             data.len() as libc::size_t);
             }
+            Ok(()) // yes, we're lying
         }
     }
     let mut w = Stderr;
-    fmt::writeln(&mut w as &mut io::Writer, args);
+    let _ = fmt::writeln(&mut w as &mut io::Writer, args);
 }
 
 pub fn abort(msg: &str) -> ! {
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index ef2374f6095..04e42b3eedf 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -11,6 +11,7 @@
 //! Utilities for spawning and managing processes
 
 #[allow(missing_doc)];
+#[deny(unused_must_use)];
 
 use comm::SharedChan;
 use io::Reader;
@@ -119,7 +120,8 @@ impl Process {
      * * options - Options to configure the environment of the process,
      *             the working directory and the standard IO streams.
      */
-    pub fn new(prog: &str, args: &[~str], options: ProcessOptions) -> Option<Process> {
+    pub fn new(prog: &str, args: &[~str],
+               options: ProcessOptions) -> io::IoResult<Process> {
         let ProcessOptions { env, dir, in_fd, out_fd, err_fd } = options;
         let env = env.as_ref().map(|a| a.as_slice());
         let cwd = dir.as_ref().map(|a| a.as_str().unwrap());
@@ -138,10 +140,7 @@ impl Process {
             cwd: cwd,
             io: rtio,
         };
-        match process::Process::new(rtconfig) {
-            Some(inner) => Some(Process { inner: inner }),
-            None => None
-        }
+        process::Process::new(rtconfig).map(|p| Process { inner: p })
     }
 
     /// Returns the unique id of the process
@@ -224,19 +223,17 @@ impl Process {
         let ch_clone = ch.clone();
 
         spawn(proc() {
-            let _guard = io::ignore_io_error();
             let mut error = error;
             match error {
                 Some(ref mut e) => ch.send((2, e.read_to_end())),
-                None => ch.send((2, ~[]))
+                None => ch.send((2, Ok(~[])))
             }
         });
         spawn(proc() {
-            let _guard = io::ignore_io_error();
             let mut output = output;
             match output {
                 Some(ref mut e) => ch_clone.send((1, e.read_to_end())),
-                None => ch_clone.send((1, ~[]))
+                None => ch_clone.send((1, Ok(~[])))
             }
         });
 
@@ -251,8 +248,8 @@ impl Process {
         };
 
         return ProcessOutput {status: status,
-                              output: outs,
-                              error: errs};
+                              output: outs.ok().unwrap_or(~[]),
+                              error: errs.ok().unwrap_or(~[]) };
     }
 
     /**
@@ -262,9 +259,10 @@ impl Process {
      * On Posix OSs SIGTERM will be sent to the process. On Win32
      * TerminateProcess(..) will be called.
      */
-    pub fn destroy(&mut self) {
-        self.inner.signal(io::process::PleaseExitSignal);
+    pub fn destroy(&mut self) -> io::IoResult<()> {
+        let ret = self.inner.signal(io::process::PleaseExitSignal);
         self.finish();
+        return ret;
     }
 
     /**
@@ -274,9 +272,12 @@ impl Process {
      * On Posix OSs SIGKILL will be sent to the process. On Win32
      * TerminateProcess(..) will be called.
      */
-    pub fn force_destroy(&mut self) {
-        self.inner.signal(io::process::MustDieSignal);
+    pub fn force_destroy(&mut self) -> io::IoResult<()> {
+        // This should never fail because we own the process
+        let ret = self.inner.signal(io::process::MustDieSignal);
         self.finish();
+        return ret;
+
     }
 }
 
@@ -293,18 +294,14 @@ impl Process {
  *
  * The process's exit code, or None if the child process could not be started
  */
-pub fn process_status(prog: &str, args: &[~str]) -> Option<ProcessExit> {
-    let mut opt_prog = Process::new(prog, args, ProcessOptions {
+pub fn process_status(prog: &str, args: &[~str]) -> io::IoResult<ProcessExit> {
+    Process::new(prog, args, ProcessOptions {
         env: None,
         dir: None,
         in_fd: Some(unsafe { libc::dup(libc::STDIN_FILENO) }),
         out_fd: Some(unsafe { libc::dup(libc::STDOUT_FILENO) }),
         err_fd: Some(unsafe { libc::dup(libc::STDERR_FILENO) })
-    });
-    match opt_prog {
-        Some(ref mut prog) => Some(prog.finish()),
-        None => None
-    }
+    }).map(|mut p| p.finish())
 }
 
 /**
@@ -320,12 +317,10 @@ pub fn process_status(prog: &str, args: &[~str]) -> Option<ProcessExit> {
  * The process's stdout/stderr output and exit code, or None if the child process could not be
  * started.
  */
-pub fn process_output(prog: &str, args: &[~str]) -> Option<ProcessOutput> {
-    let mut opt_prog = Process::new(prog, args, ProcessOptions::new());
-    match opt_prog {
-        Some(ref mut prog) => Some(prog.finish_with_output()),
-        None => None
-    }
+pub fn process_output(prog: &str, args: &[~str]) -> io::IoResult<ProcessOutput> {
+    Process::new(prog, args, ProcessOptions::new()).map(|mut p| {
+        p.finish_with_output()
+    })
 }
 
 #[cfg(test)]
@@ -337,33 +332,25 @@ mod tests {
     use task::spawn;
     use unstable::running_on_valgrind;
     use io::pipe::PipeStream;
-    use io::{io_error, FileNotFound};
+    use io::{FileNotFound};
     use libc::c_int;
 
     #[test]
     #[cfg(not(target_os="android"))] // FIXME(#10380)
     fn test_process_status() {
-        let mut status = run::process_status("false", []).expect("failed to exec `false`");
+        let mut status = run::process_status("false", []).unwrap();
         assert!(status.matches_exit_status(1));
 
-        status = run::process_status("true", []).expect("failed to exec `true`");
+        status = run::process_status("true", []).unwrap();
         assert!(status.success());
     }
 
     #[test]
     fn test_process_output_fail_to_start() {
-        // If the executable does not exist, then the io_error condition should be raised with
-        // IoErrorKind FileNotFound.
-
-        let mut trapped_io_error = false;
-        let opt_outp = io_error::cond.trap(|e| {
-            trapped_io_error = true;
-            assert_eq!(e.kind, FileNotFound);
-        }).inside(|| -> Option<run::ProcessOutput> {
-            run::process_output("/no-binary-by-this-name-should-exist", [])
-        });
-        assert!(trapped_io_error);
-        assert!(opt_outp.is_none());
+        match run::process_output("/no-binary-by-this-name-should-exist", []) {
+            Err(e) => assert_eq!(e.kind, FileNotFound),
+            Ok(..) => fail!()
+        }
     }
 
     #[test]
@@ -371,7 +358,7 @@ mod tests {
     fn test_process_output_output() {
 
         let run::ProcessOutput {status, output, error}
-             = run::process_output("echo", [~"hello"]).expect("failed to exec `echo`");
+             = run::process_output("echo", [~"hello"]).unwrap();
         let output_str = str::from_utf8_owned(output).unwrap();
 
         assert!(status.success());
@@ -387,7 +374,7 @@ mod tests {
     fn test_process_output_error() {
 
         let run::ProcessOutput {status, output, error}
-             = run::process_output("mkdir", [~"."]).expect("failed to exec `mkdir`");
+             = run::process_output("mkdir", [~"."]).unwrap();
 
         assert!(status.matches_exit_status(1));
         assert_eq!(output, ~[]);
@@ -408,7 +395,7 @@ mod tests {
             in_fd: Some(pipe_in.input),
             out_fd: Some(pipe_out.out),
             err_fd: Some(pipe_err.out)
-        }).expect("failed to exec `cat`");
+        }).unwrap();
 
         os::close(pipe_in.input as int);
         os::close(pipe_out.out as int);
@@ -426,27 +413,18 @@ mod tests {
 
     fn writeclose(fd: c_int, s: &str) {
         let mut writer = PipeStream::open(fd);
-        writer.write(s.as_bytes());
+        writer.write(s.as_bytes()).unwrap();
     }
 
     fn readclose(fd: c_int) -> ~str {
-        let mut res = ~[];
-        let mut reader = PipeStream::open(fd);
-        let mut buf = [0, ..1024];
-        loop {
-            match reader.read(buf) {
-                Some(n) => { res.push_all(buf.slice_to(n)); }
-                None => break
-            }
-        }
-        str::from_utf8_owned(res).unwrap()
+        PipeStream::open(fd).read_to_str().unwrap()
     }
 
     #[test]
     #[cfg(not(target_os="android"))] // FIXME(#10380)
     fn test_finish_once() {
         let mut prog = run::Process::new("false", [], run::ProcessOptions::new())
-            .expect("failed to exec `false`");
+            .unwrap();
         assert!(prog.finish().matches_exit_status(1));
     }
 
@@ -454,7 +432,7 @@ mod tests {
     #[cfg(not(target_os="android"))] // FIXME(#10380)
     fn test_finish_twice() {
         let mut prog = run::Process::new("false", [], run::ProcessOptions::new())
-            .expect("failed to exec `false`");
+            .unwrap();
         assert!(prog.finish().matches_exit_status(1));
         assert!(prog.finish().matches_exit_status(1));
     }
@@ -464,7 +442,7 @@ mod tests {
     fn test_finish_with_output_once() {
 
         let mut prog = run::Process::new("echo", [~"hello"], run::ProcessOptions::new())
-            .expect("failed to exec `echo`");
+            .unwrap();
         let run::ProcessOutput {status, output, error}
             = prog.finish_with_output();
         let output_str = str::from_utf8_owned(output).unwrap();
@@ -482,7 +460,7 @@ mod tests {
     fn test_finish_with_output_twice() {
 
         let mut prog = run::Process::new("echo", [~"hello"], run::ProcessOptions::new())
-            .expect("failed to exec `echo`");
+            .unwrap();
         let run::ProcessOutput {status, output, error}
             = prog.finish_with_output();
 
@@ -511,14 +489,14 @@ mod tests {
         run::Process::new("pwd", [], run::ProcessOptions {
             dir: dir,
             .. run::ProcessOptions::new()
-        }).expect("failed to exec `pwd`")
+        }).unwrap()
     }
     #[cfg(unix,target_os="android")]
     fn run_pwd(dir: Option<&Path>) -> run::Process {
         run::Process::new("/system/bin/sh", [~"-c",~"pwd"], run::ProcessOptions {
             dir: dir,
             .. run::ProcessOptions::new()
-        }).expect("failed to exec `/system/bin/sh`")
+        }).unwrap()
     }
 
     #[cfg(windows)]
@@ -526,7 +504,7 @@ mod tests {
         run::Process::new("cmd", [~"/c", ~"cd"], run::ProcessOptions {
             dir: dir,
             .. run::ProcessOptions::new()
-        }).expect("failed to run `cmd`")
+        }).unwrap()
     }
 
     #[test]
@@ -537,8 +515,8 @@ mod tests {
         let parent_dir = os::getcwd();
         let child_dir = Path::new(output.trim());
 
-        let parent_stat = parent_dir.stat();
-        let child_stat = child_dir.stat();
+        let parent_stat = parent_dir.stat().unwrap();
+        let child_stat = child_dir.stat().unwrap();
 
         assert_eq!(parent_stat.unstable.device, child_stat.unstable.device);
         assert_eq!(parent_stat.unstable.inode, child_stat.unstable.inode);
@@ -554,8 +532,8 @@ mod tests {
         let output = str::from_utf8_owned(prog.finish_with_output().output).unwrap();
         let child_dir = Path::new(output.trim());
 
-        let parent_stat = parent_dir.stat();
-        let child_stat = child_dir.stat();
+        let parent_stat = parent_dir.stat().unwrap();
+        let child_stat = child_dir.stat().unwrap();
 
         assert_eq!(parent_stat.unstable.device, child_stat.unstable.device);
         assert_eq!(parent_stat.unstable.inode, child_stat.unstable.inode);
@@ -566,14 +544,14 @@ mod tests {
         run::Process::new("env", [], run::ProcessOptions {
             env: env,
             .. run::ProcessOptions::new()
-        }).expect("failed to exec `env`")
+        }).unwrap()
     }
     #[cfg(unix,target_os="android")]
     fn run_env(env: Option<~[(~str, ~str)]>) -> run::Process {
         run::Process::new("/system/bin/sh", [~"-c",~"set"], run::ProcessOptions {
             env: env,
             .. run::ProcessOptions::new()
-        }).expect("failed to exec `/system/bin/sh`")
+        }).unwrap()
     }
 
     #[cfg(windows)]
@@ -581,7 +559,7 @@ mod tests {
         run::Process::new("cmd", [~"/c", ~"set"], run::ProcessOptions {
             env: env,
             .. run::ProcessOptions::new()
-        }).expect("failed to run `cmd`")
+        }).unwrap()
     }
 
     #[test]
diff --git a/src/libstd/task.rs b/src/libstd/task.rs
index c8b69083086..5fa0c6431ab 100644
--- a/src/libstd/task.rs
+++ b/src/libstd/task.rs
@@ -541,7 +541,7 @@ fn test_avoid_copying_the_body_task_spawn() {
 #[test]
 fn test_avoid_copying_the_body_try() {
     avoid_copying_the_body(|f| {
-        try(proc() {
+        let _ = try(proc() {
             f()
         });
     })
diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs
index 4c545de73b4..c8bd1907c5c 100644
--- a/src/libstd/to_bytes.rs
+++ b/src/libstd/to_bytes.rs
@@ -349,7 +349,7 @@ impl<A:IterBytes> ToBytes for A {
 
         let mut m = ::io::MemWriter::new();
         self.iter_bytes(lsb0, |bytes| {
-            m.write(bytes);
+            m.write(bytes).unwrap();
             true
         });
         m.unwrap()
diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs
index 3b2c86c3712..c2fa168a478 100644
--- a/src/libstd/unstable/sync.rs
+++ b/src/libstd/unstable/sync.rs
@@ -200,7 +200,7 @@ mod tests {
             // accesses will also fail.
             let x = Exclusive::new(1);
             let x2 = x.clone();
-            task::try(proc() {
+            let _ = task::try(proc() {
                 x2.with(|one| assert_eq!(*one, 2))
             });
             x.with(|one| assert_eq!(*one, 1));
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 90fe121160b..5b3b436a6fc 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -189,58 +189,61 @@ impl Level {
     }
 }
 
-fn print_maybe_styled(msg: &str, color: term::attr::Attr) {
-    local_data_key!(tls_terminal: ~Option<term::Terminal<StdWriter>>)
+fn print_maybe_styled(msg: &str, color: term::attr::Attr) -> io::IoResult<()> {
+    local_data_key!(tls_terminal: Option<term::Terminal<StdWriter>>)
+
 
     fn is_stderr_screen() -> bool {
         use std::libc;
         unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
     }
-    fn write_pretty<T: Writer>(term: &mut term::Terminal<T>, s: &str, c: term::attr::Attr) {
-        term.attr(c);
-        term.write(s.as_bytes());
-        term.reset();
+    fn write_pretty<T: Writer>(term: &mut term::Terminal<T>, s: &str,
+                               c: term::attr::Attr) -> io::IoResult<()> {
+        if_ok!(term.attr(c));
+        if_ok!(term.write(s.as_bytes()));
+        if_ok!(term.reset());
+        Ok(())
     }
 
     if is_stderr_screen() {
         local_data::get_mut(tls_terminal, |term| {
             match term {
                 Some(term) => {
-                    match **term {
+                    match *term {
                         Some(ref mut term) => write_pretty(term, msg, color),
                         None => io::stderr().write(msg.as_bytes())
                     }
                 }
                 None => {
-                    let t = ~match term::Terminal::new(io::stderr()) {
+                    let (t, ret) = match term::Terminal::new(io::stderr()) {
                         Ok(mut term) => {
-                            write_pretty(&mut term, msg, color);
-                            Some(term)
+                            let r = write_pretty(&mut term, msg, color);
+                            (Some(term), r)
                         }
                         Err(_) => {
-                            io::stderr().write(msg.as_bytes());
-                            None
+                            (None, io::stderr().write(msg.as_bytes()))
                         }
                     };
                     local_data::set(tls_terminal, t);
+                    ret
                 }
             }
-        });
+        })
     } else {
-        io::stderr().write(msg.as_bytes());
+        io::stderr().write(msg.as_bytes())
     }
 }
 
-fn print_diagnostic(topic: &str, lvl: Level, msg: &str) {
-    let mut stderr = io::stderr();
-
+fn print_diagnostic(topic: &str, lvl: Level, msg: &str) -> io::IoResult<()> {
     if !topic.is_empty() {
-        write!(&mut stderr as &mut io::Writer, "{} ", topic);
+        let mut stderr = io::stderr();
+        if_ok!(write!(&mut stderr as &mut io::Writer, "{} ", topic));
     }
 
-    print_maybe_styled(format!("{}: ", lvl.to_str()),
-                       term::attr::ForegroundColor(lvl.color()));
-    print_maybe_styled(format!("{}\n", msg), term::attr::Bold);
+    if_ok!(print_maybe_styled(format!("{}: ", lvl.to_str()),
+                              term::attr::ForegroundColor(lvl.color())));
+    if_ok!(print_maybe_styled(format!("{}\n", msg), term::attr::Bold));
+    Ok(())
 }
 
 pub struct DefaultEmitter;
@@ -250,20 +253,28 @@ impl Emitter for DefaultEmitter {
             cmsp: Option<(&codemap::CodeMap, Span)>,
             msg: &str,
             lvl: Level) {
-        match cmsp {
+        let error = match cmsp {
             Some((cm, sp)) => emit(cm, sp, msg, lvl, false),
             None => print_diagnostic("", lvl, msg),
+        };
+
+        match error {
+            Ok(()) => {}
+            Err(e) => fail!("failed to print diagnostics: {}", e),
         }
     }
 
     fn custom_emit(&self, cm: &codemap::CodeMap,
                    sp: Span, msg: &str, lvl: Level) {
-        emit(cm, sp, msg, lvl, true);
+        match emit(cm, sp, msg, lvl, true) {
+            Ok(()) => {}
+            Err(e) => fail!("failed to print diagnostics: {}", e),
+        }
     }
 }
 
 fn emit(cm: &codemap::CodeMap, sp: Span,
-        msg: &str, lvl: Level, custom: bool) {
+        msg: &str, lvl: Level, custom: bool) -> io::IoResult<()> {
     let ss = cm.span_to_str(sp);
     let lines = cm.span_to_lines(sp);
     if custom {
@@ -272,19 +283,19 @@ fn emit(cm: &codemap::CodeMap, sp: Span,
         // the span)
         let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info};
         let ses = cm.span_to_str(span_end);
-        print_diagnostic(ses, lvl, msg);
-        custom_highlight_lines(cm, sp, lvl, lines);
+        if_ok!(print_diagnostic(ses, lvl, msg));
+        if_ok!(custom_highlight_lines(cm, sp, lvl, lines));
     } else {
-        print_diagnostic(ss, lvl, msg);
-        highlight_lines(cm, sp, lvl, lines);
+        if_ok!(print_diagnostic(ss, lvl, msg));
+        if_ok!(highlight_lines(cm, sp, lvl, lines));
     }
-    print_macro_backtrace(cm, sp);
+    print_macro_backtrace(cm, sp)
 }
 
 fn highlight_lines(cm: &codemap::CodeMap,
                    sp: Span,
                    lvl: Level,
-                   lines: &codemap::FileLines) {
+                   lines: &codemap::FileLines) -> io::IoResult<()> {
     let fm = lines.file;
     let mut err = io::stderr();
     let err = &mut err as &mut io::Writer;
@@ -297,12 +308,13 @@ fn highlight_lines(cm: &codemap::CodeMap,
     }
     // Print the offending lines
     for line in display_lines.iter() {
-        write!(err, "{}:{} {}\n", fm.name, *line + 1, fm.get_line(*line as int));
+        if_ok!(write!(err, "{}:{} {}\n", fm.name, *line + 1,
+                      fm.get_line(*line as int)));
     }
     if elided {
         let last_line = display_lines[display_lines.len() - 1u];
         let s = format!("{}:{} ", fm.name, last_line + 1u);
-        write!(err, "{0:1$}...\n", "", s.len());
+        if_ok!(write!(err, "{0:1$}...\n", "", s.len()));
     }
 
     // FIXME (#3260)
@@ -334,7 +346,7 @@ fn highlight_lines(cm: &codemap::CodeMap,
                 _ => s.push_char(' '),
             };
         }
-        write!(err, "{}", s);
+        if_ok!(write!(err, "{}", s));
         let mut s = ~"^";
         let hi = cm.lookup_char_pos(sp.hi);
         if hi.col != lo.col {
@@ -342,8 +354,10 @@ fn highlight_lines(cm: &codemap::CodeMap,
             let num_squigglies = hi.col.to_uint()-lo.col.to_uint()-1u;
             for _ in range(0, num_squigglies) { s.push_char('~'); }
         }
-        print_maybe_styled(s + "\n", term::attr::ForegroundColor(lvl.color()));
+        if_ok!(print_maybe_styled(s + "\n",
+                                  term::attr::ForegroundColor(lvl.color())));
     }
+    Ok(())
 }
 
 // Here are the differences between this and the normal `highlight_lines`:
@@ -355,23 +369,23 @@ fn highlight_lines(cm: &codemap::CodeMap,
 fn custom_highlight_lines(cm: &codemap::CodeMap,
                           sp: Span,
                           lvl: Level,
-                          lines: &codemap::FileLines) {
+                          lines: &codemap::FileLines) -> io::IoResult<()> {
     let fm = lines.file;
     let mut err = io::stderr();
     let err = &mut err as &mut io::Writer;
 
     let lines = lines.lines.as_slice();
     if lines.len() > MAX_LINES {
-        write!(err, "{}:{} {}\n", fm.name,
-               lines[0] + 1, fm.get_line(lines[0] as int));
-        write!(err, "...\n");
+        if_ok!(write!(err, "{}:{} {}\n", fm.name,
+                      lines[0] + 1, fm.get_line(lines[0] as int)));
+        if_ok!(write!(err, "...\n"));
         let last_line = lines[lines.len()-1];
-        write!(err, "{}:{} {}\n", fm.name,
-               last_line + 1, fm.get_line(last_line as int));
+        if_ok!(write!(err, "{}:{} {}\n", fm.name,
+                      last_line + 1, fm.get_line(last_line as int)));
     } else {
         for line in lines.iter() {
-            write!(err, "{}:{} {}\n", fm.name,
-                   *line + 1, fm.get_line(*line as int));
+            if_ok!(write!(err, "{}:{} {}\n", fm.name,
+                          *line + 1, fm.get_line(*line as int)));
         }
     }
     let last_line_start = format!("{}:{} ", fm.name, lines[lines.len()-1]+1);
@@ -381,22 +395,24 @@ fn custom_highlight_lines(cm: &codemap::CodeMap,
     let mut s = ~"";
     for _ in range(0, skip) { s.push_char(' '); }
     s.push_char('^');
-    print_maybe_styled(s + "\n", term::attr::ForegroundColor(lvl.color()));
+    print_maybe_styled(s + "\n", term::attr::ForegroundColor(lvl.color()))
 }
 
-fn print_macro_backtrace(cm: &codemap::CodeMap, sp: Span) {
+fn print_macro_backtrace(cm: &codemap::CodeMap, sp: Span) -> io::IoResult<()> {
     for ei in sp.expn_info.iter() {
         let ss = ei.callee.span.as_ref().map_or(~"", |span| cm.span_to_str(*span));
         let (pre, post) = match ei.callee.format {
             codemap::MacroAttribute => ("#[", "]"),
             codemap::MacroBang => ("", "!")
         };
-        print_diagnostic(ss, Note,
-                         format!("in expansion of {}{}{}", pre, ei.callee.name, post));
+        if_ok!(print_diagnostic(ss, Note,
+                                format!("in expansion of {}{}{}", pre,
+                                        ei.callee.name, post)));
         let ss = cm.span_to_str(ei.call_site);
-        print_diagnostic(ss, Note, "expansion site");
-        print_macro_backtrace(cm, ei.call_site);
+        if_ok!(print_diagnostic(ss, Note, "expansion site"));
+        if_ok!(print_macro_backtrace(cm, ei.call_site));
     }
+    Ok(())
 }
 
 pub fn expect<T:Clone>(diag: @SpanHandler, opt: Option<T>, msg: || -> ~str)
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index d8d98b27793..ae93c235ad2 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -957,14 +957,13 @@ mod test {
     use ast_util;
     use codemap;
     use codemap::Spanned;
-    use fold;
     use fold::*;
     use ext::base::{CrateLoader, MacroCrate};
     use parse;
     use parse::token::{fresh_mark, gensym, intern};
     use parse::token;
     use util::parser_testing::{string_to_crate, string_to_crate_and_sess};
-    use util::parser_testing::{string_to_pat, string_to_tts, strs_to_idents};
+    use util::parser_testing::{string_to_pat, strs_to_idents};
     use visit;
     use visit::Visitor;
 
@@ -1253,14 +1252,14 @@ mod test {
                     let varref_name = mtwt_resolve(varref.segments[0].identifier);
                     let varref_marks = mtwt_marksof(varref.segments[0].identifier.ctxt,
                                                     invalid_name);
-                    if (!(varref_name==binding_name)){
+                    if !(varref_name==binding_name) {
                         println!("uh oh, should match but doesn't:");
                         println!("varref: {:?}",varref);
                         println!("binding: {:?}", bindings[binding_idx]);
                         ast_util::display_sctable(get_sctable());
                     }
                     assert_eq!(varref_name,binding_name);
-                    if (bound_ident_check) {
+                    if bound_ident_check {
                         // we're checking bound-identifier=?, and the marks
                         // should be the same, too:
                         assert_eq!(varref_marks,binding_marks.clone());
@@ -1269,7 +1268,7 @@ mod test {
                     let fail = (varref.segments.len() == 1)
                         && (mtwt_resolve(varref.segments[0].identifier) == binding_name);
                     // temp debugging:
-                    if (fail) {
+                    if fail {
                         println!("failure on test {}",test_idx);
                         println!("text of test case: \"{}\"", teststr);
                         println!("");
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index f3f947ec00d..52010b39a54 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -20,7 +20,6 @@ use parse::token::get_ident_interner;
 use parse::token;
 use print::pprust;
 
-use std::io;
 use std::io::File;
 use std::rc::Rc;
 use std::str;
@@ -109,9 +108,9 @@ pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         None => return MacResult::dummy_expr()
     };
     let file = res_rel_file(cx, sp, &Path::new(file));
-    let bytes = match io::result(|| File::open(&file).read_to_end()) {
+    let bytes = match File::open(&file).read_to_end() {
         Err(e) => {
-            cx.span_err(sp, format!("couldn't read {}: {}", file.display(), e.desc));
+            cx.span_err(sp, format!("couldn't read {}: {}", file.display(), e));
             return MacResult::dummy_expr();
         }
         Ok(bytes) => bytes,
@@ -141,9 +140,9 @@ pub fn expand_include_bin(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
         None => return MacResult::dummy_expr()
     };
     let file = res_rel_file(cx, sp, &Path::new(file));
-    match io::result(|| File::open(&file).read_to_end()) {
+    match File::open(&file).read_to_end() {
         Err(e) => {
-            cx.span_err(sp, format!("couldn't read {}: {}", file.display(), e.desc));
+            cx.span_err(sp, format!("couldn't read {}: {}", file.display(), e));
             return MacResult::dummy_expr();
         }
         Ok(bytes) => {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 8f5bbc2cdad..297ec6acf51 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -861,6 +861,7 @@ pub fn noop_fold_stmt<T: Folder>(s: &Stmt, folder: &mut T) -> SmallVector<@Stmt>
 
 #[cfg(test)]
 mod test {
+    use std::io;
     use ast;
     use util::parser_testing::{string_to_crate, matches_codepattern};
     use parse::token;
@@ -868,8 +869,9 @@ mod test {
     use super::*;
 
     // this version doesn't care about getting comments or docstrings in.
-    fn fake_print_crate(s: &mut pprust::State, crate: &ast::Crate) {
-        pprust::print_mod(s, &crate.module, crate.attrs);
+    fn fake_print_crate(s: &mut pprust::State,
+                        crate: &ast::Crate) -> io::IoResult<()> {
+        pprust::print_mod(s, &crate.module, crate.attrs)
     }
 
     // change every identifier to "zz"
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index e2460b0171a..e2aa9e3b3ee 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -33,6 +33,11 @@ This API is completely unstable and subject to change.
 extern mod extra;
 extern mod term;
 
+#[cfg(stage0)]
+macro_rules! if_ok (
+    ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
+)
+
 pub mod util {
     pub mod interner;
     #[cfg(test)]
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index 7165e7b404f..f65bc3ad7a3 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -350,7 +350,8 @@ pub fn gather_comments_and_literals(span_diagnostic:
                                     path: ~str,
                                     srdr: &mut io::Reader)
                                  -> (~[Comment], ~[Literal]) {
-    let src = str::from_utf8_owned(srdr.read_to_end()).unwrap();
+    let src = srdr.read_to_end().unwrap();
+    let src = str::from_utf8_owned(src).unwrap();
     let cm = CodeMap::new();
     let filemap = cm.new_filemap(path, src);
     let rdr = lexer::new_low_level_string_reader(span_diagnostic, filemap);
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index cec9f7c2d9f..328f0e7f221 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -19,7 +19,6 @@ use parse::attr::ParserAttr;
 use parse::parser::Parser;
 
 use std::cell::RefCell;
-use std::io;
 use std::io::File;
 use std::str;
 
@@ -232,10 +231,10 @@ pub fn file_to_filemap(sess: @ParseSess, path: &Path, spanopt: Option<Span>)
             None => sess.span_diagnostic.handler().fatal(msg),
         }
     };
-    let bytes = match io::result(|| File::open(path).read_to_end()) {
+    let bytes = match File::open(path).read_to_end() {
         Ok(bytes) => bytes,
         Err(e) => {
-            err(format!("couldn't read {}: {}", path.display(), e.desc));
+            err(format!("couldn't read {}: {}", path.display(), e));
             unreachable!()
         }
     };
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 6d2acd3d803..f1dd844fc7c 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -588,8 +588,8 @@ impl BytesContainer for InternedString {
 }
 
 impl fmt::Show for InternedString {
-    fn fmt(obj: &InternedString, f: &mut fmt::Formatter) {
-        write!(f.buf, "{}", obj.string.as_slice());
+    fn fmt(obj: &InternedString, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f.buf, "{}", obj.string.as_slice())
     }
 }
 
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 3e1f5b4cfb3..f6952261723 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -292,16 +292,17 @@ impl Printer {
     pub fn replace_last_token(&mut self, t: Token) {
         self.token[self.right] = t;
     }
-    pub fn pretty_print(&mut self, t: Token) {
+    pub fn pretty_print(&mut self, t: Token) -> io::IoResult<()> {
         debug!("pp ~[{},{}]", self.left, self.right);
         match t {
           Eof => {
             if !self.scan_stack_empty {
                 self.check_stack(0);
                 let left = self.token[self.left].clone();
-                self.advance_left(left, self.size[self.left]);
+                if_ok!(self.advance_left(left, self.size[self.left]));
             }
             self.indent(0);
+            Ok(())
           }
           Begin(b) => {
             if self.scan_stack_empty {
@@ -315,17 +316,19 @@ impl Printer {
             self.token[self.right] = t;
             self.size[self.right] = -self.right_total;
             self.scan_push(self.right);
+            Ok(())
           }
           End => {
             if self.scan_stack_empty {
                 debug!("pp End/print ~[{},{}]", self.left, self.right);
-                self.print(t, 0);
+                self.print(t, 0)
             } else {
                 debug!("pp End/buffer ~[{},{}]", self.left, self.right);
                 self.advance_right();
                 self.token[self.right] = t;
                 self.size[self.right] = -1;
                 self.scan_push(self.right);
+                Ok(())
             }
           }
           Break(b) => {
@@ -342,12 +345,13 @@ impl Printer {
             self.token[self.right] = t;
             self.size[self.right] = -self.right_total;
             self.right_total += b.blank_space;
+            Ok(())
           }
           String(ref s, len) => {
             if self.scan_stack_empty {
                 debug!("pp String('{}')/print ~[{},{}]",
                        *s, self.left, self.right);
-                self.print(t.clone(), len);
+                self.print(t.clone(), len)
             } else {
                 debug!("pp String('{}')/buffer ~[{},{}]",
                        *s, self.left, self.right);
@@ -355,12 +359,12 @@ impl Printer {
                 self.token[self.right] = t.clone();
                 self.size[self.right] = len;
                 self.right_total += len;
-                self.check_stream();
+                self.check_stream()
             }
           }
         }
     }
-    pub fn check_stream(&mut self) {
+    pub fn check_stream(&mut self) -> io::IoResult<()> {
         debug!("check_stream ~[{}, {}] with left_total={}, right_total={}",
                self.left, self.right, self.left_total, self.right_total);
         if self.right_total - self.left_total > self.space {
@@ -373,9 +377,12 @@ impl Printer {
                 }
             }
             let left = self.token[self.left].clone();
-            self.advance_left(left, self.size[self.left]);
-            if self.left != self.right { self.check_stream(); }
+            if_ok!(self.advance_left(left, self.size[self.left]));
+            if self.left != self.right {
+                if_ok!(self.check_stream());
+            }
         }
+        Ok(())
     }
     pub fn scan_push(&mut self, x: uint) {
         debug!("scan_push {}", x);
@@ -413,11 +420,11 @@ impl Printer {
         self.right %= self.buf_len;
         assert!((self.right != self.left));
     }
-    pub fn advance_left(&mut self, x: Token, L: int) {
+    pub fn advance_left(&mut self, x: Token, L: int) -> io::IoResult<()> {
         debug!("advnce_left ~[{},{}], sizeof({})={}", self.left, self.right,
                self.left, L);
         if L >= 0 {
-            self.print(x.clone(), L);
+            let ret = self.print(x.clone(), L);
             match x {
               Break(b) => self.left_total += b.blank_space,
               String(_, len) => {
@@ -429,8 +436,11 @@ impl Printer {
                 self.left += 1u;
                 self.left %= self.buf_len;
                 let left = self.token[self.left].clone();
-                self.advance_left(left, self.size[self.left]);
+                if_ok!(self.advance_left(left, self.size[self.left]));
             }
+            ret
+        } else {
+            Ok(())
         }
     }
     pub fn check_stack(&mut self, k: int) {
@@ -456,11 +466,12 @@ impl Printer {
             }
         }
     }
-    pub fn print_newline(&mut self, amount: int) {
+    pub fn print_newline(&mut self, amount: int) -> io::IoResult<()> {
         debug!("NEWLINE {}", amount);
-        write!(self.out, "\n");
+        let ret = write!(self.out, "\n");
         self.pending_indentation = 0;
         self.indent(amount);
+        return ret;
     }
     pub fn indent(&mut self, amount: int) {
         debug!("INDENT {}", amount);
@@ -478,14 +489,14 @@ impl Printer {
             }
         }
     }
-    pub fn print_str(&mut self, s: &str) {
+    pub fn print_str(&mut self, s: &str) -> io::IoResult<()> {
         while self.pending_indentation > 0 {
-            write!(self.out, " ");
+            if_ok!(write!(self.out, " "));
             self.pending_indentation -= 1;
         }
-        write!(self.out, "{}", s);
+        write!(self.out, "{}", s)
     }
-    pub fn print(&mut self, x: Token, L: int) {
+    pub fn print(&mut self, x: Token, L: int) -> io::IoResult<()> {
         debug!("print {} {} (remaining line space={})", tok_str(x.clone()), L,
                self.space);
         debug!("{}", buf_str(self.token.clone(),
@@ -509,12 +520,14 @@ impl Printer {
                     pbreak: Fits
                 });
             }
+            Ok(())
           }
           End => {
             debug!("print End -> pop End");
             let print_stack = &mut self.print_stack;
             assert!((print_stack.len() != 0u));
             print_stack.pop().unwrap();
+            Ok(())
           }
           Break(b) => {
             let top = self.get_top();
@@ -523,24 +536,28 @@ impl Printer {
                 debug!("print Break({}) in fitting block", b.blank_space);
                 self.space -= b.blank_space;
                 self.indent(b.blank_space);
+                Ok(())
               }
               Broken(Consistent) => {
                 debug!("print Break({}+{}) in consistent block",
                        top.offset, b.offset);
-                self.print_newline(top.offset + b.offset);
+                let ret = self.print_newline(top.offset + b.offset);
                 self.space = self.margin - (top.offset + b.offset);
+                ret
               }
               Broken(Inconsistent) => {
                 if L > self.space {
                     debug!("print Break({}+{}) w/ newline in inconsistent",
                            top.offset, b.offset);
-                    self.print_newline(top.offset + b.offset);
+                    let ret = self.print_newline(top.offset + b.offset);
                     self.space = self.margin - (top.offset + b.offset);
+                    ret
                 } else {
                     debug!("print Break({}) w/o newline in inconsistent",
                            b.blank_space);
                     self.indent(b.blank_space);
                     self.space -= b.blank_space;
+                    Ok(())
                 }
               }
             }
@@ -550,7 +567,7 @@ impl Printer {
             assert_eq!(L, len);
             // assert!(L <= space);
             self.space -= len;
-            self.print_str(s);
+            self.print_str(s)
           }
           Eof => {
             // Eof should never get here.
@@ -563,47 +580,59 @@ impl Printer {
 // Convenience functions to talk to the printer.
 //
 // "raw box"
-pub fn rbox(p: &mut Printer, indent: uint, b: Breaks) {
+pub fn rbox(p: &mut Printer, indent: uint, b: Breaks) -> io::IoResult<()> {
     p.pretty_print(Begin(BeginToken {
         offset: indent as int,
         breaks: b
-    }));
+    }))
 }
 
-pub fn ibox(p: &mut Printer, indent: uint) { rbox(p, indent, Inconsistent); }
+pub fn ibox(p: &mut Printer, indent: uint) -> io::IoResult<()> {
+    rbox(p, indent, Inconsistent)
+}
 
-pub fn cbox(p: &mut Printer, indent: uint) { rbox(p, indent, Consistent); }
+pub fn cbox(p: &mut Printer, indent: uint) -> io::IoResult<()> {
+    rbox(p, indent, Consistent)
+}
 
-pub fn break_offset(p: &mut Printer, n: uint, off: int) {
+pub fn break_offset(p: &mut Printer, n: uint, off: int) -> io::IoResult<()> {
     p.pretty_print(Break(BreakToken {
         offset: off,
         blank_space: n as int
-    }));
+    }))
 }
 
-pub fn end(p: &mut Printer) { p.pretty_print(End); }
+pub fn end(p: &mut Printer) -> io::IoResult<()> { p.pretty_print(End) }
 
-pub fn eof(p: &mut Printer) { p.pretty_print(Eof); }
+pub fn eof(p: &mut Printer) -> io::IoResult<()> { p.pretty_print(Eof) }
 
-pub fn word(p: &mut Printer, wrd: &str) {
-    p.pretty_print(String(/* bad */ wrd.to_str(), wrd.len() as int));
+pub fn word(p: &mut Printer, wrd: &str) -> io::IoResult<()> {
+    p.pretty_print(String(/* bad */ wrd.to_str(), wrd.len() as int))
 }
 
-pub fn huge_word(p: &mut Printer, wrd: &str) {
-    p.pretty_print(String(/* bad */ wrd.to_str(), SIZE_INFINITY));
+pub fn huge_word(p: &mut Printer, wrd: &str) -> io::IoResult<()> {
+    p.pretty_print(String(/* bad */ wrd.to_str(), SIZE_INFINITY))
 }
 
-pub fn zero_word(p: &mut Printer, wrd: &str) {
-    p.pretty_print(String(/* bad */ wrd.to_str(), 0));
+pub fn zero_word(p: &mut Printer, wrd: &str) -> io::IoResult<()> {
+    p.pretty_print(String(/* bad */ wrd.to_str(), 0))
 }
 
-pub fn spaces(p: &mut Printer, n: uint) { break_offset(p, n, 0); }
+pub fn spaces(p: &mut Printer, n: uint) -> io::IoResult<()> {
+    break_offset(p, n, 0)
+}
 
-pub fn zerobreak(p: &mut Printer) { spaces(p, 0u); }
+pub fn zerobreak(p: &mut Printer) -> io::IoResult<()> {
+    spaces(p, 0u)
+}
 
-pub fn space(p: &mut Printer) { spaces(p, 1u); }
+pub fn space(p: &mut Printer) -> io::IoResult<()> {
+    spaces(p, 1u)
+}
 
-pub fn hardbreak(p: &mut Printer) { spaces(p, SIZE_INFINITY as uint); }
+pub fn hardbreak(p: &mut Printer) -> io::IoResult<()> {
+    spaces(p, SIZE_INFINITY as uint)
+}
 
 pub fn hardbreak_tok_offset(off: int) -> Token {
     Break(BreakToken {offset: off, blank_space: SIZE_INFINITY})
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 037c69eb918..e291583d121 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -43,8 +43,8 @@ pub enum AnnNode<'a,'b> {
 }
 
 pub trait PpAnn {
-    fn pre(&self, _node: AnnNode) {}
-    fn post(&self, _node: AnnNode) {}
+    fn pre(&self, _node: AnnNode) -> io::IoResult<()> { Ok(()) }
+    fn post(&self, _node: AnnNode) -> io::IoResult<()> { Ok(()) }
 }
 
 pub struct NoAnn;
@@ -67,20 +67,20 @@ pub struct State {
     ann: @PpAnn
 }
 
-pub fn ibox(s: &mut State, u: uint) {
+pub fn ibox(s: &mut State, u: uint) -> io::IoResult<()> {
     {
         let mut boxes = s.boxes.borrow_mut();
         boxes.get().push(pp::Inconsistent);
     }
-    pp::ibox(&mut s.s, u);
+    pp::ibox(&mut s.s, u)
 }
 
-pub fn end(s: &mut State) {
+pub fn end(s: &mut State) -> io::IoResult<()> {
     {
         let mut boxes = s.boxes.borrow_mut();
         boxes.get().pop().unwrap();
     }
-    pp::end(&mut s.s);
+    pp::end(&mut s.s)
 }
 
 pub fn rust_printer(writer: ~io::Writer, intr: @IdentInterner) -> State {
@@ -121,7 +121,7 @@ pub fn print_crate(cm: @CodeMap,
                    input: &mut io::Reader,
                    out: ~io::Writer,
                    ann: @PpAnn,
-                   is_expanded: bool) {
+                   is_expanded: bool) -> io::IoResult<()> {
     let (cmnts, lits) = comments::gather_comments_and_literals(
         span_diagnostic,
         filename,
@@ -147,13 +147,14 @@ pub fn print_crate(cm: @CodeMap,
         boxes: RefCell::new(~[]),
         ann: ann
     };
-    print_crate_(&mut s, crate);
+    print_crate_(&mut s, crate)
 }
 
-pub fn print_crate_(s: &mut State, crate: &ast::Crate) {
-    print_mod(s, &crate.module, crate.attrs);
-    print_remaining_comments(s);
-    eof(&mut s.s);
+pub fn print_crate_(s: &mut State, crate: &ast::Crate) -> io::IoResult<()> {
+    if_ok!(print_mod(s, &crate.module, crate.attrs));
+    if_ok!(print_remaining_comments(s));
+    if_ok!(eof(&mut s.s));
+    Ok(())
 }
 
 pub fn ty_to_str(ty: &ast::Ty, intr: @IdentInterner) -> ~str {
@@ -203,10 +204,10 @@ pub fn fun_to_str(decl: &ast::FnDecl, purity: ast::Purity, name: ast::Ident,
     let wr = ~MemWriter::new();
     let mut s = rust_printer(wr as ~io::Writer, intr);
     print_fn(&mut s, decl, Some(purity), AbiSet::Rust(),
-             name, generics, opt_explicit_self, ast::Inherited);
-    end(&mut s); // Close the head box
-    end(&mut s); // Close the outer box
-    eof(&mut s.s);
+             name, generics, opt_explicit_self, ast::Inherited).unwrap();
+    end(&mut s).unwrap(); // Close the head box
+    end(&mut s).unwrap(); // Close the outer box
+    eof(&mut s.s).unwrap();
     unsafe {
         get_mem_writer(&mut s.s.out)
     }
@@ -216,11 +217,11 @@ pub fn block_to_str(blk: &ast::Block, intr: @IdentInterner) -> ~str {
     let wr = ~MemWriter::new();
     let mut s = rust_printer(wr as ~io::Writer, intr);
     // containing cbox, will be closed by print-block at }
-    cbox(&mut s, indent_unit);
+    cbox(&mut s, indent_unit).unwrap();
     // head-ibox, will be closed by print-block after {
-    ibox(&mut s, 0u);
-    print_block(&mut s, blk);
-    eof(&mut s.s);
+    ibox(&mut s, 0u).unwrap();
+    print_block(&mut s, blk).unwrap();
+    eof(&mut s.s).unwrap();
     unsafe {
         get_mem_writer(&mut s.s.out)
     }
@@ -238,63 +239,73 @@ pub fn variant_to_str(var: &ast::Variant, intr: @IdentInterner) -> ~str {
     to_str(var, print_variant, intr)
 }
 
-pub fn cbox(s: &mut State, u: uint) {
+pub fn cbox(s: &mut State, u: uint) -> io::IoResult<()> {
     {
         let mut boxes = s.boxes.borrow_mut();
         boxes.get().push(pp::Consistent);
     }
-    pp::cbox(&mut s.s, u);
+    pp::cbox(&mut s.s, u)
 }
 
 // "raw box"
-pub fn rbox(s: &mut State, u: uint, b: pp::Breaks) {
+pub fn rbox(s: &mut State, u: uint, b: pp::Breaks) -> io::IoResult<()> {
     {
         let mut boxes = s.boxes.borrow_mut();
         boxes.get().push(b);
     }
-    pp::rbox(&mut s.s, u, b);
+    pp::rbox(&mut s.s, u, b)
 }
 
-pub fn nbsp(s: &mut State) { word(&mut s.s, " "); }
+pub fn nbsp(s: &mut State) -> io::IoResult<()> { word(&mut s.s, " ") }
 
-pub fn word_nbsp(s: &mut State, w: &str) { word(&mut s.s, w); nbsp(s); }
+pub fn word_nbsp(s: &mut State, w: &str) -> io::IoResult<()> {
+    if_ok!(word(&mut s.s, w));
+    nbsp(s)
+}
 
-pub fn word_space(s: &mut State, w: &str) { word(&mut s.s, w); space(&mut s.s); }
+pub fn word_space(s: &mut State, w: &str) -> io::IoResult<()> {
+    if_ok!(word(&mut s.s, w));
+    space(&mut s.s)
+}
 
-pub fn popen(s: &mut State) { word(&mut s.s, "("); }
+pub fn popen(s: &mut State) -> io::IoResult<()> { word(&mut s.s, "(") }
 
-pub fn pclose(s: &mut State) { word(&mut s.s, ")"); }
+pub fn pclose(s: &mut State) -> io::IoResult<()> { word(&mut s.s, ")") }
 
-pub fn head(s: &mut State, w: &str) {
+pub fn head(s: &mut State, w: &str) -> io::IoResult<()> {
     // outer-box is consistent
-    cbox(s, indent_unit);
+    if_ok!(cbox(s, indent_unit));
     // head-box is inconsistent
-    ibox(s, w.len() + 1);
+    if_ok!(ibox(s, w.len() + 1));
     // keyword that starts the head
     if !w.is_empty() {
-        word_nbsp(s, w);
+        if_ok!(word_nbsp(s, w));
     }
+    Ok(())
 }
 
-pub fn bopen(s: &mut State) {
-    word(&mut s.s, "{");
-    end(s); // close the head-box
+pub fn bopen(s: &mut State) -> io::IoResult<()> {
+    if_ok!(word(&mut s.s, "{"));
+    if_ok!(end(s)); // close the head-box
+    Ok(())
 }
 
-pub fn bclose_(s: &mut State, span: codemap::Span, indented: uint) {
-    bclose_maybe_open(s, span, indented, true);
+pub fn bclose_(s: &mut State, span: codemap::Span,
+               indented: uint) -> io::IoResult<()> {
+    bclose_maybe_open(s, span, indented, true)
 }
 pub fn bclose_maybe_open (s: &mut State, span: codemap::Span,
-                          indented: uint, close_box: bool) {
-    maybe_print_comment(s, span.hi);
-    break_offset_if_not_bol(s, 1u, -(indented as int));
-    word(&mut s.s, "}");
+                          indented: uint, close_box: bool) -> io::IoResult<()> {
+    if_ok!(maybe_print_comment(s, span.hi));
+    if_ok!(break_offset_if_not_bol(s, 1u, -(indented as int)));
+    if_ok!(word(&mut s.s, "}"));
     if close_box {
-        end(s); // close the outer-box
+        if_ok!(end(s)); // close the outer-box
     }
+    Ok(())
 }
-pub fn bclose(s: &mut State, span: codemap::Span) {
-    bclose_(s, span, indent_unit);
+pub fn bclose(s: &mut State, span: codemap::Span) -> io::IoResult<()> {
+    bclose_(s, span, indent_unit)
 }
 
 pub fn is_begin(s: &mut State) -> bool {
@@ -316,15 +327,20 @@ pub fn in_cbox(s: &mut State) -> bool {
     return boxes.get()[len - 1u] == pp::Consistent;
 }
 
-pub fn hardbreak_if_not_bol(s: &mut State) {
+pub fn hardbreak_if_not_bol(s: &mut State) -> io::IoResult<()> {
     if !is_bol(s) {
-        hardbreak(&mut s.s)
+        if_ok!(hardbreak(&mut s.s))
     }
+    Ok(())
+}
+pub fn space_if_not_bol(s: &mut State) -> io::IoResult<()> {
+    if !is_bol(s) { if_ok!(space(&mut s.s)); }
+    Ok(())
 }
-pub fn space_if_not_bol(s: &mut State) { if !is_bol(s) { space(&mut s.s); } }
-pub fn break_offset_if_not_bol(s: &mut State, n: uint, off: int) {
+pub fn break_offset_if_not_bol(s: &mut State, n: uint,
+                               off: int) -> io::IoResult<()> {
     if !is_bol(s) {
-        break_offset(&mut s.s, n, off);
+        if_ok!(break_offset(&mut s.s, n, off));
     } else {
         if off != 0 && s.s.last_token().is_hardbreak_tok() {
             // We do something pretty sketchy here: tuck the nonzero
@@ -333,26 +349,31 @@ pub fn break_offset_if_not_bol(s: &mut State, n: uint, off: int) {
             s.s.replace_last_token(pp::hardbreak_tok_offset(off));
         }
     }
+    Ok(())
 }
 
 // Synthesizes a comment that was not textually present in the original source
 // file.
-pub fn synth_comment(s: &mut State, text: ~str) {
-    word(&mut s.s, "/*");
-    space(&mut s.s);
-    word(&mut s.s, text);
-    space(&mut s.s);
-    word(&mut s.s, "*/");
-}
-
-pub fn commasep<T>(s: &mut State, b: Breaks, elts: &[T], op: |&mut State, &T|) {
-    rbox(s, 0u, b);
+pub fn synth_comment(s: &mut State, text: ~str) -> io::IoResult<()> {
+    if_ok!(word(&mut s.s, "/*"));
+    if_ok!(space(&mut s.s));
+    if_ok!(word(&mut s.s, text));
+    if_ok!(space(&mut s.s));
+    if_ok!(word(&mut s.s, "*/"));
+    Ok(())
+}
+
+pub fn commasep<T>(s: &mut State, b: Breaks, elts: &[T],
+                   op: |&mut State, &T| -> io::IoResult<()>)
+    -> io::IoResult<()>
+{
+    if_ok!(rbox(s, 0u, b));
     let mut first = true;
     for elt in elts.iter() {
-        if first { first = false; } else { word_space(s, ","); }
-        op(s, elt);
+        if first { first = false; } else { if_ok!(word_space(s, ",")); }
+        if_ok!(op(s, elt));
     }
-    end(s);
+    end(s)
 }
 
 
@@ -360,177 +381,200 @@ pub fn commasep_cmnt<T>(
                      s: &mut State,
                      b: Breaks,
                      elts: &[T],
-                     op: |&mut State, &T|,
-                     get_span: |&T| -> codemap::Span) {
-    rbox(s, 0u, b);
+                     op: |&mut State, &T| -> io::IoResult<()>,
+                     get_span: |&T| -> codemap::Span) -> io::IoResult<()> {
+    if_ok!(rbox(s, 0u, b));
     let len = elts.len();
     let mut i = 0u;
     for elt in elts.iter() {
-        maybe_print_comment(s, get_span(elt).hi);
-        op(s, elt);
+        if_ok!(maybe_print_comment(s, get_span(elt).hi));
+        if_ok!(op(s, elt));
         i += 1u;
         if i < len {
-            word(&mut s.s, ",");
-            maybe_print_trailing_comment(s, get_span(elt),
-                                         Some(get_span(&elts[i]).hi));
-            space_if_not_bol(s);
+            if_ok!(word(&mut s.s, ","));
+            if_ok!(maybe_print_trailing_comment(s, get_span(elt),
+                                                Some(get_span(&elts[i]).hi)));
+            if_ok!(space_if_not_bol(s));
         }
     }
-    end(s);
+    end(s)
 }
 
-pub fn commasep_exprs(s: &mut State, b: Breaks, exprs: &[@ast::Expr]) {
-    commasep_cmnt(s, b, exprs, |p, &e| print_expr(p, e), |e| e.span);
+pub fn commasep_exprs(s: &mut State, b: Breaks,
+                      exprs: &[@ast::Expr]) -> io::IoResult<()> {
+    commasep_cmnt(s, b, exprs, |p, &e| print_expr(p, e), |e| e.span)
 }
 
-pub fn print_mod(s: &mut State, _mod: &ast::Mod, attrs: &[ast::Attribute]) {
-    print_inner_attributes(s, attrs);
+pub fn print_mod(s: &mut State, _mod: &ast::Mod,
+                 attrs: &[ast::Attribute]) -> io::IoResult<()> {
+    if_ok!(print_inner_attributes(s, attrs));
     for vitem in _mod.view_items.iter() {
-        print_view_item(s, vitem);
+        if_ok!(print_view_item(s, vitem));
     }
-    for item in _mod.items.iter() { print_item(s, *item); }
+    for item in _mod.items.iter() {
+        if_ok!(print_item(s, *item));
+    }
+    Ok(())
 }
 
 pub fn print_foreign_mod(s: &mut State, nmod: &ast::ForeignMod,
-                         attrs: &[ast::Attribute]) {
-    print_inner_attributes(s, attrs);
+                         attrs: &[ast::Attribute]) -> io::IoResult<()> {
+    if_ok!(print_inner_attributes(s, attrs));
     for vitem in nmod.view_items.iter() {
-        print_view_item(s, vitem);
+        if_ok!(print_view_item(s, vitem));
+    }
+    for item in nmod.items.iter() {
+        if_ok!(print_foreign_item(s, *item));
     }
-    for item in nmod.items.iter() { print_foreign_item(s, *item); }
+    Ok(())
 }
 
-pub fn print_opt_lifetime(s: &mut State, lifetime: &Option<ast::Lifetime>) {
+pub fn print_opt_lifetime(s: &mut State,
+                          lifetime: &Option<ast::Lifetime>) -> io::IoResult<()> {
     for l in lifetime.iter() {
-        print_lifetime(s, l);
-        nbsp(s);
+        if_ok!(print_lifetime(s, l));
+        if_ok!(nbsp(s));
     }
+    Ok(())
 }
 
-pub fn print_type(s: &mut State, ty: &ast::Ty) {
-    maybe_print_comment(s, ty.span.lo);
-    ibox(s, 0u);
+pub fn print_type(s: &mut State, ty: &ast::Ty) -> io::IoResult<()> {
+    if_ok!(maybe_print_comment(s, ty.span.lo));
+    if_ok!(ibox(s, 0u));
     match ty.node {
-        ast::TyNil => word(&mut s.s, "()"),
-        ast::TyBot => word(&mut s.s, "!"),
-        ast::TyBox(ty) => { word(&mut s.s, "@"); print_type(s, ty); }
-        ast::TyUniq(ty) => { word(&mut s.s, "~"); print_type(s, ty); }
+        ast::TyNil => if_ok!(word(&mut s.s, "()")),
+        ast::TyBot => if_ok!(word(&mut s.s, "!")),
+        ast::TyBox(ty) => {
+            if_ok!(word(&mut s.s, "@"));
+            if_ok!(print_type(s, ty));
+        }
+        ast::TyUniq(ty) => {
+            if_ok!(word(&mut s.s, "~"));
+            if_ok!(print_type(s, ty));
+        }
         ast::TyVec(ty) => {
-            word(&mut s.s, "[");
-            print_type(s, ty);
-            word(&mut s.s, "]");
+            if_ok!(word(&mut s.s, "["));
+            if_ok!(print_type(s, ty));
+            if_ok!(word(&mut s.s, "]"));
+        }
+        ast::TyPtr(ref mt) => {
+            if_ok!(word(&mut s.s, "*"));
+            if_ok!(print_mt(s, mt));
         }
-        ast::TyPtr(ref mt) => { word(&mut s.s, "*"); print_mt(s, mt); }
         ast::TyRptr(ref lifetime, ref mt) => {
-            word(&mut s.s, "&");
-            print_opt_lifetime(s, lifetime);
-            print_mt(s, mt);
+            if_ok!(word(&mut s.s, "&"));
+            if_ok!(print_opt_lifetime(s, lifetime));
+            if_ok!(print_mt(s, mt));
         }
         ast::TyTup(ref elts) => {
-            popen(s);
-            commasep(s, Inconsistent, *elts, print_type_ref);
+            if_ok!(popen(s));
+            if_ok!(commasep(s, Inconsistent, *elts, print_type_ref));
             if elts.len() == 1 {
-                word(&mut s.s, ",");
+                if_ok!(word(&mut s.s, ","));
             }
-            pclose(s);
+            if_ok!(pclose(s));
         }
         ast::TyBareFn(f) => {
             let generics = ast::Generics {
                 lifetimes: f.lifetimes.clone(),
                 ty_params: opt_vec::Empty
             };
-            print_ty_fn(s, Some(f.abis), None, &None,
-                        f.purity, ast::Many, f.decl, None, &None,
-                        Some(&generics), None);
+            if_ok!(print_ty_fn(s, Some(f.abis), None, &None,
+                               f.purity, ast::Many, f.decl, None, &None,
+                               Some(&generics), None));
         }
         ast::TyClosure(f) => {
             let generics = ast::Generics {
                 lifetimes: f.lifetimes.clone(),
                 ty_params: opt_vec::Empty
             };
-            print_ty_fn(s, None, Some(f.sigil), &f.region,
-                        f.purity, f.onceness, f.decl, None, &f.bounds,
-                        Some(&generics), None);
+            if_ok!(print_ty_fn(s, None, Some(f.sigil), &f.region,
+                               f.purity, f.onceness, f.decl, None, &f.bounds,
+                               Some(&generics), None));
+        }
+        ast::TyPath(ref path, ref bounds, _) => {
+            if_ok!(print_bounded_path(s, path, bounds));
         }
-        ast::TyPath(ref path, ref bounds, _) => print_bounded_path(s, path, bounds),
         ast::TyFixedLengthVec(ty, v) => {
-            word(&mut s.s, "[");
-            print_type(s, ty);
-            word(&mut s.s, ", ..");
-            print_expr(s, v);
-            word(&mut s.s, "]");
+            if_ok!(word(&mut s.s, "["));
+            if_ok!(print_type(s, ty));
+            if_ok!(word(&mut s.s, ", .."));
+            if_ok!(print_expr(s, v));
+            if_ok!(word(&mut s.s, "]"));
         }
         ast::TyTypeof(e) => {
-            word(&mut s.s, "typeof(");
-            print_expr(s, e);
-            word(&mut s.s, ")");
+            if_ok!(word(&mut s.s, "typeof("));
+            if_ok!(print_expr(s, e));
+            if_ok!(word(&mut s.s, ")"));
         }
         ast::TyInfer => {
             fail!("print_type shouldn't see a ty_infer");
         }
     }
-    end(s);
+    end(s)
 }
 
-pub fn print_type_ref(s: &mut State, ty: &P<ast::Ty>) {
-    print_type(s, *ty);
+pub fn print_type_ref(s: &mut State, ty: &P<ast::Ty>) -> io::IoResult<()> {
+    print_type(s, *ty)
 }
 
-pub fn print_foreign_item(s: &mut State, item: &ast::ForeignItem) {
-    hardbreak_if_not_bol(s);
-    maybe_print_comment(s, item.span.lo);
-    print_outer_attributes(s, item.attrs);
+pub fn print_foreign_item(s: &mut State,
+                          item: &ast::ForeignItem) -> io::IoResult<()> {
+    if_ok!(hardbreak_if_not_bol(s));
+    if_ok!(maybe_print_comment(s, item.span.lo));
+    if_ok!(print_outer_attributes(s, item.attrs));
     match item.node {
-      ast::ForeignItemFn(decl, ref generics) => {
-        print_fn(s, decl, None, AbiSet::Rust(), item.ident, generics, None,
-                 item.vis);
-        end(s); // end head-ibox
-        word(&mut s.s, ";");
-        end(s); // end the outer fn box
-      }
-      ast::ForeignItemStatic(t, m) => {
-        head(s, visibility_qualified(item.vis, "static"));
-        if m {
-            word_space(s, "mut");
+        ast::ForeignItemFn(decl, ref generics) => {
+            if_ok!(print_fn(s, decl, None, AbiSet::Rust(), item.ident, generics,
+            None, item.vis));
+            if_ok!(end(s)); // end head-ibox
+            if_ok!(word(&mut s.s, ";"));
+            if_ok!(end(s)); // end the outer fn box
+        }
+        ast::ForeignItemStatic(t, m) => {
+            if_ok!(head(s, visibility_qualified(item.vis, "static")));
+            if m {
+                if_ok!(word_space(s, "mut"));
+            }
+            if_ok!(print_ident(s, item.ident));
+            if_ok!(word_space(s, ":"));
+            if_ok!(print_type(s, t));
+            if_ok!(word(&mut s.s, ";"));
+            if_ok!(end(s)); // end the head-ibox
+            if_ok!(end(s)); // end the outer cbox
         }
-        print_ident(s, item.ident);
-        word_space(s, ":");
-        print_type(s, t);
-        word(&mut s.s, ";");
-        end(s); // end the head-ibox
-        end(s); // end the outer cbox
-      }
     }
+    Ok(())
 }
 
-pub fn print_item(s: &mut State, item: &ast::Item) {
-    hardbreak_if_not_bol(s);
-    maybe_print_comment(s, item.span.lo);
-    print_outer_attributes(s, item.attrs);
+pub fn print_item(s: &mut State, item: &ast::Item) -> io::IoResult<()> {
+    if_ok!(hardbreak_if_not_bol(s));
+    if_ok!(maybe_print_comment(s, item.span.lo));
+    if_ok!(print_outer_attributes(s, item.attrs));
     {
         let ann_node = NodeItem(s, item);
-        s.ann.pre(ann_node);
+        if_ok!(s.ann.pre(ann_node));
     }
     match item.node {
       ast::ItemStatic(ty, m, expr) => {
-        head(s, visibility_qualified(item.vis, "static"));
+        if_ok!(head(s, visibility_qualified(item.vis, "static")));
         if m == ast::MutMutable {
-            word_space(s, "mut");
+            if_ok!(word_space(s, "mut"));
         }
-        print_ident(s, item.ident);
-        word_space(s, ":");
-        print_type(s, ty);
-        space(&mut s.s);
-        end(s); // end the head-ibox
+        if_ok!(print_ident(s, item.ident));
+        if_ok!(word_space(s, ":"));
+        if_ok!(print_type(s, ty));
+        if_ok!(space(&mut s.s));
+        if_ok!(end(s)); // end the head-ibox
 
-        word_space(s, "=");
-        print_expr(s, expr);
-        word(&mut s.s, ";");
-        end(s); // end the outer cbox
+        if_ok!(word_space(s, "="));
+        if_ok!(print_expr(s, expr));
+        if_ok!(word(&mut s.s, ";"));
+        if_ok!(end(s)); // end the outer cbox
 
       }
       ast::ItemFn(decl, purity, abi, ref typarams, body) => {
-        print_fn(
+        if_ok!(print_fn(
             s,
             decl,
             Some(purity),
@@ -539,150 +583,153 @@ pub fn print_item(s: &mut State, item: &ast::Item) {
             typarams,
             None,
             item.vis
-        );
-        word(&mut s.s, " ");
-        print_block_with_attrs(s, body, item.attrs);
+        ));
+        if_ok!(word(&mut s.s, " "));
+        if_ok!(print_block_with_attrs(s, body, item.attrs));
       }
       ast::ItemMod(ref _mod) => {
-        head(s, visibility_qualified(item.vis, "mod"));
-        print_ident(s, item.ident);
-        nbsp(s);
-        bopen(s);
-        print_mod(s, _mod, item.attrs);
-        bclose(s, item.span);
+        if_ok!(head(s, visibility_qualified(item.vis, "mod")));
+        if_ok!(print_ident(s, item.ident));
+        if_ok!(nbsp(s));
+        if_ok!(bopen(s));
+        if_ok!(print_mod(s, _mod, item.attrs));
+        if_ok!(bclose(s, item.span));
       }
       ast::ItemForeignMod(ref nmod) => {
-        head(s, "extern");
-        word_nbsp(s, nmod.abis.to_str());
-        bopen(s);
-        print_foreign_mod(s, nmod, item.attrs);
-        bclose(s, item.span);
+        if_ok!(head(s, "extern"));
+        if_ok!(word_nbsp(s, nmod.abis.to_str()));
+        if_ok!(bopen(s));
+        if_ok!(print_foreign_mod(s, nmod, item.attrs));
+        if_ok!(bclose(s, item.span));
       }
       ast::ItemTy(ty, ref params) => {
-        ibox(s, indent_unit);
-        ibox(s, 0u);
-        word_nbsp(s, visibility_qualified(item.vis, "type"));
-        print_ident(s, item.ident);
-        print_generics(s, params);
-        end(s); // end the inner ibox
-
-        space(&mut s.s);
-        word_space(s, "=");
-        print_type(s, ty);
-        word(&mut s.s, ";");
-        end(s); // end the outer ibox
+        if_ok!(ibox(s, indent_unit));
+        if_ok!(ibox(s, 0u));
+        if_ok!(word_nbsp(s, visibility_qualified(item.vis, "type")));
+        if_ok!(print_ident(s, item.ident));
+        if_ok!(print_generics(s, params));
+        if_ok!(end(s)); // end the inner ibox
+
+        if_ok!(space(&mut s.s));
+        if_ok!(word_space(s, "="));
+        if_ok!(print_type(s, ty));
+        if_ok!(word(&mut s.s, ";"));
+        if_ok!(end(s)); // end the outer ibox
       }
       ast::ItemEnum(ref enum_definition, ref params) => {
-        print_enum_def(
+        if_ok!(print_enum_def(
             s,
             enum_definition,
             params,
             item.ident,
             item.span,
             item.vis
-        );
+        ));
       }
       ast::ItemStruct(struct_def, ref generics) => {
-          head(s, visibility_qualified(item.vis, "struct"));
-          print_struct(s, struct_def, generics, item.ident, item.span);
+          if_ok!(head(s, visibility_qualified(item.vis, "struct")));
+          if_ok!(print_struct(s, struct_def, generics, item.ident, item.span));
       }
 
       ast::ItemImpl(ref generics, ref opt_trait, ty, ref methods) => {
-        head(s, visibility_qualified(item.vis, "impl"));
+        if_ok!(head(s, visibility_qualified(item.vis, "impl")));
         if generics.is_parameterized() {
-            print_generics(s, generics);
-            space(&mut s.s);
+            if_ok!(print_generics(s, generics));
+            if_ok!(space(&mut s.s));
         }
 
         match opt_trait {
             &Some(ref t) => {
-                print_trait_ref(s, t);
-                space(&mut s.s);
-                word_space(s, "for");
+                if_ok!(print_trait_ref(s, t));
+                if_ok!(space(&mut s.s));
+                if_ok!(word_space(s, "for"));
             }
             &None => ()
         };
 
-        print_type(s, ty);
+        if_ok!(print_type(s, ty));
 
-        space(&mut s.s);
-        bopen(s);
-        print_inner_attributes(s, item.attrs);
+        if_ok!(space(&mut s.s));
+        if_ok!(bopen(s));
+        if_ok!(print_inner_attributes(s, item.attrs));
         for meth in methods.iter() {
-           print_method(s, *meth);
+           if_ok!(print_method(s, *meth));
         }
-        bclose(s, item.span);
+        if_ok!(bclose(s, item.span));
       }
       ast::ItemTrait(ref generics, ref traits, ref methods) => {
-        head(s, visibility_qualified(item.vis, "trait"));
-        print_ident(s, item.ident);
-        print_generics(s, generics);
+        if_ok!(head(s, visibility_qualified(item.vis, "trait")));
+        if_ok!(print_ident(s, item.ident));
+        if_ok!(print_generics(s, generics));
         if traits.len() != 0u {
-            word(&mut s.s, ":");
+            if_ok!(word(&mut s.s, ":"));
             for (i, trait_) in traits.iter().enumerate() {
-                nbsp(s);
+                if_ok!(nbsp(s));
                 if i != 0 {
-                    word_space(s, "+");
+                    if_ok!(word_space(s, "+"));
                 }
-                print_path(s, &trait_.path, false);
+                if_ok!(print_path(s, &trait_.path, false));
             }
         }
-        word(&mut s.s, " ");
-        bopen(s);
+        if_ok!(word(&mut s.s, " "));
+        if_ok!(bopen(s));
         for meth in methods.iter() {
-            print_trait_method(s, meth);
+            if_ok!(print_trait_method(s, meth));
         }
-        bclose(s, item.span);
+        if_ok!(bclose(s, item.span));
       }
       // I think it's reasonable to hide the context here:
       ast::ItemMac(codemap::Spanned { node: ast::MacInvocTT(ref pth, ref tts, _),
                                    ..}) => {
-        print_visibility(s, item.vis);
-        print_path(s, pth, false);
-        word(&mut s.s, "! ");
-        print_ident(s, item.ident);
-        cbox(s, indent_unit);
-        popen(s);
-        print_tts(s, &(tts.as_slice()));
-        pclose(s);
-        end(s);
+        if_ok!(print_visibility(s, item.vis));
+        if_ok!(print_path(s, pth, false));
+        if_ok!(word(&mut s.s, "! "));
+        if_ok!(print_ident(s, item.ident));
+        if_ok!(cbox(s, indent_unit));
+        if_ok!(popen(s));
+        if_ok!(print_tts(s, &(tts.as_slice())));
+        if_ok!(pclose(s));
+        if_ok!(end(s));
       }
     }
     {
         let ann_node = NodeItem(s, item);
-        s.ann.post(ann_node);
+        if_ok!(s.ann.post(ann_node));
     }
+    Ok(())
 }
 
-fn print_trait_ref(s: &mut State, t: &ast::TraitRef) {
-    print_path(s, &t.path, false);
+fn print_trait_ref(s: &mut State, t: &ast::TraitRef) -> io::IoResult<()> {
+    print_path(s, &t.path, false)
 }
 
 pub fn print_enum_def(s: &mut State, enum_definition: &ast::EnumDef,
                       generics: &ast::Generics, ident: ast::Ident,
-                      span: codemap::Span, visibility: ast::Visibility) {
-    head(s, visibility_qualified(visibility, "enum"));
-    print_ident(s, ident);
-    print_generics(s, generics);
-    space(&mut s.s);
-    print_variants(s, enum_definition.variants, span);
+                      span: codemap::Span,
+                      visibility: ast::Visibility) -> io::IoResult<()> {
+    if_ok!(head(s, visibility_qualified(visibility, "enum")));
+    if_ok!(print_ident(s, ident));
+    if_ok!(print_generics(s, generics));
+    if_ok!(space(&mut s.s));
+    if_ok!(print_variants(s, enum_definition.variants, span));
+    Ok(())
 }
 
 pub fn print_variants(s: &mut State,
                       variants: &[P<ast::Variant>],
-                      span: codemap::Span) {
-    bopen(s);
+                      span: codemap::Span) -> io::IoResult<()> {
+    if_ok!(bopen(s));
     for &v in variants.iter() {
-        space_if_not_bol(s);
-        maybe_print_comment(s, v.span.lo);
-        print_outer_attributes(s, v.node.attrs);
-        ibox(s, indent_unit);
-        print_variant(s, v);
-        word(&mut s.s, ",");
-        end(s);
-        maybe_print_trailing_comment(s, v.span, None);
+        if_ok!(space_if_not_bol(s));
+        if_ok!(maybe_print_comment(s, v.span.lo));
+        if_ok!(print_outer_attributes(s, v.node.attrs));
+        if_ok!(ibox(s, indent_unit));
+        if_ok!(print_variant(s, v));
+        if_ok!(word(&mut s.s, ","));
+        if_ok!(end(s));
+        if_ok!(maybe_print_trailing_comment(s, v.span, None));
     }
-    bclose(s, span);
+    bclose(s, span)
 }
 
 pub fn visibility_to_str(vis: ast::Visibility) -> ~str {
@@ -700,60 +747,62 @@ pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> ~str {
     }
 }
 
-pub fn print_visibility(s: &mut State, vis: ast::Visibility) {
+pub fn print_visibility(s: &mut State, vis: ast::Visibility) -> io::IoResult<()> {
     match vis {
         ast::Private | ast::Public =>
-        word_nbsp(s, visibility_to_str(vis)),
+            if_ok!(word_nbsp(s, visibility_to_str(vis))),
         ast::Inherited => ()
     }
+    Ok(())
 }
 
 pub fn print_struct(s: &mut State,
                     struct_def: &ast::StructDef,
                     generics: &ast::Generics,
                     ident: ast::Ident,
-                    span: codemap::Span) {
-    print_ident(s, ident);
-    print_generics(s, generics);
+                    span: codemap::Span) -> io::IoResult<()> {
+    if_ok!(print_ident(s, ident));
+    if_ok!(print_generics(s, generics));
     if ast_util::struct_def_is_tuple_like(struct_def) {
         if !struct_def.fields.is_empty() {
-            popen(s);
-            commasep(s, Inconsistent, struct_def.fields, |s, field| {
+            if_ok!(popen(s));
+            if_ok!(commasep(s, Inconsistent, struct_def.fields, |s, field| {
                 match field.node.kind {
                     ast::NamedField(..) => fail!("unexpected named field"),
                     ast::UnnamedField => {
-                        maybe_print_comment(s, field.span.lo);
-                        print_type(s, field.node.ty);
+                        if_ok!(maybe_print_comment(s, field.span.lo));
+                        if_ok!(print_type(s, field.node.ty));
                     }
                 }
-            });
-            pclose(s);
+                Ok(())
+            }));
+            if_ok!(pclose(s));
         }
-        word(&mut s.s, ";");
-        end(s);
-        end(s); // close the outer-box
+        if_ok!(word(&mut s.s, ";"));
+        if_ok!(end(s));
+        end(s) // close the outer-box
     } else {
-        nbsp(s);
-        bopen(s);
-        hardbreak_if_not_bol(s);
+        if_ok!(nbsp(s));
+        if_ok!(bopen(s));
+        if_ok!(hardbreak_if_not_bol(s));
 
         for field in struct_def.fields.iter() {
             match field.node.kind {
                 ast::UnnamedField => fail!("unexpected unnamed field"),
                 ast::NamedField(ident, visibility) => {
-                    hardbreak_if_not_bol(s);
-                    maybe_print_comment(s, field.span.lo);
-                    print_outer_attributes(s, field.node.attrs);
-                    print_visibility(s, visibility);
-                    print_ident(s, ident);
-                    word_nbsp(s, ":");
-                    print_type(s, field.node.ty);
-                    word(&mut s.s, ",");
+                    if_ok!(hardbreak_if_not_bol(s));
+                    if_ok!(maybe_print_comment(s, field.span.lo));
+                    if_ok!(print_outer_attributes(s, field.node.attrs));
+                    if_ok!(print_visibility(s, visibility));
+                    if_ok!(print_ident(s, ident));
+                    if_ok!(word_nbsp(s, ":"));
+                    if_ok!(print_type(s, field.node.ty));
+                    if_ok!(word(&mut s.s, ","));
                 }
             }
         }
 
-        bclose(s, span);
+        bclose(s, span)
     }
 }
 
@@ -764,191 +813,215 @@ pub fn print_struct(s: &mut State,
 /// appropriate macro, transcribe back into the grammar we just parsed from,
 /// and then pretty-print the resulting AST nodes (so, e.g., we print
 /// expression arguments as expressions). It can be done! I think.
-pub fn print_tt(s: &mut State, tt: &ast::TokenTree) {
+pub fn print_tt(s: &mut State, tt: &ast::TokenTree) -> io::IoResult<()> {
     match *tt {
-      ast::TTDelim(ref tts) => print_tts(s, &(tts.as_slice())),
-      ast::TTTok(_, ref tk) => {
-          word(&mut s.s, parse::token::to_str(s.intr, tk));
-      }
-      ast::TTSeq(_, ref tts, ref sep, zerok) => {
-        word(&mut s.s, "$(");
-        for tt_elt in (*tts).iter() { print_tt(s, tt_elt); }
-        word(&mut s.s, ")");
-        match *sep {
-          Some(ref tk) => word(&mut s.s, parse::token::to_str(s.intr, tk)),
-          None => ()
+        ast::TTDelim(ref tts) => print_tts(s, &(tts.as_slice())),
+        ast::TTTok(_, ref tk) => {
+            word(&mut s.s, parse::token::to_str(s.intr, tk))
+        }
+        ast::TTSeq(_, ref tts, ref sep, zerok) => {
+            if_ok!(word(&mut s.s, "$("));
+            for tt_elt in (*tts).iter() {
+                if_ok!(print_tt(s, tt_elt));
+            }
+            if_ok!(word(&mut s.s, ")"));
+            match *sep {
+                Some(ref tk) => {
+                    if_ok!(word(&mut s.s, parse::token::to_str(s.intr, tk)));
+                }
+                None => ()
+            }
+            word(&mut s.s, if zerok { "*" } else { "+" })
+        }
+        ast::TTNonterminal(_, name) => {
+            if_ok!(word(&mut s.s, "$"));
+            print_ident(s, name)
         }
-        word(&mut s.s, if zerok { "*" } else { "+" });
-      }
-      ast::TTNonterminal(_, name) => {
-        word(&mut s.s, "$");
-        print_ident(s, name);
-      }
     }
 }
 
-pub fn print_tts(s: &mut State, tts: & &[ast::TokenTree]) {
-    ibox(s, 0);
+pub fn print_tts(s: &mut State, tts: & &[ast::TokenTree]) -> io::IoResult<()> {
+    if_ok!(ibox(s, 0));
     for (i, tt) in tts.iter().enumerate() {
         if i != 0 {
-            space(&mut s.s);
+            if_ok!(space(&mut s.s));
         }
-        print_tt(s, tt);
+        if_ok!(print_tt(s, tt));
     }
-    end(s);
+    end(s)
 }
 
-pub fn print_variant(s: &mut State, v: &ast::Variant) {
-    print_visibility(s, v.node.vis);
+pub fn print_variant(s: &mut State, v: &ast::Variant) -> io::IoResult<()> {
+    if_ok!(print_visibility(s, v.node.vis));
     match v.node.kind {
         ast::TupleVariantKind(ref args) => {
-            print_ident(s, v.node.name);
+            if_ok!(print_ident(s, v.node.name));
             if !args.is_empty() {
-                popen(s);
-                fn print_variant_arg(s: &mut State, arg: &ast::VariantArg) {
-                    print_type(s, arg.ty);
+                if_ok!(popen(s));
+                fn print_variant_arg(s: &mut State,
+                                     arg: &ast::VariantArg) -> io::IoResult<()> {
+                    print_type(s, arg.ty)
                 }
-                commasep(s, Consistent, *args, print_variant_arg);
-                pclose(s);
+                if_ok!(commasep(s, Consistent, *args, print_variant_arg));
+                if_ok!(pclose(s));
             }
         }
         ast::StructVariantKind(struct_def) => {
-            head(s, "");
+            if_ok!(head(s, ""));
             let generics = ast_util::empty_generics();
-            print_struct(s, struct_def, &generics, v.node.name, v.span);
+            if_ok!(print_struct(s, struct_def, &generics, v.node.name, v.span));
         }
     }
     match v.node.disr_expr {
       Some(d) => {
-        space(&mut s.s);
-        word_space(s, "=");
-        print_expr(s, d);
+        if_ok!(space(&mut s.s));
+        if_ok!(word_space(s, "="));
+        if_ok!(print_expr(s, d));
       }
       _ => ()
     }
-}
-
-pub fn print_ty_method(s: &mut State, m: &ast::TypeMethod) {
-    hardbreak_if_not_bol(s);
-    maybe_print_comment(s, m.span.lo);
-    print_outer_attributes(s, m.attrs);
-    print_ty_fn(s,
-                None,
-                None,
-                &None,
-                m.purity,
-                ast::Many,
-                m.decl,
-                Some(m.ident),
-                &None,
-                Some(&m.generics),
-                Some(m.explicit_self.node));
-    word(&mut s.s, ";");
-}
-
-pub fn print_trait_method(s: &mut State, m: &ast::TraitMethod) {
+    Ok(())
+}
+
+pub fn print_ty_method(s: &mut State, m: &ast::TypeMethod) -> io::IoResult<()> {
+    if_ok!(hardbreak_if_not_bol(s));
+    if_ok!(maybe_print_comment(s, m.span.lo));
+    if_ok!(print_outer_attributes(s, m.attrs));
+    if_ok!(print_ty_fn(s,
+                       None,
+                       None,
+                       &None,
+                       m.purity,
+                       ast::Many,
+                       m.decl,
+                       Some(m.ident),
+                       &None,
+                       Some(&m.generics),
+                       Some(m.explicit_self.node)));
+    word(&mut s.s, ";")
+}
+
+pub fn print_trait_method(s: &mut State,
+                          m: &ast::TraitMethod) -> io::IoResult<()> {
     match *m {
         Required(ref ty_m) => print_ty_method(s, ty_m),
         Provided(m) => print_method(s, m)
     }
 }
 
-pub fn print_method(s: &mut State, meth: &ast::Method) {
-    hardbreak_if_not_bol(s);
-    maybe_print_comment(s, meth.span.lo);
-    print_outer_attributes(s, meth.attrs);
-    print_fn(s, meth.decl, Some(meth.purity), AbiSet::Rust(),
-             meth.ident, &meth.generics, Some(meth.explicit_self.node),
-             meth.vis);
-    word(&mut s.s, " ");
-    print_block_with_attrs(s, meth.body, meth.attrs);
+pub fn print_method(s: &mut State, meth: &ast::Method) -> io::IoResult<()> {
+    if_ok!(hardbreak_if_not_bol(s));
+    if_ok!(maybe_print_comment(s, meth.span.lo));
+    if_ok!(print_outer_attributes(s, meth.attrs));
+    if_ok!(print_fn(s, meth.decl, Some(meth.purity), AbiSet::Rust(),
+                    meth.ident, &meth.generics, Some(meth.explicit_self.node),
+                    meth.vis));
+    if_ok!(word(&mut s.s, " "));
+    print_block_with_attrs(s, meth.body, meth.attrs)
 }
 
-pub fn print_outer_attributes(s: &mut State, attrs: &[ast::Attribute]) {
+pub fn print_outer_attributes(s: &mut State,
+                              attrs: &[ast::Attribute]) -> io::IoResult<()> {
     let mut count = 0;
     for attr in attrs.iter() {
         match attr.node.style {
-          ast::AttrOuter => { print_attribute(s, attr); count += 1; }
+          ast::AttrOuter => {
+              if_ok!(print_attribute(s, attr));
+              count += 1;
+          }
           _ => {/* fallthrough */ }
         }
     }
-    if count > 0 { hardbreak_if_not_bol(s); }
+    if count > 0 {
+        if_ok!(hardbreak_if_not_bol(s));
+    }
+    Ok(())
 }
 
-pub fn print_inner_attributes(s: &mut State, attrs: &[ast::Attribute]) {
+pub fn print_inner_attributes(s: &mut State,
+                              attrs: &[ast::Attribute]) -> io::IoResult<()> {
     let mut count = 0;
     for attr in attrs.iter() {
         match attr.node.style {
           ast::AttrInner => {
-            print_attribute(s, attr);
+            if_ok!(print_attribute(s, attr));
             if !attr.node.is_sugared_doc {
-                word(&mut s.s, ";");
+                if_ok!(word(&mut s.s, ";"));
             }
             count += 1;
           }
           _ => {/* fallthrough */ }
         }
     }
-    if count > 0 { hardbreak_if_not_bol(s); }
+    if count > 0 {
+        if_ok!(hardbreak_if_not_bol(s));
+    }
+    Ok(())
 }
 
-pub fn print_attribute(s: &mut State, attr: &ast::Attribute) {
-    hardbreak_if_not_bol(s);
-    maybe_print_comment(s, attr.span.lo);
+pub fn print_attribute(s: &mut State, attr: &ast::Attribute) -> io::IoResult<()> {
+    if_ok!(hardbreak_if_not_bol(s));
+    if_ok!(maybe_print_comment(s, attr.span.lo));
     if attr.node.is_sugared_doc {
         let comment = attr.value_str().unwrap();
-        word(&mut s.s, comment.get());
+        if_ok!(word(&mut s.s, comment.get()));
     } else {
-        word(&mut s.s, "#[");
-        print_meta_item(s, attr.meta());
-        word(&mut s.s, "]");
+        if_ok!(word(&mut s.s, "#["));
+        if_ok!(print_meta_item(s, attr.meta()));
+        if_ok!(word(&mut s.s, "]"));
     }
+    Ok(())
 }
 
 
-pub fn print_stmt(s: &mut State, st: &ast::Stmt) {
-    maybe_print_comment(s, st.span.lo);
+pub fn print_stmt(s: &mut State, st: &ast::Stmt) -> io::IoResult<()> {
+    if_ok!(maybe_print_comment(s, st.span.lo));
     match st.node {
       ast::StmtDecl(decl, _) => {
-        print_decl(s, decl);
+        if_ok!(print_decl(s, decl));
       }
       ast::StmtExpr(expr, _) => {
-        space_if_not_bol(s);
-        print_expr(s, expr);
+        if_ok!(space_if_not_bol(s));
+        if_ok!(print_expr(s, expr));
       }
       ast::StmtSemi(expr, _) => {
-        space_if_not_bol(s);
-        print_expr(s, expr);
-        word(&mut s.s, ";");
+        if_ok!(space_if_not_bol(s));
+        if_ok!(print_expr(s, expr));
+        if_ok!(word(&mut s.s, ";"));
       }
       ast::StmtMac(ref mac, semi) => {
-        space_if_not_bol(s);
-        print_mac(s, mac);
-        if semi { word(&mut s.s, ";"); }
+        if_ok!(space_if_not_bol(s));
+        if_ok!(print_mac(s, mac));
+        if semi {
+            if_ok!(word(&mut s.s, ";"));
+        }
       }
     }
-    if parse::classify::stmt_ends_with_semi(st) { word(&mut s.s, ";"); }
-    maybe_print_trailing_comment(s, st.span, None);
+    if parse::classify::stmt_ends_with_semi(st) {
+        if_ok!(word(&mut s.s, ";"));
+    }
+    maybe_print_trailing_comment(s, st.span, None)
 }
 
-pub fn print_block(s: &mut State, blk: &ast::Block) {
-    print_possibly_embedded_block(s, blk, BlockNormal, indent_unit);
+pub fn print_block(s: &mut State, blk: &ast::Block) -> io::IoResult<()> {
+    print_possibly_embedded_block(s, blk, BlockNormal, indent_unit)
 }
 
-pub fn print_block_unclosed(s: &mut State, blk: &ast::Block) {
+pub fn print_block_unclosed(s: &mut State, blk: &ast::Block) -> io::IoResult<()> {
     print_possibly_embedded_block_(s, blk, BlockNormal, indent_unit, &[],
-                                 false);
+                                   false)
 }
 
-pub fn print_block_unclosed_indent(s: &mut State, blk: &ast::Block, indented: uint) {
-    print_possibly_embedded_block_(s, blk, BlockNormal, indented, &[], false);
+pub fn print_block_unclosed_indent(s: &mut State, blk: &ast::Block,
+                                   indented: uint) -> io::IoResult<()> {
+    print_possibly_embedded_block_(s, blk, BlockNormal, indented, &[], false)
 }
 
 pub fn print_block_with_attrs(s: &mut State,
                               blk: &ast::Block,
-                              attrs: &[ast::Attribute]) {
+                              attrs: &[ast::Attribute]) -> io::IoResult<()> {
     print_possibly_embedded_block_(s, blk, BlockNormal, indent_unit, attrs,
-                                  true);
+                                  true)
 }
 
 enum EmbedType {
@@ -959,9 +1032,9 @@ enum EmbedType {
 pub fn print_possibly_embedded_block(s: &mut State,
                                      blk: &ast::Block,
                                      embedded: EmbedType,
-                                     indented: uint) {
+                                     indented: uint) -> io::IoResult<()> {
     print_possibly_embedded_block_(
-        s, blk, embedded, indented, &[], true);
+        s, blk, embedded, indented, &[], true)
 }
 
 pub fn print_possibly_embedded_block_(s: &mut State,
@@ -969,102 +1042,106 @@ pub fn print_possibly_embedded_block_(s: &mut State,
                                       embedded: EmbedType,
                                       indented: uint,
                                       attrs: &[ast::Attribute],
-                                      close_box: bool) {
+                                      close_box: bool) -> io::IoResult<()> {
     match blk.rules {
-      ast::UnsafeBlock(..) => word_space(s, "unsafe"),
+      ast::UnsafeBlock(..) => if_ok!(word_space(s, "unsafe")),
       ast::DefaultBlock => ()
     }
-    maybe_print_comment(s, blk.span.lo);
+    if_ok!(maybe_print_comment(s, blk.span.lo));
     {
         let ann_node = NodeBlock(s, blk);
-        s.ann.pre(ann_node);
+        if_ok!(s.ann.pre(ann_node));
     }
-    match embedded {
+    if_ok!(match embedded {
         BlockBlockFn => end(s),
         BlockNormal => bopen(s)
-    }
+    });
 
-    print_inner_attributes(s, attrs);
+    if_ok!(print_inner_attributes(s, attrs));
 
-    for vi in blk.view_items.iter() { print_view_item(s, vi); }
+    for vi in blk.view_items.iter() {
+        if_ok!(print_view_item(s, vi));
+    }
     for st in blk.stmts.iter() {
-        print_stmt(s, *st);
+        if_ok!(print_stmt(s, *st));
     }
     match blk.expr {
       Some(expr) => {
-        space_if_not_bol(s);
-        print_expr(s, expr);
-        maybe_print_trailing_comment(s, expr.span, Some(blk.span.hi));
+        if_ok!(space_if_not_bol(s));
+        if_ok!(print_expr(s, expr));
+        if_ok!(maybe_print_trailing_comment(s, expr.span, Some(blk.span.hi)));
       }
       _ => ()
     }
-    bclose_maybe_open(s, blk.span, indented, close_box);
+    if_ok!(bclose_maybe_open(s, blk.span, indented, close_box));
     {
         let ann_node = NodeBlock(s, blk);
-        s.ann.post(ann_node);
+        if_ok!(s.ann.post(ann_node));
     }
+    Ok(())
 }
 
 pub fn print_if(s: &mut State, test: &ast::Expr, blk: &ast::Block,
-                elseopt: Option<@ast::Expr>, chk: bool) {
-    head(s, "if");
-    if chk { word_nbsp(s, "check"); }
-    print_expr(s, test);
-    space(&mut s.s);
-    print_block(s, blk);
-    fn do_else(s: &mut State, els: Option<@ast::Expr>) {
+                elseopt: Option<@ast::Expr>, chk: bool) -> io::IoResult<()> {
+    if_ok!(head(s, "if"));
+    if chk { if_ok!(word_nbsp(s, "check")); }
+    if_ok!(print_expr(s, test));
+    if_ok!(space(&mut s.s));
+    if_ok!(print_block(s, blk));
+    fn do_else(s: &mut State, els: Option<@ast::Expr>) -> io::IoResult<()> {
         match els {
-          Some(_else) => {
-            match _else.node {
-              // "another else-if"
-              ast::ExprIf(i, t, e) => {
-                cbox(s, indent_unit - 1u);
-                ibox(s, 0u);
-                word(&mut s.s, " else if ");
-                print_expr(s, i);
-                space(&mut s.s);
-                print_block(s, t);
-                do_else(s, e);
-              }
-              // "final else"
-              ast::ExprBlock(b) => {
-                cbox(s, indent_unit - 1u);
-                ibox(s, 0u);
-                word(&mut s.s, " else ");
-                print_block(s, b);
-              }
-              // BLEAH, constraints would be great here
-              _ => {
-                  fail!("print_if saw if with weird alternative");
-              }
+            Some(_else) => {
+                match _else.node {
+                    // "another else-if"
+                    ast::ExprIf(i, t, e) => {
+                        if_ok!(cbox(s, indent_unit - 1u));
+                        if_ok!(ibox(s, 0u));
+                        if_ok!(word(&mut s.s, " else if "));
+                        if_ok!(print_expr(s, i));
+                        if_ok!(space(&mut s.s));
+                        if_ok!(print_block(s, t));
+                        if_ok!(do_else(s, e));
+                    }
+                    // "final else"
+                    ast::ExprBlock(b) => {
+                        if_ok!(cbox(s, indent_unit - 1u));
+                        if_ok!(ibox(s, 0u));
+                        if_ok!(word(&mut s.s, " else "));
+                        if_ok!(print_block(s, b));
+                    }
+                    // BLEAH, constraints would be great here
+                    _ => {
+                        fail!("print_if saw if with weird alternative");
+                    }
+                }
             }
-          }
-          _ => {/* fall through */ }
+            _ => {/* fall through */ }
         }
+        Ok(())
     }
-    do_else(s, elseopt);
+    do_else(s, elseopt)
 }
 
-pub fn print_mac(s: &mut State, m: &ast::Mac) {
+pub fn print_mac(s: &mut State, m: &ast::Mac) -> io::IoResult<()> {
     match m.node {
       // I think it's reasonable to hide the ctxt here:
       ast::MacInvocTT(ref pth, ref tts, _) => {
-        print_path(s, pth, false);
-        word(&mut s.s, "!");
-        popen(s);
-        print_tts(s, &tts.as_slice());
-        pclose(s);
+        if_ok!(print_path(s, pth, false));
+        if_ok!(word(&mut s.s, "!"));
+        if_ok!(popen(s));
+        if_ok!(print_tts(s, &tts.as_slice()));
+        pclose(s)
       }
     }
 }
 
-pub fn print_expr_vstore(s: &mut State, t: ast::ExprVstore) {
+pub fn print_expr_vstore(s: &mut State, t: ast::ExprVstore) -> io::IoResult<()> {
     match t {
       ast::ExprVstoreUniq => word(&mut s.s, "~"),
       ast::ExprVstoreSlice => word(&mut s.s, "&"),
       ast::ExprVstoreMutSlice => {
-        word(&mut s.s, "&");
-        word(&mut s.s, "mut");
+        if_ok!(word(&mut s.s, "&"));
+        word(&mut s.s, "mut")
       }
     }
 }
@@ -1072,222 +1149,227 @@ pub fn print_expr_vstore(s: &mut State, t: ast::ExprVstore) {
 pub fn print_call_pre(s: &mut State,
                       sugar: ast::CallSugar,
                       base_args: &mut ~[@ast::Expr])
-                   -> Option<@ast::Expr> {
+                   -> io::IoResult<Option<@ast::Expr>> {
     match sugar {
         ast::ForSugar => {
-            head(s, "for");
-            Some(base_args.pop().unwrap())
+            if_ok!(head(s, "for"));
+            Ok(Some(base_args.pop().unwrap()))
         }
-        ast::NoSugar => None
+        ast::NoSugar => Ok(None)
     }
 }
 
 pub fn print_call_post(s: &mut State,
                        sugar: ast::CallSugar,
                        blk: &Option<@ast::Expr>,
-                       base_args: &mut ~[@ast::Expr]) {
+                       base_args: &mut ~[@ast::Expr]) -> io::IoResult<()> {
     if sugar == ast::NoSugar || !base_args.is_empty() {
-        popen(s);
-        commasep_exprs(s, Inconsistent, *base_args);
-        pclose(s);
+        if_ok!(popen(s));
+        if_ok!(commasep_exprs(s, Inconsistent, *base_args));
+        if_ok!(pclose(s));
     }
     if sugar != ast::NoSugar {
-        nbsp(s);
+        if_ok!(nbsp(s));
         // not sure if this can happen
-        print_expr(s, blk.unwrap());
+        if_ok!(print_expr(s, blk.unwrap()));
     }
+    Ok(())
 }
 
-pub fn print_expr(s: &mut State, expr: &ast::Expr) {
-    fn print_field(s: &mut State, field: &ast::Field) {
-        ibox(s, indent_unit);
-        print_ident(s, field.ident.node);
-        word_space(s, ":");
-        print_expr(s, field.expr);
-        end(s);
+pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
+    fn print_field(s: &mut State, field: &ast::Field) -> io::IoResult<()> {
+        if_ok!(ibox(s, indent_unit));
+        if_ok!(print_ident(s, field.ident.node));
+        if_ok!(word_space(s, ":"));
+        if_ok!(print_expr(s, field.expr));
+        if_ok!(end(s));
+        Ok(())
     }
     fn get_span(field: &ast::Field) -> codemap::Span { return field.span; }
 
-    maybe_print_comment(s, expr.span.lo);
-    ibox(s, indent_unit);
+    if_ok!(maybe_print_comment(s, expr.span.lo));
+    if_ok!(ibox(s, indent_unit));
     {
         let ann_node = NodeExpr(s, expr);
-        s.ann.pre(ann_node);
+        if_ok!(s.ann.pre(ann_node));
     }
     match expr.node {
         ast::ExprVstore(e, v) => {
-            print_expr_vstore(s, v);
-            print_expr(s, e);
+            if_ok!(print_expr_vstore(s, v));
+            if_ok!(print_expr(s, e));
         },
         ast::ExprBox(p, e) => {
-            word(&mut s.s, "box");
-            word(&mut s.s, "(");
-            print_expr(s, p);
-            word_space(s, ")");
-            print_expr(s, e);
+            if_ok!(word(&mut s.s, "box"));
+            if_ok!(word(&mut s.s, "("));
+            if_ok!(print_expr(s, p));
+            if_ok!(word_space(s, ")"));
+            if_ok!(print_expr(s, e));
         }
       ast::ExprVec(ref exprs, mutbl) => {
-        ibox(s, indent_unit);
-        word(&mut s.s, "[");
+        if_ok!(ibox(s, indent_unit));
+        if_ok!(word(&mut s.s, "["));
         if mutbl == ast::MutMutable {
-            word(&mut s.s, "mut");
-            if exprs.len() > 0u { nbsp(s); }
+            if_ok!(word(&mut s.s, "mut"));
+            if exprs.len() > 0u { if_ok!(nbsp(s)); }
         }
-        commasep_exprs(s, Inconsistent, *exprs);
-        word(&mut s.s, "]");
-        end(s);
+        if_ok!(commasep_exprs(s, Inconsistent, *exprs));
+        if_ok!(word(&mut s.s, "]"));
+        if_ok!(end(s));
       }
 
       ast::ExprRepeat(element, count, mutbl) => {
-        ibox(s, indent_unit);
-        word(&mut s.s, "[");
+        if_ok!(ibox(s, indent_unit));
+        if_ok!(word(&mut s.s, "["));
         if mutbl == ast::MutMutable {
-            word(&mut s.s, "mut");
-            nbsp(s);
+            if_ok!(word(&mut s.s, "mut"));
+            if_ok!(nbsp(s));
         }
-        print_expr(s, element);
-        word(&mut s.s, ",");
-        word(&mut s.s, "..");
-        print_expr(s, count);
-        word(&mut s.s, "]");
-        end(s);
+        if_ok!(print_expr(s, element));
+        if_ok!(word(&mut s.s, ","));
+        if_ok!(word(&mut s.s, ".."));
+        if_ok!(print_expr(s, count));
+        if_ok!(word(&mut s.s, "]"));
+        if_ok!(end(s));
       }
 
       ast::ExprStruct(ref path, ref fields, wth) => {
-        print_path(s, path, true);
-        word(&mut s.s, "{");
-        commasep_cmnt(s, Consistent, (*fields), print_field, get_span);
+        if_ok!(print_path(s, path, true));
+        if_ok!(word(&mut s.s, "{"));
+        if_ok!(commasep_cmnt(s, Consistent, (*fields), print_field, get_span));
         match wth {
             Some(expr) => {
-                ibox(s, indent_unit);
+                if_ok!(ibox(s, indent_unit));
                 if !fields.is_empty() {
-                    word(&mut s.s, ",");
-                    space(&mut s.s);
+                    if_ok!(word(&mut s.s, ","));
+                    if_ok!(space(&mut s.s));
                 }
-                word(&mut s.s, "..");
-                print_expr(s, expr);
-                end(s);
+                if_ok!(word(&mut s.s, ".."));
+                if_ok!(print_expr(s, expr));
+                if_ok!(end(s));
             }
-            _ => (word(&mut s.s, ","))
+            _ => if_ok!(word(&mut s.s, ","))
         }
-        word(&mut s.s, "}");
+        if_ok!(word(&mut s.s, "}"));
       }
       ast::ExprTup(ref exprs) => {
-        popen(s);
-        commasep_exprs(s, Inconsistent, *exprs);
+        if_ok!(popen(s));
+        if_ok!(commasep_exprs(s, Inconsistent, *exprs));
         if exprs.len() == 1 {
-            word(&mut s.s, ",");
+            if_ok!(word(&mut s.s, ","));
         }
-        pclose(s);
+        if_ok!(pclose(s));
       }
       ast::ExprCall(func, ref args, sugar) => {
         let mut base_args = (*args).clone();
-        let blk = print_call_pre(s, sugar, &mut base_args);
-        print_expr(s, func);
-        print_call_post(s, sugar, &blk, &mut base_args);
+        let blk = if_ok!(print_call_pre(s, sugar, &mut base_args));
+        if_ok!(print_expr(s, func));
+        if_ok!(print_call_post(s, sugar, &blk, &mut base_args));
       }
       ast::ExprMethodCall(_, ident, ref tys, ref args, sugar) => {
         let mut base_args = args.slice_from(1).to_owned();
-        let blk = print_call_pre(s, sugar, &mut base_args);
-        print_expr(s, args[0]);
-        word(&mut s.s, ".");
-        print_ident(s, ident);
+        let blk = if_ok!(print_call_pre(s, sugar, &mut base_args));
+        if_ok!(print_expr(s, args[0]));
+        if_ok!(word(&mut s.s, "."));
+        if_ok!(print_ident(s, ident));
         if tys.len() > 0u {
-            word(&mut s.s, "::<");
-            commasep(s, Inconsistent, *tys, print_type_ref);
-            word(&mut s.s, ">");
+            if_ok!(word(&mut s.s, "::<"));
+            if_ok!(commasep(s, Inconsistent, *tys, print_type_ref));
+            if_ok!(word(&mut s.s, ">"));
         }
-        print_call_post(s, sugar, &blk, &mut base_args);
+        if_ok!(print_call_post(s, sugar, &blk, &mut base_args));
       }
       ast::ExprBinary(_, op, lhs, rhs) => {
-        print_expr(s, lhs);
-        space(&mut s.s);
-        word_space(s, ast_util::binop_to_str(op));
-        print_expr(s, rhs);
+        if_ok!(print_expr(s, lhs));
+        if_ok!(space(&mut s.s));
+        if_ok!(word_space(s, ast_util::binop_to_str(op)));
+        if_ok!(print_expr(s, rhs));
       }
       ast::ExprUnary(_, op, expr) => {
-        word(&mut s.s, ast_util::unop_to_str(op));
-        print_expr(s, expr);
+        if_ok!(word(&mut s.s, ast_util::unop_to_str(op)));
+        if_ok!(print_expr(s, expr));
       }
       ast::ExprAddrOf(m, expr) => {
-        word(&mut s.s, "&");
-        print_mutability(s, m);
+        if_ok!(word(&mut s.s, "&"));
+        if_ok!(print_mutability(s, m));
         // Avoid `& &e` => `&&e`.
         match (m, &expr.node) {
-            (ast::MutImmutable, &ast::ExprAddrOf(..)) => space(&mut s.s),
+            (ast::MutImmutable, &ast::ExprAddrOf(..)) => if_ok!(space(&mut s.s)),
             _ => { }
         }
-        print_expr(s, expr);
+        if_ok!(print_expr(s, expr));
       }
-      ast::ExprLit(lit) => print_literal(s, lit),
+      ast::ExprLit(lit) => if_ok!(print_literal(s, lit)),
       ast::ExprCast(expr, ty) => {
-        print_expr(s, expr);
-        space(&mut s.s);
-        word_space(s, "as");
-        print_type(s, ty);
+        if_ok!(print_expr(s, expr));
+        if_ok!(space(&mut s.s));
+        if_ok!(word_space(s, "as"));
+        if_ok!(print_type(s, ty));
       }
       ast::ExprIf(test, blk, elseopt) => {
-        print_if(s, test, blk, elseopt, false);
+        if_ok!(print_if(s, test, blk, elseopt, false));
       }
       ast::ExprWhile(test, blk) => {
-        head(s, "while");
-        print_expr(s, test);
-        space(&mut s.s);
-        print_block(s, blk);
+        if_ok!(head(s, "while"));
+        if_ok!(print_expr(s, test));
+        if_ok!(space(&mut s.s));
+        if_ok!(print_block(s, blk));
       }
       ast::ExprForLoop(pat, iter, blk, opt_ident) => {
         for ident in opt_ident.iter() {
-            word(&mut s.s, "'");
-            print_ident(s, *ident);
-            word_space(s, ":");
-        }
-        head(s, "for");
-        print_pat(s, pat);
-        space(&mut s.s);
-        word_space(s, "in");
-        print_expr(s, iter);
-        space(&mut s.s);
-        print_block(s, blk);
+            if_ok!(word(&mut s.s, "'"));
+            if_ok!(print_ident(s, *ident));
+            if_ok!(word_space(s, ":"));
+        }
+        if_ok!(head(s, "for"));
+        if_ok!(print_pat(s, pat));
+        if_ok!(space(&mut s.s));
+        if_ok!(word_space(s, "in"));
+        if_ok!(print_expr(s, iter));
+        if_ok!(space(&mut s.s));
+        if_ok!(print_block(s, blk));
       }
       ast::ExprLoop(blk, opt_ident) => {
         for ident in opt_ident.iter() {
-            word(&mut s.s, "'");
-            print_ident(s, *ident);
-            word_space(s, ":");
+            if_ok!(word(&mut s.s, "'"));
+            if_ok!(print_ident(s, *ident));
+            if_ok!(word_space(s, ":"));
         }
-        head(s, "loop");
-        space(&mut s.s);
-        print_block(s, blk);
+        if_ok!(head(s, "loop"));
+        if_ok!(space(&mut s.s));
+        if_ok!(print_block(s, blk));
       }
       ast::ExprMatch(expr, ref arms) => {
-        cbox(s, indent_unit);
-        ibox(s, 4);
-        word_nbsp(s, "match");
-        print_expr(s, expr);
-        space(&mut s.s);
-        bopen(s);
+        if_ok!(cbox(s, indent_unit));
+        if_ok!(ibox(s, 4));
+        if_ok!(word_nbsp(s, "match"));
+        if_ok!(print_expr(s, expr));
+        if_ok!(space(&mut s.s));
+        if_ok!(bopen(s));
         let len = arms.len();
         for (i, arm) in arms.iter().enumerate() {
-            space(&mut s.s);
-            cbox(s, indent_unit);
-            ibox(s, 0u);
+            if_ok!(space(&mut s.s));
+            if_ok!(cbox(s, indent_unit));
+            if_ok!(ibox(s, 0u));
             let mut first = true;
             for p in arm.pats.iter() {
                 if first {
                     first = false;
-                } else { space(&mut s.s); word_space(s, "|"); }
-                print_pat(s, *p);
+                } else {
+                    if_ok!(space(&mut s.s));
+                    if_ok!(word_space(s, "|"));
+                }
+                if_ok!(print_pat(s, *p));
             }
-            space(&mut s.s);
+            if_ok!(space(&mut s.s));
             match arm.guard {
               Some(e) => {
-                word_space(s, "if");
-                print_expr(s, e);
-                space(&mut s.s);
+                if_ok!(word_space(s, "if"));
+                if_ok!(print_expr(s, e));
+                if_ok!(space(&mut s.s));
               }
               None => ()
             }
-            word_space(s, "=>");
+            if_ok!(word_space(s, "=>"));
 
             // Extract the expression from the extra block the parser adds
             // in the case of foo => expr
@@ -1301,28 +1383,28 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) {
                         match expr.node {
                             ast::ExprBlock(blk) => {
                                 // the block will close the pattern's ibox
-                                print_block_unclosed_indent(
-                                    s, blk, indent_unit);
+                                if_ok!(print_block_unclosed_indent(
+                                    s, blk, indent_unit));
                             }
                             _ => {
-                                end(s); // close the ibox for the pattern
-                                print_expr(s, expr);
+                                if_ok!(end(s)); // close the ibox for the pattern
+                                if_ok!(print_expr(s, expr));
                             }
                         }
                         if !expr_is_simple_block(expr)
                             && i < len - 1 {
-                            word(&mut s.s, ",");
+                            if_ok!(word(&mut s.s, ","));
                         }
-                        end(s); // close enclosing cbox
+                        if_ok!(end(s)); // close enclosing cbox
                     }
                     None => fail!()
                 }
             } else {
                 // the block will close the pattern's ibox
-                print_block_unclosed_indent(s, arm.body, indent_unit);
+                if_ok!(print_block_unclosed_indent(s, arm.body, indent_unit));
             }
         }
-        bclose_(s, expr.span, indent_unit);
+        if_ok!(bclose_(s, expr.span, indent_unit));
       }
       ast::ExprFnBlock(decl, body) => {
         // in do/for blocks we don't want to show an empty
@@ -1330,26 +1412,26 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) {
         // we are inside.
         //
         // if !decl.inputs.is_empty() {
-        print_fn_block_args(s, decl);
-        space(&mut s.s);
+        if_ok!(print_fn_block_args(s, decl));
+        if_ok!(space(&mut s.s));
         // }
         assert!(body.stmts.is_empty());
         assert!(body.expr.is_some());
         // we extract the block, so as not to create another set of boxes
         match body.expr.unwrap().node {
             ast::ExprBlock(blk) => {
-                print_block_unclosed(s, blk);
+                if_ok!(print_block_unclosed(s, blk));
             }
             _ => {
                 // this is a bare expression
-                print_expr(s, body.expr.unwrap());
-                end(s); // need to close a box
+                if_ok!(print_expr(s, body.expr.unwrap()));
+                if_ok!(end(s)); // need to close a box
             }
         }
         // a box will be closed by print_expr, but we didn't want an overall
         // wrapper so we closed the corresponding opening. so create an
         // empty box to satisfy the close.
-        ibox(s, 0);
+        if_ok!(ibox(s, 0));
       }
       ast::ExprProc(decl, body) => {
         // in do/for blocks we don't want to show an empty
@@ -1357,197 +1439,208 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) {
         // we are inside.
         //
         // if !decl.inputs.is_empty() {
-        print_proc_args(s, decl);
-        space(&mut s.s);
+        if_ok!(print_proc_args(s, decl));
+        if_ok!(space(&mut s.s));
         // }
         assert!(body.stmts.is_empty());
         assert!(body.expr.is_some());
         // we extract the block, so as not to create another set of boxes
         match body.expr.unwrap().node {
             ast::ExprBlock(blk) => {
-                print_block_unclosed(s, blk);
+                if_ok!(print_block_unclosed(s, blk));
             }
             _ => {
                 // this is a bare expression
-                print_expr(s, body.expr.unwrap());
-                end(s); // need to close a box
+                if_ok!(print_expr(s, body.expr.unwrap()));
+                if_ok!(end(s)); // need to close a box
             }
         }
         // a box will be closed by print_expr, but we didn't want an overall
         // wrapper so we closed the corresponding opening. so create an
         // empty box to satisfy the close.
-        ibox(s, 0);
+        if_ok!(ibox(s, 0));
       }
       ast::ExprBlock(blk) => {
         // containing cbox, will be closed by print-block at }
-        cbox(s, indent_unit);
+        if_ok!(cbox(s, indent_unit));
         // head-box, will be closed by print-block after {
-        ibox(s, 0u);
-        print_block(s, blk);
+        if_ok!(ibox(s, 0u));
+        if_ok!(print_block(s, blk));
       }
       ast::ExprAssign(lhs, rhs) => {
-        print_expr(s, lhs);
-        space(&mut s.s);
-        word_space(s, "=");
-        print_expr(s, rhs);
+        if_ok!(print_expr(s, lhs));
+        if_ok!(space(&mut s.s));
+        if_ok!(word_space(s, "="));
+        if_ok!(print_expr(s, rhs));
       }
       ast::ExprAssignOp(_, op, lhs, rhs) => {
-        print_expr(s, lhs);
-        space(&mut s.s);
-        word(&mut s.s, ast_util::binop_to_str(op));
-        word_space(s, "=");
-        print_expr(s, rhs);
+        if_ok!(print_expr(s, lhs));
+        if_ok!(space(&mut s.s));
+        if_ok!(word(&mut s.s, ast_util::binop_to_str(op)));
+        if_ok!(word_space(s, "="));
+        if_ok!(print_expr(s, rhs));
       }
       ast::ExprField(expr, id, ref tys) => {
-        print_expr(s, expr);
-        word(&mut s.s, ".");
-        print_ident(s, id);
+        if_ok!(print_expr(s, expr));
+        if_ok!(word(&mut s.s, "."));
+        if_ok!(print_ident(s, id));
         if tys.len() > 0u {
-            word(&mut s.s, "::<");
-            commasep(s, Inconsistent, *tys, print_type_ref);
-            word(&mut s.s, ">");
+            if_ok!(word(&mut s.s, "::<"));
+            if_ok!(commasep(s, Inconsistent, *tys, print_type_ref));
+            if_ok!(word(&mut s.s, ">"));
         }
       }
       ast::ExprIndex(_, expr, index) => {
-        print_expr(s, expr);
-        word(&mut s.s, "[");
-        print_expr(s, index);
-        word(&mut s.s, "]");
+        if_ok!(print_expr(s, expr));
+        if_ok!(word(&mut s.s, "["));
+        if_ok!(print_expr(s, index));
+        if_ok!(word(&mut s.s, "]"));
       }
-      ast::ExprPath(ref path) => print_path(s, path, true),
+      ast::ExprPath(ref path) => if_ok!(print_path(s, path, true)),
       ast::ExprBreak(opt_ident) => {
-        word(&mut s.s, "break");
-        space(&mut s.s);
+        if_ok!(word(&mut s.s, "break"));
+        if_ok!(space(&mut s.s));
         for ident in opt_ident.iter() {
-            word(&mut s.s, "'");
-            print_name(s, *ident);
-            space(&mut s.s);
+            if_ok!(word(&mut s.s, "'"));
+            if_ok!(print_name(s, *ident));
+            if_ok!(space(&mut s.s));
         }
       }
       ast::ExprAgain(opt_ident) => {
-        word(&mut s.s, "continue");
-        space(&mut s.s);
+        if_ok!(word(&mut s.s, "continue"));
+        if_ok!(space(&mut s.s));
         for ident in opt_ident.iter() {
-            word(&mut s.s, "'");
-            print_name(s, *ident);
-            space(&mut s.s)
+            if_ok!(word(&mut s.s, "'"));
+            if_ok!(print_name(s, *ident));
+            if_ok!(space(&mut s.s))
         }
       }
       ast::ExprRet(result) => {
-        word(&mut s.s, "return");
+        if_ok!(word(&mut s.s, "return"));
         match result {
-          Some(expr) => { word(&mut s.s, " "); print_expr(s, expr); }
+          Some(expr) => {
+              if_ok!(word(&mut s.s, " "));
+              if_ok!(print_expr(s, expr));
+          }
           _ => ()
         }
       }
       ast::ExprLogLevel => {
-        word(&mut s.s, "__log_level");
-        popen(s);
-        pclose(s);
+        if_ok!(word(&mut s.s, "__log_level"));
+        if_ok!(popen(s));
+        if_ok!(pclose(s));
       }
       ast::ExprInlineAsm(ref a) => {
         if a.volatile {
-            word(&mut s.s, "__volatile__ asm!");
+            if_ok!(word(&mut s.s, "__volatile__ asm!"));
         } else {
-            word(&mut s.s, "asm!");
+            if_ok!(word(&mut s.s, "asm!"));
         }
-        popen(s);
-        print_string(s, a.asm.get(), a.asm_str_style);
-        word_space(s, ":");
+        if_ok!(popen(s));
+        if_ok!(print_string(s, a.asm.get(), a.asm_str_style));
+        if_ok!(word_space(s, ":"));
         for &(ref co, o) in a.outputs.iter() {
-            print_string(s, co.get(), ast::CookedStr);
-            popen(s);
-            print_expr(s, o);
-            pclose(s);
-            word_space(s, ",");
+            if_ok!(print_string(s, co.get(), ast::CookedStr));
+            if_ok!(popen(s));
+            if_ok!(print_expr(s, o));
+            if_ok!(pclose(s));
+            if_ok!(word_space(s, ","));
         }
-        word_space(s, ":");
+        if_ok!(word_space(s, ":"));
         for &(ref co, o) in a.inputs.iter() {
-            print_string(s, co.get(), ast::CookedStr);
-            popen(s);
-            print_expr(s, o);
-            pclose(s);
-            word_space(s, ",");
+            if_ok!(print_string(s, co.get(), ast::CookedStr));
+            if_ok!(popen(s));
+            if_ok!(print_expr(s, o));
+            if_ok!(pclose(s));
+            if_ok!(word_space(s, ","));
         }
-        word_space(s, ":");
-        print_string(s, a.clobbers.get(), ast::CookedStr);
-        pclose(s);
+        if_ok!(word_space(s, ":"));
+        if_ok!(print_string(s, a.clobbers.get(), ast::CookedStr));
+        if_ok!(pclose(s));
       }
-      ast::ExprMac(ref m) => print_mac(s, m),
+      ast::ExprMac(ref m) => if_ok!(print_mac(s, m)),
       ast::ExprParen(e) => {
-          popen(s);
-          print_expr(s, e);
-          pclose(s);
+          if_ok!(popen(s));
+          if_ok!(print_expr(s, e));
+          if_ok!(pclose(s));
       }
     }
     {
         let ann_node = NodeExpr(s, expr);
-        s.ann.post(ann_node);
+        if_ok!(s.ann.post(ann_node));
     }
-    end(s);
+    end(s)
 }
 
-pub fn print_local_decl(s: &mut State, loc: &ast::Local) {
-    print_pat(s, loc.pat);
+pub fn print_local_decl(s: &mut State, loc: &ast::Local) -> io::IoResult<()> {
+    if_ok!(print_pat(s, loc.pat));
     match loc.ty.node {
         ast::TyInfer => {}
-        _ => { word_space(s, ":"); print_type(s, loc.ty); }
+        _ => {
+            if_ok!(word_space(s, ":"));
+            if_ok!(print_type(s, loc.ty));
+        }
     }
+    Ok(())
 }
 
-pub fn print_decl(s: &mut State, decl: &ast::Decl) {
-    maybe_print_comment(s, decl.span.lo);
+pub fn print_decl(s: &mut State, decl: &ast::Decl) -> io::IoResult<()> {
+    if_ok!(maybe_print_comment(s, decl.span.lo));
     match decl.node {
       ast::DeclLocal(ref loc) => {
-        space_if_not_bol(s);
-        ibox(s, indent_unit);
-        word_nbsp(s, "let");
-
-        fn print_local(s: &mut State, loc: &ast::Local) {
-            ibox(s, indent_unit);
-            print_local_decl(s, loc);
-            end(s);
+        if_ok!(space_if_not_bol(s));
+        if_ok!(ibox(s, indent_unit));
+        if_ok!(word_nbsp(s, "let"));
+
+        fn print_local(s: &mut State, loc: &ast::Local) -> io::IoResult<()> {
+            if_ok!(ibox(s, indent_unit));
+            if_ok!(print_local_decl(s, loc));
+            if_ok!(end(s));
             match loc.init {
               Some(init) => {
-                nbsp(s);
-                word_space(s, "=");
-                print_expr(s, init);
+                if_ok!(nbsp(s));
+                if_ok!(word_space(s, "="));
+                if_ok!(print_expr(s, init));
               }
               _ => ()
             }
+            Ok(())
         }
 
-        print_local(s, *loc);
-        end(s);
+        if_ok!(print_local(s, *loc));
+        end(s)
       }
       ast::DeclItem(item) => print_item(s, item)
     }
 }
 
-pub fn print_ident(s: &mut State, ident: ast::Ident) {
+pub fn print_ident(s: &mut State, ident: ast::Ident) -> io::IoResult<()> {
     let string = token::get_ident(ident.name);
-    word(&mut s.s, string.get());
+    word(&mut s.s, string.get())
 }
 
-pub fn print_name(s: &mut State, name: ast::Name) {
+pub fn print_name(s: &mut State, name: ast::Name) -> io::IoResult<()> {
     let string = token::get_ident(name);
-    word(&mut s.s, string.get());
+    word(&mut s.s, string.get())
 }
 
-pub fn print_for_decl(s: &mut State, loc: &ast::Local, coll: &ast::Expr) {
-    print_local_decl(s, loc);
-    space(&mut s.s);
-    word_space(s, "in");
-    print_expr(s, coll);
+pub fn print_for_decl(s: &mut State, loc: &ast::Local,
+                      coll: &ast::Expr) -> io::IoResult<()> {
+    if_ok!(print_local_decl(s, loc));
+    if_ok!(space(&mut s.s));
+    if_ok!(word_space(s, "in"));
+    print_expr(s, coll)
 }
 
 fn print_path_(s: &mut State,
                path: &ast::Path,
                colons_before_params: bool,
-               opt_bounds: &Option<OptVec<ast::TyParamBound>>) {
-    maybe_print_comment(s, path.span.lo);
+               opt_bounds: &Option<OptVec<ast::TyParamBound>>)
+    -> io::IoResult<()>
+{
+    if_ok!(maybe_print_comment(s, path.span.lo));
     if path.global {
-        word(&mut s.s, "::");
+        if_ok!(word(&mut s.s, "::"));
     }
 
     let mut first = true;
@@ -1555,198 +1648,207 @@ fn print_path_(s: &mut State,
         if first {
             first = false
         } else {
-            word(&mut s.s, "::")
+            if_ok!(word(&mut s.s, "::"))
         }
 
-        print_ident(s, segment.identifier);
+        if_ok!(print_ident(s, segment.identifier));
 
         // If this is the last segment, print the bounds.
         if i == path.segments.len() - 1 {
             match *opt_bounds {
                 None => {}
-                Some(ref bounds) => print_bounds(s, bounds, true),
+                Some(ref bounds) => if_ok!(print_bounds(s, bounds, true)),
             }
         }
 
         if !segment.lifetimes.is_empty() || !segment.types.is_empty() {
             if colons_before_params {
-                word(&mut s.s, "::")
+                if_ok!(word(&mut s.s, "::"))
             }
-            word(&mut s.s, "<");
+            if_ok!(word(&mut s.s, "<"));
 
             let mut comma = false;
             for lifetime in segment.lifetimes.iter() {
                 if comma {
-                    word_space(s, ",")
+                    if_ok!(word_space(s, ","))
                 }
-                print_lifetime(s, lifetime);
+                if_ok!(print_lifetime(s, lifetime));
                 comma = true;
             }
 
             if !segment.types.is_empty() {
                 if comma {
-                    word_space(s, ",")
+                    if_ok!(word_space(s, ","))
                 }
-                commasep(s,
-                         Inconsistent,
-                         segment.types.map_to_vec(|&t| t),
-                         print_type_ref);
+                if_ok!(commasep(s,
+                                Inconsistent,
+                                segment.types.map_to_vec(|&t| t),
+                                print_type_ref));
             }
 
-            word(&mut s.s, ">")
+            if_ok!(word(&mut s.s, ">"))
         }
     }
+    Ok(())
 }
 
-pub fn print_path(s: &mut State, path: &ast::Path, colons_before_params: bool) {
+pub fn print_path(s: &mut State, path: &ast::Path,
+                  colons_before_params: bool) -> io::IoResult<()> {
     print_path_(s, path, colons_before_params, &None)
 }
 
 pub fn print_bounded_path(s: &mut State, path: &ast::Path,
-                          bounds: &Option<OptVec<ast::TyParamBound>>) {
+                          bounds: &Option<OptVec<ast::TyParamBound>>)
+    -> io::IoResult<()>
+{
     print_path_(s, path, false, bounds)
 }
 
-pub fn print_pat(s: &mut State, pat: &ast::Pat) {
-    maybe_print_comment(s, pat.span.lo);
+pub fn print_pat(s: &mut State, pat: &ast::Pat) -> io::IoResult<()> {
+    if_ok!(maybe_print_comment(s, pat.span.lo));
     {
         let ann_node = NodePat(s, pat);
-        s.ann.pre(ann_node);
+        if_ok!(s.ann.pre(ann_node));
     }
     /* Pat isn't normalized, but the beauty of it
      is that it doesn't matter */
     match pat.node {
-      ast::PatWild => word(&mut s.s, "_"),
-      ast::PatWildMulti => word(&mut s.s, ".."),
+      ast::PatWild => if_ok!(word(&mut s.s, "_")),
+      ast::PatWildMulti => if_ok!(word(&mut s.s, "..")),
       ast::PatIdent(binding_mode, ref path, sub) => {
           match binding_mode {
               ast::BindByRef(mutbl) => {
-                  word_nbsp(s, "ref");
-                  print_mutability(s, mutbl);
+                  if_ok!(word_nbsp(s, "ref"));
+                  if_ok!(print_mutability(s, mutbl));
               }
               ast::BindByValue(ast::MutImmutable) => {}
               ast::BindByValue(ast::MutMutable) => {
-                  word_nbsp(s, "mut");
+                  if_ok!(word_nbsp(s, "mut"));
               }
           }
-          print_path(s, path, true);
+          if_ok!(print_path(s, path, true));
           match sub {
               Some(p) => {
-                  word(&mut s.s, "@");
-                  print_pat(s, p);
+                  if_ok!(word(&mut s.s, "@"));
+                  if_ok!(print_pat(s, p));
               }
               None => ()
           }
       }
       ast::PatEnum(ref path, ref args_) => {
-        print_path(s, path, true);
+        if_ok!(print_path(s, path, true));
         match *args_ {
-          None => word(&mut s.s, "(..)"),
+          None => if_ok!(word(&mut s.s, "(..)")),
           Some(ref args) => {
             if !args.is_empty() {
-              popen(s);
-              commasep(s, Inconsistent, *args,
-                       |s, &p| print_pat(s, p));
-              pclose(s);
+              if_ok!(popen(s));
+              if_ok!(commasep(s, Inconsistent, *args,
+                              |s, &p| print_pat(s, p)));
+              if_ok!(pclose(s));
             } else { }
           }
         }
       }
       ast::PatStruct(ref path, ref fields, etc) => {
-        print_path(s, path, true);
-        word(&mut s.s, "{");
-        fn print_field(s: &mut State, f: &ast::FieldPat) {
-            cbox(s, indent_unit);
-            print_ident(s, f.ident);
-            word_space(s, ":");
-            print_pat(s, f.pat);
-            end(s);
+        if_ok!(print_path(s, path, true));
+        if_ok!(word(&mut s.s, "{"));
+        fn print_field(s: &mut State, f: &ast::FieldPat) -> io::IoResult<()> {
+            if_ok!(cbox(s, indent_unit));
+            if_ok!(print_ident(s, f.ident));
+            if_ok!(word_space(s, ":"));
+            if_ok!(print_pat(s, f.pat));
+            if_ok!(end(s));
+            Ok(())
         }
         fn get_span(f: &ast::FieldPat) -> codemap::Span { return f.pat.span; }
-        commasep_cmnt(s, Consistent, *fields,
-                      |s, f| print_field(s,f),
-                      get_span);
+        if_ok!(commasep_cmnt(s, Consistent, *fields,
+                             |s, f| print_field(s,f),
+                             get_span));
         if etc {
-            if fields.len() != 0u { word_space(s, ","); }
-            word(&mut s.s, "..");
+            if fields.len() != 0u { if_ok!(word_space(s, ",")); }
+            if_ok!(word(&mut s.s, ".."));
         }
-        word(&mut s.s, "}");
+        if_ok!(word(&mut s.s, "}"));
       }
       ast::PatTup(ref elts) => {
-        popen(s);
-        commasep(s, Inconsistent, *elts, |s, &p| print_pat(s, p));
+        if_ok!(popen(s));
+        if_ok!(commasep(s, Inconsistent, *elts, |s, &p| print_pat(s, p)));
         if elts.len() == 1 {
-            word(&mut s.s, ",");
+            if_ok!(word(&mut s.s, ","));
         }
-        pclose(s);
+        if_ok!(pclose(s));
       }
       ast::PatUniq(inner) => {
-          word(&mut s.s, "~");
-          print_pat(s, inner);
+          if_ok!(word(&mut s.s, "~"));
+          if_ok!(print_pat(s, inner));
       }
       ast::PatRegion(inner) => {
-          word(&mut s.s, "&");
-          print_pat(s, inner);
+          if_ok!(word(&mut s.s, "&"));
+          if_ok!(print_pat(s, inner));
       }
-      ast::PatLit(e) => print_expr(s, e),
+      ast::PatLit(e) => if_ok!(print_expr(s, e)),
       ast::PatRange(begin, end) => {
-        print_expr(s, begin);
-        space(&mut s.s);
-        word(&mut s.s, "..");
-        print_expr(s, end);
+        if_ok!(print_expr(s, begin));
+        if_ok!(space(&mut s.s));
+        if_ok!(word(&mut s.s, ".."));
+        if_ok!(print_expr(s, end));
       }
       ast::PatVec(ref before, slice, ref after) => {
-        word(&mut s.s, "[");
-        commasep(s, Inconsistent, *before, |s, &p| print_pat(s, p));
+        if_ok!(word(&mut s.s, "["));
+        if_ok!(commasep(s, Inconsistent, *before, |s, &p| print_pat(s, p)));
         for &p in slice.iter() {
-            if !before.is_empty() { word_space(s, ","); }
+            if !before.is_empty() { if_ok!(word_space(s, ",")); }
             match *p {
                 ast::Pat { node: ast::PatWildMulti, .. } => {
                     // this case is handled by print_pat
                 }
-                _ => word(&mut s.s, ".."),
+                _ => if_ok!(word(&mut s.s, "..")),
             }
-            print_pat(s, p);
-            if !after.is_empty() { word_space(s, ","); }
+            if_ok!(print_pat(s, p));
+            if !after.is_empty() { if_ok!(word_space(s, ",")); }
         }
-        commasep(s, Inconsistent, *after, |s, &p| print_pat(s, p));
-        word(&mut s.s, "]");
+        if_ok!(commasep(s, Inconsistent, *after, |s, &p| print_pat(s, p)));
+        if_ok!(word(&mut s.s, "]"));
       }
     }
     {
         let ann_node = NodePat(s, pat);
-        s.ann.post(ann_node);
+        if_ok!(s.ann.post(ann_node));
     }
+    Ok(())
 }
 
-pub fn explicit_self_to_str(explicit_self: &ast::ExplicitSelf_, intr: @IdentInterner) -> ~str {
-    to_str(explicit_self, |a, &b| { print_explicit_self(a, b, ast::MutImmutable); () }, intr)
+pub fn explicit_self_to_str(explicit_self: &ast::ExplicitSelf_,
+                            intr: @IdentInterner) -> ~str {
+    to_str(explicit_self, |a, &b| {
+        print_explicit_self(a, b, ast::MutImmutable).map(|_| ())
+    }, intr)
 }
 
 // Returns whether it printed anything
 fn print_explicit_self(s: &mut State,
                        explicit_self: ast::ExplicitSelf_,
-                       mutbl: ast::Mutability) -> bool {
-    print_mutability(s, mutbl);
+                       mutbl: ast::Mutability) -> io::IoResult<bool> {
+    if_ok!(print_mutability(s, mutbl));
     match explicit_self {
-        ast::SelfStatic => { return false; }
+        ast::SelfStatic => { return Ok(false); }
         ast::SelfValue => {
-            word(&mut s.s, "self");
+            if_ok!(word(&mut s.s, "self"));
         }
         ast::SelfUniq => {
-            word(&mut s.s, "~self");
+            if_ok!(word(&mut s.s, "~self"));
         }
         ast::SelfRegion(ref lt, m) => {
-            word(&mut s.s, "&");
-            print_opt_lifetime(s, lt);
-            print_mutability(s, m);
-            word(&mut s.s, "self");
+            if_ok!(word(&mut s.s, "&"));
+            if_ok!(print_opt_lifetime(s, lt));
+            if_ok!(print_mutability(s, m));
+            if_ok!(word(&mut s.s, "self"));
         }
         ast::SelfBox => {
-            word(&mut s.s, "@self");
+            if_ok!(word(&mut s.s, "@self"));
         }
     }
-    return true;
+    return Ok(true);
 }
 
 pub fn print_fn(s: &mut State,
@@ -1756,20 +1858,24 @@ pub fn print_fn(s: &mut State,
                 name: ast::Ident,
                 generics: &ast::Generics,
                 opt_explicit_self: Option<ast::ExplicitSelf_>,
-                vis: ast::Visibility) {
-    head(s, "");
-    print_fn_header_info(s, opt_explicit_self, purity, abis, ast::Many, None, vis);
-    nbsp(s);
-    print_ident(s, name);
-    print_generics(s, generics);
-    print_fn_args_and_ret(s, decl, opt_explicit_self);
+                vis: ast::Visibility) -> io::IoResult<()> {
+    if_ok!(head(s, ""));
+    if_ok!(print_fn_header_info(s, opt_explicit_self, purity, abis,
+                                ast::Many, None, vis));
+    if_ok!(nbsp(s));
+    if_ok!(print_ident(s, name));
+    if_ok!(print_generics(s, generics));
+    if_ok!(print_fn_args_and_ret(s, decl, opt_explicit_self));
+    Ok(())
 }
 
 pub fn print_fn_args(s: &mut State, decl: &ast::FnDecl,
-                 opt_explicit_self: Option<ast::ExplicitSelf_>) {
+                     opt_explicit_self: Option<ast::ExplicitSelf_>)
+    -> io::IoResult<()>
+{
     // It is unfortunate to duplicate the commasep logic, but we want the
     // self type and the args all in the same box.
-    rbox(s, 0u, Inconsistent);
+    if_ok!(rbox(s, 0u, Inconsistent));
     let mut first = true;
     for &explicit_self in opt_explicit_self.iter() {
         let m = match explicit_self {
@@ -1779,7 +1885,7 @@ pub fn print_fn_args(s: &mut State, decl: &ast::FnDecl,
                 _ => ast::MutImmutable
             }
         };
-        first = !print_explicit_self(s, explicit_self, m);
+        first = !if_ok!(print_explicit_self(s, explicit_self, m));
     }
 
     // HACK(eddyb) ignore the separately printed self argument.
@@ -1790,117 +1896,126 @@ pub fn print_fn_args(s: &mut State, decl: &ast::FnDecl,
     };
 
     for arg in args.iter() {
-        if first { first = false; } else { word_space(s, ","); }
-        print_arg(s, arg);
+        if first { first = false; } else { if_ok!(word_space(s, ",")); }
+        if_ok!(print_arg(s, arg));
     }
 
-    end(s);
+    end(s)
 }
 
 pub fn print_fn_args_and_ret(s: &mut State, decl: &ast::FnDecl,
-                             opt_explicit_self: Option<ast::ExplicitSelf_>) {
-    popen(s);
-    print_fn_args(s, decl, opt_explicit_self);
+                             opt_explicit_self: Option<ast::ExplicitSelf_>)
+    -> io::IoResult<()>
+{
+    if_ok!(popen(s));
+    if_ok!(print_fn_args(s, decl, opt_explicit_self));
     if decl.variadic {
-        word(&mut s.s, ", ...");
+        if_ok!(word(&mut s.s, ", ..."));
     }
-    pclose(s);
+    if_ok!(pclose(s));
 
-    maybe_print_comment(s, decl.output.span.lo);
+    if_ok!(maybe_print_comment(s, decl.output.span.lo));
     match decl.output.node {
         ast::TyNil => {}
         _ => {
-            space_if_not_bol(s);
-            word_space(s, "->");
-            print_type(s, decl.output);
+            if_ok!(space_if_not_bol(s));
+            if_ok!(word_space(s, "->"));
+            if_ok!(print_type(s, decl.output));
         }
     }
+    Ok(())
 }
 
-pub fn print_fn_block_args(s: &mut State, decl: &ast::FnDecl) {
-    word(&mut s.s, "|");
-    print_fn_args(s, decl, None);
-    word(&mut s.s, "|");
+pub fn print_fn_block_args(s: &mut State,
+                           decl: &ast::FnDecl) -> io::IoResult<()> {
+    if_ok!(word(&mut s.s, "|"));
+    if_ok!(print_fn_args(s, decl, None));
+    if_ok!(word(&mut s.s, "|"));
 
     match decl.output.node {
         ast::TyInfer => {}
         _ => {
-            space_if_not_bol(s);
-            word_space(s, "->");
-            print_type(s, decl.output);
+            if_ok!(space_if_not_bol(s));
+            if_ok!(word_space(s, "->"));
+            if_ok!(print_type(s, decl.output));
         }
     }
 
-    maybe_print_comment(s, decl.output.span.lo);
+    maybe_print_comment(s, decl.output.span.lo)
 }
 
-pub fn print_proc_args(s: &mut State, decl: &ast::FnDecl) {
-    word(&mut s.s, "proc");
-    word(&mut s.s, "(");
-    print_fn_args(s, decl, None);
-    word(&mut s.s, ")");
+pub fn print_proc_args(s: &mut State, decl: &ast::FnDecl) -> io::IoResult<()> {
+    if_ok!(word(&mut s.s, "proc"));
+    if_ok!(word(&mut s.s, "("));
+    if_ok!(print_fn_args(s, decl, None));
+    if_ok!(word(&mut s.s, ")"));
 
     match decl.output.node {
         ast::TyInfer => {}
         _ => {
-            space_if_not_bol(s);
-            word_space(s, "->");
-            print_type(s, decl.output);
+            if_ok!(space_if_not_bol(s));
+            if_ok!(word_space(s, "->"));
+            if_ok!(print_type(s, decl.output));
         }
     }
 
-    maybe_print_comment(s, decl.output.span.lo);
+    maybe_print_comment(s, decl.output.span.lo)
 }
 
 pub fn print_bounds(s: &mut State, bounds: &OptVec<ast::TyParamBound>,
-                    print_colon_anyway: bool) {
+                    print_colon_anyway: bool) -> io::IoResult<()> {
     if !bounds.is_empty() {
-        word(&mut s.s, ":");
+        if_ok!(word(&mut s.s, ":"));
         let mut first = true;
         for bound in bounds.iter() {
-            nbsp(s);
+            if_ok!(nbsp(s));
             if first {
                 first = false;
             } else {
-                word_space(s, "+");
+                if_ok!(word_space(s, "+"));
             }
 
-            match *bound {
+            if_ok!(match *bound {
                 TraitTyParamBound(ref tref) => print_trait_ref(s, tref),
                 RegionTyParamBound => word(&mut s.s, "'static"),
-            }
+            })
         }
     } else if print_colon_anyway {
-        word(&mut s.s, ":");
+        if_ok!(word(&mut s.s, ":"));
     }
+    Ok(())
 }
 
-pub fn print_lifetime(s: &mut State, lifetime: &ast::Lifetime) {
-    word(&mut s.s, "'");
-    print_ident(s, lifetime.ident);
+pub fn print_lifetime(s: &mut State,
+                      lifetime: &ast::Lifetime) -> io::IoResult<()> {
+    if_ok!(word(&mut s.s, "'"));
+    print_ident(s, lifetime.ident)
 }
 
-pub fn print_generics(s: &mut State, generics: &ast::Generics) {
+pub fn print_generics(s: &mut State,
+                      generics: &ast::Generics) -> io::IoResult<()> {
     let total = generics.lifetimes.len() + generics.ty_params.len();
     if total > 0 {
-        word(&mut s.s, "<");
-        fn print_item(s: &mut State, generics: &ast::Generics, idx: uint) {
+        if_ok!(word(&mut s.s, "<"));
+        fn print_item(s: &mut State, generics: &ast::Generics,
+                      idx: uint) -> io::IoResult<()> {
             if idx < generics.lifetimes.len() {
                 let lifetime = generics.lifetimes.get(idx);
-                print_lifetime(s, lifetime);
+                print_lifetime(s, lifetime)
             } else {
                 let idx = idx - generics.lifetimes.len();
                 let param = generics.ty_params.get(idx);
-                print_ident(s, param.ident);
-                print_bounds(s, &param.bounds, false);
+                if_ok!(print_ident(s, param.ident));
+                if_ok!(print_bounds(s, &param.bounds, false));
                 match param.default {
                     Some(default) => {
-                        space(&mut s.s);
-                        word_space(s, "=");
-                        print_type(s, default);
+                        if_ok!(space(&mut s.s));
+                        if_ok!(word_space(s, "="));
+                        if_ok!(print_type(s, default));
                     }
                     _ => {}
                 }
+                Ok(())
             }
         }
 
@@ -1909,113 +2024,119 @@ pub fn print_generics(s: &mut State, generics: &ast::Generics) {
             ints.push(i);
         }
 
-        commasep(s, Inconsistent, ints,
-                 |s, &i| print_item(s, generics, i));
-        word(&mut s.s, ">");
+        if_ok!(commasep(s, Inconsistent, ints,
+                        |s, &i| print_item(s, generics, i)));
+        if_ok!(word(&mut s.s, ">"));
     }
+    Ok(())
 }
 
-pub fn print_meta_item(s: &mut State, item: &ast::MetaItem) {
-    ibox(s, indent_unit);
+pub fn print_meta_item(s: &mut State, item: &ast::MetaItem) -> io::IoResult<()> {
+    if_ok!(ibox(s, indent_unit));
     match item.node {
-      ast::MetaWord(ref name) => word(&mut s.s, name.get()),
-      ast::MetaNameValue(ref name, ref value) => {
-        word_space(s, name.get());
-        word_space(s, "=");
-        print_literal(s, value);
-      }
-      ast::MetaList(ref name, ref items) => {
-        word(&mut s.s, name.get());
-        popen(s);
-        commasep(s,
-                 Consistent,
-                 items.as_slice(),
-                 |p, &i| print_meta_item(p, i));
-        pclose(s);
-      }
+        ast::MetaWord(ref name) => {
+            if_ok!(word(&mut s.s, name.get()));
+        }
+        ast::MetaNameValue(ref name, ref value) => {
+            if_ok!(word_space(s, name.get()));
+            if_ok!(word_space(s, "="));
+            if_ok!(print_literal(s, value));
+        }
+        ast::MetaList(ref name, ref items) => {
+            if_ok!(word(&mut s.s, name.get()));
+            if_ok!(popen(s));
+            if_ok!(commasep(s,
+                            Consistent,
+                            items.as_slice(),
+                            |p, &i| print_meta_item(p, i)));
+            if_ok!(pclose(s));
+        }
     }
-    end(s);
+    end(s)
 }
 
-pub fn print_view_path(s: &mut State, vp: &ast::ViewPath) {
+pub fn print_view_path(s: &mut State, vp: &ast::ViewPath) -> io::IoResult<()> {
     match vp.node {
       ast::ViewPathSimple(ident, ref path, _) => {
         // FIXME(#6993) can't compare identifiers directly here
         if path.segments.last().unwrap().identifier.name != ident.name {
-            print_ident(s, ident);
-            space(&mut s.s);
-            word_space(s, "=");
+            if_ok!(print_ident(s, ident));
+            if_ok!(space(&mut s.s));
+            if_ok!(word_space(s, "="));
         }
-        print_path(s, path, false);
+        print_path(s, path, false)
       }
 
       ast::ViewPathGlob(ref path, _) => {
-        print_path(s, path, false);
-        word(&mut s.s, "::*");
+        if_ok!(print_path(s, path, false));
+        word(&mut s.s, "::*")
       }
 
       ast::ViewPathList(ref path, ref idents, _) => {
         if path.segments.is_empty() {
-            word(&mut s.s, "{");
+            if_ok!(word(&mut s.s, "{"));
         } else {
-            print_path(s, path, false);
-            word(&mut s.s, "::{");
+            if_ok!(print_path(s, path, false));
+            if_ok!(word(&mut s.s, "::{"));
         }
-        commasep(s, Inconsistent, (*idents), |s, w| {
-            print_ident(s, w.node.name);
-        });
-        word(&mut s.s, "}");
+        if_ok!(commasep(s, Inconsistent, (*idents), |s, w| {
+            print_ident(s, w.node.name)
+        }));
+        word(&mut s.s, "}")
       }
     }
 }
 
-pub fn print_view_paths(s: &mut State, vps: &[@ast::ViewPath]) {
-    commasep(s, Inconsistent, vps, |p, &vp| print_view_path(p, vp));
+pub fn print_view_paths(s: &mut State,
+                        vps: &[@ast::ViewPath]) -> io::IoResult<()> {
+    commasep(s, Inconsistent, vps, |p, &vp| print_view_path(p, vp))
 }
 
-pub fn print_view_item(s: &mut State, item: &ast::ViewItem) {
-    hardbreak_if_not_bol(s);
-    maybe_print_comment(s, item.span.lo);
-    print_outer_attributes(s, item.attrs);
-    print_visibility(s, item.vis);
+pub fn print_view_item(s: &mut State, item: &ast::ViewItem) -> io::IoResult<()> {
+    if_ok!(hardbreak_if_not_bol(s));
+    if_ok!(maybe_print_comment(s, item.span.lo));
+    if_ok!(print_outer_attributes(s, item.attrs));
+    if_ok!(print_visibility(s, item.vis));
     match item.node {
         ast::ViewItemExternMod(id, ref optional_path, _) => {
-            head(s, "extern mod");
-            print_ident(s, id);
+            if_ok!(head(s, "extern mod"));
+            if_ok!(print_ident(s, id));
             for &(ref p, style) in optional_path.iter() {
-                space(&mut s.s);
-                word(&mut s.s, "=");
-                space(&mut s.s);
-                print_string(s, p.get(), style);
+                if_ok!(space(&mut s.s));
+                if_ok!(word(&mut s.s, "="));
+                if_ok!(space(&mut s.s));
+                if_ok!(print_string(s, p.get(), style));
             }
         }
 
         ast::ViewItemUse(ref vps) => {
-            head(s, "use");
-            print_view_paths(s, *vps);
+            if_ok!(head(s, "use"));
+            if_ok!(print_view_paths(s, *vps));
         }
     }
-    word(&mut s.s, ";");
-    end(s); // end inner head-block
-    end(s); // end outer head-block
+    if_ok!(word(&mut s.s, ";"));
+    if_ok!(end(s)); // end inner head-block
+    if_ok!(end(s)); // end outer head-block
+    Ok(())
 }
 
-pub fn print_mutability(s: &mut State, mutbl: ast::Mutability) {
+pub fn print_mutability(s: &mut State,
+                        mutbl: ast::Mutability) -> io::IoResult<()> {
     match mutbl {
       ast::MutMutable => word_nbsp(s, "mut"),
-      ast::MutImmutable => {/* nothing */ }
+      ast::MutImmutable => Ok(()),
     }
 }
 
-pub fn print_mt(s: &mut State, mt: &ast::MutTy) {
-    print_mutability(s, mt.mutbl);
-    print_type(s, mt.ty);
+pub fn print_mt(s: &mut State, mt: &ast::MutTy) -> io::IoResult<()> {
+    if_ok!(print_mutability(s, mt.mutbl));
+    print_type(s, mt.ty)
 }
 
-pub fn print_arg(s: &mut State, input: &ast::Arg) {
-    ibox(s, indent_unit);
+pub fn print_arg(s: &mut State, input: &ast::Arg) -> io::IoResult<()> {
+    if_ok!(ibox(s, indent_unit));
     match input.ty.node {
-        ast::TyInfer => print_pat(s, input.pat),
+        ast::TyInfer => if_ok!(print_pat(s, input.pat)),
         _ => {
             match input.pat.node {
                 ast::PatIdent(_, ref path, _) if
@@ -2025,15 +2146,15 @@ pub fn print_arg(s: &mut State, input: &ast::Arg) {
                     // Do nothing.
                 }
                 _ => {
-                    print_pat(s, input.pat);
-                    word(&mut s.s, ":");
-                    space(&mut s.s);
+                    if_ok!(print_pat(s, input.pat));
+                    if_ok!(word(&mut s.s, ":"));
+                    if_ok!(space(&mut s.s));
                 }
             }
-            print_type(s, input.ty);
+            if_ok!(print_type(s, input.ty));
         }
     }
-    end(s);
+    end(s)
 }
 
 pub fn print_ty_fn(s: &mut State,
@@ -2046,116 +2167,132 @@ pub fn print_ty_fn(s: &mut State,
                    id: Option<ast::Ident>,
                    opt_bounds: &Option<OptVec<ast::TyParamBound>>,
                    generics: Option<&ast::Generics>,
-                   opt_explicit_self: Option<ast::ExplicitSelf_>) {
-    ibox(s, indent_unit);
+                   opt_explicit_self: Option<ast::ExplicitSelf_>)
+    -> io::IoResult<()>
+{
+    if_ok!(ibox(s, indent_unit));
 
     // Duplicates the logic in `print_fn_header_info()`.  This is because that
     // function prints the sigil in the wrong place.  That should be fixed.
     if opt_sigil == Some(ast::OwnedSigil) && onceness == ast::Once {
-        word(&mut s.s, "proc");
+        if_ok!(word(&mut s.s, "proc"));
     } else if opt_sigil == Some(ast::BorrowedSigil) {
-        print_extern_opt_abis(s, opt_abis);
+        if_ok!(print_extern_opt_abis(s, opt_abis));
         for lifetime in opt_region.iter() {
-            print_lifetime(s, lifetime);
+            if_ok!(print_lifetime(s, lifetime));
         }
-        print_purity(s, purity);
-        print_onceness(s, onceness);
+        if_ok!(print_purity(s, purity));
+        if_ok!(print_onceness(s, onceness));
     } else {
-        print_opt_abis_and_extern_if_nondefault(s, opt_abis);
-        print_opt_sigil(s, opt_sigil);
-        print_opt_lifetime(s, opt_region);
-        print_purity(s, purity);
-        print_onceness(s, onceness);
-        word(&mut s.s, "fn");
+        if_ok!(print_opt_abis_and_extern_if_nondefault(s, opt_abis));
+        if_ok!(print_opt_sigil(s, opt_sigil));
+        if_ok!(print_opt_lifetime(s, opt_region));
+        if_ok!(print_purity(s, purity));
+        if_ok!(print_onceness(s, onceness));
+        if_ok!(word(&mut s.s, "fn"));
     }
 
-    match id { Some(id) => { word(&mut s.s, " "); print_ident(s, id); } _ => () }
+    match id {
+        Some(id) => {
+            if_ok!(word(&mut s.s, " "));
+            if_ok!(print_ident(s, id));
+        }
+        _ => ()
+    }
 
     if opt_sigil != Some(ast::BorrowedSigil) {
         opt_bounds.as_ref().map(|bounds| print_bounds(s, bounds, true));
     }
 
-    match generics { Some(g) => print_generics(s, g), _ => () }
-    zerobreak(&mut s.s);
+    match generics { Some(g) => if_ok!(print_generics(s, g)), _ => () }
+    if_ok!(zerobreak(&mut s.s));
 
     if opt_sigil == Some(ast::BorrowedSigil) {
-        word(&mut s.s, "|");
+        if_ok!(word(&mut s.s, "|"));
     } else {
-        popen(s);
+        if_ok!(popen(s));
     }
 
-    print_fn_args(s, decl, opt_explicit_self);
+    if_ok!(print_fn_args(s, decl, opt_explicit_self));
 
     if opt_sigil == Some(ast::BorrowedSigil) {
-        word(&mut s.s, "|");
+        if_ok!(word(&mut s.s, "|"));
 
         opt_bounds.as_ref().map(|bounds| print_bounds(s, bounds, true));
     } else {
         if decl.variadic {
-            word(&mut s.s, ", ...");
+            if_ok!(word(&mut s.s, ", ..."));
         }
-        pclose(s);
+        if_ok!(pclose(s));
     }
 
-    maybe_print_comment(s, decl.output.span.lo);
+    if_ok!(maybe_print_comment(s, decl.output.span.lo));
 
     match decl.output.node {
         ast::TyNil => {}
         _ => {
-            space_if_not_bol(s);
-            ibox(s, indent_unit);
-            word_space(s, "->");
-            if decl.cf == ast::NoReturn { word_nbsp(s, "!"); }
-            else { print_type(s, decl.output); }
-            end(s);
+            if_ok!(space_if_not_bol(s));
+            if_ok!(ibox(s, indent_unit));
+            if_ok!(word_space(s, "->"));
+            if decl.cf == ast::NoReturn {
+                if_ok!(word_nbsp(s, "!"));
+            } else {
+                if_ok!(print_type(s, decl.output));
+            }
+            if_ok!(end(s));
         }
     }
 
-    end(s);
+    end(s)
 }
 
 pub fn maybe_print_trailing_comment(s: &mut State, span: codemap::Span,
-                                    next_pos: Option<BytePos>) {
+                                    next_pos: Option<BytePos>)
+    -> io::IoResult<()>
+{
     let cm;
-    match s.cm { Some(ccm) => cm = ccm, _ => return }
+    match s.cm { Some(ccm) => cm = ccm, _ => return Ok(()) }
     match next_comment(s) {
-      Some(ref cmnt) => {
-        if (*cmnt).style != comments::Trailing { return; }
-        let span_line = cm.lookup_char_pos(span.hi);
-        let comment_line = cm.lookup_char_pos((*cmnt).pos);
-        let mut next = (*cmnt).pos + BytePos(1);
-        match next_pos { None => (), Some(p) => next = p }
-        if span.hi < (*cmnt).pos && (*cmnt).pos < next &&
-               span_line.line == comment_line.line {
-            print_comment(s, cmnt);
-            s.cur_cmnt_and_lit.cur_cmnt += 1u;
+        Some(ref cmnt) => {
+            if (*cmnt).style != comments::Trailing { return Ok(()) }
+            let span_line = cm.lookup_char_pos(span.hi);
+            let comment_line = cm.lookup_char_pos((*cmnt).pos);
+            let mut next = (*cmnt).pos + BytePos(1);
+            match next_pos { None => (), Some(p) => next = p }
+            if span.hi < (*cmnt).pos && (*cmnt).pos < next &&
+                span_line.line == comment_line.line {
+                    if_ok!(print_comment(s, cmnt));
+                    s.cur_cmnt_and_lit.cur_cmnt += 1u;
+                }
         }
-      }
-      _ => ()
+        _ => ()
     }
+    Ok(())
 }
 
-pub fn print_remaining_comments(s: &mut State) {
+pub fn print_remaining_comments(s: &mut State) -> io::IoResult<()> {
     // If there aren't any remaining comments, then we need to manually
     // make sure there is a line break at the end.
-    if next_comment(s).is_none() { hardbreak(&mut s.s); }
+    if next_comment(s).is_none() {
+        if_ok!(hardbreak(&mut s.s));
+    }
     loop {
         match next_comment(s) {
-          Some(ref cmnt) => {
-            print_comment(s, cmnt);
-            s.cur_cmnt_and_lit.cur_cmnt += 1u;
-          }
-          _ => break
+            Some(ref cmnt) => {
+                if_ok!(print_comment(s, cmnt));
+                s.cur_cmnt_and_lit.cur_cmnt += 1u;
+            }
+            _ => break
         }
     }
+    Ok(())
 }
 
-pub fn print_literal(s: &mut State, lit: &ast::Lit) {
-    maybe_print_comment(s, lit.span.lo);
+pub fn print_literal(s: &mut State, lit: &ast::Lit) -> io::IoResult<()> {
+    if_ok!(maybe_print_comment(s, lit.span.lo));
     match next_lit(s, lit.span.lo) {
       Some(ref ltrl) => {
-        word(&mut s.s, (*ltrl).lit);
-        return;
+        return word(&mut s.s, (*ltrl).lit);
       }
       _ => ()
     }
@@ -2165,46 +2302,48 @@ pub fn print_literal(s: &mut State, lit: &ast::Lit) {
           let mut res = ~"'";
           char::from_u32(ch).unwrap().escape_default(|c| res.push_char(c));
           res.push_char('\'');
-          word(&mut s.s, res);
+          word(&mut s.s, res)
       }
       ast::LitInt(i, t) => {
         if i < 0_i64 {
             word(&mut s.s,
                  ~"-" + (-i as u64).to_str_radix(10u)
-                 + ast_util::int_ty_to_str(t));
+                 + ast_util::int_ty_to_str(t))
         } else {
             word(&mut s.s,
                  (i as u64).to_str_radix(10u)
-                 + ast_util::int_ty_to_str(t));
+                 + ast_util::int_ty_to_str(t))
         }
       }
       ast::LitUint(u, t) => {
         word(&mut s.s,
              u.to_str_radix(10u)
-             + ast_util::uint_ty_to_str(t));
+             + ast_util::uint_ty_to_str(t))
       }
       ast::LitIntUnsuffixed(i) => {
         if i < 0_i64 {
-            word(&mut s.s, ~"-" + (-i as u64).to_str_radix(10u));
+            word(&mut s.s, ~"-" + (-i as u64).to_str_radix(10u))
         } else {
-            word(&mut s.s, (i as u64).to_str_radix(10u));
+            word(&mut s.s, (i as u64).to_str_radix(10u))
         }
       }
+
       ast::LitFloat(ref f, t) => {
-        word(&mut s.s, f.get() + ast_util::float_ty_to_str(t));
+        word(&mut s.s, f.get() + ast_util::float_ty_to_str(t))
       }
       ast::LitFloatUnsuffixed(ref f) => word(&mut s.s, f.get()),
       ast::LitNil => word(&mut s.s, "()"),
       ast::LitBool(val) => {
-        if val { word(&mut s.s, "true"); } else { word(&mut s.s, "false"); }
+        if val { word(&mut s.s, "true") } else { word(&mut s.s, "false") }
       }
       ast::LitBinary(ref arr) => {
-        ibox(s, indent_unit);
-        word(&mut s.s, "[");
-        commasep_cmnt(s, Inconsistent, *arr.borrow(), |s, u| word(&mut s.s, format!("{}", *u)),
-                      |_| lit.span);
-        word(&mut s.s, "]");
-        end(s);
+        if_ok!(ibox(s, indent_unit));
+        if_ok!(word(&mut s.s, "["));
+        if_ok!(commasep_cmnt(s, Inconsistent, *arr.borrow(),
+                             |s, u| word(&mut s.s, format!("{}", *u)),
+                             |_| lit.span));
+        if_ok!(word(&mut s.s, "]"));
+        end(s)
       }
     }
 }
@@ -2228,49 +2367,55 @@ pub fn next_lit(s: &mut State, pos: BytePos) -> Option<comments::Literal> {
     }
 }
 
-pub fn maybe_print_comment(s: &mut State, pos: BytePos) {
+pub fn maybe_print_comment(s: &mut State, pos: BytePos) -> io::IoResult<()> {
     loop {
         match next_comment(s) {
           Some(ref cmnt) => {
             if (*cmnt).pos < pos {
-                print_comment(s, cmnt);
+                if_ok!(print_comment(s, cmnt));
                 s.cur_cmnt_and_lit.cur_cmnt += 1u;
             } else { break; }
           }
           _ => break
         }
     }
+    Ok(())
 }
 
-pub fn print_comment(s: &mut State, cmnt: &comments::Comment) {
+pub fn print_comment(s: &mut State,
+                     cmnt: &comments::Comment) -> io::IoResult<()> {
     match cmnt.style {
         comments::Mixed => {
             assert_eq!(cmnt.lines.len(), 1u);
-            zerobreak(&mut s.s);
-            word(&mut s.s, cmnt.lines[0]);
-            zerobreak(&mut s.s);
+            if_ok!(zerobreak(&mut s.s));
+            if_ok!(word(&mut s.s, cmnt.lines[0]));
+            if_ok!(zerobreak(&mut s.s));
         }
         comments::Isolated => {
-            pprust::hardbreak_if_not_bol(s);
+            if_ok!(pprust::hardbreak_if_not_bol(s));
             for line in cmnt.lines.iter() {
                 // Don't print empty lines because they will end up as trailing
                 // whitespace
-                if !line.is_empty() { word(&mut s.s, *line); }
-                hardbreak(&mut s.s);
+                if !line.is_empty() {
+                    if_ok!(word(&mut s.s, *line));
+                }
+                if_ok!(hardbreak(&mut s.s));
             }
         }
         comments::Trailing => {
-            word(&mut s.s, " ");
+            if_ok!(word(&mut s.s, " "));
             if cmnt.lines.len() == 1u {
-                word(&mut s.s, cmnt.lines[0]);
-                hardbreak(&mut s.s);
+                if_ok!(word(&mut s.s, cmnt.lines[0]));
+                if_ok!(hardbreak(&mut s.s));
             } else {
-                ibox(s, 0u);
+                if_ok!(ibox(s, 0u));
                 for line in cmnt.lines.iter() {
-                    if !line.is_empty() { word(&mut s.s, *line); }
-                    hardbreak(&mut s.s);
+                    if !line.is_empty() {
+                        if_ok!(word(&mut s.s, *line));
+                    }
+                    if_ok!(hardbreak(&mut s.s));
                 }
-                end(s);
+                if_ok!(end(s));
             }
         }
         comments::BlankLine => {
@@ -2279,19 +2424,23 @@ pub fn print_comment(s: &mut State, cmnt: &comments::Comment) {
                 pp::String(s, _) => ";" == s,
                 _ => false
             };
-            if is_semi || is_begin(s) || is_end(s) { hardbreak(&mut s.s); }
-            hardbreak(&mut s.s);
+            if is_semi || is_begin(s) || is_end(s) {
+                if_ok!(hardbreak(&mut s.s));
+            }
+            if_ok!(hardbreak(&mut s.s));
         }
     }
+    Ok(())
 }
 
-pub fn print_string(s: &mut State, st: &str, style: ast::StrStyle) {
+pub fn print_string(s: &mut State, st: &str,
+                    style: ast::StrStyle) -> io::IoResult<()> {
     let st = match style {
         ast::CookedStr => format!("\"{}\"", st.escape_default()),
         ast::RawStr(n) => format!("r{delim}\"{string}\"{delim}",
                                   delim="#".repeat(n), string=st)
     };
-    word(&mut s.s, st);
+    word(&mut s.s, st)
 }
 
 // FIXME(pcwalton): A nasty function to extract the string from an `io::Writer`
@@ -2304,11 +2453,12 @@ unsafe fn get_mem_writer(writer: &mut ~io::Writer) -> ~str {
     result
 }
 
-pub fn to_str<T>(t: &T, f: |&mut State, &T|, intr: @IdentInterner) -> ~str {
+pub fn to_str<T>(t: &T, f: |&mut State, &T| -> io::IoResult<()>,
+                 intr: @IdentInterner) -> ~str {
     let wr = ~MemWriter::new();
     let mut s = rust_printer(wr as ~io::Writer, intr);
-    f(&mut s, t);
-    eof(&mut s.s);
+    f(&mut s, t).unwrap();
+    eof(&mut s.s).unwrap();
     unsafe {
         get_mem_writer(&mut s.s.out)
     }
@@ -2327,44 +2477,52 @@ pub fn next_comment(s: &mut State) -> Option<comments::Comment> {
     }
 }
 
-pub fn print_opt_purity(s: &mut State, opt_purity: Option<ast::Purity>) {
+pub fn print_opt_purity(s: &mut State,
+                        opt_purity: Option<ast::Purity>) -> io::IoResult<()> {
     match opt_purity {
         Some(ast::ImpureFn) => { }
         Some(purity) => {
-            word_nbsp(s, purity_to_str(purity));
+            if_ok!(word_nbsp(s, purity_to_str(purity)));
         }
         None => {}
     }
+    Ok(())
 }
 
 pub fn print_opt_abis_and_extern_if_nondefault(s: &mut State,
-                                               opt_abis: Option<AbiSet>) {
+                                               opt_abis: Option<AbiSet>)
+    -> io::IoResult<()>
+{
     match opt_abis {
         Some(abis) if !abis.is_rust() => {
-            word_nbsp(s, "extern");
-            word_nbsp(s, abis.to_str());
+            if_ok!(word_nbsp(s, "extern"));
+            if_ok!(word_nbsp(s, abis.to_str()));
         }
         Some(_) | None => {}
     };
+    Ok(())
 }
 
-pub fn print_extern_opt_abis(s: &mut State, opt_abis: Option<AbiSet>) {
+pub fn print_extern_opt_abis(s: &mut State,
+                             opt_abis: Option<AbiSet>) -> io::IoResult<()> {
     match opt_abis {
         Some(abis) => {
-            word_nbsp(s, "extern");
-            word_nbsp(s, abis.to_str());
+            if_ok!(word_nbsp(s, "extern"));
+            if_ok!(word_nbsp(s, abis.to_str()));
         }
         None => {}
-    };
+    }
+    Ok(())
 }
 
-pub fn print_opt_sigil(s: &mut State, opt_sigil: Option<ast::Sigil>) {
+pub fn print_opt_sigil(s: &mut State,
+                       opt_sigil: Option<ast::Sigil>) -> io::IoResult<()> {
     match opt_sigil {
-        Some(ast::BorrowedSigil) => { word(&mut s.s, "&"); }
-        Some(ast::OwnedSigil) => { word(&mut s.s, "~"); }
-        Some(ast::ManagedSigil) => { word(&mut s.s, "@"); }
-        None => {}
-    };
+        Some(ast::BorrowedSigil) => word(&mut s.s, "&"),
+        Some(ast::OwnedSigil) => word(&mut s.s, "~"),
+        Some(ast::ManagedSigil) => word(&mut s.s, "@"),
+        None => Ok(())
+    }
 }
 
 pub fn print_fn_header_info(s: &mut State,
@@ -2373,23 +2531,24 @@ pub fn print_fn_header_info(s: &mut State,
                             abis: AbiSet,
                             onceness: ast::Onceness,
                             opt_sigil: Option<ast::Sigil>,
-                            vis: ast::Visibility) {
-    word(&mut s.s, visibility_qualified(vis, ""));
+                            vis: ast::Visibility) -> io::IoResult<()> {
+    if_ok!(word(&mut s.s, visibility_qualified(vis, "")));
 
     if abis != AbiSet::Rust() {
-        word_nbsp(s, "extern");
-        word_nbsp(s, abis.to_str());
+        if_ok!(word_nbsp(s, "extern"));
+        if_ok!(word_nbsp(s, abis.to_str()));
 
         if opt_purity != Some(ast::ExternFn) {
-            print_opt_purity(s, opt_purity);
+            if_ok!(print_opt_purity(s, opt_purity));
         }
     } else {
-        print_opt_purity(s, opt_purity);
+        if_ok!(print_opt_purity(s, opt_purity));
     }
 
-    print_onceness(s, onceness);
-    word(&mut s.s, "fn");
-    print_opt_sigil(s, opt_sigil);
+    if_ok!(print_onceness(s, onceness));
+    if_ok!(word(&mut s.s, "fn"));
+    if_ok!(print_opt_sigil(s, opt_sigil));
+    Ok(())
 }
 
 pub fn purity_to_str(p: ast::Purity) -> &'static str {
@@ -2407,17 +2566,17 @@ pub fn onceness_to_str(o: ast::Onceness) -> &'static str {
     }
 }
 
-pub fn print_purity(s: &mut State, p: ast::Purity) {
+pub fn print_purity(s: &mut State, p: ast::Purity) -> io::IoResult<()> {
     match p {
-      ast::ImpureFn => (),
+      ast::ImpureFn => Ok(()),
       _ => word_nbsp(s, purity_to_str(p))
     }
 }
 
-pub fn print_onceness(s: &mut State, o: ast::Onceness) {
+pub fn print_onceness(s: &mut State, o: ast::Onceness) -> io::IoResult<()> {
     match o {
-        ast::Once => { word_nbsp(s, "once"); }
-        ast::Many => {}
+        ast::Once => word_nbsp(s, "once"),
+        ast::Many => Ok(())
     }
 }
 
diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs
index 58c2bed7a45..aa22f47221b 100644
--- a/src/libsyntax/util/parser_testing.rs
+++ b/src/libsyntax/util/parser_testing.rs
@@ -101,30 +101,30 @@ pub fn matches_codepattern(a : &str, b : &str) -> bool {
     let mut idx_a = 0;
     let mut idx_b = 0;
     loop {
-        if (idx_a == a.len() && idx_b == b.len()) {
+        if idx_a == a.len() && idx_b == b.len() {
             return true;
         }
-        else if (idx_a == a.len()) {return false;}
-        else if (idx_b == b.len()) {
+        else if idx_a == a.len() {return false;}
+        else if idx_b == b.len() {
             // maybe the stuff left in a is all ws?
-            if (is_whitespace(a.char_at(idx_a))) {
-                return (scan_for_non_ws_or_end(a,idx_a) == a.len());
+            if is_whitespace(a.char_at(idx_a)) {
+                return scan_for_non_ws_or_end(a,idx_a) == a.len();
             } else {
                 return false;
             }
         }
         // ws in both given and pattern:
-        else if (is_whitespace(a.char_at(idx_a))
-           && is_whitespace(b.char_at(idx_b))) {
+        else if is_whitespace(a.char_at(idx_a))
+           && is_whitespace(b.char_at(idx_b)) {
             idx_a = scan_for_non_ws_or_end(a,idx_a);
             idx_b = scan_for_non_ws_or_end(b,idx_b);
         }
         // ws in given only:
-        else if (is_whitespace(a.char_at(idx_a))) {
+        else if is_whitespace(a.char_at(idx_a)) {
             idx_a = scan_for_non_ws_or_end(a,idx_a);
         }
         // *don't* silently eat ws in expected only.
-        else if (a.char_at(idx_a) == b.char_at(idx_b)) {
+        else if a.char_at(idx_a) == b.char_at(idx_b) {
             idx_a += 1;
             idx_b += 1;
         }
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index 01ebf58628f..c4481a1a07f 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -19,15 +19,21 @@
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")];
 
+#[feature(macro_rules)];
 #[deny(non_camel_case_types)];
 #[allow(missing_doc)];
 
 use std::os;
+use std::io;
 use terminfo::TermInfo;
 use terminfo::searcher::open;
 use terminfo::parser::compiled::{parse, msys_terminfo};
 use terminfo::parm::{expand, Number, Variables};
 
+macro_rules! if_ok (
+    ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
+)
+
 pub mod terminfo;
 
 // FIXME (#2807): Windows support.
@@ -141,45 +147,48 @@ impl<T: Writer> Terminal<T> {
     /// If the color is a bright color, but the terminal only supports 8 colors,
     /// the corresponding normal color will be used instead.
     ///
-    /// Returns true if the color was set, false otherwise.
-    pub fn fg(&mut self, color: color::Color) -> bool {
+    /// Returns Ok(true) if the color was set, Ok(false) otherwise, and Err(e)
+    /// if there was an I/O error
+    pub fn fg(&mut self, color: color::Color) -> io::IoResult<bool> {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
             let s = expand(*self.ti.strings.find_equiv(&("setaf")).unwrap(),
                            [Number(color as int)], &mut Variables::new());
             if s.is_ok() {
-                self.out.write(s.unwrap());
-                return true
+                if_ok!(self.out.write(s.unwrap()));
+                return Ok(true)
             } else {
                 warn!("{}", s.unwrap_err());
             }
         }
-        false
+        Ok(false)
     }
     /// Sets the background color to the given color.
     ///
     /// If the color is a bright color, but the terminal only supports 8 colors,
     /// the corresponding normal color will be used instead.
     ///
-    /// Returns true if the color was set, false otherwise.
-    pub fn bg(&mut self, color: color::Color) -> bool {
+    /// Returns Ok(true) if the color was set, Ok(false) otherwise, and Err(e)
+    /// if there was an I/O error
+    pub fn bg(&mut self, color: color::Color) -> io::IoResult<bool> {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
             let s = expand(*self.ti.strings.find_equiv(&("setab")).unwrap(),
                            [Number(color as int)], &mut Variables::new());
             if s.is_ok() {
-                self.out.write(s.unwrap());
-                return true
+                if_ok!(self.out.write(s.unwrap()));
+                return Ok(true)
             } else {
                 warn!("{}", s.unwrap_err());
             }
         }
-        false
+        Ok(false)
     }
 
     /// Sets the given terminal attribute, if supported.
-    /// Returns true if the attribute was supported, false otherwise.
-    pub fn attr(&mut self, attr: attr::Attr) -> bool {
+    /// Returns Ok(true) if the attribute was supported, Ok(false) otherwise,
+    /// and Err(e) if there was an I/O error.
+    pub fn attr(&mut self, attr: attr::Attr) -> io::IoResult<bool> {
         match attr {
             attr::ForegroundColor(c) => self.fg(c),
             attr::BackgroundColor(c) => self.bg(c),
@@ -189,13 +198,13 @@ impl<T: Writer> Terminal<T> {
                 if parm.is_some() {
                     let s = expand(*parm.unwrap(), [], &mut Variables::new());
                     if s.is_ok() {
-                        self.out.write(s.unwrap());
-                        return true
+                        if_ok!(self.out.write(s.unwrap()));
+                        return Ok(true)
                     } else {
                         warn!("{}", s.unwrap_err());
                     }
                 }
-                false
+                Ok(false)
             }
         }
     }
@@ -214,7 +223,7 @@ impl<T: Writer> Terminal<T> {
     }
 
     /// Resets all terminal attributes and color to the default.
-    pub fn reset(&mut self) {
+    pub fn reset(&mut self) -> io::IoResult<()> {
         let mut cap = self.ti.strings.find_equiv(&("sgr0"));
         if cap.is_none() {
             // are there any terminals that have color/attrs and not sgr0?
@@ -228,7 +237,7 @@ impl<T: Writer> Terminal<T> {
             expand(*op, [], &mut Variables::new())
         });
         if s.is_ok() {
-            self.out.write(s.unwrap());
+            return self.out.write(s.unwrap())
         } else if self.num_colors > 0 {
             warn!("{}", s.unwrap_err());
         } else {
@@ -236,6 +245,7 @@ impl<T: Writer> Terminal<T> {
             // but it's not worth testing all known attributes just for this.
             debug!("{}", s.unwrap_err());
         }
+        Ok(())
     }
 
     fn dim_if_necessary(&self, color: color::Color) -> color::Color {
@@ -252,11 +262,11 @@ impl<T: Writer> Terminal<T> {
 }
 
 impl<T: Writer> Writer for Terminal<T> {
-    fn write(&mut self, buf: &[u8]) {
-        self.out.write(buf);
+    fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
+        self.out.write(buf)
     }
 
-    fn flush(&mut self) {
-        self.out.flush();
+    fn flush(&mut self) -> io::IoResult<()> {
+        self.out.flush()
     }
 }
diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs
index b0104faf4b5..31f12bd45e6 100644
--- a/src/libterm/terminfo/parser/compiled.rs
+++ b/src/libterm/terminfo/parser/compiled.rs
@@ -162,6 +162,10 @@ pub static stringnames: &'static[&'static str] = &'static[ "cbt", "_", "cr", "cs
 /// Parse a compiled terminfo entry, using long capability names if `longnames` is true
 pub fn parse(file: &mut io::Reader,
              longnames: bool) -> Result<~TermInfo, ~str> {
+    macro_rules! if_ok( ($e:expr) => (
+        match $e { Ok(e) => e, Err(e) => return Err(format!("{}", e)) }
+    ) )
+
     let bnames;
     let snames;
     let nnames;
@@ -177,17 +181,17 @@ pub fn parse(file: &mut io::Reader,
     }
 
     // Check magic number
-    let magic = file.read_le_u16();
+    let magic = if_ok!(file.read_le_u16());
     if magic != 0x011A {
         return Err(format!("invalid magic number: expected {:x} but found {:x}",
                            0x011A, magic as uint));
     }
 
-    let names_bytes          = file.read_le_i16() as int;
-    let bools_bytes          = file.read_le_i16() as int;
-    let numbers_count        = file.read_le_i16() as int;
-    let string_offsets_count = file.read_le_i16() as int;
-    let string_table_bytes   = file.read_le_i16() as int;
+    let names_bytes          = if_ok!(file.read_le_i16()) as int;
+    let bools_bytes          = if_ok!(file.read_le_i16()) as int;
+    let numbers_count        = if_ok!(file.read_le_i16()) as int;
+    let string_offsets_count = if_ok!(file.read_le_i16()) as int;
+    let string_table_bytes   = if_ok!(file.read_le_i16()) as int;
 
     assert!(names_bytes          > 0);
 
@@ -216,18 +220,21 @@ pub fn parse(file: &mut io::Reader,
     }
 
     // don't read NUL
-    let names_str = str::from_utf8_owned(file.read_bytes(names_bytes as uint - 1)).unwrap();
+    let bytes = if_ok!(file.read_bytes(names_bytes as uint - 1));
+    let names_str = match str::from_utf8_owned(bytes) {
+        Some(s) => s, None => return Err(~"input not utf-8"),
+    };
 
     let term_names: ~[~str] = names_str.split('|').map(|s| s.to_owned()).collect();
 
-    file.read_byte(); // consume NUL
+    if_ok!(file.read_byte()); // consume NUL
 
     debug!("term names: {:?}", term_names);
 
     let mut bools_map = HashMap::new();
     if bools_bytes != 0 {
         for i in range(0, bools_bytes) {
-            let b = file.read_byte().unwrap();
+            let b = if_ok!(file.read_byte());
             if b < 0 {
                 error!("EOF reading bools after {} entries", i);
                 return Err(~"error: expected more bools but hit EOF");
@@ -242,13 +249,13 @@ pub fn parse(file: &mut io::Reader,
 
     if (bools_bytes + names_bytes) % 2 == 1 {
         debug!("adjusting for padding between bools and numbers");
-        file.read_byte(); // compensate for padding
+        if_ok!(file.read_byte()); // compensate for padding
     }
 
     let mut numbers_map = HashMap::new();
     if numbers_count != 0 {
         for i in range(0, numbers_count) {
-            let n = file.read_le_u16();
+            let n = if_ok!(file.read_le_u16());
             if n != 0xFFFF {
                 debug!("{}\\#{}", nnames[i], n);
                 numbers_map.insert(nnames[i].to_owned(), n);
@@ -263,12 +270,12 @@ pub fn parse(file: &mut io::Reader,
     if string_offsets_count != 0 {
         let mut string_offsets = vec::with_capacity(10);
         for _ in range(0, string_offsets_count) {
-            string_offsets.push(file.read_le_u16());
+            string_offsets.push(if_ok!(file.read_le_u16()));
         }
 
         debug!("offsets: {:?}", string_offsets);
 
-        let string_table = file.read_bytes(string_table_bytes as uint);
+        let string_table = if_ok!(file.read_bytes(string_table_bytes as uint));
 
         if string_table.len() != string_table_bytes as uint {
             error!("EOF reading string table after {} bytes, wanted {}", string_table.len(),
diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs
index 8cbb0902697..5b536d9aafa 100644
--- a/src/libterm/terminfo/searcher.rs
+++ b/src/libterm/terminfo/searcher.rs
@@ -77,8 +77,8 @@ pub fn open(term: &str) -> Result<File, ~str> {
     match get_dbpath_for_term(term) {
         Some(x) => {
             match File::open(x) {
-                Some(file) => Ok(file),
-                None => Err(~"error opening file"),
+                Ok(file) => Ok(file),
+                Err(e) => Err(format!("error opening file: {}", e)),
             }
         }
         None => Err(format!("could not find terminfo entry for {}", term))
@@ -106,7 +106,7 @@ fn test_get_dbpath_for_term() {
 #[test]
 #[ignore(reason = "see test_get_dbpath_for_term")]
 fn test_open() {
-    open("screen");
+    open("screen").unwrap();
     let t = open("nonexistent terminal that hopefully does not exist");
     assert!(t.is_err());
 }
diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs
index a0e9f96b31d..6f4a4c43b03 100644
--- a/src/test/bench/shootout-mandelbrot.rs
+++ b/src/test/bench/shootout-mandelbrot.rs
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::io;
 use std::io::BufferedWriter;
 
 struct DummyWriter;
 impl Writer for DummyWriter {
-    fn write(&mut self, _: &[u8]) {}
+    fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) }
 }
 
 static ITER: int = 50;
diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs
index 43167458e86..771e545ece8 100644
--- a/src/test/bench/shootout-reverse-complement.rs
+++ b/src/test/bench/shootout-reverse-complement.rs
@@ -36,11 +36,12 @@ fn make_complements() -> [u8, ..256] {
 
 fn main() {
     let complements = make_complements();
-    let mut data = if std::os::getenv("RUST_BENCH").is_some() {
+    let data = if std::os::getenv("RUST_BENCH").is_some() {
         File::open(&Path::new("shootout-k-nucleotide.data")).read_to_end()
     } else {
         stdin().read_to_end()
     };
+    let mut data = data.unwrap();
 
     for seq in data.mut_split(|c| *c == '>' as u8) {
         // skip header and last \n
diff --git a/src/test/run-pass/capturing-logging.rs b/src/test/run-pass/capturing-logging.rs
index 171424d8b3b..17cd8db9d39 100644
--- a/src/test/run-pass/capturing-logging.rs
+++ b/src/test/run-pass/capturing-logging.rs
@@ -43,5 +43,5 @@ fn main() {
         debug!("debug");
         info!("info");
     });
-    assert_eq!(r.read_to_str(), ~"info\n");
+    assert_eq!(r.read_to_str().unwrap(), ~"info\n");
 }
diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs
index 3442e971f4f..f3ddc002333 100644
--- a/src/test/run-pass/core-run-destroy.rs
+++ b/src/test/run-pass/core-run-destroy.rs
@@ -27,8 +27,7 @@ fn test_destroy_once() {
     #[cfg(target_os="android")]
     static PROG: &'static str = "ls"; // android don't have echo binary
 
-    let mut p = run::Process::new(PROG, [], run::ProcessOptions::new())
-        .expect(format!("failed to exec `{}`", PROG));
+    let mut p = run::Process::new(PROG, [], run::ProcessOptions::new()).unwrap();
     p.destroy(); // this shouldn't crash (and nor should the destructor)
 }
 
@@ -39,12 +38,12 @@ fn test_destroy_twice() {
     #[cfg(target_os="android")]
     static PROG: &'static str = "ls"; // android don't have echo binary
 
-    let mut p = run::Process::new(PROG, [], run::ProcessOptions::new())
-        .expect(format!("failed to exec `{}`", PROG));
+    let mut p = match run::Process::new(PROG, [], run::ProcessOptions::new()) {
+        Ok(p) => p,
+        Err(e) => fail!("wut: {}", e),
+    };
     p.destroy(); // this shouldnt crash...
-    io::io_error::cond.trap(|_| {}).inside(|| {
-        p.destroy(); // ...and nor should this (and nor should the destructor)
-    })
+    p.destroy(); // ...and nor should this (and nor should the destructor)
 }
 
 fn test_destroy_actually_kills(force: bool) {
@@ -61,14 +60,14 @@ fn test_destroy_actually_kills(force: bool) {
     #[cfg(unix,not(target_os="android"))]
     fn process_exists(pid: libc::pid_t) -> bool {
         let run::ProcessOutput {output, ..} = run::process_output("ps", [~"-p", pid.to_str()])
-            .expect("failed to exec `ps`");
+            .unwrap();
         str::from_utf8_owned(output).unwrap().contains(pid.to_str())
     }
 
     #[cfg(unix,target_os="android")]
     fn process_exists(pid: libc::pid_t) -> bool {
         let run::ProcessOutput {output, ..} = run::process_output("/system/bin/ps", [pid.to_str()])
-            .expect("failed to exec `/system/bin/ps`");
+            .unwrap();
         str::from_utf8_owned(output).unwrap().contains(~"root")
     }
 
@@ -93,7 +92,7 @@ fn test_destroy_actually_kills(force: bool) {
 
     // this process will stay alive indefinitely trying to read from stdin
     let mut p = run::Process::new(BLOCK_COMMAND, [], run::ProcessOptions::new())
-        .expect(format!("failed to exec `{}`", BLOCK_COMMAND));
+        .unwrap();
 
     assert!(process_exists(p.get_id()));
 
diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs
index cc59ce5d8b2..b66446b0cfe 100644
--- a/src/test/run-pass/ifmt.rs
+++ b/src/test/run-pass/ifmt.rs
@@ -12,6 +12,7 @@
 
 #[feature(macro_rules)];
 #[deny(warnings)];
+#[allow(unused_must_use)];
 
 use std::fmt;
 use std::io::MemWriter;
@@ -22,10 +23,14 @@ struct A;
 struct B;
 
 impl fmt::Signed for A {
-    fn fmt(_: &A, f: &mut fmt::Formatter) { f.buf.write("aloha".as_bytes()); }
+    fn fmt(_: &A, f: &mut fmt::Formatter) -> fmt::Result {
+        f.buf.write("aloha".as_bytes())
+    }
 }
 impl fmt::Signed for B {
-    fn fmt(_: &B, f: &mut fmt::Formatter) { f.buf.write("adios".as_bytes()); }
+    fn fmt(_: &B, f: &mut fmt::Formatter) -> fmt::Result {
+        f.buf.write("adios".as_bytes())
+    }
 }
 
 macro_rules! t(($a:expr, $b:expr) => { assert_eq!($a, $b.to_owned()) })
@@ -286,9 +291,9 @@ fn test_format_args() {
     let mut buf = MemWriter::new();
     {
         let w = &mut buf as &mut io::Writer;
-        format_args!(|args| { fmt::write(w, args) }, "{}", 1);
-        format_args!(|args| { fmt::write(w, args) }, "test");
-        format_args!(|args| { fmt::write(w, args) }, "{test}", test=3);
+        format_args!(|args| { fmt::write(w, args); }, "{}", 1);
+        format_args!(|args| { fmt::write(w, args); }, "test");
+        format_args!(|args| { fmt::write(w, args); }, "{test}", test=3);
     }
     let s = str::from_utf8_owned(buf.unwrap()).unwrap();
     t!(s, "1test3");
diff --git a/src/test/run-pass/issue-8398.rs b/src/test/run-pass/issue-8398.rs
index f9169618c2a..0884db63326 100644
--- a/src/test/run-pass/issue-8398.rs
+++ b/src/test/run-pass/issue-8398.rs
@@ -11,7 +11,7 @@
 use std::io;
 
 fn foo(a: &mut io::Writer) {
-    a.write([])
+    a.write([]).unwrap();
 }
 
 pub fn main(){}
diff --git a/src/test/run-pass/logging-only-prints-once.rs b/src/test/run-pass/logging-only-prints-once.rs
index 4aef239f796..dccdc8ae3ba 100644
--- a/src/test/run-pass/logging-only-prints-once.rs
+++ b/src/test/run-pass/logging-only-prints-once.rs
@@ -17,10 +17,11 @@ use std::fmt;
 struct Foo(Cell<int>);
 
 impl fmt::Show for Foo {
-    fn fmt(f: &Foo, _fmt: &mut fmt::Formatter) {
+    fn fmt(f: &Foo, _fmt: &mut fmt::Formatter) -> fmt::Result {
         let Foo(ref f) = *f;
         assert!(f.get() == 0);
         f.set(1);
+        Ok(())
     }
 }
 
diff --git a/src/test/run-pass/signal-exit-status.rs b/src/test/run-pass/signal-exit-status.rs
index dc74e9fb470..0e8ca4d9942 100644
--- a/src/test/run-pass/signal-exit-status.rs
+++ b/src/test/run-pass/signal-exit-status.rs
@@ -19,8 +19,7 @@ pub fn main() {
         // Raise a segfault.
         unsafe { *(0 as *mut int) = 0; }
     } else {
-        let status = run::process_status(args[0], [~"signal"])
-            .expect("failed to exec `signal`");
+        let status = run::process_status(args[0], [~"signal"]).unwrap();
         // Windows does not have signal, so we get exit status 0xC0000028 (STATUS_BAD_STACK).
         match status {
             process::ExitSignal(_) if cfg!(unix) => {},
diff --git a/src/test/run-pass/stat.rs b/src/test/run-pass/stat.rs
index b186a682810..7f04da0734d 100644
--- a/src/test/run-pass/stat.rs
+++ b/src/test/run-pass/stat.rs
@@ -21,8 +21,8 @@ pub fn main() {
 
     {
         match File::create(&path) {
-            None => unreachable!(),
-            Some(f) => {
+            Err(..) => unreachable!(),
+            Ok(f) => {
                 let mut f = f;
                 for _ in range(0u, 1000) {
                     f.write([0]);
@@ -32,5 +32,5 @@ pub fn main() {
     }
 
     assert!(path.exists());
-    assert_eq!(path.stat().size, 1000);
+    assert_eq!(path.stat().unwrap().size, 1000);
 }