diff --git a/library/core/src/future/into_future.rs b/library/core/src/future/into_future.rs
index 8014dacdd98da..d22094130ad9a 100644
--- a/library/core/src/future/into_future.rs
+++ b/library/core/src/future/into_future.rs
@@ -1,6 +1,109 @@
 use crate::future::Future;
 
 /// Conversion into a `Future`.
+///
+/// By implementing `Intofuture` for a type, you define how it will be
+/// converted to a future.
+///
+/// # `.await` desugaring
+///
+/// The `.await` keyword desugars into a call to `IntoFuture::into_future`
+/// first before polling the future to completion. `IntoFuture` is implemented
+/// for all `T: Future` which means the `into_future` method will be available
+/// on all futures.
+///
+/// ```no_run
+/// #![feature(into_future)]
+///
+/// use std::future::IntoFuture;
+///
+/// # async fn foo() {
+/// let v = async { "meow" };
+/// let mut fut = v.into_future();
+/// assert_eq!("meow", fut.await);
+/// # }
+/// ```
+///
+/// # Async builders
+///
+/// When implementing futures manually there will often be a choice between
+/// implementing `Future` or `IntoFuture` for a type. Implementing `Future` is a
+/// good choice in most cases. But implementing `IntoFuture` is most useful when
+/// implementing "async builder" types, which allows the type to be modified
+/// multiple times before being `.await`ed.
+///
+/// ```rust
+/// #![feature(into_future)]
+///
+/// use std::future::{ready, Ready, IntoFuture};
+///
+/// /// Eventually multiply two numbers
+/// pub struct Multiply {
+///     num: u16,
+///     factor: u16,
+/// }
+///
+/// impl Multiply {
+///     /// Construct a new instance of `Multiply`.
+///     pub fn new(num: u16, factor: u16) -> Self {
+///         Self { num, factor }
+///     }
+///
+///     /// Set the number to multiply by the factor.
+///     pub fn number(mut self, num: u16) -> Self {
+///         self.num = num;
+///         self
+///     }
+///
+///     /// Set the factor to multiply the number with.
+///     pub fn factor(mut self, factor: u16) -> Self {
+///         self.factor = factor;
+///         self
+///     }
+/// }
+///
+/// impl IntoFuture for Multiply {
+///     type Output = u16;
+///     type IntoFuture = Ready<Self::Output>;
+///
+///     fn into_future(self) -> Self::IntoFuture {
+///         ready(self.num * self.factor)
+///     }
+/// }
+///
+/// // NOTE: Rust does not yet have an `async fn main` function, that functionality
+/// // currently only exists in the ecosystem.
+/// async fn run() {
+///     let num = Multiply::new(0, 0)  // initialize the builder to number: 0, factor: 0
+///         .number(2)                 // change the number to 2
+///         .factor(2)                 // change the factor to 2
+///         .await;                    // convert to future and .await
+///
+///     assert_eq!(num, 4);
+/// }
+/// ```
+///
+/// # Usage in trait bounds
+///
+/// Using `IntoFuture` in trait bounds allows a function to be generic over both
+/// `Future` and `IntoFuture`. This is convenient for users of the function, so
+/// when they are using it they don't have to make an extra call to
+/// `IntoFuture::into_future` to obtain an instance of `Future`:
+///
+/// ```rust
+/// #![feature(into_future)]
+///
+/// use std::future::IntoFuture;
+///
+/// /// Convert the output of a future to a string.
+/// async fn fut_to_string<Fut>(fut: Fut) -> String
+/// where
+///     Fut: IntoFuture,
+///     Fut::Output: std::fmt::Debug,
+/// {
+///     format!("{:?}", fut.await)
+/// }
+/// ```
 #[unstable(feature = "into_future", issue = "67644")]
 pub trait IntoFuture {
     /// The output that the future will produce on completion.
@@ -12,6 +115,22 @@ pub trait IntoFuture {
     type IntoFuture: Future<Output = Self::Output>;
 
     /// Creates a future from a value.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// #![feature(into_future)]
+    ///
+    /// use std::future::IntoFuture;
+    ///
+    /// # async fn foo() {
+    /// let v = async { "meow" };
+    /// let mut fut = v.into_future();
+    /// assert_eq!("meow", fut.await);
+    /// # }
+    /// ```
     #[unstable(feature = "into_future", issue = "67644")]
     #[lang = "into_future"]
     fn into_future(self) -> Self::IntoFuture;
diff --git a/library/std/src/io/impls.rs b/library/std/src/io/impls.rs
index 0ca58efe1fe2f..95072547302eb 100644
--- a/library/std/src/io/impls.rs
+++ b/library/std/src/io/impls.rs
@@ -441,14 +441,12 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
 impl<A: Allocator> Write for VecDeque<u8, A> {
     #[inline]
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.reserve(buf.len());
         self.extend(buf);
         Ok(buf.len())
     }
 
     #[inline]
     fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
-        self.reserve(buf.len());
         self.extend(buf);
         Ok(())
     }
diff --git a/library/std/src/io/readbuf.rs b/library/std/src/io/readbuf.rs
index c655bc889308c..78d1113f8375a 100644
--- a/library/std/src/io/readbuf.rs
+++ b/library/std/src/io/readbuf.rs
@@ -166,8 +166,8 @@ impl<'a> ReadBuf<'a> {
     ///
     /// The number of initialized bytes is not changed, and the contents of the buffer are not modified.
     #[inline]
-    pub fn clear(&mut self) {
-        self.set_filled(0); // The assertion in `set_filled` is optimized out
+    pub fn clear(&mut self) -> &mut Self {
+        self.set_filled(0) // The assertion in `set_filled` is optimized out
     }
 
     /// Increases the size of the filled region of the buffer.
@@ -178,8 +178,8 @@ impl<'a> ReadBuf<'a> {
     ///
     /// Panics if the filled region of the buffer would become larger than the initialized region.
     #[inline]
-    pub fn add_filled(&mut self, n: usize) {
-        self.set_filled(self.filled + n);
+    pub fn add_filled(&mut self, n: usize) -> &mut Self {
+        self.set_filled(self.filled + n)
     }
 
     /// Sets the size of the filled region of the buffer.
@@ -193,10 +193,11 @@ impl<'a> ReadBuf<'a> {
     ///
     /// Panics if the filled region of the buffer would become larger than the initialized region.
     #[inline]
-    pub fn set_filled(&mut self, n: usize) {
+    pub fn set_filled(&mut self, n: usize) -> &mut Self {
         assert!(n <= self.initialized);
 
         self.filled = n;
+        self
     }
 
     /// Asserts that the first `n` unfilled bytes of the buffer are initialized.
@@ -208,8 +209,9 @@ impl<'a> ReadBuf<'a> {
     ///
     /// The caller must ensure that the first `n` unfilled bytes of the buffer have already been initialized.
     #[inline]
-    pub unsafe fn assume_init(&mut self, n: usize) {
+    pub unsafe fn assume_init(&mut self, n: usize) -> &mut Self {
         self.initialized = cmp::max(self.initialized, self.filled + n);
+        self
     }
 
     /// Appends data to the buffer, advancing the written position and possibly also the initialized position.
@@ -227,7 +229,9 @@ impl<'a> ReadBuf<'a> {
         }
 
         // SAFETY: We just added the entire contents of buf to the filled section.
-        unsafe { self.assume_init(buf.len()) }
+        unsafe {
+            self.assume_init(buf.len());
+        }
         self.add_filled(buf.len());
     }