diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index a66789bf287..3b48ff30960 100644
--- a/src/libstd/io/error.rs
+++ b/src/libstd/io/error.rs
@@ -17,11 +17,37 @@ use option::Option::{self, Some, None};
 use result;
 use sys;
 
-/// A type for results generated by I/O related functions where the `Err` type
-/// is hard-wired to `io::Error`.
+/// A specialized [`Result`][result] type for I/O operations.
+///
+/// [result]: ../result/enum.Result.html
+///
+/// This type is broadly used across `std::io` for any operation which may
+/// produce an error.
 ///
 /// This typedef is generally used to avoid writing out `io::Error` directly and
-/// is otherwise a direct mapping to `std::result::Result`.
+/// is otherwise a direct mapping to `Result`.
+///
+/// While usual Rust style is to import types directly, aliases of `Result`
+/// often are not, to make it easier to distinguish between them. `Result` is
+/// generally assumed to be `std::result::Result`, and so users of this alias
+/// will generally use `io::Result` instead of shadowing the prelude's import
+/// of `std::result::Result`.
+///
+/// # Examples
+///
+/// A convenience function that bubbles an `io::Result` to its caller:
+///
+/// ```
+/// use std::io;
+///
+/// fn get_string() -> io::Result<String> {
+///     let mut buffer = String::new();
+///
+///     try!(io::stdin().read_line(&mut buffer));
+///
+///     Ok(buffer)
+/// }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub type Result<T> = result::Result<T, Error>;
 
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 2a64d0f6e8c..62bbb939a71 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -154,15 +154,42 @@ pub struct StdinLock<'a> {
     inner: MutexGuard<'a, BufReader<Maybe<StdinRaw>>>,
 }
 
-/// Creates a new handle to the global standard input stream of this process.
+/// Constructs a new handle to the standard input of the current process.
 ///
-/// The handle returned refers to a globally shared buffer between all threads.
-/// Access is synchronized and can be explicitly controlled with the `lock()`
-/// method.
+/// Each handle returned is a reference to a shared global buffer whose access
+/// is synchronized via a mutex. If you need more explicit control over
+/// locking, see the [lock() method][lock].
 ///
-/// The `Read` trait is implemented for the returned value but the `BufRead`
-/// trait is not due to the global nature of the standard input stream. The
-/// locked version, `StdinLock`, implements both `Read` and `BufRead`, however.
+/// [lock]: struct.Stdin.html#method.lock
+///
+/// # Examples
+///
+/// Using implicit synchronization:
+///
+/// ```
+/// use std::io::{self, Read};
+///
+/// # fn foo() -> io::Result<String> {
+/// let mut buffer = String::new();
+/// try!(io::stdin().read_to_string(&mut buffer));
+/// # Ok(buffer)
+/// # }
+/// ```
+///
+/// Using explicit synchronization:
+///
+/// ```
+/// use std::io::{self, Read};
+///
+/// # fn foo() -> io::Result<String> {
+/// let mut buffer = String::new();
+/// let stdin = io::stdin();
+/// let mut handle = stdin.lock();
+///
+/// try!(handle.read_to_string(&mut buffer));
+/// # Ok(buffer)
+/// # }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdin() -> Stdin {
     static INSTANCE: Lazy<Mutex<BufReader<Maybe<StdinRaw>>>> = Lazy::new(stdin_init);
@@ -298,13 +325,42 @@ pub struct StdoutLock<'a> {
     inner: ReentrantMutexGuard<'a, RefCell<LineWriter<Maybe<StdoutRaw>>>>,
 }
 
-/// Constructs a new reference to the standard output of the current process.
+/// Constructs a new handle to the standard output of the current process.
 ///
 /// Each handle returned is a reference to a shared global buffer whose access
-/// is synchronized via a mutex. Explicit control over synchronization is
-/// provided via the `lock` method.
+/// is synchronized via a mutex. If you need more explicit control over
+/// locking, see the [lock() method][lock].
 ///
-/// The returned handle implements the `Write` trait.
+/// [lock]: struct.Stdout.html#method.lock
+///
+/// # Examples
+///
+/// Using implicit synchronization:
+///
+/// ```
+/// use std::io::{self, Write};
+///
+/// # fn foo() -> io::Result<()> {
+/// try!(io::stdout().write(b"hello world"));
+///
+/// # Ok(())
+/// # }
+/// ```
+///
+/// Using explicit synchronization:
+///
+/// ```
+/// use std::io::{self, Write};
+///
+/// # fn foo() -> io::Result<()> {
+/// let stdout = io::stdout();
+/// let mut handle = stdout.lock();
+///
+/// try!(handle.write(b"hello world"));
+///
+/// # Ok(())
+/// # }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stdout() -> Stdout {
     static INSTANCE: Lazy<ReentrantMutex<RefCell<LineWriter<Maybe<StdoutRaw>>>>>
@@ -376,12 +432,38 @@ pub struct StderrLock<'a> {
     inner: ReentrantMutexGuard<'a, RefCell<Maybe<StderrRaw>>>,
 }
 
-/// Constructs a new reference to the standard error stream of a process.
+/// Constructs a new handle to the standard error of the current process.
 ///
-/// Each returned handle is synchronized amongst all other handles created from
-/// this function. No handles are buffered, however.
+/// This handle is not buffered.
 ///
-/// The returned handle implements the `Write` trait.
+/// # Examples
+///
+/// Using implicit synchronization:
+///
+/// ```
+/// use std::io::{self, Write};
+///
+/// # fn foo() -> io::Result<()> {
+/// try!(io::stderr().write(b"hello world"));
+///
+/// # Ok(())
+/// # }
+/// ```
+///
+/// Using explicit synchronization:
+///
+/// ```
+/// use std::io::{self, Write};
+///
+/// # fn foo() -> io::Result<()> {
+/// let stderr = io::stderr();
+/// let mut handle = stderr.lock();
+///
+/// try!(handle.write(b"hello world"));
+///
+/// # Ok(())
+/// # }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn stderr() -> Stderr {
     static INSTANCE: Lazy<ReentrantMutex<RefCell<Maybe<StderrRaw>>>> = Lazy::new(stderr_init);
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index d8c999f8948..c0bced26bef 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -28,6 +28,22 @@ use io::{self, Read, Write, ErrorKind, BufRead};
 /// This function will return an error immediately if any call to `read` or
 /// `write` returns an error. All instances of `ErrorKind::Interrupted` are
 /// handled by this function and the underlying operation is retried.
+///
+/// # Examples
+///
+/// ```
+/// use std::io;
+///
+/// # fn foo() -> io::Result<()> {
+/// let mut reader: &[u8] = b"hello";
+/// let mut writer: Vec<u8> = vec![];
+///
+/// try!(io::copy(&mut reader, &mut writer));
+///
+/// assert_eq!(reader, &writer[..]);
+/// # Ok(())
+/// # }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn copy<R: Read, W: Write>(reader: &mut R, writer: &mut W) -> io::Result<u64> {
     let mut buf = [0; super::DEFAULT_BUF_SIZE];
@@ -48,9 +64,24 @@ pub fn copy<R: Read, W: Write>(reader: &mut R, writer: &mut W) -> io::Result<u64
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Empty { _priv: () }
 
-/// Creates an instance of an empty reader.
+/// Constructs a new handle to an empty reader.
 ///
 /// All reads from the returned reader will return `Ok(0)`.
+///
+/// # Examples
+///
+/// A slightly sad example of not reading anything into a buffer:
+///
+/// ```
+/// use std::io;
+/// use std::io::Read;
+///
+/// # fn foo() -> io::Result<String> {
+/// let mut buffer = String::new();
+/// try!(io::empty().read_to_string(&mut buffer));
+/// # Ok(buffer)
+/// # }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn empty() -> Empty { Empty { _priv: () } }