about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-04-13 22:24:33 +0000
committerbors <bors@rust-lang.org>2019-04-13 22:24:33 +0000
commit00856722bad5e9d96048319fb41f4b7e249820cd (patch)
tree9c813b5a9ac58b59d765a510e2f03c84446b6962 /src/libstd
parente4c66afba5d69356879570aeff22db5a38566a86 (diff)
parentcf370b40dc9955ed3cff90f94b96507513ad6ded (diff)
downloadrust-00856722bad5e9d96048319fb41f4b7e249820cd.tar.gz
rust-00856722bad5e9d96048319fb41f4b7e249820cd.zip
Auto merge of #59949 - Centril:rollup-lsiqq1g, r=Centril
Rollup of 16 pull requests

Successful merges:

 - #59675 (Stabilize the `alloc` crate.)
 - #59708 (Mark variables captured by reference as mutable correctly)
 - #59735 (remove lookup_char_pos_adj)
 - #59747 (Copy book.toml unstable book generator)
 - #59796 (Retire `IsNotConst` naming)
 - #59804 (Clean up jobserver integration)
 - #59818 (Eliminate `FnBox` usages from libstd.)
 - #59830 (Fix links on keyword docs.)
 - #59835 (Re-export NonZero signed variant in std)
 - #59852 (std: Add `{read,write}_vectored` for more types)
 - #59855 (Fix attributes position in type declaration)
 - #59858 (Make duplicate matcher bindings a hard error)
 - #59899 (In `-Zprint-type-size` output, sort enum variants by size.)
 - #59912 (MaybeUninit: remove deprecated functions)
 - #59925 (Fix paste error in split_ascii_whitespace docs.)
 - #59930 (Exclude some copies of old book editions from search engines)

Failed merges:

r? @ghost
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/fs.rs20
-rw-r--r--src/libstd/io/stdio.rs51
-rw-r--r--src/libstd/keyword_docs.rs55
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libstd/num.rs2
-rw-r--r--src/libstd/process.rs16
-rw-r--r--src/libstd/sys/cloudabi/shims/fs.rs10
-rw-r--r--src/libstd/sys/cloudabi/shims/pipe.rs10
-rw-r--r--src/libstd/sys/cloudabi/thread.rs3
-rw-r--r--src/libstd/sys/redox/fs.rs10
-rw-r--r--src/libstd/sys/redox/pipe.rs10
-rw-r--r--src/libstd/sys/redox/thread.rs3
-rw-r--r--src/libstd/sys/sgx/fs.rs10
-rw-r--r--src/libstd/sys/sgx/pipe.rs15
-rw-r--r--src/libstd/sys/sgx/thread.rs8
-rw-r--r--src/libstd/sys/unix/fs.rs10
-rw-r--r--src/libstd/sys/unix/pipe.rs10
-rw-r--r--src/libstd/sys/unix/stdio.rs30
-rw-r--r--src/libstd/sys/unix/thread.rs3
-rw-r--r--src/libstd/sys/wasi/pipe.rs10
-rw-r--r--src/libstd/sys/wasi/stdio.rs18
-rw-r--r--src/libstd/sys/wasi/thread.rs3
-rw-r--r--src/libstd/sys/wasm/fs.rs10
-rw-r--r--src/libstd/sys/wasm/pipe.rs10
-rw-r--r--src/libstd/sys/wasm/thread.rs3
-rw-r--r--src/libstd/sys/windows/fs.rs10
-rw-r--r--src/libstd/sys/windows/handle.rs14
-rw-r--r--src/libstd/sys/windows/pipe.rs10
-rw-r--r--src/libstd/sys/windows/thread.rs3
-rw-r--r--src/libstd/sys_common/at_exit_imp.rs5
-rw-r--r--src/libstd/sys_common/thread.rs3
-rw-r--r--src/libstd/thread/mod.rs5
32 files changed, 289 insertions, 92 deletions
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 14ff4d72f87..dea198d8c91 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -9,7 +9,7 @@
 
 use crate::fmt;
 use crate::ffi::OsString;
-use crate::io::{self, SeekFrom, Seek, Read, Initializer, Write};
+use crate::io::{self, SeekFrom, Seek, Read, Initializer, Write, IoVec, IoVecMut};
 use crate::path::{Path, PathBuf};
 use crate::sys::fs as fs_imp;
 use crate::sys_common::{AsInnerMut, FromInner, AsInner, IntoInner};
@@ -615,6 +615,10 @@ impl Read for File {
         self.inner.read(buf)
     }
 
+    fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        self.inner.read_vectored(bufs)
+    }
+
     #[inline]
     unsafe fn initializer(&self) -> Initializer {
         Initializer::nop()
@@ -625,6 +629,11 @@ impl Write for File {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.write(buf)
     }
+
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.inner.write_vectored(bufs)
+    }
+
     fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -639,6 +648,10 @@ impl Read for &File {
         self.inner.read(buf)
     }
 
+    fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        self.inner.read_vectored(bufs)
+    }
+
     #[inline]
     unsafe fn initializer(&self) -> Initializer {
         Initializer::nop()
@@ -649,6 +662,11 @@ impl Write for &File {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.write(buf)
     }
+
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.inner.write_vectored(bufs)
+    }
+
     fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 0bbff5769ab..1848ddeab65 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -5,7 +5,7 @@ use crate::io::prelude::*;
 use crate::cell::RefCell;
 use crate::fmt;
 use crate::io::lazy::Lazy;
-use crate::io::{self, Initializer, BufReader, LineWriter};
+use crate::io::{self, Initializer, BufReader, LineWriter, IoVec, IoVecMut};
 use crate::sync::{Arc, Mutex, MutexGuard};
 use crate::sys::stdio;
 use crate::sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
@@ -75,6 +75,10 @@ fn stderr_raw() -> io::Result<StderrRaw> { stdio::Stderr::new().map(StderrRaw) }
 impl Read for StdinRaw {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
 
+    fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        self.0.read_vectored(bufs)
+    }
+
     #[inline]
     unsafe fn initializer(&self) -> Initializer {
         Initializer::nop()
@@ -82,10 +86,20 @@ impl Read for StdinRaw {
 }
 impl Write for StdoutRaw {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.0.write_vectored(bufs)
+    }
+
     fn flush(&mut self) -> io::Result<()> { self.0.flush() }
 }
 impl Write for StderrRaw {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.0.write_vectored(bufs)
+    }
+
     fn flush(&mut self) -> io::Result<()> { self.0.flush() }
 }
 
@@ -102,6 +116,14 @@ impl<W: io::Write> io::Write for Maybe<W> {
         }
     }
 
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        let total = bufs.iter().map(|b| b.len()).sum();
+        match self {
+            Maybe::Real(w) => handle_ebadf(w.write_vectored(bufs), total),
+            Maybe::Fake => Ok(total),
+        }
+    }
+
     fn flush(&mut self) -> io::Result<()> {
         match *self {
             Maybe::Real(ref mut w) => handle_ebadf(w.flush(), ()),
@@ -117,6 +139,13 @@ impl<R: io::Read> io::Read for Maybe<R> {
             Maybe::Fake => Ok(0)
         }
     }
+
+    fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        match self {
+            Maybe::Real(r) => handle_ebadf(r.read_vectored(bufs), 0),
+            Maybe::Fake => Ok(0)
+        }
+    }
 }
 
 fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
@@ -305,6 +334,9 @@ impl Read for Stdin {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.lock().read(buf)
     }
+    fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        self.lock().read_vectored(bufs)
+    }
     #[inline]
     unsafe fn initializer(&self) -> Initializer {
         Initializer::nop()
@@ -325,6 +357,11 @@ impl Read for StdinLock<'_> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
+
+    fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        self.inner.read_vectored(bufs)
+    }
+
     #[inline]
     unsafe fn initializer(&self) -> Initializer {
         Initializer::nop()
@@ -483,6 +520,9 @@ impl Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.lock().write(buf)
     }
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.lock().write_vectored(bufs)
+    }
     fn flush(&mut self) -> io::Result<()> {
         self.lock().flush()
     }
@@ -498,6 +538,9 @@ impl Write for StdoutLock<'_> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.borrow_mut().write(buf)
     }
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.inner.borrow_mut().write_vectored(bufs)
+    }
     fn flush(&mut self) -> io::Result<()> {
         self.inner.borrow_mut().flush()
     }
@@ -636,6 +679,9 @@ impl Write for Stderr {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.lock().write(buf)
     }
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.lock().write_vectored(bufs)
+    }
     fn flush(&mut self) -> io::Result<()> {
         self.lock().flush()
     }
@@ -651,6 +697,9 @@ impl Write for StderrLock<'_> {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.inner.borrow_mut().write(buf)
     }
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.inner.borrow_mut().write_vectored(bufs)
+    }
     fn flush(&mut self) -> io::Result<()> {
         self.inner.borrow_mut().flush()
     }
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index 7b0d1549e06..ffe50f11e8a 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -25,8 +25,7 @@
 ///
 /// For more information on what `as` is capable of, see the [Reference]
 ///
-/// [Reference]:
-/// https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions
+/// [Reference]: ../reference/expressions/operator-expr.html#type-cast-expressions
 /// [`crate`]: keyword.crate.html
 mod as_keyword { }
 
@@ -80,8 +79,8 @@ mod as_keyword { }
 ///
 /// [pointer]: primitive.pointer.html
 /// [Rust Book]:
-/// https://doc.rust-lang.org/stable/book/2018-edition/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants
-/// [Reference]: https://doc.rust-lang.org/reference/items/constant-items.html
+/// ../book/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants
+/// [Reference]: ../reference/items/constant-items.html
 mod const_keyword { }
 
 #[doc(keyword = "crate")]
@@ -114,7 +113,7 @@ mod const_keyword { }
 /// }
 /// ```
 ///
-/// [Reference]: https://doc.rust-lang.org/reference/items/extern-crates.html
+/// [Reference]: ../reference/items/extern-crates.html
 mod crate_keyword { }
 
 #[doc(keyword = "enum")]
@@ -169,8 +168,8 @@ mod crate_keyword { }
 ///
 /// [Algebraic Data Types]: https://en.wikipedia.org/wiki/Algebraic_data_type
 /// [`Option`]: option/enum.Option.html
-/// [Rust Book]: https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html
-/// [Reference]: https://doc.rust-lang.org/reference/items/enumerations.html
+/// [Rust Book]: ../book/ch06-01-defining-an-enum.html
+/// [Reference]: ../reference/items/enumerations.html
 mod enum_keyword { }
 
 #[doc(keyword = "extern")]
@@ -211,8 +210,8 @@ mod enum_keyword { }
 /// For more information on FFI, check the [Rust book] or the [Reference].
 ///
 /// [Rust book]:
-/// https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code
-/// [Reference]: https://doc.rust-lang.org/reference/items/external-blocks.html
+/// ../book/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code
+/// [Reference]: ../reference/items/external-blocks.html
 mod extern_keyword { }
 
 #[doc(keyword = "fn")]
@@ -278,8 +277,8 @@ mod extern_keyword { }
 ///
 /// [`impl`]: keyword.impl.html
 /// [`extern`]: keyword.extern.html
-/// [Rust book]: https://doc.rust-lang.org/book/ch03-03-how-functions-work.html
-/// [Reference]: https://doc.rust-lang.org/reference/items/functions.html
+/// [Rust book]: ../book/ch03-03-how-functions-work.html
+/// [Reference]: ../reference/items/functions.html
 mod fn_keyword { }
 
 #[doc(keyword = "for")]
@@ -352,12 +351,11 @@ mod fn_keyword { }
 /// For more information on for-loops, see the [Rust book] or the [Reference].
 ///
 /// [`impl`]: keyword.impl.html
-/// [higher-ranked trait bounds]:
-/// https://doc.rust-lang.org/nightly/reference/trait-bounds.html#higher-ranked-trait-bounds
+/// [higher-ranked trait bounds]: ../reference/trait-bounds.html#higher-ranked-trait-bounds
 /// [`IntoIterator`]: iter/trait.IntoIterator.html
 /// [Rust book]:
-/// https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for
-/// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops
+/// ../book/ch03-05-control-flow.html#looping-through-a-collection-with-for
+/// [Reference]: ../reference/expressions/loop-expr.html#iterator-loops
 mod for_keyword { }
 
 #[doc(keyword = "if")]
@@ -430,9 +428,8 @@ mod for_keyword { }
 ///
 /// For more information on `if` expressions, see the [Rust book] or the [Reference].
 ///
-/// [Rust book]:
-/// https://doc.rust-lang.org/stable/book/2018-edition/ch03-05-control-flow.html#if-expressions
-/// [Reference]: https://doc.rust-lang.org/reference/expressions/if-expr.html
+/// [Rust book]: ../book/ch03-05-control-flow.html#if-expressions
+/// [Reference]: ../reference/expressions/if-expr.html
 mod if_keyword { }
 
 #[doc(keyword = "impl")]
@@ -493,10 +490,9 @@ mod if_keyword { }
 ///
 /// For more information on `impl Trait` syntax, see the [Rust book][book2].
 ///
-/// [book1]: https://doc.rust-lang.org/stable/book/2018-edition/ch05-03-method-syntax.html
-/// [Reference]: https://doc.rust-lang.org/reference/items/implementations.html
-/// [book2]:
-/// https://doc.rust-lang.org/stable/book/2018-edition/ch10-02-traits.html#returning-traits
+/// [book1]: ../book/ch05-03-method-syntax.html
+/// [Reference]: ../reference/items/implementations.html
+/// [book2]: ../book/ch10-02-traits.html#returning-types-that-implement-traits
 mod impl_keyword { }
 
 #[doc(keyword = "let")]
@@ -554,13 +550,12 @@ mod impl_keyword { }
 /// enumerations. `while let` also exists, which runs a loop with a pattern matched value until
 /// that pattern can't be matched.
 ///
-/// For more information on the `let` keyword, see the [Rust book] or the [Reference]
+/// For more information on the `let` keyword, see the [Rust book][book2] or the [Reference]
 ///
-/// [book1]: https://doc.rust-lang.org/stable/book/2018-edition/ch06-02-match.html
+/// [book1]: ../book/ch06-02-match.html
 /// [`if`]: keyword.if.html
-/// [book2]:
-/// https://doc.rust-lang.org/stable/book/2018-edition/ch18-01-all-the-places-for-patterns.html#let-statements
-/// [Reference]: https://doc.rust-lang.org/reference/statements.html#let-statements
+/// [book2]: ../book/ch18-01-all-the-places-for-patterns.html#let-statements
+/// [Reference]: ../reference/statements.html#let-statements
 mod let_keyword { }
 
 #[doc(keyword = "loop")]
@@ -605,7 +600,7 @@ mod let_keyword { }
 ///
 /// For more information on `loop` and loops in general, see the [Reference].
 ///
-/// [Reference]: https://doc.rust-lang.org/reference/expressions/loop-expr.html
+/// [Reference]: ../reference/expressions/loop-expr.html
 mod loop_keyword { }
 
 #[doc(keyword = "struct")]
@@ -712,6 +707,6 @@ mod loop_keyword { }
 /// [Reference][reference].
 ///
 /// [`PhantomData`]: marker/struct.PhantomData.html
-/// [book]: https://doc.rust-lang.org/book/ch05-01-defining-structs.html
-/// [reference]: https://doc.rust-lang.org/reference/items/structs.html
+/// [book]: ../book/ch05-01-defining-structs.html
+/// [reference]: ../reference/items/structs.html
 mod struct_keyword { }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index d11dee8fc97..ee6ba3f438f 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -229,7 +229,6 @@
 #![feature(align_offset)]
 #![feature(alloc_error_handler)]
 #![feature(alloc_layout_extra)]
-#![feature(alloc)]
 #![feature(allocator_api)]
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
diff --git a/src/libstd/num.rs b/src/libstd/num.rs
index 828d5720eec..d67d0b55a79 100644
--- a/src/libstd/num.rs
+++ b/src/libstd/num.rs
@@ -13,6 +13,8 @@ pub use core::num::Wrapping;
 
 #[stable(feature = "nonzero", since = "1.28.0")]
 pub use core::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize};
+#[stable(feature = "signed_nonzero", since = "1.34.0")]
+pub use core::num::{NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize};
 
 #[cfg(test)] use crate::fmt;
 #[cfg(test)] use crate::ops::{Add, Sub, Mul, Div, Rem};
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index e0c9b7cad86..ef5626700e8 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -111,7 +111,7 @@ use crate::io::prelude::*;
 use crate::ffi::OsStr;
 use crate::fmt;
 use crate::fs;
-use crate::io::{self, Initializer};
+use crate::io::{self, Initializer, IoVec, IoVecMut};
 use crate::path::Path;
 use crate::str;
 use crate::sys::pipe::{read2, AnonPipe};
@@ -225,6 +225,10 @@ impl Write for ChildStdin {
         self.inner.write(buf)
     }
 
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.inner.write_vectored(bufs)
+    }
+
     fn flush(&mut self) -> io::Result<()> {
         Ok(())
     }
@@ -271,6 +275,11 @@ impl Read for ChildStdout {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
+
+    fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        self.inner.read_vectored(bufs)
+    }
+
     #[inline]
     unsafe fn initializer(&self) -> Initializer {
         Initializer::nop()
@@ -318,6 +327,11 @@ impl Read for ChildStderr {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
+
+    fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        self.inner.read_vectored(bufs)
+    }
+
     #[inline]
     unsafe fn initializer(&self) -> Initializer {
         Initializer::nop()
diff --git a/src/libstd/sys/cloudabi/shims/fs.rs b/src/libstd/sys/cloudabi/shims/fs.rs
index ee045b8e515..abd7f0fd3ee 100644
--- a/src/libstd/sys/cloudabi/shims/fs.rs
+++ b/src/libstd/sys/cloudabi/shims/fs.rs
@@ -1,7 +1,7 @@
 use crate::ffi::OsString;
 use crate::fmt;
 use crate::hash::{Hash, Hasher};
-use crate::io::{self, SeekFrom};
+use crate::io::{self, SeekFrom, IoVec, IoVecMut};
 use crate::path::{Path, PathBuf};
 use crate::sys::time::SystemTime;
 use crate::sys::{unsupported, Void};
@@ -198,10 +198,18 @@ impl File {
         match self.0 {}
     }
 
+    pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
         match self.0 {}
     }
 
+    pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn flush(&self) -> io::Result<()> {
         match self.0 {}
     }
diff --git a/src/libstd/sys/cloudabi/shims/pipe.rs b/src/libstd/sys/cloudabi/shims/pipe.rs
index f3debb95047..804d3e001ac 100644
--- a/src/libstd/sys/cloudabi/shims/pipe.rs
+++ b/src/libstd/sys/cloudabi/shims/pipe.rs
@@ -1,4 +1,4 @@
-use crate::io;
+use crate::io::{self, IoVec, IoVecMut};
 use crate::sys::Void;
 
 pub struct AnonPipe(Void);
@@ -8,10 +8,18 @@ impl AnonPipe {
         match self.0 {}
     }
 
+    pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
         match self.0 {}
     }
 
+    pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn diverge(&self) -> ! {
         match self.0 {}
     }
diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs
index f853346e0e6..7da16c4d247 100644
--- a/src/libstd/sys/cloudabi/thread.rs
+++ b/src/libstd/sys/cloudabi/thread.rs
@@ -1,4 +1,3 @@
-use crate::boxed::FnBox;
 use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
@@ -22,7 +21,7 @@ unsafe impl Sync for Thread {}
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>) -> io::Result<Thread> {
+    pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
         let p = box p;
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
diff --git a/src/libstd/sys/redox/fs.rs b/src/libstd/sys/redox/fs.rs
index ebefbc94210..c86c6000eae 100644
--- a/src/libstd/sys/redox/fs.rs
+++ b/src/libstd/sys/redox/fs.rs
@@ -2,7 +2,7 @@ use crate::os::unix::prelude::*;
 
 use crate::ffi::{OsString, OsStr};
 use crate::fmt;
-use crate::io::{self, Error, SeekFrom};
+use crate::io::{self, Error, SeekFrom, IoVec, IoVecMut};
 use crate::path::{Path, PathBuf};
 use crate::sync::Arc;
 use crate::sys::fd::FileDesc;
@@ -278,10 +278,18 @@ impl File {
         self.0.read(buf)
     }
 
+    pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        crate::io::default_read_vectored(|buf| self.read(buf), bufs)
+    }
+
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
         self.0.write(buf)
     }
 
+    pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        crate::io::default_write_vectored(|buf| self.write(buf), bufs)
+    }
+
     pub fn flush(&self) -> io::Result<()> { Ok(()) }
 
     pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
diff --git a/src/libstd/sys/redox/pipe.rs b/src/libstd/sys/redox/pipe.rs
index 911ba9c3f65..b926968f7b3 100644
--- a/src/libstd/sys/redox/pipe.rs
+++ b/src/libstd/sys/redox/pipe.rs
@@ -1,4 +1,4 @@
-use crate::io;
+use crate::io::{self, IoVec, IoVecMut};
 use crate::sys::{cvt, syscall};
 use crate::sys::fd::FileDesc;
 
@@ -24,10 +24,18 @@ impl AnonPipe {
         self.0.read(buf)
     }
 
+    pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        crate::io::default_read_vectored(|buf| self.read(buf), bufs)
+    }
+
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
         self.0.write(buf)
     }
 
+    pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        crate::io::default_write_vectored(|buf| self.write(buf), bufs)
+    }
+
     pub fn fd(&self) -> &FileDesc { &self.0 }
     pub fn into_fd(self) -> FileDesc { self.0 }
 }
diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs
index ae0b91b4d6c..9d40a7e8bb8 100644
--- a/src/libstd/sys/redox/thread.rs
+++ b/src/libstd/sys/redox/thread.rs
@@ -1,4 +1,3 @@
-use crate::boxed::FnBox;
 use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
@@ -19,7 +18,7 @@ unsafe impl Sync for Thread {}
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(_stack: usize, p: Box<dyn FnBox()>) -> io::Result<Thread> {
+    pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
         let p = box p;
 
         let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?;
diff --git a/src/libstd/sys/sgx/fs.rs b/src/libstd/sys/sgx/fs.rs
index 68c8e9356a8..c3c898eb23e 100644
--- a/src/libstd/sys/sgx/fs.rs
+++ b/src/libstd/sys/sgx/fs.rs
@@ -1,7 +1,7 @@
 use crate::ffi::OsString;
 use crate::fmt;
 use crate::hash::{Hash, Hasher};
-use crate::io::{self, SeekFrom};
+use crate::io::{self, SeekFrom, IoVec, IoVecMut};
 use crate::path::{Path, PathBuf};
 use crate::sys::time::SystemTime;
 use crate::sys::{unsupported, Void};
@@ -200,10 +200,18 @@ impl File {
         match self.0 {}
     }
 
+    pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
         match self.0 {}
     }
 
+    pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn flush(&self) -> io::Result<()> {
         match self.0 {}
     }
diff --git a/src/libstd/sys/sgx/pipe.rs b/src/libstd/sys/sgx/pipe.rs
index 2582b993b60..804d3e001ac 100644
--- a/src/libstd/sys/sgx/pipe.rs
+++ b/src/libstd/sys/sgx/pipe.rs
@@ -1,4 +1,4 @@
-use crate::io;
+use crate::io::{self, IoVec, IoVecMut};
 use crate::sys::Void;
 
 pub struct AnonPipe(Void);
@@ -8,18 +8,23 @@ impl AnonPipe {
         match self.0 {}
     }
 
+    pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
         match self.0 {}
     }
 
+    pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn diverge(&self) -> ! {
         match self.0 {}
     }
 }
 
-pub fn read2(p1: AnonPipe,
-             _v1: &mut Vec<u8>,
-             _p2: AnonPipe,
-             _v2: &mut Vec<u8>) -> io::Result<()> {
+pub fn read2(p1: AnonPipe, _v1: &mut Vec<u8>, _p2: AnonPipe, _v2: &mut Vec<u8>) -> io::Result<()> {
     match p1.0 {}
 }
diff --git a/src/libstd/sys/sgx/thread.rs b/src/libstd/sys/sgx/thread.rs
index 565a523ebe0..b9f42d4ad1c 100644
--- a/src/libstd/sys/sgx/thread.rs
+++ b/src/libstd/sys/sgx/thread.rs
@@ -1,5 +1,4 @@
 #![cfg_attr(test, allow(dead_code))] // why is this necessary?
-use crate::boxed::FnBox;
 use crate::ffi::CStr;
 use crate::io;
 use crate::time::Duration;
@@ -13,17 +12,16 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
 mod task_queue {
     use crate::sync::{Mutex, MutexGuard, Once};
     use crate::sync::mpsc;
-    use crate::boxed::FnBox;
 
     pub type JoinHandle = mpsc::Receiver<()>;
 
     pub(super) struct Task {
-        p: Box<dyn FnBox()>,
+        p: Box<dyn FnOnce()>,
         done: mpsc::Sender<()>,
     }
 
     impl Task {
-        pub(super) fn new(p: Box<dyn FnBox()>) -> (Task, JoinHandle) {
+        pub(super) fn new(p: Box<dyn FnOnce()>) -> (Task, JoinHandle) {
             let (done, recv) = mpsc::channel();
             (Task { p, done }, recv)
         }
@@ -51,7 +49,7 @@ mod task_queue {
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(_stack: usize, p: Box<dyn FnBox()>)
+    pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>)
         -> io::Result<Thread>
     {
         let mut queue_lock = task_queue::lock();
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index dc3dcb5817c..a14db108c34 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -2,7 +2,7 @@ use crate::os::unix::prelude::*;
 
 use crate::ffi::{CString, CStr, OsString, OsStr};
 use crate::fmt;
-use crate::io::{self, Error, ErrorKind, SeekFrom};
+use crate::io::{self, Error, ErrorKind, SeekFrom, IoVec, IoVecMut};
 use crate::mem;
 use crate::path::{Path, PathBuf};
 use crate::ptr;
@@ -560,6 +560,10 @@ impl File {
         self.0.read(buf)
     }
 
+    pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        self.0.read_vectored(bufs)
+    }
+
     pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
         self.0.read_at(buf, offset)
     }
@@ -568,6 +572,10 @@ impl File {
         self.0.write(buf)
     }
 
+    pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.0.write_vectored(bufs)
+    }
+
     pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
         self.0.write_at(buf, offset)
     }
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index bc3c026adab..a7792d42af9 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -1,4 +1,4 @@
-use crate::io;
+use crate::io::{self, IoVec, IoVecMut};
 use crate::mem;
 use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sys::fd::FileDesc;
@@ -60,10 +60,18 @@ impl AnonPipe {
         self.0.read(buf)
     }
 
+    pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        self.0.read_vectored(bufs)
+    }
+
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
         self.0.write(buf)
     }
 
+    pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.0.write_vectored(bufs)
+    }
+
     pub fn fd(&self) -> &FileDesc { &self.0 }
     pub fn into_fd(self) -> FileDesc { self.0 }
 }
diff --git a/src/libstd/sys/unix/stdio.rs b/src/libstd/sys/unix/stdio.rs
index 35f163bbdb1..bc2986f624e 100644
--- a/src/libstd/sys/unix/stdio.rs
+++ b/src/libstd/sys/unix/stdio.rs
@@ -1,5 +1,6 @@
-use crate::io;
+use crate::io::{self, IoVec, IoVecMut};
 use crate::sys::fd::FileDesc;
+use crate::mem::ManuallyDrop;
 
 pub struct Stdin(());
 pub struct Stdout(());
@@ -11,10 +12,11 @@ impl Stdin {
 
 impl io::Read for Stdin {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        let fd = FileDesc::new(libc::STDIN_FILENO);
-        let ret = fd.read(buf);
-        fd.into_raw(); // do not close this FD
-        ret
+        ManuallyDrop::new(FileDesc::new(libc::STDIN_FILENO)).read(buf)
+    }
+
+    fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        ManuallyDrop::new(FileDesc::new(libc::STDIN_FILENO)).read_vectored(bufs)
     }
 }
 
@@ -24,10 +26,11 @@ impl Stdout {
 
 impl io::Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        let fd = FileDesc::new(libc::STDOUT_FILENO);
-        let ret = fd.write(buf);
-        fd.into_raw(); // do not close this FD
-        ret
+        ManuallyDrop::new(FileDesc::new(libc::STDOUT_FILENO)).write(buf)
+    }
+
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        ManuallyDrop::new(FileDesc::new(libc::STDOUT_FILENO)).write_vectored(bufs)
     }
 
     fn flush(&mut self) -> io::Result<()> {
@@ -41,10 +44,11 @@ impl Stderr {
 
 impl io::Write for Stderr {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        let fd = FileDesc::new(libc::STDERR_FILENO);
-        let ret = fd.write(buf);
-        fd.into_raw(); // do not close this FD
-        ret
+        ManuallyDrop::new(FileDesc::new(libc::STDERR_FILENO)).write(buf)
+    }
+
+    fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        ManuallyDrop::new(FileDesc::new(libc::STDERR_FILENO)).write_vectored(bufs)
     }
 
     fn flush(&mut self) -> io::Result<()> {
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index feb15e8f585..f7d604ac4c8 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -1,4 +1,3 @@
-use crate::boxed::FnBox;
 use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
@@ -39,7 +38,7 @@ unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t,
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>)
+    pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
                           -> io::Result<Thread> {
         let p = box p;
         let mut native: libc::pthread_t = mem::zeroed();
diff --git a/src/libstd/sys/wasi/pipe.rs b/src/libstd/sys/wasi/pipe.rs
index 2582b993b60..aa6bf8076f6 100644
--- a/src/libstd/sys/wasi/pipe.rs
+++ b/src/libstd/sys/wasi/pipe.rs
@@ -1,4 +1,4 @@
-use crate::io;
+use crate::io::{self, IoVec, IoVecMut};
 use crate::sys::Void;
 
 pub struct AnonPipe(Void);
@@ -8,10 +8,18 @@ impl AnonPipe {
         match self.0 {}
     }
 
+    pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
         match self.0 {}
     }
 
+    pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn diverge(&self) -> ! {
         match self.0 {}
     }
diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs
index 19294788666..bdad4084891 100644
--- a/src/libstd/sys/wasi/stdio.rs
+++ b/src/libstd/sys/wasi/stdio.rs
@@ -13,8 +13,12 @@ impl Stdin {
     }
 
     pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
+        self.read_vectored(&mut [IoVecMut::new(data)])
+    }
+
+    pub fn read_vectored(&self, data: &mut [IoVecMut<'_>]) -> io::Result<usize> {
         ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) })
-            .read(&mut [IoVecMut::new(data)])
+            .read(data)
     }
 }
 
@@ -24,8 +28,12 @@ impl Stdout {
     }
 
     pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        self.write_vectored(&[IoVec::new(data)])
+    }
+
+    pub fn write_vectored(&self, data: &[IoVec<'_>]) -> io::Result<usize> {
         ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDOUT_FILENO as u32) })
-            .write(&[IoVec::new(data)])
+            .write(data)
     }
 
     pub fn flush(&self) -> io::Result<()> {
@@ -39,8 +47,12 @@ impl Stderr {
     }
 
     pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+        self.write_vectored(&[IoVec::new(data)])
+    }
+
+    pub fn write_vectored(&self, data: &[IoVec<'_>]) -> io::Result<usize> {
         ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDERR_FILENO as u32) })
-            .write(&[IoVec::new(data)])
+            .write(data)
     }
 
     pub fn flush(&self) -> io::Result<()> {
diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs
index 9d3c6ac59d1..5e69e4d948f 100644
--- a/src/libstd/sys/wasi/thread.rs
+++ b/src/libstd/sys/wasi/thread.rs
@@ -1,4 +1,3 @@
-use crate::boxed::FnBox;
 use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
@@ -13,7 +12,7 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(_stack: usize, _p: Box<dyn FnBox()>)
+    pub unsafe fn new(_stack: usize, _p: Box<dyn FnOnce()>)
         -> io::Result<Thread>
     {
         unsupported()
diff --git a/src/libstd/sys/wasm/fs.rs b/src/libstd/sys/wasm/fs.rs
index 68c8e9356a8..c3c898eb23e 100644
--- a/src/libstd/sys/wasm/fs.rs
+++ b/src/libstd/sys/wasm/fs.rs
@@ -1,7 +1,7 @@
 use crate::ffi::OsString;
 use crate::fmt;
 use crate::hash::{Hash, Hasher};
-use crate::io::{self, SeekFrom};
+use crate::io::{self, SeekFrom, IoVec, IoVecMut};
 use crate::path::{Path, PathBuf};
 use crate::sys::time::SystemTime;
 use crate::sys::{unsupported, Void};
@@ -200,10 +200,18 @@ impl File {
         match self.0 {}
     }
 
+    pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
         match self.0 {}
     }
 
+    pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn flush(&self) -> io::Result<()> {
         match self.0 {}
     }
diff --git a/src/libstd/sys/wasm/pipe.rs b/src/libstd/sys/wasm/pipe.rs
index 2582b993b60..aa6bf8076f6 100644
--- a/src/libstd/sys/wasm/pipe.rs
+++ b/src/libstd/sys/wasm/pipe.rs
@@ -1,4 +1,4 @@
-use crate::io;
+use crate::io::{self, IoVec, IoVecMut};
 use crate::sys::Void;
 
 pub struct AnonPipe(Void);
@@ -8,10 +8,18 @@ impl AnonPipe {
         match self.0 {}
     }
 
+    pub fn read_vectored(&self, _bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
         match self.0 {}
     }
 
+    pub fn write_vectored(&self, _bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        match self.0 {}
+    }
+
     pub fn diverge(&self) -> ! {
         match self.0 {}
     }
diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs
index a65c413119f..1dc786cd5d7 100644
--- a/src/libstd/sys/wasm/thread.rs
+++ b/src/libstd/sys/wasm/thread.rs
@@ -1,4 +1,3 @@
-use crate::boxed::FnBox;
 use crate::ffi::CStr;
 use crate::io;
 use crate::sys::{unsupported, Void};
@@ -10,7 +9,7 @@ pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(_stack: usize, _p: Box<dyn FnBox()>)
+    pub unsafe fn new(_stack: usize, _p: Box<dyn FnOnce()>)
         -> io::Result<Thread>
     {
         unsupported()
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index 4ebbb0707f7..1d8e47a4793 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -2,7 +2,7 @@ use crate::os::windows::prelude::*;
 
 use crate::ffi::OsString;
 use crate::fmt;
-use crate::io::{self, Error, SeekFrom};
+use crate::io::{self, Error, SeekFrom, IoVec, IoVecMut};
 use crate::mem;
 use crate::path::{Path, PathBuf};
 use crate::ptr;
@@ -314,6 +314,10 @@ impl File {
         self.handle.read(buf)
     }
 
+    pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        self.handle.read_vectored(bufs)
+    }
+
     pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
         self.handle.read_at(buf, offset)
     }
@@ -322,6 +326,10 @@ impl File {
         self.handle.write(buf)
     }
 
+    pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.handle.write_vectored(bufs)
+    }
+
     pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
         self.handle.write_at(buf, offset)
     }
diff --git a/src/libstd/sys/windows/handle.rs b/src/libstd/sys/windows/handle.rs
index 02549088c87..c3fa6c4e0bd 100644
--- a/src/libstd/sys/windows/handle.rs
+++ b/src/libstd/sys/windows/handle.rs
@@ -1,7 +1,7 @@
 #![unstable(issue = "0", feature = "windows_handle")]
 
 use crate::cmp;
-use crate::io::{self, ErrorKind, Read};
+use crate::io::{self, ErrorKind, Read, IoVec, IoVecMut};
 use crate::mem;
 use crate::ops::Deref;
 use crate::ptr;
@@ -89,6 +89,10 @@ impl RawHandle {
         }
     }
 
+    pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        crate::io::default_read_vectored(|buf| self.read(buf), bufs)
+    }
+
     pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
         let mut read = 0;
         let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
@@ -169,6 +173,10 @@ impl RawHandle {
         Ok(amt as usize)
     }
 
+    pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        crate::io::default_write_vectored(|buf| self.write(buf), bufs)
+    }
+
     pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
         let mut written = 0;
         let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
@@ -199,4 +207,8 @@ impl<'a> Read for &'a RawHandle {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         (**self).read(buf)
     }
+
+    fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        (**self).read_vectored(bufs)
+    }
 }
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index b38727830f3..6613d3a0567 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -1,7 +1,7 @@
 use crate::os::windows::prelude::*;
 
 use crate::ffi::OsStr;
-use crate::io;
+use crate::io::{self, IoVec, IoVecMut};
 use crate::mem;
 use crate::path::Path;
 use crate::ptr;
@@ -166,9 +166,17 @@ impl AnonPipe {
         self.inner.read(buf)
     }
 
+    pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result<usize> {
+        self.inner.read_vectored(bufs)
+    }
+
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
         self.inner.write(buf)
     }
+
+    pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result<usize> {
+        self.inner.write_vectored(bufs)
+    }
 }
 
 pub fn read2(p1: AnonPipe,
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index 1b0a811f13b..ebdf3612e06 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -1,4 +1,3 @@
-use crate::boxed::FnBox;
 use crate::io;
 use crate::ffi::CStr;
 use crate::mem;
@@ -20,7 +19,7 @@ pub struct Thread {
 
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(stack: usize, p: Box<dyn FnBox()>)
+    pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
                           -> io::Result<Thread> {
         let p = box p;
 
diff --git a/src/libstd/sys_common/at_exit_imp.rs b/src/libstd/sys_common/at_exit_imp.rs
index 1181b861611..cdb72ee872e 100644
--- a/src/libstd/sys_common/at_exit_imp.rs
+++ b/src/libstd/sys_common/at_exit_imp.rs
@@ -2,12 +2,11 @@
 //!
 //! Documentation can be found on the `rt::at_exit` function.
 
-use crate::boxed::FnBox;
 use crate::ptr;
 use crate::mem;
 use crate::sys_common::mutex::Mutex;
 
-type Queue = Vec<Box<dyn FnBox()>>;
+type Queue = Vec<Box<dyn FnOnce()>>;
 
 // NB these are specifically not types from `std::sync` as they currently rely
 // on poisoning and this module needs to operate at a lower level than requiring
@@ -61,7 +60,7 @@ pub fn cleanup() {
     }
 }
 
-pub fn push(f: Box<dyn FnBox()>) -> bool {
+pub fn push(f: Box<dyn FnOnce()>) -> bool {
     unsafe {
         let _guard = LOCK.lock();
         if init() {
diff --git a/src/libstd/sys_common/thread.rs b/src/libstd/sys_common/thread.rs
index b2142e75308..6ab0d5cbe9c 100644
--- a/src/libstd/sys_common/thread.rs
+++ b/src/libstd/sys_common/thread.rs
@@ -1,4 +1,3 @@
-use crate::boxed::FnBox;
 use crate::env;
 use crate::sync::atomic::{self, Ordering};
 use crate::sys::stack_overflow;
@@ -11,7 +10,7 @@ pub unsafe fn start_thread(main: *mut u8) {
     let _handler = stack_overflow::Handler::new();
 
     // Finally, let's run some code.
-    Box::from_raw(main as *mut Box<dyn FnBox()>)()
+    Box::from_raw(main as *mut Box<dyn FnOnce()>)()
 }
 
 pub fn min_stack() -> usize {
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index cb507971091..c59226e0c0b 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -157,7 +157,6 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::any::Any;
-use crate::boxed::FnBox;
 use crate::cell::UnsafeCell;
 use crate::ffi::{CStr, CString};
 use crate::fmt;
@@ -488,7 +487,9 @@ impl Builder {
             // returning.
             native: Some(imp::Thread::new(
                 stack_size,
-                mem::transmute::<Box<dyn FnBox() + 'a>, Box<dyn FnBox() + 'static>>(Box::new(main))
+                mem::transmute::<Box<dyn FnOnce() + 'a>, Box<dyn FnOnce() + 'static>>(Box::new(
+                    main,
+                )),
             )?),
             thread: my_thread,
             packet: Packet(my_packet),