about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2019-05-21 15:37:07 -0700
committerAlex Crichton <alex@alexcrichton.com>2019-05-21 15:37:07 -0700
commitfe3dd0b50fef21d14591c960a9610bafb224cdbf (patch)
treeee0b62d8e500d4ce4b6f50b4fe5d9056b9826072 /src/libstd
parente764f475ca7fffd6167ea991afc7d1b2b3f642dc (diff)
parent50a0defd5a93523067ef239936cc2e0755220904 (diff)
downloadrust-fe3dd0b50fef21d14591c960a9610bafb224cdbf.tar.gz
rust-fe3dd0b50fef21d14591c960a9610bafb224cdbf.zip
Merge remote-tracking branch 'origin/master' into azure-pipelines
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/Cargo.toml6
-rw-r--r--src/libstd/alloc.rs5
-rw-r--r--src/libstd/build.rs3
-rw-r--r--src/libstd/collections/hash/map.rs11
-rw-r--r--src/libstd/collections/hash/set.rs56
-rw-r--r--src/libstd/env.rs7
-rw-r--r--src/libstd/error.rs35
-rw-r--r--src/libstd/ffi/c_str.rs9
-rw-r--r--src/libstd/ffi/os_str.rs2
-rw-r--r--src/libstd/fs.rs2
-rw-r--r--src/libstd/io/buffered.rs2
-rw-r--r--src/libstd/io/mod.rs13
-rw-r--r--src/libstd/keyword_docs.rs294
-rw-r--r--src/libstd/lib.rs2
-rw-r--r--src/libstd/macros.rs55
-rw-r--r--src/libstd/net/addr.rs17
-rw-r--r--src/libstd/net/tcp.rs4
-rw-r--r--src/libstd/net/udp.rs4
-rw-r--r--src/libstd/os/bitrig/fs.rs138
-rw-r--r--src/libstd/os/bitrig/mod.rs6
-rw-r--r--src/libstd/os/bitrig/raw.rs71
-rw-r--r--src/libstd/os/mod.rs1
-rw-r--r--src/libstd/path.rs10
-rw-r--r--src/libstd/sync/mpsc/mod.rs85
-rw-r--r--src/libstd/sync/mpsc/oneshot.rs72
-rw-r--r--src/libstd/sync/mpsc/select.rs352
-rw-r--r--src/libstd/sync/mpsc/select_tests.rs413
-rw-r--r--src/libstd/sync/mpsc/shared.rs35
-rw-r--r--src/libstd/sync/mpsc/stream.rs53
-rw-r--r--src/libstd/sync/mpsc/sync.rs37
-rw-r--r--src/libstd/sync/mutex.rs2
-rw-r--r--src/libstd/sync/rwlock.rs2
-rw-r--r--src/libstd/sys/unix/args.rs3
-rw-r--r--src/libstd/sys/unix/env.rs11
-rw-r--r--src/libstd/sys/unix/ext/net.rs4
-rw-r--r--src/libstd/sys/unix/fs.rs10
-rw-r--r--src/libstd/sys/unix/mod.rs1
-rw-r--r--src/libstd/sys/unix/os.rs5
-rw-r--r--src/libstd/sys/unix/rand.rs12
-rw-r--r--src/libstd/sys/unix/stack_overflow.rs3
-rw-r--r--src/libstd/sys/unix/thread.rs9
-rw-r--r--src/libstd/sys/wasm/args.rs4
-rw-r--r--src/libstd/sys/windows/args.rs2
-rw-r--r--src/libstd/sys_common/net.rs4
-rw-r--r--src/libstd/thread/mod.rs1
45 files changed, 476 insertions, 1397 deletions
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index ad5d62f667a..55e8b39974e 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -3,7 +3,7 @@ authors = ["The Rust Project Developers"]
 name = "std"
 version = "0.0.0"
 build = "build.rs"
-license = "MIT/Apache-2.0"
+license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust.git"
 description = "The Rust Standard Library"
 edition = "2018"
@@ -19,7 +19,7 @@ panic_unwind = { path = "../libpanic_unwind", optional = true }
 panic_abort = { path = "../libpanic_abort" }
 core = { path = "../libcore" }
 libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of-std'] }
-compiler_builtins = { version = "0.1.12" }
+compiler_builtins = { version = "0.1.14" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 hashbrown = { version = "0.3.0", features = ['rustc-dep-of-std'] }
@@ -54,7 +54,7 @@ default = ["compiler_builtins_c", "std_detect_file_io", "std_detect_dlsym_getaux
 backtrace = ["backtrace-sys"]
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
-compiler_builtins_c = ["compiler_builtins/c"]
+compiler_builtins_c = ["alloc/compiler-builtins-c"]
 llvm-libunwind = ["unwind/llvm-libunwind"]
 
 # Make panics and failed asserts immediately abort without formatting any message
diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs
index 4241f47b661..ff52974775b 100644
--- a/src/libstd/alloc.rs
+++ b/src/libstd/alloc.rs
@@ -173,6 +173,9 @@ static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
 /// about the allocation that failed.
 ///
 /// The allocation error hook is a global resource.
+///
+/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html
+/// [`take_alloc_error_hook`]: fn.take_alloc_error_hook.html
 #[unstable(feature = "alloc_error_hook", issue = "51245")]
 pub fn set_alloc_error_hook(hook: fn(Layout)) {
     HOOK.store(hook as *mut (), Ordering::SeqCst);
@@ -183,6 +186,8 @@ pub fn set_alloc_error_hook(hook: fn(Layout)) {
 /// *See also the function [`set_alloc_error_hook`].*
 ///
 /// If no custom hook is registered, the default hook will be returned.
+///
+/// [`set_alloc_error_hook`]: fn.set_alloc_error_hook.html
 #[unstable(feature = "alloc_error_hook", issue = "51245")]
 pub fn take_alloc_error_hook() -> fn(Layout) {
     let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst);
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index 726c2732153..7a6c97ebaa2 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -20,8 +20,7 @@ fn main() {
     } else if target.contains("netbsd") {
         println!("cargo:rustc-link-lib=pthread");
         println!("cargo:rustc-link-lib=rt");
-    } else if target.contains("dragonfly") || target.contains("bitrig") ||
-              target.contains("openbsd") {
+    } else if target.contains("dragonfly") || target.contains("openbsd") {
         println!("cargo:rustc-link-lib=pthread");
     } else if target.contains("solaris") {
         println!("cargo:rustc-link-lib=socket");
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index f9fb392f9f5..5a2fe2b244f 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -1225,11 +1225,13 @@ pub struct RawEntryBuilderMut<'a, K: 'a, V: 'a, S: 'a> {
 ///
 /// This is a lower-level version of [`Entry`].
 ///
-/// This `enum` is constructed from the [`raw_entry`] method on [`HashMap`].
+/// This `enum` is constructed through the [`raw_entry_mut`] method on [`HashMap`],
+/// then calling one of the methods of that [`RawEntryBuilderMut`].
 ///
 /// [`HashMap`]: struct.HashMap.html
 /// [`Entry`]: enum.Entry.html
-/// [`raw_entry`]: struct.HashMap.html#method.raw_entry
+/// [`raw_entry_mut`]: struct.HashMap.html#method.raw_entry_mut
+/// [`RawEntryBuilderMut`]: struct.RawEntryBuilderMut.html
 #[unstable(feature = "hash_raw_entry", issue = "56167")]
 pub enum RawEntryMut<'a, K: 'a, V: 'a, S: 'a> {
     /// An occupied entry.
@@ -2492,7 +2494,10 @@ impl DefaultHasher {
 
 #[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
 impl Default for DefaultHasher {
-    /// Creates a new `DefaultHasher` using [`new`][DefaultHasher::new].
+    // FIXME: here should link `new` to [DefaultHasher::new], but it occurs intra-doc link
+    // resolution failure when re-exporting libstd items. When #56922 fixed,
+    // link `new` to [DefaultHasher::new] again.
+    /// Creates a new `DefaultHasher` using `new`.
     /// See its documentation for more.
     fn default() -> DefaultHasher {
         DefaultHasher::new()
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index b56a27c80bc..403914c0707 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -618,6 +618,62 @@ impl<T, S> HashSet<T, S>
         self.map.get_key_value(value).map(|(k, _)| k)
     }
 
+    /// Inserts the given `value` into the set if it is not present, then
+    /// returns a reference to the value in the set.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+    /// assert_eq!(set.len(), 3);
+    /// assert_eq!(set.get_or_insert(2), &2);
+    /// assert_eq!(set.get_or_insert(100), &100);
+    /// assert_eq!(set.len(), 4); // 100 was inserted
+    /// ```
+    #[inline]
+    #[unstable(feature = "hash_set_entry", issue = "60896")]
+    pub fn get_or_insert(&mut self, value: T) -> &T {
+        // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
+        // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
+        self.map.raw_entry_mut().from_key(&value).or_insert(value, ()).0
+    }
+
+    /// Inserts a value computed from `f` into the set if the given `value` is
+    /// not present, then returns a reference to the value in the set.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(hash_set_entry)]
+    ///
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set: HashSet<String> = ["cat", "dog", "horse"]
+    ///     .iter().map(|&pet| pet.to_owned()).collect();
+    ///
+    /// assert_eq!(set.len(), 3);
+    /// for &pet in &["cat", "dog", "fish"] {
+    ///     let value = set.get_or_insert_with(pet, str::to_owned);
+    ///     assert_eq!(value, pet);
+    /// }
+    /// assert_eq!(set.len(), 4); // a new "fish" was inserted
+    /// ```
+    #[inline]
+    #[unstable(feature = "hash_set_entry", issue = "60896")]
+    pub fn get_or_insert_with<Q: ?Sized, F>(&mut self, value: &Q, f: F) -> &T
+        where T: Borrow<Q>,
+              Q: Hash + Eq,
+              F: FnOnce(&Q) -> T
+    {
+        // Although the raw entry gives us `&mut T`, we only return `&T` to be consistent with
+        // `get`. Key mutation is "raw" because you're not supposed to affect `Eq` or `Hash`.
+        self.map.raw_entry_mut().from_key(value).or_insert_with(|| (f(value), ())).0
+    }
+
     /// Returns `true` if `self` has no elements in common with `other`.
     /// This is equivalent to checking for an empty intersection.
     ///
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index c0d0c23e469..260624a8bd8 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -746,6 +746,10 @@ impl Iterator for Args {
         self.inner.next().map(|s| s.into_string().unwrap())
     }
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+    #[inline]
+    fn last(mut self) -> Option<String> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "env", since = "1.0.0")]
@@ -781,6 +785,8 @@ impl Iterator for ArgsOs {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> { self.inner.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
+    #[inline]
+    fn last(mut self) -> Option<OsString> { self.next_back() }
 }
 
 #[stable(feature = "env", since = "1.0.0")]
@@ -845,7 +851,6 @@ pub mod consts {
     /// - ios
     /// - freebsd
     /// - dragonfly
-    /// - bitrig
     /// - netbsd
     /// - openbsd
     /// - solaris
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 081fff0562b..aeb822fa99e 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -197,16 +197,29 @@ pub trait Error: Debug + Display {
     fn source(&self) -> Option<&(dyn Error + 'static)> { None }
 
     /// Gets the `TypeId` of `self`
-    #[stable(feature = "error_type_id", since = "1.34.0")]
-    fn type_id(&self) -> TypeId where Self: 'static {
+    #[doc(hidden)]
+    #[unstable(feature = "error_type_id",
+               reason = "this is memory unsafe to override in user code",
+               issue = "60784")]
+    fn type_id(&self, _: private::Internal) -> TypeId where Self: 'static {
         TypeId::of::<Self>()
     }
 }
 
+mod private {
+    // This is a hack to prevent `type_id` from being overridden by `Error`
+    // implementations, since that can enable unsound downcasting.
+    #[unstable(feature = "error_type_id", issue = "60784")]
+    #[derive(Debug)]
+    pub struct Internal;
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
     /// Converts a type of [`Error`] into a box of dyn [`Error`].
     ///
+    /// [`Error`]: ../error/trait.Error.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -244,6 +257,8 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync +
     /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of dyn [`Error`] +
     /// [`Send`] + [`Sync`].
     ///
+    /// [`Error`]: ../error/trait.Error.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -285,6 +300,8 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync +
 impl From<String> for Box<dyn Error + Send + Sync> {
     /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
     ///
+    /// [`Error`]: ../error/trait.Error.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -318,6 +335,8 @@ impl From<String> for Box<dyn Error + Send + Sync> {
 impl From<String> for Box<dyn Error> {
     /// Converts a [`String`] into a box of dyn [`Error`].
     ///
+    /// [`Error`]: ../error/trait.Error.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -339,6 +358,8 @@ impl From<String> for Box<dyn Error> {
 impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
     /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
     ///
+    /// [`Error`]: ../error/trait.Error.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -359,6 +380,8 @@ impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
 impl From<&str> for Box<dyn Error> {
     /// Converts a [`str`] into a box of dyn [`Error`].
     ///
+    /// [`Error`]: ../error/trait.Error.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -378,6 +401,9 @@ impl From<&str> for Box<dyn Error> {
 impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
     /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
     ///
+    /// [`Cow`]: ../borrow/enum.Cow.html
+    /// [`Error`]: ../error/trait.Error.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -399,6 +425,9 @@ impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
 impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
     /// Converts a [`Cow`] into a box of dyn [`Error`].
     ///
+    /// [`Cow`]: ../borrow/enum.Cow.html
+    /// [`Error`]: ../error/trait.Error.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -572,7 +601,7 @@ impl dyn Error + 'static {
         let t = TypeId::of::<T>();
 
         // Get TypeId of the type in the trait object
-        let boxed = self.type_id();
+        let boxed = self.type_id(private::Internal);
 
         // Compare both TypeIds on equality
         t == boxed
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index f93583dff81..5c6c43017cf 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -43,7 +43,9 @@ use crate::sys;
 /// `CString` implements a [`as_ptr`] method through the [`Deref`]
 /// trait. This method will give you a `*const c_char` which you can
 /// feed directly to extern functions that expect a nul-terminated
-/// string, like C's `strdup()`.
+/// string, like C's `strdup()`. Notice that [`as_ptr`] returns a
+/// read-only pointer; if the C code writes to it, that causes
+/// undefined behavior.
 ///
 /// # Extracting a slice of the whole C string
 ///
@@ -61,7 +63,7 @@ use crate::sys;
 ///
 /// Once you have the kind of slice you need (with or without a nul
 /// terminator), you can call the slice's own
-/// [`as_ptr`][slice.as_ptr] method to get a raw pointer to pass to
+/// [`as_ptr`][slice.as_ptr] method to get a read-only raw pointer to pass to
 /// extern functions. See the documentation for that function for a
 /// discussion on ensuring the lifetime of the raw pointer.
 ///
@@ -1043,6 +1045,9 @@ impl CStr {
     ///
     /// **WARNING**
     ///
+    /// The returned pointer is read-only; writing to it (including passing it
+    /// to C code that writes to it) causes undefined behavior.
+    ///
     /// It is your responsibility to make sure that the underlying memory is not
     /// freed too early. For example, the following code will cause undefined
     /// behavior when `ptr` is used inside the `unsafe` block:
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 13aee783750..c7c5849a00f 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -351,6 +351,8 @@ impl From<String> for OsString {
     /// Converts a [`String`] into a [`OsString`].
     ///
     /// The conversion copies the data, and includes an allocation on the heap.
+    ///
+    /// [`OsString`]: ../../std/ffi/struct.OsString.html
     fn from(s: String) -> OsString {
         OsString { inner: Buf::from_string(s) }
     }
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 991b45fd4a2..616b5eb836f 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -1812,6 +1812,8 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
 ///   function.)
 /// * `path` already exists.
 ///
+/// [`create_dir_all`]: fn.create_dir_all.html
+///
 /// # Examples
 ///
 /// ```no_run
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 5be2687d8f5..e309f81192c 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -754,7 +754,7 @@ impl<W> fmt::Display for IntoInnerError<W> {
 /// completed, rather than the entire buffer at once. Enter `LineWriter`. It
 /// does exactly that.
 ///
-/// Like [`BufWriter`], a `LineWriter`’s buffer will also be flushed when the
+/// Like [`BufWriter`][bufwriter], a `LineWriter`’s buffer will also be flushed when the
 /// `LineWriter` goes out of scope or when its internal buffer is full.
 ///
 /// [bufwriter]: struct.BufWriter.html
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 8fea6251e65..917199f8ea8 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -1579,18 +1579,13 @@ pub trait BufRead: Read {
     /// let stdin = io::stdin();
     /// let mut stdin = stdin.lock();
     ///
-    /// // we can't have two `&mut` references to `stdin`, so use a block
-    /// // to end the borrow early.
-    /// let length = {
-    ///     let buffer = stdin.fill_buf().unwrap();
+    /// let buffer = stdin.fill_buf().unwrap();
     ///
-    ///     // work with buffer
-    ///     println!("{:?}", buffer);
-    ///
-    ///     buffer.len()
-    /// };
+    /// // work with buffer
+    /// println!("{:?}", buffer);
     ///
     /// // ensure the bytes we worked with aren't returned again later
+    /// let length = buffer.len();
     /// stdin.consume(length);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index ffe50f11e8a..d133c2f5cb1 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -1,6 +1,6 @@
 #[doc(keyword = "as")]
 //
-/// The keyword for casting a value to a type.
+/// Cast between types, or rename an import.
 ///
 /// `as` is most commonly used to turn primitive types into other primitive types, but it has other
 /// uses that include turning pointers into addresses, addresses into pointers, and pointers into
@@ -29,9 +29,18 @@
 /// [`crate`]: keyword.crate.html
 mod as_keyword { }
 
+#[doc(keyword = "break")]
+//
+/// Exit early from a loop.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod break_keyword { }
+
 #[doc(keyword = "const")]
 //
-/// The keyword for defining constants.
+/// Compile-time constants and deterministic functions.
 ///
 /// Sometimes a certain value is used many times throughout a program, and it can become
 /// inconvenient to copy it over and over. What's more, it's not always possible or desirable to
@@ -83,9 +92,18 @@ mod as_keyword { }
 /// [Reference]: ../reference/items/constant-items.html
 mod const_keyword { }
 
+#[doc(keyword = "continue")]
+//
+/// Skip to the next iteration of a loop.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod continue_keyword { }
+
 #[doc(keyword = "crate")]
 //
-/// The `crate` keyword.
+/// A Rust binary or library.
 ///
 /// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are
 /// used to specify a dependency on a crate external to the one it's declared in. Crates are the
@@ -116,14 +134,24 @@ mod const_keyword { }
 /// [Reference]: ../reference/items/extern-crates.html
 mod crate_keyword { }
 
+#[doc(keyword = "else")]
+//
+/// What to do when an [`if`] condition does not hold.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`if`]: keyword.if.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod else_keyword { }
+
 #[doc(keyword = "enum")]
 //
-/// For defining enumerations.
+/// A type that can be any one of several variants.
 ///
 /// Enums in Rust are similar to those of other compiled languages like C, but have important
 /// differences that make them considerably more powerful. What Rust calls enums are more commonly
-/// known as [Algebraic Data Types] if you're coming from a functional programming background. The
-/// important detail is that each enum variant can have data to go along with it.
+/// known as [Algebraic Data Types][ADT] if you're coming from a functional programming background.
+/// The important detail is that each enum variant can have data to go along with it.
 ///
 /// ```rust
 /// # struct Coord;
@@ -166,7 +194,7 @@ mod crate_keyword { }
 ///
 /// For more information, take a look at the [Rust Book] or the [Reference]
 ///
-/// [Algebraic Data Types]: https://en.wikipedia.org/wiki/Algebraic_data_type
+/// [ADT]: https://en.wikipedia.org/wiki/Algebraic_data_type
 /// [`Option`]: option/enum.Option.html
 /// [Rust Book]: ../book/ch06-01-defining-an-enum.html
 /// [Reference]: ../reference/items/enumerations.html
@@ -174,7 +202,7 @@ mod enum_keyword { }
 
 #[doc(keyword = "extern")]
 //
-/// For external connections in Rust code.
+/// Link to or import external code.
 ///
 /// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`]
 /// keyword to make your Rust code aware of other Rust crates in your project, i.e., `extern crate
@@ -214,9 +242,19 @@ mod enum_keyword { }
 /// [Reference]: ../reference/items/external-blocks.html
 mod extern_keyword { }
 
+#[doc(keyword = "false")]
+//
+/// A value of type [`bool`] representing logical **false**.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`bool`]: primitive.bool.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod false_keyword { }
+
 #[doc(keyword = "fn")]
 //
-/// The keyword for defining functions.
+/// A function or function pointer.
 ///
 /// Functions are the primary way code is executed within Rust. Function blocks, usually just
 /// called functions, can be defined in a variety of different places and be assigned many
@@ -283,7 +321,8 @@ mod fn_keyword { }
 
 #[doc(keyword = "for")]
 //
-/// The `for` keyword.
+/// Iteration with [`in`], trait implementation with [`impl`], or [higher-ranked trait bounds]
+/// (`for<'a>`).
 ///
 /// The `for` keyword is used in many syntactic locations:
 ///
@@ -350,6 +389,7 @@ mod fn_keyword { }
 ///
 /// For more information on for-loops, see the [Rust book] or the [Reference].
 ///
+/// [`in`]: keyword.in.html
 /// [`impl`]: keyword.impl.html
 /// [higher-ranked trait bounds]: ../reference/trait-bounds.html#higher-ranked-trait-bounds
 /// [`IntoIterator`]: iter/trait.IntoIterator.html
@@ -360,7 +400,7 @@ mod for_keyword { }
 
 #[doc(keyword = "if")]
 //
-/// If statements and expressions.
+/// Evaluate a block if a condition holds.
 ///
 /// `if` is a familiar construct to most programmers, and is the main way you'll often do logic in
 /// your code. However, unlike in most languages, `if` blocks can also act as expressions.
@@ -434,7 +474,7 @@ mod if_keyword { }
 
 #[doc(keyword = "impl")]
 //
-/// The implementation-defining keyword.
+/// Implement some functionality for a type.
 ///
 /// The `impl` keyword is primarily used to define implementations on types. Inherent
 /// implementations are standalone, while trait implementations are used to implement traits for
@@ -495,9 +535,19 @@ mod if_keyword { }
 /// [book2]: ../book/ch10-02-traits.html#returning-types-that-implement-traits
 mod impl_keyword { }
 
+#[doc(keyword = "in")]
+//
+/// Iterate over a series of values with [`for`].
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`for`]: keyword.for.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod in_keyword { }
+
 #[doc(keyword = "let")]
 //
-/// The variable binding keyword.
+/// Bind a value to a variable.
 ///
 /// The primary use for the `let` keyword is in `let` statements, which are used to introduce a new
 /// set of variables into the current scope, as given by a pattern.
@@ -560,7 +610,7 @@ mod let_keyword { }
 
 #[doc(keyword = "loop")]
 //
-/// The loop-defining keyword.
+/// Loop indefinitely.
 ///
 /// `loop` is used to define the simplest kind of loop supported in Rust. It runs the code inside
 /// it until the code uses `break` or the program exits.
@@ -603,9 +653,104 @@ mod let_keyword { }
 /// [Reference]: ../reference/expressions/loop-expr.html
 mod loop_keyword { }
 
+#[doc(keyword = "match")]
+//
+/// Control flow based on pattern matching.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod match_keyword { }
+
+#[doc(keyword = "mod")]
+//
+/// Organize code into [modules].
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [modules]: ../reference/items/modules.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod mod_keyword { }
+
+#[doc(keyword = "move")]
+//
+/// Capture a [closure]'s environment by value.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [closure]: ../book/second-edition/ch13-01-closures.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod move_keyword { }
+
+#[doc(keyword = "mut")]
+//
+/// A mutable binding, reference, or pointer.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod mut_keyword { }
+
+#[doc(keyword = "pub")]
+//
+/// Make an item visible to others.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod pub_keyword { }
+
+#[doc(keyword = "ref")]
+//
+/// Bind by reference during pattern matching.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod ref_keyword { }
+
+#[doc(keyword = "return")]
+//
+/// Return a value from a function.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod return_keyword { }
+
+#[doc(keyword = "self")]
+//
+/// The receiver of a method, or the current module.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod self_keyword { }
+
+#[doc(keyword = "Self")]
+//
+/// The implementing type within a [`trait`] or [`impl`] block, or the current type within a type
+/// definition.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`impl`]: keyword.impl.html
+/// [`trait`]: keyword.trait.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod self_upper_keyword { }
+
+#[doc(keyword = "static")]
+//
+/// A place that is valid for the duration of a program.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod static_keyword { }
+
 #[doc(keyword = "struct")]
 //
-/// The keyword used to define structs.
+/// A type that is composed of other types.
 ///
 /// Structs in Rust come in three flavors: Structs with named fields, tuple structs, and unit
 /// structs.
@@ -710,3 +855,122 @@ mod loop_keyword { }
 /// [book]: ../book/ch05-01-defining-structs.html
 /// [reference]: ../reference/items/structs.html
 mod struct_keyword { }
+
+#[doc(keyword = "super")]
+//
+/// The parent of the current [module].
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [module]: ../reference/items/modules.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod super_keyword { }
+
+#[doc(keyword = "trait")]
+//
+/// A common interface for a class of types.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod trait_keyword { }
+
+#[doc(keyword = "true")]
+//
+/// A value of type [`bool`] representing logical **true**.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`bool`]: primitive.bool.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod true_keyword { }
+
+#[doc(keyword = "type")]
+//
+/// Define an alias for an existing type.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod type_keyword { }
+
+#[doc(keyword = "unsafe")]
+//
+/// Code or interfaces whose [memory safety] cannot be verified by the type system.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [memory safety]: ../book/ch19-01-unsafe-rust.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod unsafe_keyword { }
+
+#[doc(keyword = "use")]
+//
+/// Import or rename items from other crates or modules.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod use_keyword { }
+
+#[doc(keyword = "where")]
+//
+/// Add constraints that must be upheld to use an item.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod where_keyword { }
+
+#[doc(keyword = "while")]
+//
+/// Loop while a condition is upheld.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod while_keyword { }
+
+// 2018 Edition keywords
+
+#[unstable(feature = "async_await", issue = "50547")]
+#[doc(keyword = "async")]
+//
+/// Return a [`Future`] instead of blocking the current thread.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`Future`]: ./future/trait.Future.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod async_keyword { }
+
+#[unstable(feature = "async_await", issue = "50547")]
+#[doc(keyword = "await")]
+//
+/// Suspend execution until the result of a [`Future`] is ready.
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [`Future`]: ./future/trait.Future.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod await_keyword { }
+
+#[doc(keyword = "dyn")]
+//
+/// Name the type of a [trait object].
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [trait object]: ../book/ch17-02-trait-objects.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod dyn_keyword { }
+
+#[doc(keyword = "union")]
+//
+/// The [Rust equivalent of a C-style union][union].
+///
+/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
+///
+/// [union]: ../reference/items/unions.html
+/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
+mod union_keyword { }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 3976f2344e2..e044b46e0d0 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -223,6 +223,7 @@
 #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"),
             feature(global_asm, slice_index_methods,
                     decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))]
+#![cfg_attr(all(test, target_vendor = "fortanix", target_env = "sgx"), feature(fixed_size_array))]
 
 // std is implemented with unstable features, many of which are internal
 // compiler details that will never be stable
@@ -271,7 +272,6 @@
 #![feature(libc)]
 #![feature(link_args)]
 #![feature(linkage)]
-#![feature(maybe_uninit)]
 #![feature(needs_panic_runtime)]
 #![feature(never_type)]
 #![feature(nll)]
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 03aebeda47c..9af7bba97aa 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -357,61 +357,6 @@ macro_rules! dbg {
     };
 }
 
-/// Selects the first successful receive event from a number of receivers.
-///
-/// This macro is used to wait for the first event to occur on a number of
-/// receivers. It places no restrictions on the types of receivers given to
-/// this macro, this can be viewed as a heterogeneous select.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(mpsc_select)]
-///
-/// use std::thread;
-/// use std::sync::mpsc;
-///
-/// // two placeholder functions for now
-/// fn long_running_thread() {}
-/// fn calculate_the_answer() -> u32 { 42 }
-///
-/// let (tx1, rx1) = mpsc::channel();
-/// let (tx2, rx2) = mpsc::channel();
-///
-/// thread::spawn(move|| { long_running_thread(); tx1.send(()).unwrap(); });
-/// thread::spawn(move|| { tx2.send(calculate_the_answer()).unwrap(); });
-///
-/// select! {
-///     _ = rx1.recv() => println!("the long running thread finished first"),
-///     answer = rx2.recv() => {
-///         println!("the answer was: {}", answer.unwrap());
-///     }
-/// }
-/// # drop(rx1.recv());
-/// # drop(rx2.recv());
-/// ```
-///
-/// For more information about select, see the `std::sync::mpsc::Select` structure.
-#[macro_export]
-#[unstable(feature = "mpsc_select", issue = "27800")]
-#[rustc_deprecated(since = "1.32.0",
-                   reason = "channel selection will be removed in a future release")]
-macro_rules! select {
-    (
-        $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
-    ) => ({
-        use $crate::sync::mpsc::Select;
-        let sel = Select::new();
-        $( let mut $rx = sel.handle(&$rx); )+
-        unsafe {
-            $( $rx.add(); )+
-        }
-        let ret = sel.wait();
-        $( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
-        { unreachable!() }
-    })
-}
-
 #[cfg(test)]
 macro_rules! assert_approx_eq {
     ($a:expr, $b:expr) => ({
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index ec54d8a042a..ca86a175058 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -546,6 +546,9 @@ impl FromInner<c::sockaddr_in6> for SocketAddrV6 {
 #[stable(feature = "ip_from_ip", since = "1.16.0")]
 impl From<SocketAddrV4> for SocketAddr {
     /// Converts a [`SocketAddrV4`] into a [`SocketAddr::V4`].
+    ///
+    /// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
+    /// [`SocketAddr::V4`]: ../../std/net/enum.SocketAddr.html#variant.V4
     fn from(sock4: SocketAddrV4) -> SocketAddr {
         SocketAddr::V4(sock4)
     }
@@ -554,6 +557,9 @@ impl From<SocketAddrV4> for SocketAddr {
 #[stable(feature = "ip_from_ip", since = "1.16.0")]
 impl From<SocketAddrV6> for SocketAddr {
     /// Converts a [`SocketAddrV6`] into a [`SocketAddr::V6`].
+    ///
+    /// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
+    /// [`SocketAddr::V6`]: ../../std/net/enum.SocketAddr.html#variant.V6
     fn from(sock6: SocketAddrV6) -> SocketAddr {
         SocketAddr::V6(sock6)
     }
@@ -567,6 +573,13 @@ impl<I: Into<IpAddr>> From<(I, u16)> for SocketAddr {
     /// and creates a [`SocketAddr::V6`] for a [`IpAddr::V6`].
     ///
     /// `u16` is treated as port of the newly created [`SocketAddr`].
+    ///
+    /// [`IpAddr`]: ../../std/net/enum.IpAddr.html
+    /// [`IpAddr::V4`]: ../../std/net/enum.IpAddr.html#variant.V4
+    /// [`IpAddr::V6`]: ../../std/net/enum.IpAddr.html#variant.V6
+    /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+    /// [`SocketAddr::V4`]: ../../std/net/enum.SocketAddr.html#variant.V4
+    /// [`SocketAddr::V6`]: ../../std/net/enum.SocketAddr.html#variant.V6
     fn from(pieces: (I, u16)) -> SocketAddr {
         SocketAddr::new(pieces.0.into(), pieces.1)
     }
@@ -974,9 +987,9 @@ mod tests {
         // s has been moved into the tsa call
     }
 
-    // FIXME: figure out why this fails on openbsd and bitrig and fix it
+    // FIXME: figure out why this fails on openbsd and fix it
     #[test]
-    #[cfg(not(any(windows, target_os = "openbsd", target_os = "bitrig")))]
+    #[cfg(not(any(windows, target_os = "openbsd")))]
     fn to_socket_addr_str_bad() {
         assert!(tsa("1200::AB00:1234::2552:7777:1313:34300").is_err());
     }
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index 0460ac9d753..cdffa390223 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -1595,9 +1595,9 @@ mod tests {
         assert_eq!(format!("{:?}", stream), compare);
     }
 
-    // FIXME: re-enabled bitrig/openbsd tests once their socket timeout code
+    // FIXME: re-enabled openbsd tests once their socket timeout code
     //        no longer has rounding errors.
-    #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)]
+    #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd"), ignore)]
     #[cfg_attr(target_env = "sgx", ignore)] // FIXME: https://github.com/fortanix/rust-sgx/issues/31
     #[test]
     fn timeouts() {
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index d4187d2932b..61d9149952e 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -1024,9 +1024,9 @@ mod tests {
         assert_eq!(format!("{:?}", udpsock), compare);
     }
 
-    // FIXME: re-enabled bitrig/openbsd/netbsd tests once their socket timeout code
+    // FIXME: re-enabled openbsd/netbsd tests once their socket timeout code
     //        no longer has rounding errors.
-    #[cfg_attr(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"), ignore)]
+    #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd"), ignore)]
     #[test]
     fn timeouts() {
         let addr = next_test_ip4();
diff --git a/src/libstd/os/bitrig/fs.rs b/src/libstd/os/bitrig/fs.rs
deleted file mode 100644
index b5c6903c410..00000000000
--- a/src/libstd/os/bitrig/fs.rs
+++ /dev/null
@@ -1,138 +0,0 @@
-#![stable(feature = "metadata_ext", since = "1.1.0")]
-
-use crate::fs::Metadata;
-use crate::sys_common::AsInner;
-
-#[allow(deprecated)]
-use crate::os::bitrig::raw;
-
-/// OS-specific extensions to [`fs::Metadata`].
-///
-/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
-#[stable(feature = "metadata_ext", since = "1.1.0")]
-pub trait MetadataExt {
-    /// Gain a reference to the underlying `stat` structure which contains
-    /// the raw information returned by the OS.
-    ///
-    /// The contents of the returned `stat` are **not** consistent across
-    /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
-    /// cross-Unix abstractions contained within the raw stat.
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    #[rustc_deprecated(since = "1.8.0",
-                       reason = "deprecated in favor of the accessor \
-                                 methods of this trait")]
-    #[allow(deprecated)]
-    fn as_raw_stat(&self) -> &raw::stat;
-
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_dev(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_ino(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_mode(&self) -> u32;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_nlink(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_uid(&self) -> u32;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_gid(&self) -> u32;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_rdev(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_size(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_atime(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_atime_nsec(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_mtime(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_mtime_nsec(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_ctime(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_ctime_nsec(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_birthtime(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_birthtime_nsec(&self) -> i64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_blksize(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_blocks(&self) -> u64;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_flags(&self) -> u32;
-    #[stable(feature = "metadata_ext2", since = "1.8.0")]
-    fn st_gen(&self) -> u32;
-}
-
-#[stable(feature = "metadata_ext", since = "1.1.0")]
-impl MetadataExt for Metadata {
-    #[allow(deprecated)]
-    fn as_raw_stat(&self) -> &raw::stat {
-        unsafe {
-            &*(self.as_inner().as_inner() as *const libc::stat
-                                          as *const raw::stat)
-        }
-    }
-    fn st_dev(&self) -> u64 {
-        self.as_inner().as_inner().st_dev as u64
-    }
-    fn st_ino(&self) -> u64 {
-        self.as_inner().as_inner().st_ino as u64
-    }
-    fn st_mode(&self) -> u32 {
-        self.as_inner().as_inner().st_mode as u32
-    }
-    fn st_nlink(&self) -> u64 {
-        self.as_inner().as_inner().st_nlink as u64
-    }
-    fn st_uid(&self) -> u32 {
-        self.as_inner().as_inner().st_uid as u32
-    }
-    fn st_gid(&self) -> u32 {
-        self.as_inner().as_inner().st_gid as u32
-    }
-    fn st_rdev(&self) -> u64 {
-        self.as_inner().as_inner().st_rdev as u64
-    }
-    fn st_size(&self) -> u64 {
-        self.as_inner().as_inner().st_size as u64
-    }
-    fn st_atime(&self) -> i64 {
-        self.as_inner().as_inner().st_atime as i64
-    }
-    fn st_atime_nsec(&self) -> i64 {
-        self.as_inner().as_inner().st_atime_nsec as i64
-    }
-    fn st_mtime(&self) -> i64 {
-        self.as_inner().as_inner().st_mtime as i64
-    }
-    fn st_mtime_nsec(&self) -> i64 {
-        self.as_inner().as_inner().st_mtime_nsec as i64
-    }
-    fn st_ctime(&self) -> i64 {
-        self.as_inner().as_inner().st_ctime as i64
-    }
-    fn st_ctime_nsec(&self) -> i64 {
-        self.as_inner().as_inner().st_ctime_nsec as i64
-    }
-    fn st_birthtime(&self) -> i64 {
-        self.as_inner().as_inner().st_birthtime as i64
-    }
-    fn st_birthtime_nsec(&self) -> i64 {
-        self.as_inner().as_inner().st_birthtime_nsec as i64
-    }
-    fn st_blksize(&self) -> u64 {
-        self.as_inner().as_inner().st_blksize as u64
-    }
-    fn st_blocks(&self) -> u64 {
-        self.as_inner().as_inner().st_blocks as u64
-    }
-    fn st_gen(&self) -> u32 {
-        self.as_inner().as_inner().st_gen as u32
-    }
-    fn st_flags(&self) -> u32 {
-        self.as_inner().as_inner().st_flags as u32
-    }
-}
diff --git a/src/libstd/os/bitrig/mod.rs b/src/libstd/os/bitrig/mod.rs
deleted file mode 100644
index 0bc105bb2b4..00000000000
--- a/src/libstd/os/bitrig/mod.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-//! Bitrig-specific definitions
-
-#![stable(feature = "raw_ext", since = "1.1.0")]
-
-pub mod raw;
-pub mod fs;
diff --git a/src/libstd/os/bitrig/raw.rs b/src/libstd/os/bitrig/raw.rs
deleted file mode 100644
index c966d5a8e5b..00000000000
--- a/src/libstd/os/bitrig/raw.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-//! Bitrig-specific raw type definitions
-
-#![stable(feature = "raw_ext", since = "1.1.0")]
-#![rustc_deprecated(since = "1.8.0",
-                    reason = "these type aliases are no longer supported by \
-                              the standard library, the `libc` crate on \
-                              crates.io should be used instead for the correct \
-                              definitions")]
-#![allow(deprecated)]
-
-use crate::os::raw::c_long;
-use crate::os::unix::raw::{uid_t, gid_t};
-
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type fflags_t = u32;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64;
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
-
-#[stable(feature = "pthread_t", since = "1.8.0")]
-pub type pthread_t = usize;
-
-#[repr(C)]
-#[derive(Clone)]
-#[stable(feature = "raw_ext", since = "1.1.0")]
-pub struct stat {
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_mode: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_dev: i32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_ino: u64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_nlink: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_uid: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_gid: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_rdev: i32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_atime: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_atime_nsec: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_mtime: u64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_mtime_nsec: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_ctime: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_ctime_nsec: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_size: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_blocks: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_blksize: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_flags: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_gen: u32,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_birthtime: i64,
-    #[stable(feature = "raw_ext", since = "1.1.0")]
-    pub st_birthtime_nsec: i64,
-}
diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs
index 7b56d6d62cf..44cbc180b8b 100644
--- a/src/libstd/os/mod.rs
+++ b/src/libstd/os/mod.rs
@@ -39,7 +39,6 @@ cfg_if! {
 }
 
 #[cfg(target_os = "android")]    pub mod android;
-#[cfg(target_os = "bitrig")]     pub mod bitrig;
 #[cfg(target_os = "dragonfly")]  pub mod dragonfly;
 #[cfg(target_os = "freebsd")]    pub mod freebsd;
 #[cfg(target_os = "haiku")]      pub mod haiku;
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 126bc3754da..59f9e439add 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -888,6 +888,11 @@ impl<'a> Iterator for Iter<'a> {
     fn next(&mut self) -> Option<&'a OsStr> {
         self.inner.next().map(Component::as_os_str)
     }
+
+    #[inline]
+    fn last(mut self) -> Option<&'a OsStr> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -951,6 +956,11 @@ impl<'a> Iterator for Components<'a> {
         }
         None
     }
+
+    #[inline]
+    fn last(mut self) -> Option<Self::Item> {
+        self.next_back()
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index 04353fde1b4..69ecd201063 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -116,7 +116,6 @@
 //! ```
 
 #![stable(feature = "rust1", since = "1.0.0")]
-#![allow(deprecated)] // for mpsc_select
 
 // A description of how Rust's channel implementation works
 //
@@ -263,6 +262,8 @@
 // believe that there is anything fundamental that needs to change about these
 // channels, however, in order to support a more efficient select().
 //
+// FIXME: Select is now removed, so these factors are ready to be cleaned up!
+//
 // # Conclusion
 //
 // And now that you've seen all the races that I found and attempted to fix,
@@ -275,18 +276,8 @@ use crate::mem;
 use crate::cell::UnsafeCell;
 use crate::time::{Duration, Instant};
 
-#[unstable(feature = "mpsc_select", issue = "27800")]
-pub use self::select::{Select, Handle};
-use self::select::StartResult;
-use self::select::StartResult::*;
-use self::blocking::SignalToken;
-
-#[cfg(all(test, not(target_os = "emscripten")))]
-mod select_tests;
-
 mod blocking;
 mod oneshot;
-mod select;
 mod shared;
 mod stream;
 mod sync;
@@ -1514,78 +1505,6 @@ impl<T> Receiver<T> {
 
 }
 
-impl<T> select::Packet for Receiver<T> {
-    fn can_recv(&self) -> bool {
-        loop {
-            let new_port = match *unsafe { self.inner() } {
-                Flavor::Oneshot(ref p) => {
-                    match p.can_recv() {
-                        Ok(ret) => return ret,
-                        Err(upgrade) => upgrade,
-                    }
-                }
-                Flavor::Stream(ref p) => {
-                    match p.can_recv() {
-                        Ok(ret) => return ret,
-                        Err(upgrade) => upgrade,
-                    }
-                }
-                Flavor::Shared(ref p) => return p.can_recv(),
-                Flavor::Sync(ref p) => return p.can_recv(),
-            };
-            unsafe {
-                mem::swap(self.inner_mut(),
-                          new_port.inner_mut());
-            }
-        }
-    }
-
-    fn start_selection(&self, mut token: SignalToken) -> StartResult {
-        loop {
-            let (t, new_port) = match *unsafe { self.inner() } {
-                Flavor::Oneshot(ref p) => {
-                    match p.start_selection(token) {
-                        oneshot::SelSuccess => return Installed,
-                        oneshot::SelCanceled => return Abort,
-                        oneshot::SelUpgraded(t, rx) => (t, rx),
-                    }
-                }
-                Flavor::Stream(ref p) => {
-                    match p.start_selection(token) {
-                        stream::SelSuccess => return Installed,
-                        stream::SelCanceled => return Abort,
-                        stream::SelUpgraded(t, rx) => (t, rx),
-                    }
-                }
-                Flavor::Shared(ref p) => return p.start_selection(token),
-                Flavor::Sync(ref p) => return p.start_selection(token),
-            };
-            token = t;
-            unsafe {
-                mem::swap(self.inner_mut(), new_port.inner_mut());
-            }
-        }
-    }
-
-    fn abort_selection(&self) -> bool {
-        let mut was_upgrade = false;
-        loop {
-            let result = match *unsafe { self.inner() } {
-                Flavor::Oneshot(ref p) => p.abort_selection(),
-                Flavor::Stream(ref p) => p.abort_selection(was_upgrade),
-                Flavor::Shared(ref p) => return p.abort_selection(was_upgrade),
-                Flavor::Sync(ref p) => return p.abort_selection(),
-            };
-            let new_port = match result { Ok(b) => return b, Err(p) => p };
-            was_upgrade = true;
-            unsafe {
-                mem::swap(self.inner_mut(),
-                          new_port.inner_mut());
-            }
-        }
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Iterator for Iter<'a, T> {
     type Item = T;
diff --git a/src/libstd/sync/mpsc/oneshot.rs b/src/libstd/sync/mpsc/oneshot.rs
index 5c516d5de0f..e7a5cc46b31 100644
--- a/src/libstd/sync/mpsc/oneshot.rs
+++ b/src/libstd/sync/mpsc/oneshot.rs
@@ -24,7 +24,6 @@
 
 pub use self::Failure::*;
 pub use self::UpgradeResult::*;
-pub use self::SelectionResult::*;
 use self::MyUpgrade::*;
 
 use crate::sync::mpsc::Receiver;
@@ -66,12 +65,6 @@ pub enum UpgradeResult {
     UpWoke(SignalToken),
 }
 
-pub enum SelectionResult<T> {
-    SelCanceled,
-    SelUpgraded(SignalToken, Receiver<T>),
-    SelSuccess,
-}
-
 enum MyUpgrade<T> {
     NothingSent,
     SendUsed,
@@ -264,71 +257,6 @@ impl<T> Packet<T> {
     // select implementation
     ////////////////////////////////////////////////////////////////////////////
 
-    // If Ok, the value is whether this port has data, if Err, then the upgraded
-    // port needs to be checked instead of this one.
-    pub fn can_recv(&self) -> Result<bool, Receiver<T>> {
-        unsafe {
-            match self.state.load(Ordering::SeqCst) {
-                EMPTY => Ok(false), // Welp, we tried
-                DATA => Ok(true),   // we have some un-acquired data
-                DISCONNECTED if (*self.data.get()).is_some() => Ok(true), // we have data
-                DISCONNECTED => {
-                    match ptr::replace(self.upgrade.get(), SendUsed) {
-                        // The other end sent us an upgrade, so we need to
-                        // propagate upwards whether the upgrade can receive
-                        // data
-                        GoUp(upgrade) => Err(upgrade),
-
-                        // If the other end disconnected without sending an
-                        // upgrade, then we have data to receive (the channel is
-                        // disconnected).
-                        up => { ptr::write(self.upgrade.get(), up); Ok(true) }
-                    }
-                }
-                _ => unreachable!(), // we're the "one blocker"
-            }
-        }
-    }
-
-    // Attempts to start selection on this port. This can either succeed, fail
-    // because there is data, or fail because there is an upgrade pending.
-    pub fn start_selection(&self, token: SignalToken) -> SelectionResult<T> {
-        unsafe {
-            let ptr = token.cast_to_usize();
-            match self.state.compare_and_swap(EMPTY, ptr, Ordering::SeqCst) {
-                EMPTY => SelSuccess,
-                DATA => {
-                    drop(SignalToken::cast_from_usize(ptr));
-                    SelCanceled
-                }
-                DISCONNECTED if (*self.data.get()).is_some() => {
-                    drop(SignalToken::cast_from_usize(ptr));
-                    SelCanceled
-                }
-                DISCONNECTED => {
-                    match ptr::replace(self.upgrade.get(), SendUsed) {
-                        // The other end sent us an upgrade, so we need to
-                        // propagate upwards whether the upgrade can receive
-                        // data
-                        GoUp(upgrade) => {
-                            SelUpgraded(SignalToken::cast_from_usize(ptr), upgrade)
-                        }
-
-                        // If the other end disconnected without sending an
-                        // upgrade, then we have data to receive (the channel is
-                        // disconnected).
-                        up => {
-                            ptr::write(self.upgrade.get(), up);
-                            drop(SignalToken::cast_from_usize(ptr));
-                            SelCanceled
-                        }
-                    }
-                }
-                _ => unreachable!(), // we're the "one blocker"
-            }
-        }
-    }
-
     // Remove a previous selecting thread from this port. This ensures that the
     // blocked thread will no longer be visible to any other threads.
     //
diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs
deleted file mode 100644
index d1b5f2deccc..00000000000
--- a/src/libstd/sync/mpsc/select.rs
+++ /dev/null
@@ -1,352 +0,0 @@
-//! Selection over an array of receivers
-//!
-//! This module contains the implementation machinery necessary for selecting
-//! over a number of receivers. One large goal of this module is to provide an
-//! efficient interface to selecting over any receiver of any type.
-//!
-//! This is achieved through an architecture of a "receiver set" in which
-//! receivers are added to a set and then the entire set is waited on at once.
-//! The set can be waited on multiple times to prevent re-adding each receiver
-//! to the set.
-//!
-//! Usage of this module is currently encouraged to go through the use of the
-//! `select!` macro. This macro allows naturally binding of variables to the
-//! received values of receivers in a much more natural syntax then usage of the
-//! `Select` structure directly.
-//!
-//! # Examples
-//!
-//! ```rust
-//! #![feature(mpsc_select)]
-//!
-//! use std::sync::mpsc::channel;
-//!
-//! let (tx1, rx1) = channel();
-//! let (tx2, rx2) = channel();
-//!
-//! tx1.send(1).unwrap();
-//! tx2.send(2).unwrap();
-//!
-//! select! {
-//!     val = rx1.recv() => {
-//!         assert_eq!(val.unwrap(), 1);
-//!     },
-//!     val = rx2.recv() => {
-//!         assert_eq!(val.unwrap(), 2);
-//!     }
-//! }
-//! ```
-
-#![allow(dead_code)]
-#![unstable(feature = "mpsc_select",
-            reason = "This implementation, while likely sufficient, is unsafe and \
-                      likely to be error prone. At some point in the future this \
-                      module will be removed.",
-            issue = "27800")]
-#![rustc_deprecated(since = "1.32.0",
-                    reason = "channel selection will be removed in a future release")]
-
-use core::cell::{Cell, UnsafeCell};
-use core::marker;
-use core::ptr;
-use core::usize;
-
-use crate::fmt;
-use crate::sync::mpsc::{Receiver, RecvError};
-use crate::sync::mpsc::blocking::{self, SignalToken};
-
-/// The "receiver set" of the select interface. This structure is used to manage
-/// a set of receivers which are being selected over.
-pub struct Select {
-    inner: UnsafeCell<SelectInner>,
-    next_id: Cell<usize>,
-}
-
-struct SelectInner {
-    head: *mut Handle<'static, ()>,
-    tail: *mut Handle<'static, ()>,
-}
-
-impl !marker::Send for Select {}
-
-/// A handle to a receiver which is currently a member of a `Select` set of
-/// receivers. This handle is used to keep the receiver in the set as well as
-/// interact with the underlying receiver.
-pub struct Handle<'rx, T:Send+'rx> {
-    /// The ID of this handle, used to compare against the return value of
-    /// `Select::wait()`.
-    id: usize,
-    selector: *mut SelectInner,
-    next: *mut Handle<'static, ()>,
-    prev: *mut Handle<'static, ()>,
-    added: bool,
-    packet: &'rx (dyn Packet+'rx),
-
-    // due to our fun transmutes, we be sure to place this at the end. (nothing
-    // previous relies on T)
-    rx: &'rx Receiver<T>,
-}
-
-struct Packets { cur: *mut Handle<'static, ()> }
-
-#[doc(hidden)]
-#[derive(PartialEq, Eq)]
-pub enum StartResult {
-    Installed,
-    Abort,
-}
-
-#[doc(hidden)]
-pub trait Packet {
-    fn can_recv(&self) -> bool;
-    fn start_selection(&self, token: SignalToken) -> StartResult;
-    fn abort_selection(&self) -> bool;
-}
-
-impl Select {
-    /// Creates a new selection structure. This set is initially empty.
-    ///
-    /// Usage of this struct directly can sometimes be burdensome, and usage is much easier through
-    /// the `select!` macro.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(mpsc_select)]
-    ///
-    /// use std::sync::mpsc::Select;
-    ///
-    /// let select = Select::new();
-    /// ```
-    pub fn new() -> Select {
-        Select {
-            inner: UnsafeCell::new(SelectInner {
-                head: ptr::null_mut(),
-                tail: ptr::null_mut(),
-            }),
-            next_id: Cell::new(1),
-        }
-    }
-
-    /// Creates a new handle into this receiver set for a new receiver. Note
-    /// that this does *not* add the receiver to the receiver set, for that you
-    /// must call the `add` method on the handle itself.
-    pub fn handle<'a, T: Send>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> {
-        let id = self.next_id.get();
-        self.next_id.set(id + 1);
-        Handle {
-            id,
-            selector: self.inner.get(),
-            next: ptr::null_mut(),
-            prev: ptr::null_mut(),
-            added: false,
-            rx,
-            packet: rx,
-        }
-    }
-
-    /// Waits for an event on this receiver set. The returned value is *not* an
-    /// index, but rather an ID. This ID can be queried against any active
-    /// `Handle` structures (each one has an `id` method). The handle with
-    /// the matching `id` will have some sort of event available on it. The
-    /// event could either be that data is available or the corresponding
-    /// channel has been closed.
-    pub fn wait(&self) -> usize {
-        self.wait2(true)
-    }
-
-    /// Helper method for skipping the preflight checks during testing
-    pub(super) fn wait2(&self, do_preflight_checks: bool) -> usize {
-        // Note that this is currently an inefficient implementation. We in
-        // theory have knowledge about all receivers in the set ahead of time,
-        // so this method shouldn't really have to iterate over all of them yet
-        // again. The idea with this "receiver set" interface is to get the
-        // interface right this time around, and later this implementation can
-        // be optimized.
-        //
-        // This implementation can be summarized by:
-        //
-        //      fn select(receivers) {
-        //          if any receiver ready { return ready index }
-        //          deschedule {
-        //              block on all receivers
-        //          }
-        //          unblock on all receivers
-        //          return ready index
-        //      }
-        //
-        // Most notably, the iterations over all of the receivers shouldn't be
-        // necessary.
-        unsafe {
-            // Stage 1: preflight checks. Look for any packets ready to receive
-            if do_preflight_checks {
-                for handle in self.iter() {
-                    if (*handle).packet.can_recv() {
-                        return (*handle).id();
-                    }
-                }
-            }
-
-            // Stage 2: begin the blocking process
-            //
-            // Create a number of signal tokens, and install each one
-            // sequentially until one fails. If one fails, then abort the
-            // selection on the already-installed tokens.
-            let (wait_token, signal_token) = blocking::tokens();
-            for (i, handle) in self.iter().enumerate() {
-                match (*handle).packet.start_selection(signal_token.clone()) {
-                    StartResult::Installed => {}
-                    StartResult::Abort => {
-                        // Go back and abort the already-begun selections
-                        for handle in self.iter().take(i) {
-                            (*handle).packet.abort_selection();
-                        }
-                        return (*handle).id;
-                    }
-                }
-            }
-
-            // Stage 3: no messages available, actually block
-            wait_token.wait();
-
-            // Stage 4: there *must* be message available; find it.
-            //
-            // Abort the selection process on each receiver. If the abort
-            // process returns `true`, then that means that the receiver is
-            // ready to receive some data. Note that this also means that the
-            // receiver may have yet to have fully read the `to_wake` field and
-            // woken us up (although the wakeup is guaranteed to fail).
-            //
-            // This situation happens in the window of where a sender invokes
-            // increment(), sees -1, and then decides to wake up the thread. After
-            // all this is done, the sending thread will set `selecting` to
-            // `false`. Until this is done, we cannot return. If we were to
-            // return, then a sender could wake up a receiver which has gone
-            // back to sleep after this call to `select`.
-            //
-            // Note that it is a "fairly small window" in which an increment()
-            // views that it should wake a thread up until the `selecting` bit
-            // is set to false. For now, the implementation currently just spins
-            // in a yield loop. This is very distasteful, but this
-            // implementation is already nowhere near what it should ideally be.
-            // A rewrite should focus on avoiding a yield loop, and for now this
-            // implementation is tying us over to a more efficient "don't
-            // iterate over everything every time" implementation.
-            let mut ready_id = usize::MAX;
-            for handle in self.iter() {
-                if (*handle).packet.abort_selection() {
-                    ready_id = (*handle).id;
-                }
-            }
-
-            // We must have found a ready receiver
-            assert!(ready_id != usize::MAX);
-            return ready_id;
-        }
-    }
-
-    fn iter(&self) -> Packets { Packets { cur: unsafe { &*self.inner.get() }.head } }
-}
-
-impl<'rx, T: Send> Handle<'rx, T> {
-    /// Retrieves the ID of this handle.
-    #[inline]
-    pub fn id(&self) -> usize { self.id }
-
-    /// Blocks to receive a value on the underlying receiver, returning `Some` on
-    /// success or `None` if the channel disconnects. This function has the same
-    /// semantics as `Receiver.recv`
-    pub fn recv(&mut self) -> Result<T, RecvError> { self.rx.recv() }
-
-    /// Adds this handle to the receiver set that the handle was created from. This
-    /// method can be called multiple times, but it has no effect if `add` was
-    /// called previously.
-    ///
-    /// This method is unsafe because it requires that the `Handle` is not moved
-    /// while it is added to the `Select` set.
-    pub unsafe fn add(&mut self) {
-        if self.added { return }
-        let selector = &mut *self.selector;
-        let me = self as *mut Handle<'rx, T> as *mut Handle<'static, ()>;
-
-        if selector.head.is_null() {
-            selector.head = me;
-            selector.tail = me;
-        } else {
-            (*me).prev = selector.tail;
-            assert!((*me).next.is_null());
-            (*selector.tail).next = me;
-            selector.tail = me;
-        }
-        self.added = true;
-    }
-
-    /// Removes this handle from the `Select` set. This method is unsafe because
-    /// it has no guarantee that the `Handle` was not moved since `add` was
-    /// called.
-    pub unsafe fn remove(&mut self) {
-        if !self.added { return }
-
-        let selector = &mut *self.selector;
-        let me = self as *mut Handle<'rx, T> as *mut Handle<'static, ()>;
-
-        if self.prev.is_null() {
-            assert_eq!(selector.head, me);
-            selector.head = self.next;
-        } else {
-            (*self.prev).next = self.next;
-        }
-        if self.next.is_null() {
-            assert_eq!(selector.tail, me);
-            selector.tail = self.prev;
-        } else {
-            (*self.next).prev = self.prev;
-        }
-
-        self.next = ptr::null_mut();
-        self.prev = ptr::null_mut();
-
-        self.added = false;
-    }
-}
-
-impl Drop for Select {
-    fn drop(&mut self) {
-        unsafe {
-            assert!((&*self.inner.get()).head.is_null());
-            assert!((&*self.inner.get()).tail.is_null());
-        }
-    }
-}
-
-impl<T: Send> Drop for Handle<'_, T> {
-    fn drop(&mut self) {
-        unsafe { self.remove() }
-    }
-}
-
-impl Iterator for Packets {
-    type Item = *mut Handle<'static, ()>;
-
-    fn next(&mut self) -> Option<*mut Handle<'static, ()>> {
-        if self.cur.is_null() {
-            None
-        } else {
-            let ret = Some(self.cur);
-            unsafe { self.cur = (*self.cur).next; }
-            ret
-        }
-    }
-}
-
-impl fmt::Debug for Select {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Select").finish()
-    }
-}
-
-impl<T: Send> fmt::Debug for Handle<'_, T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Handle").finish()
-    }
-}
diff --git a/src/libstd/sync/mpsc/select_tests.rs b/src/libstd/sync/mpsc/select_tests.rs
deleted file mode 100644
index 18d93462c78..00000000000
--- a/src/libstd/sync/mpsc/select_tests.rs
+++ /dev/null
@@ -1,413 +0,0 @@
-#![allow(unused_imports)]
-
-/// This file exists to hack around https://github.com/rust-lang/rust/issues/47238
-
-use crate::thread;
-use crate::sync::mpsc::*;
-
-// Don't use the libstd version so we can pull in the right Select structure
-// (std::comm points at the wrong one)
-macro_rules! select {
-    (
-        $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
-    ) => ({
-        let sel = Select::new();
-        $( let mut $rx = sel.handle(&$rx); )+
-        unsafe {
-            $( $rx.add(); )+
-        }
-        let ret = sel.wait();
-        $( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
-        { unreachable!() }
-    })
-}
-
-#[test]
-fn smoke() {
-    let (tx1, rx1) = channel::<i32>();
-    let (tx2, rx2) = channel::<i32>();
-    tx1.send(1).unwrap();
-    select! {
-        foo = rx1.recv() => { assert_eq!(foo.unwrap(), 1); },
-        _bar = rx2.recv() => { panic!() }
-    }
-    tx2.send(2).unwrap();
-    select! {
-        _foo = rx1.recv() => { panic!() },
-        bar = rx2.recv() => { assert_eq!(bar.unwrap(), 2) }
-    }
-    drop(tx1);
-    select! {
-        foo = rx1.recv() => { assert!(foo.is_err()); },
-        _bar = rx2.recv() => { panic!() }
-    }
-    drop(tx2);
-    select! {
-        bar = rx2.recv() => { assert!(bar.is_err()); }
-    }
-}
-
-#[test]
-fn smoke2() {
-    let (_tx1, rx1) = channel::<i32>();
-    let (_tx2, rx2) = channel::<i32>();
-    let (_tx3, rx3) = channel::<i32>();
-    let (_tx4, rx4) = channel::<i32>();
-    let (tx5, rx5) = channel::<i32>();
-    tx5.send(4).unwrap();
-    select! {
-        _foo = rx1.recv() => { panic!("1") },
-        _foo = rx2.recv() => { panic!("2") },
-        _foo = rx3.recv() => { panic!("3") },
-        _foo = rx4.recv() => { panic!("4") },
-        foo = rx5.recv() => { assert_eq!(foo.unwrap(), 4); }
-    }
-}
-
-#[test]
-fn closed() {
-    let (_tx1, rx1) = channel::<i32>();
-    let (tx2, rx2) = channel::<i32>();
-    drop(tx2);
-
-    select! {
-        _a1 = rx1.recv() => { panic!() },
-        a2 = rx2.recv() => { assert!(a2.is_err()); }
-    }
-}
-
-#[test]
-fn unblocks() {
-    let (tx1, rx1) = channel::<i32>();
-    let (_tx2, rx2) = channel::<i32>();
-    let (tx3, rx3) = channel::<i32>();
-
-    let _t = thread::spawn(move|| {
-        for _ in 0..20 { thread::yield_now(); }
-        tx1.send(1).unwrap();
-        rx3.recv().unwrap();
-        for _ in 0..20 { thread::yield_now(); }
-    });
-
-    select! {
-        a = rx1.recv() => { assert_eq!(a.unwrap(), 1); },
-        _b = rx2.recv() => { panic!() }
-    }
-    tx3.send(1).unwrap();
-    select! {
-        a = rx1.recv() => { assert!(a.is_err()) },
-        _b = rx2.recv() => { panic!() }
-    }
-}
-
-#[test]
-fn both_ready() {
-    let (tx1, rx1) = channel::<i32>();
-    let (tx2, rx2) = channel::<i32>();
-    let (tx3, rx3) = channel::<()>();
-
-    let _t = thread::spawn(move|| {
-        for _ in 0..20 { thread::yield_now(); }
-        tx1.send(1).unwrap();
-        tx2.send(2).unwrap();
-        rx3.recv().unwrap();
-    });
-
-    select! {
-        a = rx1.recv() => { assert_eq!(a.unwrap(), 1); },
-        a = rx2.recv() => { assert_eq!(a.unwrap(), 2); }
-    }
-    select! {
-        a = rx1.recv() => { assert_eq!(a.unwrap(), 1); },
-        a = rx2.recv() => { assert_eq!(a.unwrap(), 2); }
-    }
-    assert_eq!(rx1.try_recv(), Err(TryRecvError::Empty));
-    assert_eq!(rx2.try_recv(), Err(TryRecvError::Empty));
-    tx3.send(()).unwrap();
-}
-
-#[test]
-fn stress() {
-    const AMT: i32 = 10000;
-    let (tx1, rx1) = channel::<i32>();
-    let (tx2, rx2) = channel::<i32>();
-    let (tx3, rx3) = channel::<()>();
-
-    let _t = thread::spawn(move|| {
-        for i in 0..AMT {
-            if i % 2 == 0 {
-                tx1.send(i).unwrap();
-            } else {
-                tx2.send(i).unwrap();
-            }
-            rx3.recv().unwrap();
-        }
-    });
-
-    for i in 0..AMT {
-        select! {
-            i1 = rx1.recv() => { assert!(i % 2 == 0 && i == i1.unwrap()); },
-            i2 = rx2.recv() => { assert!(i % 2 == 1 && i == i2.unwrap()); }
-        }
-        tx3.send(()).unwrap();
-    }
-}
-
-#[allow(unused_must_use)]
-#[test]
-fn cloning() {
-    let (tx1, rx1) = channel::<i32>();
-    let (_tx2, rx2) = channel::<i32>();
-    let (tx3, rx3) = channel::<()>();
-
-    let _t = thread::spawn(move|| {
-        rx3.recv().unwrap();
-        tx1.clone();
-        assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty));
-        tx1.send(2).unwrap();
-        rx3.recv().unwrap();
-    });
-
-    tx3.send(()).unwrap();
-    select! {
-        _i1 = rx1.recv() => {},
-        _i2 = rx2.recv() => panic!()
-    }
-    tx3.send(()).unwrap();
-}
-
-#[allow(unused_must_use)]
-#[test]
-fn cloning2() {
-    let (tx1, rx1) = channel::<i32>();
-    let (_tx2, rx2) = channel::<i32>();
-    let (tx3, rx3) = channel::<()>();
-
-    let _t = thread::spawn(move|| {
-        rx3.recv().unwrap();
-        tx1.clone();
-        assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty));
-        tx1.send(2).unwrap();
-        rx3.recv().unwrap();
-    });
-
-    tx3.send(()).unwrap();
-    select! {
-        _i1 = rx1.recv() => {},
-        _i2 = rx2.recv() => panic!()
-    }
-    tx3.send(()).unwrap();
-}
-
-#[test]
-fn cloning3() {
-    let (tx1, rx1) = channel::<()>();
-    let (tx2, rx2) = channel::<()>();
-    let (tx3, rx3) = channel::<()>();
-    let _t = thread::spawn(move|| {
-        let s = Select::new();
-        let mut h1 = s.handle(&rx1);
-        let mut h2 = s.handle(&rx2);
-        unsafe { h2.add(); }
-        unsafe { h1.add(); }
-        assert_eq!(s.wait(), h2.id());
-        tx3.send(()).unwrap();
-    });
-
-    for _ in 0..1000 { thread::yield_now(); }
-    drop(tx1.clone());
-    tx2.send(()).unwrap();
-    rx3.recv().unwrap();
-}
-
-#[test]
-fn preflight1() {
-    let (tx, rx) = channel();
-    tx.send(()).unwrap();
-    select! {
-        _n = rx.recv() => {}
-    }
-}
-
-#[test]
-fn preflight2() {
-    let (tx, rx) = channel();
-    tx.send(()).unwrap();
-    tx.send(()).unwrap();
-    select! {
-        _n = rx.recv() => {}
-    }
-}
-
-#[test]
-fn preflight3() {
-    let (tx, rx) = channel();
-    drop(tx.clone());
-    tx.send(()).unwrap();
-    select! {
-        _n = rx.recv() => {}
-    }
-}
-
-#[test]
-fn preflight4() {
-    let (tx, rx) = channel();
-    tx.send(()).unwrap();
-    let s = Select::new();
-    let mut h = s.handle(&rx);
-    unsafe { h.add(); }
-    assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn preflight5() {
-    let (tx, rx) = channel();
-    tx.send(()).unwrap();
-    tx.send(()).unwrap();
-    let s = Select::new();
-    let mut h = s.handle(&rx);
-    unsafe { h.add(); }
-    assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn preflight6() {
-    let (tx, rx) = channel();
-    drop(tx.clone());
-    tx.send(()).unwrap();
-    let s = Select::new();
-    let mut h = s.handle(&rx);
-    unsafe { h.add(); }
-    assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn preflight7() {
-    let (tx, rx) = channel::<()>();
-    drop(tx);
-    let s = Select::new();
-    let mut h = s.handle(&rx);
-    unsafe { h.add(); }
-    assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn preflight8() {
-    let (tx, rx) = channel();
-    tx.send(()).unwrap();
-    drop(tx);
-    rx.recv().unwrap();
-    let s = Select::new();
-    let mut h = s.handle(&rx);
-    unsafe { h.add(); }
-    assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn preflight9() {
-    let (tx, rx) = channel();
-    drop(tx.clone());
-    tx.send(()).unwrap();
-    drop(tx);
-    rx.recv().unwrap();
-    let s = Select::new();
-    let mut h = s.handle(&rx);
-    unsafe { h.add(); }
-    assert_eq!(s.wait2(false), h.id());
-}
-
-#[test]
-fn oneshot_data_waiting() {
-    let (tx1, rx1) = channel();
-    let (tx2, rx2) = channel();
-    let _t = thread::spawn(move|| {
-        select! {
-            _n = rx1.recv() => {}
-        }
-        tx2.send(()).unwrap();
-    });
-
-    for _ in 0..100 { thread::yield_now() }
-    tx1.send(()).unwrap();
-    rx2.recv().unwrap();
-}
-
-#[test]
-fn stream_data_waiting() {
-    let (tx1, rx1) = channel();
-    let (tx2, rx2) = channel();
-    tx1.send(()).unwrap();
-    tx1.send(()).unwrap();
-    rx1.recv().unwrap();
-    rx1.recv().unwrap();
-    let _t = thread::spawn(move|| {
-        select! {
-            _n = rx1.recv() => {}
-        }
-        tx2.send(()).unwrap();
-    });
-
-    for _ in 0..100 { thread::yield_now() }
-    tx1.send(()).unwrap();
-    rx2.recv().unwrap();
-}
-
-#[test]
-fn shared_data_waiting() {
-    let (tx1, rx1) = channel();
-    let (tx2, rx2) = channel();
-    drop(tx1.clone());
-    tx1.send(()).unwrap();
-    rx1.recv().unwrap();
-    let _t = thread::spawn(move|| {
-        select! {
-            _n = rx1.recv() => {}
-        }
-        tx2.send(()).unwrap();
-    });
-
-    for _ in 0..100 { thread::yield_now() }
-    tx1.send(()).unwrap();
-    rx2.recv().unwrap();
-}
-
-#[test]
-fn sync1() {
-    let (tx, rx) = sync_channel::<i32>(1);
-    tx.send(1).unwrap();
-    select! {
-        n = rx.recv() => { assert_eq!(n.unwrap(), 1); }
-    }
-}
-
-#[test]
-fn sync2() {
-    let (tx, rx) = sync_channel::<i32>(0);
-    let _t = thread::spawn(move|| {
-        for _ in 0..100 { thread::yield_now() }
-        tx.send(1).unwrap();
-    });
-    select! {
-        n = rx.recv() => { assert_eq!(n.unwrap(), 1); }
-    }
-}
-
-#[test]
-fn sync3() {
-    let (tx1, rx1) = sync_channel::<i32>(0);
-    let (tx2, rx2): (Sender<i32>, Receiver<i32>) = channel();
-    let _t = thread::spawn(move|| { tx1.send(1).unwrap(); });
-    let _t = thread::spawn(move|| { tx2.send(2).unwrap(); });
-    select! {
-        n = rx1.recv() => {
-            let n = n.unwrap();
-            assert_eq!(n, 1);
-            assert_eq!(rx2.recv().unwrap(), 2);
-        },
-        n = rx2.recv() => {
-            let n = n.unwrap();
-            assert_eq!(n, 2);
-            assert_eq!(rx1.recv().unwrap(), 1);
-        }
-    }
-}
diff --git a/src/libstd/sync/mpsc/shared.rs b/src/libstd/sync/mpsc/shared.rs
index cc70a620365..dbcdcdac932 100644
--- a/src/libstd/sync/mpsc/shared.rs
+++ b/src/libstd/sync/mpsc/shared.rs
@@ -9,6 +9,7 @@
 /// channels are quite similar, and this is no coincidence!
 
 pub use self::Failure::*;
+use self::StartResult::*;
 
 use core::cmp;
 use core::intrinsics::abort;
@@ -19,8 +20,6 @@ use crate::ptr;
 use crate::sync::atomic::{AtomicUsize, AtomicIsize, AtomicBool, Ordering};
 use crate::sync::mpsc::blocking::{self, SignalToken};
 use crate::sync::mpsc::mpsc_queue as mpsc;
-use crate::sync::mpsc::select::StartResult::*;
-use crate::sync::mpsc::select::StartResult;
 use crate::sync::{Mutex, MutexGuard};
 use crate::thread;
 use crate::time::Instant;
@@ -57,6 +56,12 @@ pub enum Failure {
     Disconnected,
 }
 
+#[derive(PartialEq, Eq)]
+enum StartResult {
+    Installed,
+    Abort,
+}
+
 impl<T> Packet<T> {
     // Creation of a packet *must* be followed by a call to postinit_lock
     // and later by inherit_blocker
@@ -394,16 +399,6 @@ impl<T> Packet<T> {
     // select implementation
     ////////////////////////////////////////////////////////////////////////////
 
-    // Helper function for select, tests whether this port can receive without
-    // blocking (obviously not an atomic decision).
-    //
-    // This is different than the stream version because there's no need to peek
-    // at the queue, we can just look at the local count.
-    pub fn can_recv(&self) -> bool {
-        let cnt = self.cnt.load(Ordering::SeqCst);
-        cnt == DISCONNECTED || cnt - unsafe { *self.steals.get() } > 0
-    }
-
     // increment the count on the channel (used for selection)
     fn bump(&self, amt: isize) -> isize {
         match self.cnt.fetch_add(amt, Ordering::SeqCst) {
@@ -415,22 +410,6 @@ impl<T> Packet<T> {
         }
     }
 
-    // Inserts the signal token for selection on this port, returning true if
-    // blocking should proceed.
-    //
-    // The code here is the same as in stream.rs, except that it doesn't need to
-    // peek at the channel to see if an upgrade is pending.
-    pub fn start_selection(&self, token: SignalToken) -> StartResult {
-        match self.decrement(token) {
-            Installed => Installed,
-            Abort => {
-                let prev = self.bump(1);
-                assert!(prev == DISCONNECTED || prev >= 0);
-                Abort
-            }
-        }
-    }
-
     // Cancels a previous thread waiting on this port, returning whether there's
     // data on the port.
     //
diff --git a/src/libstd/sync/mpsc/stream.rs b/src/libstd/sync/mpsc/stream.rs
index 7ae6f68b514..40877282761 100644
--- a/src/libstd/sync/mpsc/stream.rs
+++ b/src/libstd/sync/mpsc/stream.rs
@@ -9,7 +9,6 @@
 
 pub use self::Failure::*;
 pub use self::UpgradeResult::*;
-pub use self::SelectionResult::*;
 use self::Message::*;
 
 use core::cmp;
@@ -60,12 +59,6 @@ pub enum UpgradeResult {
     UpWoke(SignalToken),
 }
 
-pub enum SelectionResult<T> {
-    SelSuccess,
-    SelCanceled,
-    SelUpgraded(SignalToken, Receiver<T>),
-}
-
 // Any message could contain an "upgrade request" to a new shared port, so the
 // internal queue it's a queue of T, but rather Message<T>
 enum Message<T> {
@@ -338,27 +331,6 @@ impl<T> Packet<T> {
     // select implementation
     ////////////////////////////////////////////////////////////////////////////
 
-    // Tests to see whether this port can receive without blocking. If Ok is
-    // returned, then that's the answer. If Err is returned, then the returned
-    // port needs to be queried instead (an upgrade happened)
-    pub fn can_recv(&self) -> Result<bool, Receiver<T>> {
-        // We peek at the queue to see if there's anything on it, and we use
-        // this return value to determine if we should pop from the queue and
-        // upgrade this channel immediately. If it looks like we've got an
-        // upgrade pending, then go through the whole recv rigamarole to update
-        // the internal state.
-        match self.queue.peek() {
-            Some(&mut GoUp(..)) => {
-                match self.recv(None) {
-                    Err(Upgraded(port)) => Err(port),
-                    _ => unreachable!(),
-                }
-            }
-            Some(..) => Ok(true),
-            None => Ok(false)
-        }
-    }
-
     // increment the count on the channel (used for selection)
     fn bump(&self, amt: isize) -> isize {
         match self.queue.producer_addition().cnt.fetch_add(amt, Ordering::SeqCst) {
@@ -370,31 +342,6 @@ impl<T> Packet<T> {
         }
     }
 
-    // Attempts to start selecting on this port. Like a oneshot, this can fail
-    // immediately because of an upgrade.
-    pub fn start_selection(&self, token: SignalToken) -> SelectionResult<T> {
-        match self.decrement(token) {
-            Ok(()) => SelSuccess,
-            Err(token) => {
-                let ret = match self.queue.peek() {
-                    Some(&mut GoUp(..)) => {
-                        match self.queue.pop() {
-                            Some(GoUp(port)) => SelUpgraded(token, port),
-                            _ => unreachable!(),
-                        }
-                    }
-                    Some(..) => SelCanceled,
-                    None => SelCanceled,
-                };
-                // Undo our decrement above, and we should be guaranteed that the
-                // previous value is positive because we're not going to sleep
-                let prev = self.bump(1);
-                assert!(prev == DISCONNECTED || prev >= 0);
-                ret
-            }
-        }
-    }
-
     // Removes a previous thread from being blocked in this port
     pub fn abort_selection(&self,
                            was_upgrade: bool) -> Result<bool, Receiver<T>> {
diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs
index b2d9f4c6491..3c4f8e077c9 100644
--- a/src/libstd/sync/mpsc/sync.rs
+++ b/src/libstd/sync/mpsc/sync.rs
@@ -33,7 +33,6 @@ use core::ptr;
 
 use crate::sync::atomic::{Ordering, AtomicUsize};
 use crate::sync::mpsc::blocking::{self, WaitToken, SignalToken};
-use crate::sync::mpsc::select::StartResult::{self, Installed, Abort};
 use crate::sync::{Mutex, MutexGuard};
 use crate::time::Instant;
 
@@ -406,42 +405,6 @@ impl<T> Packet<T> {
         while let Some(token) = queue.dequeue() { token.signal(); }
         waiter.map(|t| t.signal());
     }
-
-    ////////////////////////////////////////////////////////////////////////////
-    // select implementation
-    ////////////////////////////////////////////////////////////////////////////
-
-    // If Ok, the value is whether this port has data, if Err, then the upgraded
-    // port needs to be checked instead of this one.
-    pub fn can_recv(&self) -> bool {
-        let guard = self.lock.lock().unwrap();
-        guard.disconnected || guard.buf.size() > 0
-    }
-
-    // Attempts to start selection on this port. This can either succeed or fail
-    // because there is data waiting.
-    pub fn start_selection(&self, token: SignalToken) -> StartResult {
-        let mut guard = self.lock.lock().unwrap();
-        if guard.disconnected || guard.buf.size() > 0 {
-            Abort
-        } else {
-            match mem::replace(&mut guard.blocker, BlockedReceiver(token)) {
-                NoneBlocked => {}
-                BlockedSender(..) => unreachable!(),
-                BlockedReceiver(..) => unreachable!(),
-            }
-            Installed
-        }
-    }
-
-    // Remove a previous selecting thread from this port. This ensures that the
-    // blocked thread will no longer be visible to any other threads.
-    //
-    // The return value indicates whether there's data on this port.
-    pub fn abort_selection(&self) -> bool {
-        let mut guard = self.lock.lock().unwrap();
-        abort_selection(&mut guard)
-    }
 }
 
 impl<T> Drop for Packet<T> {
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index 11ac34fcb24..87c2318a937 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -376,6 +376,8 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Mutex<T> {
 impl<T> From<T> for Mutex<T> {
     /// Creates a new mutex in an unlocked state ready for use.
     /// This is equivalent to [`Mutex::new`].
+    ///
+    /// [`Mutex::new`]: ../../std/sync/struct.Mutex.html#method.new
     fn from(t: T) -> Self {
         Mutex::new(t)
     }
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 1299a744095..b1b56f321fc 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -453,6 +453,8 @@ impl<T: Default> Default for RwLock<T> {
 impl<T> From<T> for RwLock<T> {
     /// Creates a new instance of an `RwLock<T>` which is unlocked.
     /// This is equivalent to [`RwLock::new`].
+    ///
+    /// [`RwLock::new`]: ../../std/sync/struct.RwLock.html#method.new
     fn from(t: T) -> Self {
         RwLock::new(t)
     }
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs
index 18de1096df2..6ba947d4598 100644
--- a/src/libstd/sys/unix/args.rs
+++ b/src/libstd/sys/unix/args.rs
@@ -35,6 +35,8 @@ impl Iterator for Args {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> { self.iter.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
+    #[inline]
+    fn last(mut self) -> Option<OsString> { self.next_back() }
 }
 
 impl ExactSizeIterator for Args {
@@ -49,7 +51,6 @@ impl DoubleEndedIterator for Args {
           target_os = "android",
           target_os = "freebsd",
           target_os = "dragonfly",
-          target_os = "bitrig",
           target_os = "netbsd",
           target_os = "openbsd",
           target_os = "solaris",
diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs
index f9592d5c45f..891013406a1 100644
--- a/src/libstd/sys/unix/env.rs
+++ b/src/libstd/sys/unix/env.rs
@@ -53,17 +53,6 @@ pub mod os {
     pub const EXE_EXTENSION: &str = "";
 }
 
-#[cfg(target_os = "bitrig")]
-pub mod os {
-    pub const FAMILY: &str = "unix";
-    pub const OS: &str = "bitrig";
-    pub const DLL_PREFIX: &str = "lib";
-    pub const DLL_SUFFIX: &str = ".so";
-    pub const DLL_EXTENSION: &str = "so";
-    pub const EXE_SUFFIX: &str = "";
-    pub const EXE_EXTENSION: &str = "";
-}
-
 #[cfg(target_os = "netbsd")]
 pub mod os {
     pub const FAMILY: &str = "unix";
diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs
index 45a850aa4a8..3ccb0a1b1ab 100644
--- a/src/libstd/sys/unix/ext/net.rs
+++ b/src/libstd/sys/unix/ext/net.rs
@@ -32,12 +32,12 @@ use crate::sys_common::{self, AsInner, FromInner, IntoInner};
 #[cfg(any(target_os = "linux", target_os = "android",
           target_os = "dragonfly", target_os = "freebsd",
           target_os = "openbsd", target_os = "netbsd",
-          target_os = "haiku", target_os = "bitrig"))]
+          target_os = "haiku"))]
 use libc::MSG_NOSIGNAL;
 #[cfg(not(any(target_os = "linux", target_os = "android",
               target_os = "dragonfly", target_os = "freebsd",
               target_os = "openbsd", target_os = "netbsd",
-              target_os = "haiku", target_os = "bitrig")))]
+              target_os = "haiku")))]
 const MSG_NOSIGNAL: libc::c_int = 0x0;
 
 fn sun_path_offset() -> usize {
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 22c05a72a91..cc1f0790d43 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -147,8 +147,7 @@ impl FileAttr {
         }))
     }
 
-    #[cfg(any(target_os = "bitrig",
-              target_os = "freebsd",
+    #[cfg(any(target_os = "freebsd",
               target_os = "openbsd",
               target_os = "macos",
               target_os = "ios"))]
@@ -159,8 +158,7 @@ impl FileAttr {
         }))
     }
 
-    #[cfg(not(any(target_os = "bitrig",
-                  target_os = "freebsd",
+    #[cfg(not(any(target_os = "freebsd",
                   target_os = "openbsd",
                   target_os = "macos",
                   target_os = "ios")))]
@@ -355,7 +353,6 @@ impl DirEntry {
 
     #[cfg(any(target_os = "freebsd",
               target_os = "openbsd",
-              target_os = "bitrig",
               target_os = "netbsd",
               target_os = "dragonfly"))]
     pub fn ino(&self) -> u64 {
@@ -367,8 +364,7 @@ impl DirEntry {
               target_os = "netbsd",
               target_os = "openbsd",
               target_os = "freebsd",
-              target_os = "dragonfly",
-              target_os = "bitrig"))]
+              target_os = "dragonfly"))]
     fn name_bytes(&self) -> &[u8] {
         use crate::slice;
         unsafe {
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index 90e26449ae2..c2b264ff8de 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -5,7 +5,6 @@ use crate::io::ErrorKind;
 #[cfg(any(rustdoc, target_os = "linux"))] pub use crate::os::linux as platform;
 
 #[cfg(all(not(rustdoc), target_os = "android"))]   pub use crate::os::android as platform;
-#[cfg(all(not(rustdoc), target_os = "bitrig"))]    pub use crate::os::bitrig as platform;
 #[cfg(all(not(rustdoc), target_os = "dragonfly"))] pub use crate::os::dragonfly as platform;
 #[cfg(all(not(rustdoc), target_os = "freebsd"))]   pub use crate::os::freebsd as platform;
 #[cfg(all(not(rustdoc), target_os = "haiku"))]     pub use crate::os::haiku as platform;
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 726b17969b7..dad19eabf7d 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -33,8 +33,7 @@ extern {
                    target_os = "fuchsia",
                    target_os = "l4re"),
                link_name = "__errno_location")]
-    #[cfg_attr(any(target_os = "bitrig",
-                   target_os = "netbsd",
+    #[cfg_attr(any(target_os = "netbsd",
                    target_os = "openbsd",
                    target_os = "android",
                    target_os = "hermit",
@@ -257,7 +256,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
     sysctl().or_else(|_| procfs())
 }
 
-#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
+#[cfg(target_os = "openbsd")]
 pub fn current_exe() -> io::Result<PathBuf> {
     unsafe {
         let mut mib = [libc::CTL_KERN,
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs
index e923b9aa29b..71c62461ee9 100644
--- a/src/libstd/sys/unix/rand.rs
+++ b/src/libstd/sys/unix/rand.rs
@@ -13,7 +13,6 @@ pub fn hashmap_random_keys() -> (u64, u64) {
 
 #[cfg(all(unix,
           not(target_os = "ios"),
-          not(all(target_os = "macos", miri)),
           not(target_os = "openbsd"),
           not(target_os = "freebsd"),
           not(target_os = "fuchsia")))]
@@ -48,7 +47,12 @@ mod imp {
                 let err = errno() as libc::c_int;
                 if err == libc::EINTR {
                     continue;
-                } else if err == libc::ENOSYS {
+                } else if err == libc::ENOSYS || err == libc::EPERM {
+                    // Fall back to reading /dev/urandom if `getrandom` is not
+                    // supported on the current kernel.
+                    //
+                    // Also fall back in case it is disabled by something like
+                    // seccomp or inside of virtual machines.
                     GETRANDOM_UNAVAILABLE.store(true, Ordering::Relaxed);
                     return false;
                 } else if err == libc::EAGAIN {
@@ -107,9 +111,7 @@ mod imp {
 // once per thread in `hashmap_random_keys`. Therefore `SecRandomCopyBytes` is
 // only used on iOS where direct access to `/dev/urandom` is blocked by the
 // sandbox.
-// HACK: However, we do use this when running in Miri on macOS; intercepting this is much
-// easier than intercepting accesses to /dev/urandom.
-#[cfg(any(target_os = "ios", all(target_os = "macos", miri)))]
+#[cfg(target_os = "ios")]
 mod imp {
     use crate::io;
     use crate::ptr;
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 561279e8278..fe1095fa0c2 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -25,7 +25,6 @@ impl Drop for Handler {
 
 #[cfg(any(target_os = "linux",
           target_os = "macos",
-          target_os = "bitrig",
           target_os = "dragonfly",
           target_os = "freebsd",
           target_os = "solaris",
@@ -139,7 +138,6 @@ mod imp {
 
     #[cfg(any(target_os = "linux",
               target_os = "macos",
-              target_os = "bitrig",
               target_os = "freebsd",
               target_os = "netbsd",
               target_os = "openbsd",
@@ -185,7 +183,6 @@ mod imp {
 
 #[cfg(not(any(target_os = "linux",
               target_os = "macos",
-              target_os = "bitrig",
               target_os = "dragonfly",
               target_os = "freebsd",
               target_os = "solaris",
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index f7d604ac4c8..f4a1783ce89 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -99,7 +99,6 @@ impl Thread {
 
     #[cfg(any(target_os = "freebsd",
               target_os = "dragonfly",
-              target_os = "bitrig",
               target_os = "openbsd"))]
     pub fn set_name(name: &CStr) {
         unsafe {
@@ -189,7 +188,6 @@ impl Drop for Thread {
 #[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))),
           not(target_os = "freebsd"),
           not(target_os = "macos"),
-          not(target_os = "bitrig"),
           not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
           not(target_os = "openbsd"),
           not(target_os = "solaris")))]
@@ -205,7 +203,6 @@ pub mod guard {
 #[cfg(any(all(target_os = "linux", not(target_env = "musl")),
           target_os = "freebsd",
           target_os = "macos",
-          target_os = "bitrig",
           all(target_os = "netbsd", not(target_vendor = "rumprun")),
           target_os = "openbsd",
           target_os = "solaris"))]
@@ -236,16 +233,15 @@ pub mod guard {
         Some(stackaddr as *mut libc::c_void)
     }
 
-    #[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
+    #[cfg(target_os = "openbsd")]
     unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
         let mut current_stack: libc::stack_t = crate::mem::zeroed();
         assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(),
                                              &mut current_stack), 0);
 
-        let extra = if cfg!(target_os = "bitrig") {3} else {1} * PAGE_SIZE;
         let stackaddr = if libc::pthread_main_np() == 1 {
             // main thread
-            current_stack.ss_sp as usize - current_stack.ss_size + extra
+            current_stack.ss_sp as usize - current_stack.ss_size + PAGE_SIZE
         } else {
             // new thread
             current_stack.ss_sp as usize - current_stack.ss_size
@@ -343,7 +339,6 @@ pub mod guard {
     }
 
     #[cfg(any(target_os = "macos",
-              target_os = "bitrig",
               target_os = "openbsd",
               target_os = "solaris"))]
     pub unsafe fn current() -> Option<Guard> {
diff --git a/src/libstd/sys/wasm/args.rs b/src/libstd/sys/wasm/args.rs
index b3c77b86995..6766099c1ec 100644
--- a/src/libstd/sys/wasm/args.rs
+++ b/src/libstd/sys/wasm/args.rs
@@ -37,6 +37,10 @@ impl Iterator for Args {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+    #[inline]
+    fn last(mut self) -> Option<OsString> {
+        self.next_back()
+    }
 }
 
 impl ExactSizeIterator for Args {
diff --git a/src/libstd/sys/windows/args.rs b/src/libstd/sys/windows/args.rs
index b04bb484eed..744d7ec59d3 100644
--- a/src/libstd/sys/windows/args.rs
+++ b/src/libstd/sys/windows/args.rs
@@ -181,6 +181,8 @@ impl Iterator for Args {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> { self.parsed_args_list.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.parsed_args_list.size_hint() }
+    #[inline]
+    fn last(mut self) -> Option<OsString> { self.next_back() }
 }
 
 impl DoubleEndedIterator for Args {
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs
index cf1dc20b52f..391f670346f 100644
--- a/src/libstd/sys_common/net.rs
+++ b/src/libstd/sys_common/net.rs
@@ -37,12 +37,12 @@ use crate::sys::net::netc::IPV6_DROP_MEMBERSHIP;
 #[cfg(any(target_os = "linux", target_os = "android",
           target_os = "dragonfly", target_os = "freebsd",
           target_os = "openbsd", target_os = "netbsd",
-          target_os = "haiku", target_os = "bitrig"))]
+          target_os = "haiku"))]
 use libc::MSG_NOSIGNAL;
 #[cfg(not(any(target_os = "linux", target_os = "android",
               target_os = "dragonfly", target_os = "freebsd",
               target_os = "openbsd", target_os = "netbsd",
-              target_os = "haiku", target_os = "bitrig")))]
+              target_os = "haiku")))]
 const MSG_NOSIGNAL: c_int = 0x0;
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index fce28ffd9c3..35de4f4008b 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -443,6 +443,7 @@ impl Builder {
     /// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
     /// [`io::Result`]: ../../std/io/type.Result.html
     /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
+    /// [`JoinHandle::join`]: ../../std/thread/struct.JoinHandle.html#method.join
     #[unstable(feature = "thread_spawn_unchecked", issue = "55132")]
     pub unsafe fn spawn_unchecked<'a, F, T>(self, f: F) -> io::Result<JoinHandle<T>> where
         F: FnOnce() -> T, F: Send + 'a, T: Send + 'a