about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorphosphorus <steepout@qq.com>2019-08-19 00:34:02 -0500
committerGitHub <noreply@github.com>2019-08-19 00:34:02 -0500
commit92f08b78a12ff119af853cb2bf58468208ea6a90 (patch)
treeb4636f43c056de11dd69130ce47039343a9f52c5 /src/libstd
parent963184bbb670c1ffa97fc28a98cd5e8473118859 (diff)
parenta807902dd6b4222179776c3f3c33da8dafdd4da1 (diff)
downloadrust-92f08b78a12ff119af853cb2bf58468208ea6a90.tar.gz
rust-92f08b78a12ff119af853cb2bf58468208ea6a90.zip
Merge pull request #1 from rust-lang/master
Pull from newest repo
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/Cargo.toml35
-rw-r--r--src/libstd/alloc.rs5
-rw-r--r--src/libstd/build.rs6
-rw-r--r--src/libstd/collections/hash/map.rs32
-rw-r--r--src/libstd/collections/hash/set.rs8
-rw-r--r--src/libstd/collections/mod.rs2
-rw-r--r--src/libstd/env.rs27
-rw-r--r--src/libstd/error.rs58
-rw-r--r--src/libstd/f32.rs8
-rw-r--r--src/libstd/f64.rs8
-rw-r--r--src/libstd/ffi/c_str.rs21
-rw-r--r--src/libstd/ffi/mod.rs2
-rw-r--r--src/libstd/ffi/os_str.rs15
-rw-r--r--src/libstd/fs.rs10
-rw-r--r--src/libstd/future.rs6
-rw-r--r--src/libstd/io/buffered.rs43
-rw-r--r--src/libstd/io/mod.rs232
-rw-r--r--src/libstd/io/util.rs18
-rw-r--r--src/libstd/keyword_docs.rs71
-rw-r--r--src/libstd/lib.rs90
-rw-r--r--src/libstd/macros.rs658
-rw-r--r--src/libstd/net/addr.rs13
-rw-r--r--src/libstd/net/ip.rs944
-rw-r--r--src/libstd/net/udp.rs4
-rw-r--r--src/libstd/os/linux/fs.rs7
-rw-r--r--src/libstd/os/linux/raw.rs56
-rw-r--r--src/libstd/os/mod.rs6
-rw-r--r--src/libstd/os/raw/mod.rs42
-rw-r--r--src/libstd/os/redox/fs.rs383
-rw-r--r--src/libstd/os/redox/mod.rs6
-rw-r--r--src/libstd/os/redox/raw.rs67
-rw-r--r--src/libstd/os/vxworks/fs.rs84
-rw-r--r--src/libstd/os/vxworks/mod.rs6
-rw-r--r--src/libstd/os/vxworks/raw.rs7
-rw-r--r--src/libstd/panic.rs6
-rw-r--r--src/libstd/panicking.rs11
-rw-r--r--src/libstd/path.rs26
-rw-r--r--src/libstd/prelude/mod.rs3
-rw-r--r--src/libstd/prelude/v1.rs63
-rw-r--r--src/libstd/primitive_docs.rs49
-rw-r--r--src/libstd/process.rs32
-rw-r--r--src/libstd/sync/condvar.rs36
-rw-r--r--src/libstd/sync/mod.rs1
-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.rs55
-rw-r--r--src/libstd/sync/mutex.rs2
-rw-r--r--src/libstd/sync/once.rs5
-rw-r--r--src/libstd/sync/rwlock.rs2
-rw-r--r--src/libstd/sys/cloudabi/abi/cloudabi.rs5
-rw-r--r--src/libstd/sys/cloudabi/backtrace.rs116
-rw-r--r--src/libstd/sys/cloudabi/condvar.rs29
-rw-r--r--src/libstd/sys/cloudabi/io.rs14
-rw-r--r--src/libstd/sys/cloudabi/mod.rs11
-rw-r--r--src/libstd/sys/cloudabi/mutex.rs33
-rw-r--r--src/libstd/sys/cloudabi/rwlock.rs15
-rw-r--r--src/libstd/sys/cloudabi/thread.rs7
-rw-r--r--src/libstd/sys/cloudabi/time.rs12
-rw-r--r--src/libstd/sys/mod.rs16
-rw-r--r--src/libstd/sys/redox/backtrace/mod.rs32
-rw-r--r--src/libstd/sys/redox/backtrace/printing.rs1
-rw-r--r--src/libstd/sys/redox/backtrace/tracing.rs99
-rw-r--r--src/libstd/sys/redox/condvar.rs111
-rw-r--r--src/libstd/sys/redox/ext/fs.rs339
-rw-r--r--src/libstd/sys/redox/ext/mod.rs45
-rw-r--r--src/libstd/sys/redox/ext/net.rs759
-rw-r--r--src/libstd/sys/redox/ext/thread.rs39
-rw-r--r--src/libstd/sys/redox/fast_thread_local.rs111
-rw-r--r--src/libstd/sys/redox/fd.rs88
-rw-r--r--src/libstd/sys/redox/fs.rs447
-rw-r--r--src/libstd/sys/redox/io.rs32
-rw-r--r--src/libstd/sys/redox/memchr.rs4
-rw-r--r--src/libstd/sys/redox/mod.rs98
-rw-r--r--src/libstd/sys/redox/mutex.rs169
-rw-r--r--src/libstd/sys/redox/net/dns/answer.rs12
-rw-r--r--src/libstd/sys/redox/net/dns/mod.rs205
-rw-r--r--src/libstd/sys/redox/net/dns/query.rs8
-rw-r--r--src/libstd/sys/redox/net/mod.rs140
-rw-r--r--src/libstd/sys/redox/net/netc.rs47
-rw-r--r--src/libstd/sys/redox/net/tcp.rs251
-rw-r--r--src/libstd/sys/redox/net/udp.rs237
-rw-r--r--src/libstd/sys/redox/path.rs29
-rw-r--r--src/libstd/sys/redox/pipe.rs101
-rw-r--r--src/libstd/sys/redox/process.rs614
-rw-r--r--src/libstd/sys/redox/rand.rs3
-rw-r--r--src/libstd/sys/redox/rwlock.rs51
-rw-r--r--src/libstd/sys/redox/syscall/arch/arm.rs73
-rw-r--r--src/libstd/sys/redox/syscall/arch/x86.rs73
-rw-r--r--src/libstd/sys/redox/syscall/arch/x86_64.rs74
-rw-r--r--src/libstd/sys/redox/syscall/call.rs348
-rw-r--r--src/libstd/sys/redox/syscall/data.rs191
-rw-r--r--src/libstd/sys/redox/syscall/error.rs315
-rw-r--r--src/libstd/sys/redox/syscall/flag.rs148
-rw-r--r--src/libstd/sys/redox/syscall/mod.rs33
-rw-r--r--src/libstd/sys/redox/syscall/number.rs73
-rw-r--r--src/libstd/sys/redox/thread.rs84
-rw-r--r--src/libstd/sys/redox/thread_local.rs61
-rw-r--r--src/libstd/sys/redox/time.rs207
-rw-r--r--src/libstd/sys/sgx/abi/usercalls/alloc.rs12
-rw-r--r--src/libstd/sys/sgx/backtrace.rs98
-rw-r--r--src/libstd/sys/sgx/io.rs14
-rw-r--r--src/libstd/sys/sgx/mod.rs4
-rw-r--r--src/libstd/sys/unix/alloc.rs12
-rw-r--r--src/libstd/sys/unix/args.rs5
-rw-r--r--src/libstd/sys/unix/condvar.rs18
-rw-r--r--src/libstd/sys/unix/env.rs11
-rw-r--r--src/libstd/sys/unix/ext/fs.rs2
-rw-r--r--src/libstd/sys/unix/ext/net.rs15
-rw-r--r--src/libstd/sys/unix/fast_thread_local.rs6
-rw-r--r--src/libstd/sys/unix/fd.rs8
-rw-r--r--src/libstd/sys/unix/fs.rs27
-rw-r--r--src/libstd/sys/unix/io.rs25
-rw-r--r--src/libstd/sys/unix/mod.rs3
-rw-r--r--src/libstd/sys/unix/mutex.rs24
-rw-r--r--src/libstd/sys/unix/os.rs30
-rw-r--r--src/libstd/sys/unix/pipe.rs3
-rw-r--r--src/libstd/sys/unix/process/process_common.rs24
-rw-r--r--src/libstd/sys/unix/process/process_unix.rs115
-rw-r--r--src/libstd/sys/unix/rand.rs22
-rw-r--r--src/libstd/sys/unix/thread.rs18
-rw-r--r--src/libstd/sys/unix/time.rs25
-rw-r--r--src/libstd/sys/vxworks/alloc.rs53
-rw-r--r--src/libstd/sys/vxworks/args.rs (renamed from src/libstd/sys/redox/args.rs)49
-rw-r--r--src/libstd/sys/vxworks/backtrace/mod.rs (renamed from src/libstd/sys/unix/backtrace/mod.rs)0
-rw-r--r--src/libstd/sys/vxworks/backtrace/printing/dladdr.rs (renamed from src/libstd/sys/unix/backtrace/printing/dladdr.rs)1
-rw-r--r--src/libstd/sys/vxworks/backtrace/printing/mod.rs (renamed from src/libstd/sys/unix/backtrace/printing/mod.rs)0
-rw-r--r--src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs (renamed from src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs)0
-rw-r--r--src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs (renamed from src/libstd/sys/unix/backtrace/tracing/gcc_s.rs)0
-rw-r--r--src/libstd/sys/vxworks/backtrace/tracing/mod.rs (renamed from src/libstd/sys/unix/backtrace/tracing/mod.rs)0
-rw-r--r--src/libstd/sys/vxworks/cmath.rs (renamed from src/libstd/sys/redox/cmath.rs)0
-rw-r--r--src/libstd/sys/vxworks/condvar.rs96
-rw-r--r--src/libstd/sys/vxworks/env.rs (renamed from src/libstd/sys/redox/env.rs)4
-rw-r--r--src/libstd/sys/vxworks/ext/ffi.rs (renamed from src/libstd/sys/redox/ext/ffi.rs)6
-rw-r--r--src/libstd/sys/vxworks/ext/fs.rs801
-rw-r--r--src/libstd/sys/vxworks/ext/io.rs (renamed from src/libstd/sys/redox/ext/io.rs)80
-rw-r--r--src/libstd/sys/vxworks/ext/mod.rs20
-rw-r--r--src/libstd/sys/vxworks/ext/net.rs1825
-rw-r--r--src/libstd/sys/vxworks/ext/process.rs (renamed from src/libstd/sys/redox/ext/process.rs)32
-rw-r--r--src/libstd/sys/vxworks/ext/raw.rs5
-rw-r--r--src/libstd/sys/vxworks/fast_thread_local.rs36
-rw-r--r--src/libstd/sys/vxworks/fd.rs188
-rw-r--r--src/libstd/sys/vxworks/fs.rs575
-rw-r--r--src/libstd/sys/vxworks/io.rs86
-rw-r--r--src/libstd/sys/vxworks/memchr.rs24
-rw-r--r--src/libstd/sys/vxworks/mod.rs125
-rw-r--r--src/libstd/sys/vxworks/mutex.rs127
-rw-r--r--src/libstd/sys/vxworks/net.rs357
-rw-r--r--src/libstd/sys/vxworks/os.rs (renamed from src/libstd/sys/redox/os.rs)191
-rw-r--r--src/libstd/sys/vxworks/path.rs19
-rw-r--r--src/libstd/sys/vxworks/pipe.rs95
-rw-r--r--src/libstd/sys/vxworks/process/mod.rs7
-rw-r--r--src/libstd/sys/vxworks/process/process_common.rs405
-rw-r--r--src/libstd/sys/vxworks/process/process_vxworks.rs156
-rw-r--r--src/libstd/sys/vxworks/process/rtp.rs298
-rw-r--r--src/libstd/sys/vxworks/rand.rs31
-rw-r--r--src/libstd/sys/vxworks/rwlock.rs113
-rw-r--r--src/libstd/sys/vxworks/stack_overflow.rs41
-rw-r--r--src/libstd/sys/vxworks/stdio.rs (renamed from src/libstd/sys/redox/stdio.rs)19
-rw-r--r--src/libstd/sys/vxworks/thread.rs143
-rw-r--r--src/libstd/sys/vxworks/thread_local.rs34
-rw-r--r--src/libstd/sys/vxworks/time.rs224
-rw-r--r--src/libstd/sys/vxworks/weak.rs60
-rw-r--r--src/libstd/sys/wasi/args.rs2
-rw-r--r--src/libstd/sys/wasi/backtrace.rs27
-rw-r--r--src/libstd/sys/wasi/io.rs25
-rw-r--r--src/libstd/sys/wasi/mod.rs4
-rw-r--r--src/libstd/sys/wasm/args.rs4
-rw-r--r--src/libstd/sys/wasm/backtrace.rs27
-rw-r--r--src/libstd/sys/wasm/fast_thread_local.rs9
-rw-r--r--src/libstd/sys/wasm/io.rs14
-rw-r--r--src/libstd/sys/wasm/mod.rs9
-rw-r--r--src/libstd/sys/wasm/thread.rs76
-rw-r--r--src/libstd/sys/wasm/thread_local.rs32
-rw-r--r--src/libstd/sys/wasm/thread_local_atomics.rs61
-rw-r--r--src/libstd/sys/windows/args.rs2
-rw-r--r--src/libstd/sys/windows/backtrace/backtrace_gnu.rs53
-rw-r--r--src/libstd/sys/windows/backtrace/mod.rs355
-rw-r--r--src/libstd/sys/windows/backtrace/printing/mod.rs24
-rw-r--r--src/libstd/sys/windows/backtrace/printing/msvc.rs208
-rw-r--r--src/libstd/sys/windows/c.rs592
-rw-r--r--src/libstd/sys/windows/compat.rs2
-rw-r--r--src/libstd/sys/windows/dynamic_lib.rs44
-rw-r--r--src/libstd/sys/windows/ext/fs.rs30
-rw-r--r--src/libstd/sys/windows/fast_thread_local.rs4
-rw-r--r--src/libstd/sys/windows/fs.rs90
-rw-r--r--src/libstd/sys/windows/io.rs25
-rw-r--r--src/libstd/sys/windows/mod.rs19
-rw-r--r--src/libstd/sys/windows/net.rs51
-rw-r--r--src/libstd/sys/windows/os.rs23
-rw-r--r--src/libstd/sys/windows/path.rs2
-rw-r--r--src/libstd/sys/windows/pipe.rs11
-rw-r--r--src/libstd/sys/windows/process.rs7
-rw-r--r--src/libstd/sys/windows/rand.rs18
-rw-r--r--src/libstd/sys/windows/stack_overflow_uwp.rs (renamed from src/libstd/sys/redox/stack_overflow.rs)10
-rw-r--r--src/libstd/sys/windows/stdio_uwp.rs85
-rw-r--r--src/libstd/sys_common/alloc.rs3
-rw-r--r--src/libstd/sys_common/backtrace.rs304
-rw-r--r--src/libstd/sys_common/gnu/libbacktrace.rs175
-rw-r--r--src/libstd/sys_common/gnu/mod.rs5
-rw-r--r--src/libstd/sys_common/io.rs2
-rw-r--r--src/libstd/sys_common/mod.rs9
-rw-r--r--src/libstd/sys_common/os_str_bytes.rs6
-rw-r--r--src/libstd/thread/local.rs295
-rw-r--r--src/libstd/thread/mod.rs3
-rw-r--r--src/libstd/time.rs10
209 files changed, 9626 insertions, 10269 deletions
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 55e8b39974e..3288d0b4df2 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -15,16 +15,27 @@ crate-type = ["dylib", "rlib"]
 
 [dependencies]
 alloc = { path = "../liballoc" }
+cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
 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.14" }
+compiler_builtins = { version = "0.1.16" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
-hashbrown = { version = "0.3.0", features = ['rustc-dep-of-std'] }
-rustc-demangle = { version = "0.1.10", features = ['rustc-dep-of-std'] }
-backtrace-sys = { version = "0.1.24", features = ["rustc-dep-of-std"], optional = true }
+hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] }
+
+[dependencies.backtrace]
+version = "0.3.34"
+default-features = false # don't use coresymbolication on OSX
+features = [
+  "rustc-dep-of-std", # enable build support for integrating into libstd
+  "dbghelp",          # backtrace/symbolize on MSVC
+  "libbacktrace",     # symbolize on most platforms
+  "libunwind",        # backtrace on most platforms
+  "dladdr",           # symbolize on platforms w/o libbacktrace
+]
+optional = true
 
 [dev-dependencies]
 rand = "0.6.1"
@@ -49,12 +60,11 @@ fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
 cc = "1.0"
 
 [features]
-default = ["compiler_builtins_c", "std_detect_file_io", "std_detect_dlsym_getauxval"]
+default = ["std_detect_file_io", "std_detect_dlsym_getauxval"]
 
-backtrace = ["backtrace-sys"]
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
-compiler_builtins_c = ["alloc/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
@@ -65,16 +75,13 @@ panic_immediate_abort = ["core/panic_immediate_abort"]
 # requires rebuilding the standard library to use it.
 wasm_syscall = []
 
-# An off-by-default features to enable libstd to assume that wasm-bindgen is in
-# the environment for hooking up some thread-related information like the
-# current thread id and accessing/getting the current thread's TCB
-wasm-bindgen-threads = []
-
-# Enable std_detect default features for stdsimd:
-# https://github.com/rust-lang-nursery/stdsimd/blob/master/crates/std_detect/Cargo.toml
+# Enable std_detect default features for stdarch/crates/std_detect:
+# https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml
 std_detect_file_io = []
 std_detect_dlsym_getauxval = []
 
 [package.metadata.fortanix-sgx]
 # Maximum possible number of threads when testing
 threads = 125
+# Maximum heap size
+heap_size = 0x8000000
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 7a6c97ebaa2..8db7bc12cd3 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -1,5 +1,3 @@
-#![deny(warnings)]
-
 use std::env;
 
 fn main() {
@@ -39,6 +37,10 @@ fn main() {
         println!("cargo:rustc-link-lib=framework=Security");
         println!("cargo:rustc-link-lib=framework=Foundation");
         println!("cargo:rustc-link-lib=resolv");
+    } else if target.contains("uwp") {
+        println!("cargo:rustc-link-lib=ws2_32");
+        // For BCryptGenRandom
+        println!("cargo:rustc-link-lib=bcrypt");
     } else if target.contains("windows") {
         println!("cargo:rustc-link-lib=advapi32");
         println!("cargo:rustc-link-lib=ws2_32");
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 478f63ab3d7..a0538986a22 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -6,7 +6,7 @@ use hashbrown::hash_map as base;
 
 use crate::borrow::Borrow;
 use crate::cell::Cell;
-use crate::collections::CollectionAllocErr;
+use crate::collections::TryReserveError;
 use crate::fmt::{self, Debug};
 #[allow(deprecated)]
 use crate::hash::{BuildHasher, Hash, Hasher, SipHasher13};
@@ -588,7 +588,7 @@ where
     /// ```
     #[inline]
     #[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
-    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.base
             .try_reserve(additional)
             .map_err(map_collection_alloc_err)
@@ -2494,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()
@@ -2539,10 +2542,13 @@ fn map_entry<'a, K: 'a, V: 'a>(raw: base::RustcEntry<'a, K, V>) -> Entry<'a, K,
 }
 
 #[inline]
-fn map_collection_alloc_err(err: hashbrown::CollectionAllocErr) -> CollectionAllocErr {
+fn map_collection_alloc_err(err: hashbrown::CollectionAllocErr) -> TryReserveError {
     match err {
-        hashbrown::CollectionAllocErr::CapacityOverflow => CollectionAllocErr::CapacityOverflow,
-        hashbrown::CollectionAllocErr::AllocErr => CollectionAllocErr::AllocErr,
+        hashbrown::CollectionAllocErr::CapacityOverflow => TryReserveError::CapacityOverflow,
+        hashbrown::CollectionAllocErr::AllocErr { layout } => TryReserveError::AllocError {
+            layout,
+            non_exhaustive: (),
+        },
     }
 }
 
@@ -2602,9 +2608,15 @@ mod test_map {
     use super::RandomState;
     use crate::cell::RefCell;
     use rand::{thread_rng, Rng};
-    use realstd::collections::CollectionAllocErr::*;
+    use realstd::collections::TryReserveError::*;
     use realstd::usize;
 
+    // https://github.com/rust-lang/rust/issues/62301
+    fn _assert_hashmap_is_unwind_safe() {
+        fn assert_unwind_safe<T: crate::panic::UnwindSafe>() {}
+        assert_unwind_safe::<HashMap<(), crate::cell::UnsafeCell<()>>>();
+    }
+
     #[test]
     fn test_zero_capacities() {
         type HM = HashMap<i32, i32>;
@@ -3129,13 +3141,15 @@ mod test_map {
 
     #[test]
     fn test_from_iter() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+        let xs = [(1, 1), (2, 2), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
 
         let map: HashMap<_, _> = xs.iter().cloned().collect();
 
         for &(k, v) in &xs {
             assert_eq!(map.get(&k), Some(&v));
         }
+
+        assert_eq!(map.iter().len(), xs.len() - 1);
     }
 
     #[test]
@@ -3394,7 +3408,7 @@ mod test_map {
             panic!("usize::MAX should trigger an overflow!");
         }
 
-        if let Err(AllocErr) = empty_bytes.try_reserve(MAX_USIZE / 8) {
+        if let Err(AllocError { .. }) = empty_bytes.try_reserve(MAX_USIZE / 8) {
         } else {
             panic!("usize::MAX / 8 should trigger an OOM!")
         }
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 403914c0707..26db651ef89 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -1,5 +1,5 @@
 use crate::borrow::Borrow;
-use crate::collections::CollectionAllocErr;
+use crate::collections::TryReserveError;
 use crate::fmt;
 use crate::hash::{Hash, BuildHasher};
 use crate::iter::{Chain, FromIterator, FusedIterator};
@@ -383,7 +383,7 @@ impl<T, S> HashSet<T, S>
     /// ```
     #[inline]
     #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-    pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
         self.map.try_reserve(additional)
     }
 
@@ -1782,13 +1782,15 @@ mod test_set {
 
     #[test]
     fn test_from_iter() {
-        let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
+        let xs = [1, 2, 2, 3, 4, 5, 6, 7, 8, 9];
 
         let set: HashSet<_> = xs.iter().cloned().collect();
 
         for x in &xs {
             assert!(set.contains(x));
         }
+
+        assert_eq!(set.iter().len(), xs.len() - 1);
     }
 
     #[test]
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index 15c2532f8b4..f5957466be8 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -427,7 +427,7 @@ pub use self::hash_map::HashMap;
 pub use self::hash_set::HashSet;
 
 #[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
-pub use alloc_crate::collections::CollectionAllocErr;
+pub use alloc_crate::collections::TryReserveError;
 
 mod hash;
 
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index 260624a8bd8..eca93399e58 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -182,6 +182,12 @@ impl fmt::Debug for VarsOs {
 /// * Environment variable is not present
 /// * Environment variable is not valid unicode
 ///
+/// # Panics
+///
+/// This function may panic if `key` is empty, contains an ASCII equals sign
+/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
+/// character.
+///
 /// # Examples
 ///
 /// ```
@@ -210,6 +216,12 @@ fn _var(key: &OsStr) -> Result<String, VarError> {
 ///
 /// [`None`]: ../option/enum.Option.html#variant.None
 ///
+/// # Panics
+///
+/// This function may panic if `key` is empty, contains an ASCII equals sign
+/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
+/// character.
+///
 /// # Examples
 ///
 /// ```
@@ -465,7 +477,7 @@ pub struct JoinPathsError {
 /// # }
 /// ```
 ///
-/// Using `env::join_paths` with `env::spit_paths` to append an item to the `PATH` environment
+/// Using `env::join_paths` with [`env::split_paths`] to append an item to the `PATH` environment
 /// variable:
 ///
 /// ```
@@ -483,6 +495,8 @@ pub struct JoinPathsError {
 ///     Ok(())
 /// }
 /// ```
+///
+/// [`env::split_paths`]: fn.split_paths.html
 #[stable(feature = "env", since = "1.0.0")]
 pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
     where I: IntoIterator<Item=T>, T: AsRef<OsStr>
@@ -746,10 +760,6 @@ 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")]
@@ -785,8 +795,6 @@ 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")]
@@ -979,6 +987,11 @@ mod arch {
     pub const ARCH: &str = "wasm32";
 }
 
+#[cfg(target_arch = "hexagon")]
+mod arch {
+    pub const ARCH: &'static str = "hexagon";
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 62282006a40..117a430eec6 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -94,7 +94,7 @@ pub trait Error: Debug + Display {
     ///         "I'm the superhero of errors"
     ///     }
     ///
-    ///     fn cause(&self) -> Option<&Error> {
+    ///     fn cause(&self) -> Option<&dyn Error> {
     ///         Some(&self.side)
     ///     }
     /// }
@@ -218,6 +218,8 @@ mod private {
 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
     ///
     /// ```
@@ -242,7 +244,7 @@ impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
     ///
     /// let an_error = AnError;
     /// assert!(0 == mem::size_of_val(&an_error));
-    /// let a_boxed_error = Box::<Error>::from(an_error);
+    /// let a_boxed_error = Box::<dyn Error>::from(an_error);
     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
     /// ```
     fn from(err: E) -> Box<dyn Error + 'a> {
@@ -252,8 +254,10 @@ impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
-    /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of dyn [`Error`] +
-    /// [`Send`] + [`Sync`].
+    /// Converts a type of [`Error`] + [`trait@Send`] + [`trait@Sync`] into a box of
+    /// dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
+    ///
+    /// [`Error`]: ../error/trait.Error.html
     ///
     /// # Examples
     ///
@@ -283,7 +287,7 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync +
     ///
     /// let an_error = AnError;
     /// assert!(0 == mem::size_of_val(&an_error));
-    /// let a_boxed_error = Box::<Error + Send + Sync>::from(an_error);
+    /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
     /// assert!(
     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
     /// ```
@@ -294,7 +298,9 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync +
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl From<String> for Box<dyn Error + Send + Sync> {
-    /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
+    /// Converts a [`String`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
+    ///
+    /// [`Error`]: ../error/trait.Error.html
     ///
     /// # Examples
     ///
@@ -303,12 +309,11 @@ impl From<String> for Box<dyn Error + Send + Sync> {
     /// use std::mem;
     ///
     /// let a_string_error = "a string error".to_string();
-    /// let a_boxed_error = Box::<Error + Send + Sync>::from(a_string_error);
+    /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
     /// assert!(
     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
     /// ```
     fn from(err: String) -> Box<dyn Error + Send + Sync> {
-        #[derive(Debug)]
         struct StringError(String);
 
         impl Error for StringError {
@@ -321,6 +326,13 @@ impl From<String> for Box<dyn Error + Send + Sync> {
             }
         }
 
+        // Purposefully skip printing "StringError(..)"
+        impl Debug for StringError {
+            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+                Debug::fmt(&self.0, f)
+            }
+        }
+
         Box::new(StringError(err))
     }
 }
@@ -329,6 +341,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
     ///
     /// ```
@@ -336,7 +350,7 @@ impl From<String> for Box<dyn Error> {
     /// use std::mem;
     ///
     /// let a_string_error = "a string error".to_string();
-    /// let a_boxed_error = Box::<Error>::from(a_string_error);
+    /// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
     /// ```
     fn from(str_err: String) -> Box<dyn Error> {
@@ -348,7 +362,9 @@ impl From<String> for Box<dyn Error> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
-    /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`].
+    /// Converts a [`str`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
+    ///
+    /// [`Error`]: ../error/trait.Error.html
     ///
     /// # Examples
     ///
@@ -357,7 +373,7 @@ impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
     /// use std::mem;
     ///
     /// let a_str_error = "a str error";
-    /// let a_boxed_error = Box::<Error + Send + Sync>::from(a_str_error);
+    /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
     /// assert!(
     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
     /// ```
@@ -370,6 +386,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
     ///
     /// ```
@@ -377,7 +395,7 @@ impl From<&str> for Box<dyn Error> {
     /// use std::mem;
     ///
     /// let a_str_error = "a str error";
-    /// let a_boxed_error = Box::<Error>::from(a_str_error);
+    /// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
     /// ```
     fn from(err: &str) -> Box<dyn Error> {
@@ -387,7 +405,10 @@ impl From<&str> for Box<dyn Error> {
 
 #[stable(feature = "cow_box_error", since = "1.22.0")]
 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`].
+    /// Converts a [`Cow`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`].
+    ///
+    /// [`Cow`]: ../borrow/enum.Cow.html
+    /// [`Error`]: ../error/trait.Error.html
     ///
     /// # Examples
     ///
@@ -397,7 +418,7 @@ impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
     /// use std::borrow::Cow;
     ///
     /// let a_cow_str_error = Cow::from("a str error");
-    /// let a_boxed_error = Box::<Error + Send + Sync>::from(a_cow_str_error);
+    /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
     /// assert!(
     ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
     /// ```
@@ -410,6 +431,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
     ///
     /// ```
@@ -418,7 +442,7 @@ impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
     /// use std::borrow::Cow;
     ///
     /// let a_cow_str_error = Cow::from("a str error");
-    /// let a_boxed_error = Box::<Error>::from(a_cow_str_error);
+    /// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
     /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
     /// ```
     fn from(err: Cow<'a, str>) -> Box<dyn Error> {
@@ -536,6 +560,10 @@ impl<T: Error> Error for Box<T> {
     fn cause(&self) -> Option<&dyn Error> {
         Error::cause(&**self)
     }
+
+    fn source(&self) -> Option<&(dyn Error + 'static)> {
+        Error::source(&**self)
+    }
 }
 
 #[stable(feature = "fmt_error", since = "1.11.0")]
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 133540ed6b9..f649170c403 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -188,7 +188,7 @@ impl f32 {
         if self.is_nan() {
             NAN
         } else {
-            unsafe { intrinsics::copysignf32(1.0, self) }
+            1.0_f32.copysign(self)
         }
     }
 
@@ -256,7 +256,6 @@ impl f32 {
     /// # Examples
     ///
     /// ```
-    /// #![feature(euclidean_division)]
     /// let a: f32 = 7.0;
     /// let b = 4.0;
     /// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0
@@ -265,7 +264,7 @@ impl f32 {
     /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
     /// ```
     #[inline]
-    #[unstable(feature = "euclidean_division", issue = "49048")]
+    #[stable(feature = "euclidean_division", since = "1.38.0")]
     pub fn div_euclid(self, rhs: f32) -> f32 {
         let q = (self / rhs).trunc();
         if self % rhs < 0.0 {
@@ -288,7 +287,6 @@ impl f32 {
     /// # Examples
     ///
     /// ```
-    /// #![feature(euclidean_division)]
     /// let a: f32 = 7.0;
     /// let b = 4.0;
     /// assert_eq!(a.rem_euclid(b), 3.0);
@@ -299,7 +297,7 @@ impl f32 {
     /// assert!((-std::f32::EPSILON).rem_euclid(3.0) != 0.0);
     /// ```
     #[inline]
-    #[unstable(feature = "euclidean_division", issue = "49048")]
+    #[stable(feature = "euclidean_division", since = "1.38.0")]
     pub fn rem_euclid(self, rhs: f32) -> f32 {
         let r = self % rhs;
         if r < 0.0 {
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index 87467aeed8b..f61630997dc 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -166,7 +166,7 @@ impl f64 {
         if self.is_nan() {
             NAN
         } else {
-            unsafe { intrinsics::copysignf64(1.0, self) }
+            1.0_f64.copysign(self)
         }
     }
 
@@ -232,7 +232,6 @@ impl f64 {
     /// # Examples
     ///
     /// ```
-    /// #![feature(euclidean_division)]
     /// let a: f64 = 7.0;
     /// let b = 4.0;
     /// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0
@@ -241,7 +240,7 @@ impl f64 {
     /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
     /// ```
     #[inline]
-    #[unstable(feature = "euclidean_division", issue = "49048")]
+    #[stable(feature = "euclidean_division", since = "1.38.0")]
     pub fn div_euclid(self, rhs: f64) -> f64 {
         let q = (self / rhs).trunc();
         if self % rhs < 0.0 {
@@ -264,7 +263,6 @@ impl f64 {
     /// # Examples
     ///
     /// ```
-    /// #![feature(euclidean_division)]
     /// let a: f64 = 7.0;
     /// let b = 4.0;
     /// assert_eq!(a.rem_euclid(b), 3.0);
@@ -275,7 +273,7 @@ impl f64 {
     /// assert!((-std::f64::EPSILON).rem_euclid(3.0) != 0.0);
     /// ```
     #[inline]
-    #[unstable(feature = "euclidean_division", issue = "49048")]
+    #[stable(feature = "euclidean_division", since = "1.38.0")]
     pub fn rem_euclid(self, rhs: f64) -> f64 {
         let r = self % rhs;
         if r < 0.0 {
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 5c6c43017cf..512839a12c0 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -195,6 +195,12 @@ pub struct CString {
 /// [`from_ptr`]: #method.from_ptr
 #[derive(Hash)]
 #[stable(feature = "rust1", since = "1.0.0")]
+// FIXME:
+// `fn from` in `impl From<&CStr> for Box<CStr>` current implementation relies
+// on `CStr` being layout-compatible with `[u8]`.
+// When attribute privacy is implemented, `CStr` should be annotated as `#[repr(transparent)]`.
+// Anyway, `CStr` representation and layout are considered implementation detail, are
+// not documented and must not be relied upon.
 pub struct CStr {
     // FIXME: this should not be represented with a DST slice but rather with
     //        just a raw `c_char` along with some form of marker to make
@@ -599,11 +605,12 @@ impl CString {
     ///
     /// [`Drop`]: ../ops/trait.Drop.html
     fn into_inner(self) -> Box<[u8]> {
-        unsafe {
-            let result = ptr::read(&self.inner);
-            mem::forget(self);
-            result
-        }
+        // Rationale: `mem::forget(self)` invalidates the previous call to `ptr::read(&self.inner)`
+        // so we use `ManuallyDrop` to ensure `self` is not dropped.
+        // Then we can return the box directly without invalidating it.
+        // See https://github.com/rust-lang/rust/issues/62553.
+        let this = mem::ManuallyDrop::new(self);
+        unsafe { ptr::read(&this.inner) }
     }
 }
 
@@ -1054,7 +1061,7 @@ impl CStr {
     ///
     /// ```no_run
     /// # #![allow(unused_must_use)]
-    /// use std::ffi::{CString};
+    /// use std::ffi::CString;
     ///
     /// let ptr = CString::new("Hello").expect("CString::new failed").as_ptr();
     /// unsafe {
@@ -1070,7 +1077,7 @@ impl CStr {
     ///
     /// ```no_run
     /// # #![allow(unused_must_use)]
-    /// use std::ffi::{CString};
+    /// use std::ffi::CString;
     ///
     /// let hello = CString::new("Hello").expect("CString::new failed");
     /// let ptr = hello.as_ptr();
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
index 7a38f0ebd5a..69fcfa8b39c 100644
--- a/src/libstd/ffi/mod.rs
+++ b/src/libstd/ffi/mod.rs
@@ -170,7 +170,7 @@ pub use core::ffi::c_void;
            reason = "the `c_variadic` feature has not been properly tested on \
                      all supported platforms",
            issue = "44930")]
-pub use core::ffi::VaList;
+pub use core::ffi::{VaList, VaListImpl};
 
 mod c_str;
 mod os_str;
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 13aee783750..1f384cbada3 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -32,7 +32,7 @@ use crate::sys_common::{AsInner, IntoInner, FromInner};
 /// in each pair are owned strings; the latter are borrowed
 /// references.
 ///
-/// Note, `OsString` and `OsStr` internally do not necessarily hold strings in
+/// Note, `OsString` and [`OsStr`] internally do not necessarily hold strings in
 /// the form native to the platform; While on Unix, strings are stored as a
 /// sequence of 8-bit values, on Windows, where strings are 16-bit value based
 /// as just discussed, strings are also actually stored as a sequence of 8-bit
@@ -97,6 +97,12 @@ pub struct OsString {
 /// [`String`]: ../string/struct.String.html
 /// [conversions]: index.html#conversions
 #[stable(feature = "rust1", since = "1.0.0")]
+// FIXME:
+// `OsStr::from_inner` current implementation relies
+// on `OsStr` being layout-compatible with `Slice`.
+// When attribute privacy is implemented, `OsStr` should be annotated as `#[repr(transparent)]`.
+// Anyway, `OsStr` representation and layout are considered implementation detail, are
+// not documented and must not be relied upon.
 pub struct OsStr {
     inner: Slice
 }
@@ -351,6 +357,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) }
     }
@@ -665,10 +673,11 @@ impl From<&OsStr> for Box<OsStr> {
 
 #[stable(feature = "os_string_from_box", since = "1.18.0")]
 impl From<Box<OsStr>> for OsString {
-    /// Converts a `Box<OsStr>` into a `OsString` without copying or allocating.
+    /// Converts a [`Box`]`<`[`OsStr`]`>` into a `OsString` without copying or
+    /// allocating.
     ///
     /// [`Box`]: ../boxed/struct.Box.html
-    /// [`OsString`]: ../ffi/struct.OsString.html
+    /// [`OsStr`]: ../ffi/struct.OsStr.html
     fn from(boxed: Box<OsStr>) -> OsString {
         boxed.into_os_string()
     }
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 991b45fd4a2..5f76875bd66 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -468,6 +468,8 @@ impl File {
     /// # Errors
     ///
     /// This function will return an error if the file is not opened for writing.
+    /// Also, std::io::ErrorKind::InvalidInput will be returned if the desired
+    /// length would cause an overflow due to the implementation specifics.
     ///
     /// # Examples
     ///
@@ -1812,6 +1814,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
@@ -1974,7 +1978,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// use std::path::Path;
 ///
 /// // one possible implementation of walking a directory only visiting files
-/// fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<()> {
+/// fn visit_dirs(dir: &Path, cb: &dyn Fn(&DirEntry)) -> io::Result<()> {
 ///     if dir.is_dir() {
 ///         for entry in fs::read_dir(dir)? {
 ///             let entry = entry?;
@@ -3314,11 +3318,11 @@ mod tests {
         fs::create_dir_all(&d).unwrap();
         File::create(&f).unwrap();
         if cfg!(not(windows)) {
-            symlink_dir("../d/e", &c).unwrap();
+            symlink_file("../d/e", &c).unwrap();
             symlink_file("../f", &e).unwrap();
         }
         if cfg!(windows) {
-            symlink_dir(r"..\d\e", &c).unwrap();
+            symlink_file(r"..\d\e", &c).unwrap();
             symlink_file(r"..\f", &e).unwrap();
         }
 
diff --git a/src/libstd/future.rs b/src/libstd/future.rs
index c18a314116b..0406549ff07 100644
--- a/src/libstd/future.rs
+++ b/src/libstd/future.rs
@@ -16,12 +16,14 @@ pub use core::future::*;
 ///
 /// This function returns a `GenFuture` underneath, but hides it in `impl Trait` to give
 /// better error messages (`impl Future` rather than `GenFuture<[closure.....]>`).
+#[doc(hidden)]
 #[unstable(feature = "gen_future", issue = "50547")]
 pub fn from_generator<T: Generator<Yield = ()>>(x: T) -> impl Future<Output = T::Return> {
     GenFuture(x)
 }
 
 /// A wrapper around generators used to implement `Future` for `async`/`await` code.
+#[doc(hidden)]
 #[unstable(feature = "gen_future", issue = "50547")]
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
 struct GenFuture<T: Generator<Yield = ()>>(T);
@@ -30,6 +32,7 @@ struct GenFuture<T: Generator<Yield = ()>>(T);
 // self-referential borrows in the underlying generator.
 impl<T: Generator<Yield = ()>> !Unpin for GenFuture<T> {}
 
+#[doc(hidden)]
 #[unstable(feature = "gen_future", issue = "50547")]
 impl<T: Generator<Yield = ()>> Future for GenFuture<T> {
     type Output = T::Return;
@@ -57,6 +60,7 @@ impl Drop for SetOnDrop {
     }
 }
 
+#[doc(hidden)]
 #[unstable(feature = "gen_future", issue = "50547")]
 /// Sets the thread-local task context used by async/await futures.
 pub fn set_task_context<F, R>(cx: &mut Context<'_>, f: F) -> R
@@ -74,6 +78,7 @@ where
     f()
 }
 
+#[doc(hidden)]
 #[unstable(feature = "gen_future", issue = "50547")]
 /// Retrieves the thread-local task context used by async/await futures.
 ///
@@ -105,6 +110,7 @@ where
     unsafe { f(cx_ptr.as_mut()) }
 }
 
+#[doc(hidden)]
 #[unstable(feature = "gen_future", issue = "50547")]
 /// Polls a future in the current thread-local task waker.
 pub fn poll_with_tls_context<F>(f: Pin<&mut F>) -> Poll<F::Output>
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 5be2687d8f5..aaf628e6c26 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -158,7 +158,6 @@ impl<R> BufReader<R> {
     /// # Examples
     ///
     /// ```no_run
-    /// # #![feature(bufreader_buffer)]
     /// use std::io::{BufReader, BufRead};
     /// use std::fs::File;
     ///
@@ -173,7 +172,7 @@ impl<R> BufReader<R> {
     ///     Ok(())
     /// }
     /// ```
-    #[unstable(feature = "bufreader_buffer", issue = "45323")]
+    #[stable(feature = "bufreader_buffer", since = "1.37.0")]
     pub fn buffer(&self) -> &[u8] {
         &self.buf[self.pos..self.cap]
     }
@@ -552,7 +551,6 @@ impl<W: Write> BufWriter<W> {
     /// # Examples
     ///
     /// ```no_run
-    /// # #![feature(bufreader_buffer)]
     /// use std::io::BufWriter;
     /// use std::net::TcpStream;
     ///
@@ -561,7 +559,7 @@ impl<W: Write> BufWriter<W> {
     /// // See how many bytes are currently buffered
     /// let bytes_buffered = buf_writer.buffer().len();
     /// ```
-    #[unstable(feature = "bufreader_buffer", issue = "45323")]
+    #[stable(feature = "bufreader_buffer", since = "1.37.0")]
     pub fn buffer(&self) -> &[u8] {
         &self.buf
     }
@@ -754,7 +752,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
@@ -1163,6 +1161,41 @@ mod tests {
     }
 
     #[test]
+    fn test_buffered_reader_seek_underflow_discard_buffer_between_seeks() {
+        // gimmick reader that returns Err after first seek
+        struct ErrAfterFirstSeekReader {
+            first_seek: bool,
+        }
+        impl Read for ErrAfterFirstSeekReader {
+            fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+                for x in &mut *buf {
+                    *x = 0;
+                }
+                Ok(buf.len())
+            }
+        }
+        impl Seek for ErrAfterFirstSeekReader {
+            fn seek(&mut self, _: SeekFrom) -> io::Result<u64> {
+                if self.first_seek {
+                    self.first_seek = false;
+                    Ok(0)
+                } else {
+                    Err(io::Error::new(io::ErrorKind::Other, "oh no!"))
+                }
+            }
+        }
+
+        let mut reader = BufReader::with_capacity(5, ErrAfterFirstSeekReader { first_seek: true });
+        assert_eq!(reader.fill_buf().ok(), Some(&[0, 0, 0, 0, 0][..]));
+
+        // The following seek will require two underlying seeks.  The first will
+        // succeed but the second will fail.  This should still invalidate the
+        // buffer.
+        assert!(reader.seek(SeekFrom::Current(i64::min_value())).is_err());
+        assert_eq!(reader.buffer().len(), 0);
+    }
+
+    #[test]
     fn test_buffered_writer() {
         let inner = Vec::new();
         let mut writer = BufWriter::with_capacity(2, inner);
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 8fea6251e65..f2b6ce6feb2 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -506,9 +506,18 @@ pub trait Read {
     ///
     /// No guarantees are provided about the contents of `buf` when this
     /// function is called, implementations cannot rely on any property of the
-    /// contents of `buf` being true. It is recommended that implementations
+    /// contents of `buf` being true. It is recommended that *implementations*
     /// only write data to `buf` instead of reading its contents.
     ///
+    /// Correspondingly, however, *callers* of this method may not assume any guarantees
+    /// about how the implementation uses `buf`. The trait is safe to implement,
+    /// so it is possible that the code that's supposed to write to the buffer might also read
+    /// from it. It is your responsibility to make sure that `buf` is initialized
+    /// before calling `read`. Calling `read` with an uninitialized `buf` (of the kind one
+    /// obtains via [`MaybeUninit<T>`]) is not safe, and can lead to undefined behavior.
+    ///
+    /// [`MaybeUninit<T>`]: ../mem/union.MaybeUninit.html
+    ///
     /// # Errors
     ///
     /// If this function encounters any form of I/O or other error, an error
@@ -933,6 +942,62 @@ impl<'a> IoSliceMut<'a> {
     pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
         IoSliceMut(sys::io::IoSliceMut::new(buf))
     }
+
+    /// Advance the internal cursor of the slice.
+    ///
+    /// # Notes
+    ///
+    /// Elements in the slice may be modified if the cursor is not advanced to
+    /// the end of the slice. For example if we have a slice of buffers with 2
+    /// `IoSliceMut`s, both of length 8, and we advance the cursor by 10 bytes
+    /// the first `IoSliceMut` will be untouched however the second will be
+    /// modified to remove the first 2 bytes (10 - 8).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(io_slice_advance)]
+    ///
+    /// use std::io::IoSliceMut;
+    /// use std::mem;
+    /// use std::ops::Deref;
+    ///
+    /// let mut buf1 = [1; 8];
+    /// let mut buf2 = [2; 16];
+    /// let mut buf3 = [3; 8];
+    /// let mut bufs = &mut [
+    ///     IoSliceMut::new(&mut buf1),
+    ///     IoSliceMut::new(&mut buf2),
+    ///     IoSliceMut::new(&mut buf3),
+    /// ][..];
+    ///
+    /// // Mark 10 bytes as read.
+    /// bufs = IoSliceMut::advance(mem::replace(&mut bufs, &mut []), 10);
+    /// assert_eq!(bufs[0].deref(), [2; 14].as_ref());
+    /// assert_eq!(bufs[1].deref(), [3; 8].as_ref());
+    /// ```
+    #[unstable(feature = "io_slice_advance", issue = "62726")]
+    #[inline]
+    pub fn advance<'b>(bufs: &'b mut [IoSliceMut<'a>], n: usize) -> &'b mut [IoSliceMut<'a>] {
+        // Number of buffers to remove.
+        let mut remove = 0;
+        // Total length of all the to be removed buffers.
+        let mut accumulated_len = 0;
+        for buf in bufs.iter() {
+            if accumulated_len + buf.len() > n {
+                break;
+            } else {
+                accumulated_len += buf.len();
+                remove += 1;
+            }
+        }
+
+        let bufs = &mut bufs[remove..];
+        if !bufs.is_empty() {
+            bufs[0].0.advance(n - accumulated_len)
+        }
+        bufs
+    }
 }
 
 #[stable(feature = "iovec", since = "1.36.0")]
@@ -980,6 +1045,61 @@ impl<'a> IoSlice<'a> {
     pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
         IoSlice(sys::io::IoSlice::new(buf))
     }
+
+    /// Advance the internal cursor of the slice.
+    ///
+    /// # Notes
+    ///
+    /// Elements in the slice may be modified if the cursor is not advanced to
+    /// the end of the slice. For example if we have a slice of buffers with 2
+    /// `IoSlice`s, both of length 8, and we advance the cursor by 10 bytes the
+    /// first `IoSlice` will be untouched however the second will be modified to
+    /// remove the first 2 bytes (10 - 8).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(io_slice_advance)]
+    ///
+    /// use std::io::IoSlice;
+    /// use std::mem;
+    /// use std::ops::Deref;
+    ///
+    /// let mut buf1 = [1; 8];
+    /// let mut buf2 = [2; 16];
+    /// let mut buf3 = [3; 8];
+    /// let mut bufs = &mut [
+    ///     IoSlice::new(&mut buf1),
+    ///     IoSlice::new(&mut buf2),
+    ///     IoSlice::new(&mut buf3),
+    /// ][..];
+    ///
+    /// // Mark 10 bytes as written.
+    /// bufs = IoSlice::advance(mem::replace(&mut bufs, &mut []), 10);
+    /// assert_eq!(bufs[0].deref(), [2; 14].as_ref());
+    /// assert_eq!(bufs[1].deref(), [3; 8].as_ref());
+    #[unstable(feature = "io_slice_advance", issue = "62726")]
+    #[inline]
+    pub fn advance<'b>(bufs: &'b mut [IoSlice<'a>], n: usize) -> &'b mut [IoSlice<'a>] {
+        // Number of buffers to remove.
+        let mut remove = 0;
+        // Total length of all the to be removed buffers.
+        let mut accumulated_len = 0;
+        for buf in bufs.iter() {
+            if accumulated_len + buf.len() > n {
+                break;
+            } else {
+                accumulated_len += buf.len();
+                remove += 1;
+            }
+        }
+
+        let bufs = &mut bufs[remove..];
+        if !bufs.is_empty() {
+            bufs[0].0.advance(n - accumulated_len)
+        }
+        bufs
+    }
 }
 
 #[stable(feature = "iovec", since = "1.36.0")]
@@ -1096,7 +1216,7 @@ pub trait Write {
     /// an [`Err`] variant.
     ///
     /// If the return value is [`Ok(n)`] then it must be guaranteed that
-    /// `0 <= n <= buf.len()`. A return value of `0` typically means that the
+    /// `n <= buf.len()`. A return value of `0` typically means that the
     /// underlying object is no longer able to accept bytes and will likely not
     /// be able to in the future as well, or that the buffer provided is empty.
     ///
@@ -1135,7 +1255,7 @@ pub trait Write {
 
     /// Like `write`, except that it writes from a slice of buffers.
     ///
-    /// Data is copied to from each buffer in order, with the final buffer
+    /// Data is copied from each buffer in order, with the final buffer
     /// read from possibly being only partially consumed. This method must
     /// behave as a call to `write` with the buffers concatenated would.
     ///
@@ -1579,18 +1699,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")]
@@ -1919,7 +2034,7 @@ impl<T: Read, U: Read> Read for Chain<T, U> {
     fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
         if !self.done_first {
             match self.first.read(buf)? {
-                0 if buf.len() != 0 => self.done_first = true,
+                0 if !buf.is_empty() => self.done_first = true,
                 n => return Ok(n),
             }
         }
@@ -1951,7 +2066,7 @@ impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
     fn fill_buf(&mut self) -> Result<&[u8]> {
         if !self.done_first {
             match self.first.fill_buf()? {
-                buf if buf.len() == 0 => { self.done_first = true; }
+                buf if buf.is_empty() => { self.done_first = true; }
                 buf => return Ok(buf),
             }
         }
@@ -2264,8 +2379,10 @@ impl<B: BufRead> Iterator for Lines<B> {
 #[cfg(test)]
 mod tests {
     use crate::io::prelude::*;
-    use crate::io;
     use super::{Cursor, SeekFrom, repeat};
+    use crate::io::{self, IoSlice, IoSliceMut};
+    use crate::mem;
+    use crate::ops::Deref;
 
     #[test]
     #[cfg_attr(target_os = "emscripten", ignore)]
@@ -2533,4 +2650,89 @@ mod tests {
 
         Ok(())
     }
+
+    #[test]
+    fn io_slice_mut_advance() {
+        let mut buf1 = [1; 8];
+        let mut buf2 = [2; 16];
+        let mut buf3 = [3; 8];
+        let mut bufs = &mut [
+            IoSliceMut::new(&mut buf1),
+            IoSliceMut::new(&mut buf2),
+            IoSliceMut::new(&mut buf3),
+        ][..];
+
+        // Only in a single buffer..
+        bufs = IoSliceMut::advance(mem::replace(&mut bufs, &mut []), 1);
+        assert_eq!(bufs[0].deref(), [1; 7].as_ref());
+        assert_eq!(bufs[1].deref(), [2; 16].as_ref());
+        assert_eq!(bufs[2].deref(), [3; 8].as_ref());
+
+        // Removing a buffer, leaving others as is.
+        bufs = IoSliceMut::advance(mem::replace(&mut bufs, &mut []), 7);
+        assert_eq!(bufs[0].deref(), [2; 16].as_ref());
+        assert_eq!(bufs[1].deref(), [3; 8].as_ref());
+
+        // Removing a buffer and removing from the next buffer.
+        bufs = IoSliceMut::advance(mem::replace(&mut bufs, &mut []), 18);
+        assert_eq!(bufs[0].deref(), [3; 6].as_ref());
+    }
+
+    #[test]
+    fn io_slice_mut_advance_empty_slice() {
+        let mut empty_bufs = &mut [][..];
+        // Shouldn't panic.
+        IoSliceMut::advance(&mut empty_bufs, 1);
+    }
+
+    #[test]
+    fn io_slice_mut_advance_beyond_total_length() {
+        let mut buf1 = [1; 8];
+        let mut bufs = &mut [IoSliceMut::new(&mut buf1)][..];
+
+        // Going beyond the total length should be ok.
+        bufs = IoSliceMut::advance(mem::replace(&mut bufs, &mut []), 9);
+        assert!(bufs.is_empty());
+    }
+
+    #[test]
+    fn io_slice_advance() {
+        let mut buf1 = [1; 8];
+        let mut buf2 = [2; 16];
+        let mut buf3 = [3; 8];
+        let mut bufs =
+            &mut [IoSlice::new(&mut buf1), IoSlice::new(&mut buf2), IoSlice::new(&mut buf3)][..];
+
+        // Only in a single buffer..
+        bufs = IoSlice::advance(mem::replace(&mut bufs, &mut []), 1);
+        assert_eq!(bufs[0].deref(), [1; 7].as_ref());
+        assert_eq!(bufs[1].deref(), [2; 16].as_ref());
+        assert_eq!(bufs[2].deref(), [3; 8].as_ref());
+
+        // Removing a buffer, leaving others as is.
+        bufs = IoSlice::advance(mem::replace(&mut bufs, &mut []), 7);
+        assert_eq!(bufs[0].deref(), [2; 16].as_ref());
+        assert_eq!(bufs[1].deref(), [3; 8].as_ref());
+
+        // Removing a buffer and removing from the next buffer.
+        bufs = IoSlice::advance(mem::replace(&mut bufs, &mut []), 18);
+        assert_eq!(bufs[0].deref(), [3; 6].as_ref());
+    }
+
+    #[test]
+    fn io_slice_advance_empty_slice() {
+        let mut empty_bufs = &mut [][..];
+        // Shouldn't panic.
+        IoSlice::advance(&mut empty_bufs, 1);
+    }
+
+    #[test]
+    fn io_slice_advance_beyond_total_length() {
+        let mut buf1 = [1; 8];
+        let mut bufs = &mut [IoSlice::new(&mut buf1)][..];
+
+        // Going beyond the total length should be ok.
+        bufs = IoSlice::advance(mem::replace(&mut bufs, &mut []), 9);
+        assert!(bufs.is_empty());
+    }
 }
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index 7c4eae6512d..33cc87eb795 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -2,7 +2,7 @@
 
 use crate::fmt;
 use crate::io::{self, Read, Initializer, Write, ErrorKind, BufRead, IoSlice, IoSliceMut};
-use crate::mem;
+use crate::mem::MaybeUninit;
 
 /// Copies the entire contents of a reader into a writer.
 ///
@@ -43,21 +43,23 @@ use crate::mem;
 pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>
     where R: Read, W: Write
 {
-    let mut buf = unsafe {
-        let mut buf: [u8; super::DEFAULT_BUF_SIZE] = mem::uninitialized();
-        reader.initializer().initialize(&mut buf);
-        buf
-    };
+    let mut buf = MaybeUninit::<[u8; super::DEFAULT_BUF_SIZE]>::uninit();
+    // FIXME(#53491): This is calling `get_mut` and `get_ref` on an uninitialized
+    // `MaybeUninit`. Revisit this once we decided whether that is valid or not.
+    // This is still technically undefined behavior due to creating a reference
+    // to uninitialized data, but within libstd we can rely on more guarantees
+    // than if this code were in an external lib.
+    unsafe { reader.initializer().initialize(buf.get_mut()); }
 
     let mut written = 0;
     loop {
-        let len = match reader.read(&mut buf) {
+        let len = match reader.read(unsafe { buf.get_mut() }) {
             Ok(0) => return Ok(written),
             Ok(len) => len,
             Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
             Err(e) => return Err(e),
         };
-        writer.write_all(&buf[..len])?;
+        writer.write_all(unsafe { &buf.get_ref()[..len] })?;
         written += len as u64;
     }
 }
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index d133c2f5cb1..f5018485ef7 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -119,7 +119,7 @@ mod continue_keyword { }
 /// The `as` keyword can be used to change what the crate is referred to as in your project. If a
 /// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores.
 ///
-/// `crate` is also used as in conjunction with `pub` to signify that the item it's attached to
+/// `crate` can also be used as in conjunction with `pub` to signify that the item it's attached to
 /// is public only to other members of the same crate it's in.
 ///
 /// ```rust
@@ -131,6 +131,10 @@ mod continue_keyword { }
 /// }
 /// ```
 ///
+/// `crate` is also used to represent the absolute path of a module, where `crate` refers to the
+/// root of the current crate. For instance, `crate::foo::bar` refers to the name `bar` inside the
+/// module `foo`, from anywhere else in the same crate.
+///
 /// [Reference]: ../reference/items/extern-crates.html
 mod crate_keyword { }
 
@@ -608,6 +612,62 @@ mod in_keyword { }
 /// [Reference]: ../reference/statements.html#let-statements
 mod let_keyword { }
 
+#[doc(keyword = "while")]
+//
+/// Loop while a condition is upheld.
+///
+/// A `while` expression is used for predicate loops. The `while` expression runs the conditional
+/// expression before running the loop body, then runs the loop body if the conditional
+/// expression evaluates to `true`, or exits the loop otherwise.
+///
+/// ```rust
+/// let mut counter = 0;
+///
+/// while counter < 10 {
+///     println!("{}", counter);
+///     counter += 1;
+/// }
+/// ```
+///
+/// Like the [`for`] expression, we can use `break` and `continue`. A `while` expression
+/// cannot break with a value and always evaluates to `()` unlike [`loop`].
+///
+/// ```rust
+/// let mut i = 1;
+///
+/// while i < 100 {
+///     i *= 2;
+///     if i == 64 {
+///         break; // Exit when `i` is 64.
+///     }
+/// }
+/// ```
+///
+/// As `if` expressions have their pattern matching variant in `if let`, so too do `while`
+/// expressions with `while let`. The `while let` expression matches the pattern against the
+/// expression, then runs the loop body if pattern matching succeeds, or exits the loop otherwise.
+/// We can use `break` and `continue` in `while let` expressions just like in `while`.
+///
+/// ```rust
+/// let mut counter = Some(0);
+///
+/// while let Some(i) = counter {
+///     if i == 10 {
+///         counter = None;
+///     } else {
+///         println!("{}", i);
+///         counter = Some (i + 1);
+///     }
+/// }
+/// ```
+///
+/// For more information on `while` and loops in general, see the [reference].
+///
+/// [`for`]: keyword.for.html
+/// [`loop`]: keyword.loop.html
+/// [reference]: ../reference/expressions/loop-expr.html#predicate-loops
+mod while_keyword { }
+
 #[doc(keyword = "loop")]
 //
 /// Loop indefinitely.
@@ -922,15 +982,6 @@ mod use_keyword { }
 /// [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")]
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 2401946536f..c3882bacf87 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -205,13 +205,12 @@
 // Don't link to std. We are std.
 #![no_std]
 
-//#![warn(deprecated_in_future)] // FIXME: std still has quite a few uses of `mem::uninitialized`
+#![warn(deprecated_in_future)]
 #![warn(missing_docs)]
 #![warn(missing_debug_implementations)]
 #![deny(intra_doc_link_resolution_failure)] // rustdoc is run without -D warnings
-
-#![deny(rust_2018_idioms)]
 #![allow(explicit_outlives_requirements)]
+#![allow(unused_lifetimes)]
 
 // Tell the compiler to link to either panic_abort or panic_unwind
 #![needs_panic_runtime]
@@ -219,11 +218,12 @@
 // std may use features in a platform-specific way
 #![allow(unused_features)]
 
-#![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))]
+#![cfg_attr(test, feature(print_internals, set_stdio, update_panic_count))]
 #![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))]
+            feature(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, maybe_uninit_extra))]
 
 // std is implemented with unstable features, many of which are internal
 // compiler details that will never be stable
@@ -237,6 +237,7 @@
 #![feature(arbitrary_self_types)]
 #![feature(array_error_internals)]
 #![feature(asm)]
+#![feature(associated_type_bounds)]
 #![feature(bind_by_move_pattern_guards)]
 #![feature(box_syntax)]
 #![feature(c_variadic)]
@@ -249,7 +250,9 @@
 #![feature(concat_idents)]
 #![feature(const_cstr_unchecked)]
 #![feature(const_raw_ptr_deref)]
+#![feature(container_error_extra)]
 #![feature(core_intrinsics)]
+#![feature(custom_test_frameworks)]
 #![feature(doc_alias)]
 #![feature(doc_cfg)]
 #![feature(doc_keyword)]
@@ -261,8 +264,9 @@
 #![feature(exhaustive_patterns)]
 #![feature(external_doc)]
 #![feature(fn_traits)]
-#![feature(fnbox)]
+#![feature(format_args_nl)]
 #![feature(generator_trait)]
+#![feature(global_asm)]
 #![feature(hash_raw_entry)]
 #![feature(hashmap_internals)]
 #![feature(int_error_internals)]
@@ -272,7 +276,10 @@
 #![feature(libc)]
 #![feature(link_args)]
 #![feature(linkage)]
-#![feature(maybe_uninit)]
+#![feature(log_syntax)]
+#![feature(maybe_uninit_ref)]
+#![feature(maybe_uninit_slice)]
+#![feature(mem_take)]
 #![feature(needs_panic_runtime)]
 #![feature(never_type)]
 #![feature(nll)]
@@ -298,9 +305,11 @@
 #![feature(stdsimd)]
 #![feature(stmt_expr_attributes)]
 #![feature(str_internals)]
+#![feature(test)]
 #![feature(thread_local)]
 #![feature(todo_macro)]
 #![feature(toowned_clone_into)]
+#![feature(trace_macros)]
 #![feature(try_reserve)]
 #![feature(unboxed_closures)]
 #![feature(untagged_unions)]
@@ -318,12 +327,6 @@ use prelude::v1::*;
 // Access to Bencher, etc.
 #[cfg(test)] extern crate test;
 
-// Re-export a few macros from core
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use core::{assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne};
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use core::{unreachable, unimplemented, write, writeln, r#try, todo};
-
 #[allow(unused_imports)] // macros from `alloc` are not used on all platforms
 #[macro_use]
 extern crate alloc as alloc_crate;
@@ -336,6 +339,12 @@ extern crate libc;
 #[allow(unused_extern_crates)]
 extern crate unwind;
 
+// Only needed for now for the `std_detect` module until that crate changes to
+// use `cfg_if::cfg_if!`
+#[macro_use]
+#[cfg(not(test))]
+extern crate cfg_if;
+
 // During testing, this crate is not actually the "real" std library, but rather
 // it links to the real std library, which was compiled from this same source
 // code. So any lang items std defines are conditionally excluded (or else they
@@ -486,12 +495,12 @@ mod memchr;
 pub mod rt;
 
 // Pull in the `std_detect` crate directly into libstd. The contents of
-// `std_detect` are in a different repository: rust-lang-nursery/stdsimd.
+// `std_detect` are in a different repository: rust-lang/stdarch.
 //
 // `std_detect` depends on libstd, but the contents of this module are
 // set up in such a way that directly pulling it here works such that the
 // crate uses the this crate as its libstd.
-#[path = "../stdsimd/crates/std_detect/src/mod.rs"]
+#[path = "../stdarch/crates/std_detect/src/mod.rs"]
 #[allow(missing_debug_implementations, missing_docs, dead_code)]
 #[unstable(feature = "stdsimd", issue = "48556")]
 #[cfg(not(test))]
@@ -502,6 +511,53 @@ mod std_detect;
 #[cfg(not(test))]
 pub use std_detect::detect;
 
+// Re-export macros defined in libcore.
+#[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated, deprecated_in_future)]
+pub use core::{
+    // Stable
+    assert_eq,
+    assert_ne,
+    debug_assert_eq,
+    debug_assert_ne,
+    debug_assert,
+    r#try,
+    unimplemented,
+    unreachable,
+    write,
+    writeln,
+    // Unstable
+    todo,
+};
+
+// Re-export built-in macros defined through libcore.
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+pub use core::{
+    // Stable
+    assert,
+    cfg,
+    column,
+    compile_error,
+    concat,
+    env,
+    file,
+    format_args,
+    include,
+    include_bytes,
+    include_str,
+    line,
+    module_path,
+    option_env,
+    stringify,
+    // Unstable
+    asm,
+    concat_idents,
+    format_args_nl,
+    global_asm,
+    log_syntax,
+    trace_macros,
+};
+
 // Include a number of private modules that exist solely to provide
 // the rustdoc documentation for primitive types. Using `include!`
 // because rustdoc only looks for these modules at the crate level.
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 03aebeda47c..cbeaf20b13a 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -53,20 +53,20 @@
 /// ```
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow_internal_unstable(__rust_unstable_column, libstd_sys_internals)]
+#[allow_internal_unstable(libstd_sys_internals)]
 macro_rules! panic {
     () => ({
-        panic!("explicit panic")
+        $crate::panic!("explicit panic")
     });
     ($msg:expr) => ({
-        $crate::rt::begin_panic($msg, &(file!(), line!(), __rust_unstable_column!()))
+        $crate::rt::begin_panic($msg, &($crate::file!(), $crate::line!(), $crate::column!()))
     });
     ($msg:expr,) => ({
-        panic!($msg)
+        $crate::panic!($msg)
     });
     ($fmt:expr, $($arg:tt)+) => ({
-        $crate::rt::begin_panic_fmt(&format_args!($fmt, $($arg)+),
-                                    &(file!(), line!(), __rust_unstable_column!()))
+        $crate::rt::begin_panic_fmt(&$crate::format_args!($fmt, $($arg)+),
+                                    &($crate::file!(), $crate::line!(), $crate::column!()))
     });
 }
 
@@ -113,13 +113,13 @@ macro_rules! panic {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable(print_internals)]
 macro_rules! print {
-    ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
+    ($($arg:tt)*) => ($crate::io::_print($crate::format_args!($($arg)*)));
 }
 
 /// Prints to the standard output, with a newline.
 ///
 /// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
-/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
+/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)).
 ///
 /// Use the [`format!`] syntax to write data to the standard output.
 /// See [`std::fmt`] for more information.
@@ -145,9 +145,9 @@ macro_rules! print {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable(print_internals, format_args_nl)]
 macro_rules! println {
-    () => (print!("\n"));
+    () => ($crate::print!("\n"));
     ($($arg:tt)*) => ({
-        $crate::io::_print(format_args_nl!($($arg)*));
+        $crate::io::_print($crate::format_args_nl!($($arg)*));
     })
 }
 
@@ -176,7 +176,7 @@ macro_rules! println {
 #[stable(feature = "eprint", since = "1.19.0")]
 #[allow_internal_unstable(print_internals)]
 macro_rules! eprint {
-    ($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*)));
+    ($($arg:tt)*) => ($crate::io::_eprint($crate::format_args!($($arg)*)));
 }
 
 /// Prints to the standard error, with a newline.
@@ -204,9 +204,9 @@ macro_rules! eprint {
 #[stable(feature = "eprint", since = "1.19.0")]
 #[allow_internal_unstable(print_internals, format_args_nl)]
 macro_rules! eprintln {
-    () => (eprint!("\n"));
+    () => ($crate::eprint!("\n"));
     ($($arg:tt)*) => ({
-        $crate::io::_eprint(format_args_nl!($($arg)*));
+        $crate::io::_eprint($crate::format_args_nl!($($arg)*));
     })
 }
 
@@ -337,81 +337,26 @@ macro_rules! eprintln {
 #[stable(feature = "dbg_macro", since = "1.32.0")]
 macro_rules! dbg {
     () => {
-        eprintln!("[{}:{}]", file!(), line!());
+        $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());
     };
     ($val:expr) => {
         // Use of `match` here is intentional because it affects the lifetimes
         // of temporaries - https://stackoverflow.com/a/48732525/1063961
         match $val {
             tmp => {
-                eprintln!("[{}:{}] {} = {:#?}",
-                    file!(), line!(), stringify!($val), &tmp);
+                $crate::eprintln!("[{}:{}] {} = {:#?}",
+                    $crate::file!(), $crate::line!(), $crate::stringify!($val), &tmp);
                 tmp
             }
         }
     };
     // Trailing comma with single argument is ignored
-    ($val:expr,) => { dbg!($val) };
+    ($val:expr,) => { $crate::dbg!($val) };
     ($($val:expr),+ $(,)?) => {
-        ($(dbg!($val)),+,)
+        ($($crate::dbg!($val)),+,)
     };
 }
 
-/// 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) => ({
@@ -420,570 +365,3 @@ macro_rules! assert_approx_eq {
                 "{} is not approximately equal to {}", *a, *b);
     })
 }
-
-/// Built-in macros to the compiler itself.
-///
-/// These macros do not have any corresponding definition with a `macro_rules!`
-/// macro, but are documented here. Their implementations can be found hardcoded
-/// into libsyntax itself.
-#[cfg(rustdoc)]
-mod builtin {
-
-    /// Causes compilation to fail with the given error message when encountered.
-    ///
-    /// This macro should be used when a crate uses a conditional compilation strategy to provide
-    /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
-    /// which emits an error at *runtime*, rather than during compilation.
-    ///
-    /// # Examples
-    ///
-    /// Two such examples are macros and `#[cfg]` environments.
-    ///
-    /// Emit better compiler error if a macro is passed invalid values. Without the final branch,
-    /// the compiler would still emit an error, but the error's message would not mention the two
-    /// valid values.
-    ///
-    /// ```compile_fail
-    /// macro_rules! give_me_foo_or_bar {
-    ///     (foo) => {};
-    ///     (bar) => {};
-    ///     ($x:ident) => {
-    ///         compile_error!("This macro only accepts `foo` or `bar`");
-    ///     }
-    /// }
-    ///
-    /// give_me_foo_or_bar!(neither);
-    /// // ^ will fail at compile time with message "This macro only accepts `foo` or `bar`"
-    /// ```
-    ///
-    /// Emit compiler error if one of a number of features isn't available.
-    ///
-    /// ```compile_fail
-    /// #[cfg(not(any(feature = "foo", feature = "bar")))]
-    /// compile_error!("Either feature \"foo\" or \"bar\" must be enabled for this crate.")
-    /// ```
-    ///
-    /// [`panic!`]: ../std/macro.panic.html
-    #[stable(feature = "compile_error_macro", since = "1.20.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! compile_error {
-        ($msg:expr) => ({ /* compiler built-in */ });
-        ($msg:expr,) => ({ /* compiler built-in */ });
-    }
-
-    /// Constructs parameters for the other string-formatting macros.
-    ///
-    /// This macro functions by taking a formatting string literal containing
-    /// `{}` for each additional argument passed. `format_args!` prepares the
-    /// additional parameters to ensure the output can be interpreted as a string
-    /// and canonicalizes the arguments into a single type. Any value that implements
-    /// the [`Display`] trait can be passed to `format_args!`, as can any
-    /// [`Debug`] implementation be passed to a `{:?}` within the formatting string.
-    ///
-    /// This macro produces a value of type [`fmt::Arguments`]. This value can be
-    /// passed to the macros within [`std::fmt`] for performing useful redirection.
-    /// All other formatting macros ([`format!`], [`write!`], [`println!`], etc) are
-    /// proxied through this one. `format_args!`, unlike its derived macros, avoids
-    /// heap allocations.
-    ///
-    /// You can use the [`fmt::Arguments`] value that `format_args!` returns
-    /// in `Debug` and `Display` contexts as seen below. The example also shows
-    /// that `Debug` and `Display` format to the same thing: the interpolated
-    /// format string in `format_args!`.
-    ///
-    /// ```rust
-    /// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
-    /// let display = format!("{}", format_args!("{} foo {:?}", 1, 2));
-    /// assert_eq!("1 foo 2", display);
-    /// assert_eq!(display, debug);
-    /// ```
-    ///
-    /// For more information, see the documentation in [`std::fmt`].
-    ///
-    /// [`Display`]: ../std/fmt/trait.Display.html
-    /// [`Debug`]: ../std/fmt/trait.Debug.html
-    /// [`fmt::Arguments`]: ../std/fmt/struct.Arguments.html
-    /// [`std::fmt`]: ../std/fmt/index.html
-    /// [`format!`]: ../std/macro.format.html
-    /// [`write!`]: ../std/macro.write.html
-    /// [`println!`]: ../std/macro.println.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::fmt;
-    ///
-    /// let s = fmt::format(format_args!("hello {}", "world"));
-    /// assert_eq!(s, format!("hello {}", "world"));
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! format_args {
-        ($fmt:expr) => ({ /* compiler built-in */ });
-        ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
-    }
-
-    /// Inspects an environment variable at compile time.
-    ///
-    /// This macro will expand to the value of the named environment variable at
-    /// compile time, yielding an expression of type `&'static str`.
-    ///
-    /// If the environment variable is not defined, then a compilation error
-    /// will be emitted. To not emit a compile error, use the [`option_env!`]
-    /// macro instead.
-    ///
-    /// [`option_env!`]: ../std/macro.option_env.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let path: &'static str = env!("PATH");
-    /// println!("the $PATH variable at the time of compiling was: {}", path);
-    /// ```
-    ///
-    /// You can customize the error message by passing a string as the second
-    /// parameter:
-    ///
-    /// ```compile_fail
-    /// let doc: &'static str = env!("documentation", "what's that?!");
-    /// ```
-    ///
-    /// If the `documentation` environment variable is not defined, you'll get
-    /// the following error:
-    ///
-    /// ```text
-    /// error: what's that?!
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! env {
-        ($name:expr) => ({ /* compiler built-in */ });
-        ($name:expr,) => ({ /* compiler built-in */ });
-    }
-
-    /// Optionally inspects an environment variable at compile time.
-    ///
-    /// If the named environment variable is present at compile time, this will
-    /// expand into an expression of type `Option<&'static str>` whose value is
-    /// `Some` of the value of the environment variable. If the environment
-    /// variable is not present, then this will expand to `None`. See
-    /// [`Option<T>`][option] for more information on this type.
-    ///
-    /// A compile time error is never emitted when using this macro regardless
-    /// of whether the environment variable is present or not.
-    ///
-    /// [option]: ../std/option/enum.Option.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let key: Option<&'static str> = option_env!("SECRET_KEY");
-    /// println!("the secret key might be: {:?}", key);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! option_env {
-        ($name:expr) => ({ /* compiler built-in */ });
-        ($name:expr,) => ({ /* compiler built-in */ });
-    }
-
-    /// Concatenates identifiers into one identifier.
-    ///
-    /// This macro takes any number of comma-separated identifiers, and
-    /// concatenates them all into one, yielding an expression which is a new
-    /// identifier. Note that hygiene makes it such that this macro cannot
-    /// capture local variables. Also, as a general rule, macros are only
-    /// allowed in item, statement or expression position. That means while
-    /// you may use this macro for referring to existing variables, functions or
-    /// modules etc, you cannot define a new one with it.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(concat_idents)]
-    ///
-    /// # fn main() {
-    /// fn foobar() -> u32 { 23 }
-    ///
-    /// let f = concat_idents!(foo, bar);
-    /// println!("{}", f());
-    ///
-    /// // fn concat_idents!(new, fun, name) { } // not usable in this way!
-    /// # }
-    /// ```
-    #[unstable(feature = "concat_idents_macro", issue = "29599")]
-    #[rustc_doc_only_macro]
-    macro_rules! concat_idents {
-        ($($e:ident),+) => ({ /* compiler built-in */ });
-        ($($e:ident,)+) => ({ /* compiler built-in */ });
-    }
-
-    /// Concatenates literals into a static string slice.
-    ///
-    /// This macro takes any number of comma-separated literals, yielding an
-    /// expression of type `&'static str` which represents all of the literals
-    /// concatenated left-to-right.
-    ///
-    /// Integer and floating point literals are stringified in order to be
-    /// concatenated.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let s = concat!("test", 10, 'b', true);
-    /// assert_eq!(s, "test10btrue");
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! concat {
-        ($($e:expr),*) => ({ /* compiler built-in */ });
-        ($($e:expr,)*) => ({ /* compiler built-in */ });
-    }
-
-    /// Expands to the line number on which it was invoked.
-    ///
-    /// With [`column!`] and [`file!`], these macros provide debugging information for
-    /// developers about the location within the source.
-    ///
-    /// The expanded expression has type `u32` and is 1-based, so the first line
-    /// in each file evaluates to 1, the second to 2, etc. This is consistent
-    /// with error messages by common compilers or popular editors.
-    /// The returned line is *not necessarily* the line of the `line!` invocation itself,
-    /// but rather the first macro invocation leading up to the invocation
-    /// of the `line!` macro.
-    ///
-    /// [`column!`]: macro.column.html
-    /// [`file!`]: macro.file.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let current_line = line!();
-    /// println!("defined on line: {}", current_line);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! line { () => ({ /* compiler built-in */ }) }
-
-    /// Expands to the column number at which it was invoked.
-    ///
-    /// With [`line!`] and [`file!`], these macros provide debugging information for
-    /// developers about the location within the source.
-    ///
-    /// The expanded expression has type `u32` and is 1-based, so the first column
-    /// in each line evaluates to 1, the second to 2, etc. This is consistent
-    /// with error messages by common compilers or popular editors.
-    /// The returned column is *not necessarily* the line of the `column!` invocation itself,
-    /// but rather the first macro invocation leading up to the invocation
-    /// of the `column!` macro.
-    ///
-    /// [`line!`]: macro.line.html
-    /// [`file!`]: macro.file.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let current_col = column!();
-    /// println!("defined on column: {}", current_col);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! column { () => ({ /* compiler built-in */ }) }
-
-    /// Expands to the file name in which it was invoked.
-    ///
-    /// With [`line!`] and [`column!`], these macros provide debugging information for
-    /// developers about the location within the source.
-    ///
-    ///
-    /// The expanded expression has type `&'static str`, and the returned file
-    /// is not the invocation of the `file!` macro itself, but rather the
-    /// first macro invocation leading up to the invocation of the `file!`
-    /// macro.
-    ///
-    /// [`line!`]: macro.line.html
-    /// [`column!`]: macro.column.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let this_file = file!();
-    /// println!("defined in file: {}", this_file);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! file { () => ({ /* compiler built-in */ }) }
-
-    /// Stringifies its arguments.
-    ///
-    /// This macro will yield an expression of type `&'static str` which is the
-    /// stringification of all the tokens passed to the macro. No restrictions
-    /// are placed on the syntax of the macro invocation itself.
-    ///
-    /// Note that the expanded results of the input tokens may change in the
-    /// future. You should be careful if you rely on the output.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let one_plus_one = stringify!(1 + 1);
-    /// assert_eq!(one_plus_one, "1 + 1");
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! stringify { ($($t:tt)*) => ({ /* compiler built-in */ }) }
-
-    /// Includes a utf8-encoded file as a string.
-    ///
-    /// The file is located relative to the current file. (similarly to how
-    /// modules are found)
-    ///
-    /// This macro will yield an expression of type `&'static str` which is the
-    /// contents of the file.
-    ///
-    /// # Examples
-    ///
-    /// Assume there are two files in the same directory with the following
-    /// contents:
-    ///
-    /// File 'spanish.in':
-    ///
-    /// ```text
-    /// adiós
-    /// ```
-    ///
-    /// File 'main.rs':
-    ///
-    /// ```ignore (cannot-doctest-external-file-dependency)
-    /// fn main() {
-    ///     let my_str = include_str!("spanish.in");
-    ///     assert_eq!(my_str, "adiós\n");
-    ///     print!("{}", my_str);
-    /// }
-    /// ```
-    ///
-    /// Compiling 'main.rs' and running the resulting binary will print "adiós".
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! include_str {
-        ($file:expr) => ({ /* compiler built-in */ });
-        ($file:expr,) => ({ /* compiler built-in */ });
-    }
-
-    /// Includes a file as a reference to a byte array.
-    ///
-    /// The file is located relative to the current file. (similarly to how
-    /// modules are found)
-    ///
-    /// This macro will yield an expression of type `&'static [u8; N]` which is
-    /// the contents of the file.
-    ///
-    /// # Examples
-    ///
-    /// Assume there are two files in the same directory with the following
-    /// contents:
-    ///
-    /// File 'spanish.in':
-    ///
-    /// ```text
-    /// adiós
-    /// ```
-    ///
-    /// File 'main.rs':
-    ///
-    /// ```ignore (cannot-doctest-external-file-dependency)
-    /// fn main() {
-    ///     let bytes = include_bytes!("spanish.in");
-    ///     assert_eq!(bytes, b"adi\xc3\xb3s\n");
-    ///     print!("{}", String::from_utf8_lossy(bytes));
-    /// }
-    /// ```
-    ///
-    /// Compiling 'main.rs' and running the resulting binary will print "adiós".
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! include_bytes {
-        ($file:expr) => ({ /* compiler built-in */ });
-        ($file:expr,) => ({ /* compiler built-in */ });
-    }
-
-    /// Expands to a string that represents the current module path.
-    ///
-    /// The current module path can be thought of as the hierarchy of modules
-    /// leading back up to the crate root. The first component of the path
-    /// returned is the name of the crate currently being compiled.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// mod test {
-    ///     pub fn foo() {
-    ///         assert!(module_path!().ends_with("test"));
-    ///     }
-    /// }
-    ///
-    /// test::foo();
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! module_path { () => ({ /* compiler built-in */ }) }
-
-    /// Evaluates boolean combinations of configuration flags at compile-time.
-    ///
-    /// In addition to the `#[cfg]` attribute, this macro is provided to allow
-    /// boolean expression evaluation of configuration flags. This frequently
-    /// leads to less duplicated code.
-    ///
-    /// The syntax given to this macro is the same syntax as the [`cfg`]
-    /// attribute.
-    ///
-    /// [`cfg`]: ../reference/conditional-compilation.html#the-cfg-attribute
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// let my_directory = if cfg!(windows) {
-    ///     "windows-specific-directory"
-    /// } else {
-    ///     "unix-directory"
-    /// };
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) }
-
-    /// Parses a file as an expression or an item according to the context.
-    ///
-    /// The file is located relative to the current file (similarly to how
-    /// modules are found).
-    ///
-    /// Using this macro is often a bad idea, because if the file is
-    /// parsed as an expression, it is going to be placed in the
-    /// surrounding code unhygienically. This could result in variables
-    /// or functions being different from what the file expected if
-    /// there are variables or functions that have the same name in
-    /// the current file.
-    ///
-    /// # Examples
-    ///
-    /// Assume there are two files in the same directory with the following
-    /// contents:
-    ///
-    /// File 'monkeys.in':
-    ///
-    /// ```ignore (only-for-syntax-highlight)
-    /// ['🙈', '🙊', '🙉']
-    ///     .iter()
-    ///     .cycle()
-    ///     .take(6)
-    ///     .collect::<String>()
-    /// ```
-    ///
-    /// File 'main.rs':
-    ///
-    /// ```ignore (cannot-doctest-external-file-dependency)
-    /// fn main() {
-    ///     let my_string = include!("monkeys.in");
-    ///     assert_eq!("🙈🙊🙉🙈🙊🙉", my_string);
-    ///     println!("{}", my_string);
-    /// }
-    /// ```
-    ///
-    /// Compiling 'main.rs' and running the resulting binary will print
-    /// "🙈🙊🙉🙈🙊🙉".
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! include {
-        ($file:expr) => ({ /* compiler built-in */ });
-        ($file:expr,) => ({ /* compiler built-in */ });
-    }
-
-    /// Asserts that a boolean expression is `true` at runtime.
-    ///
-    /// This will invoke the [`panic!`] macro if the provided expression cannot be
-    /// evaluated to `true` at runtime.
-    ///
-    /// # Uses
-    ///
-    /// Assertions are always checked in both debug and release builds, and cannot
-    /// be disabled. See [`debug_assert!`] for assertions that are not enabled in
-    /// release builds by default.
-    ///
-    /// Unsafe code relies on `assert!` to enforce run-time invariants that, if
-    /// violated could lead to unsafety.
-    ///
-    /// Other use-cases of `assert!` include testing and enforcing run-time
-    /// invariants in safe code (whose violation cannot result in unsafety).
-    ///
-    /// # Custom Messages
-    ///
-    /// This macro has a second form, where a custom panic message can
-    /// be provided with or without arguments for formatting. See [`std::fmt`]
-    /// for syntax for this form.
-    ///
-    /// [`panic!`]: macro.panic.html
-    /// [`debug_assert!`]: macro.debug_assert.html
-    /// [`std::fmt`]: ../std/fmt/index.html
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// // the panic message for these assertions is the stringified value of the
-    /// // expression given.
-    /// assert!(true);
-    ///
-    /// fn some_computation() -> bool { true } // a very simple function
-    ///
-    /// assert!(some_computation());
-    ///
-    /// // assert with a custom message
-    /// let x = true;
-    /// assert!(x, "x wasn't true!");
-    ///
-    /// let a = 3; let b = 27;
-    /// assert!(a + b == 30, "a = {}, b = {}", a, b);
-    /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_doc_only_macro]
-    macro_rules! assert {
-        ($cond:expr) => ({ /* compiler built-in */ });
-        ($cond:expr,) => ({ /* compiler built-in */ });
-        ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ });
-    }
-}
-
-/// Defines `#[cfg]` if-else statements.
-///
-/// This is similar to the `if/elif` C preprocessor macro by allowing definition
-/// of a cascade of `#[cfg]` cases, emitting the implementation which matches
-/// first.
-///
-/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
-/// without having to rewrite each clause multiple times.
-macro_rules! cfg_if {
-    ($(
-        if #[cfg($($meta:meta),*)] { $($it:item)* }
-    ) else * else {
-        $($it2:item)*
-    }) => {
-        __cfg_if_items! {
-            () ;
-            $( ( ($($meta),*) ($($it)*) ), )*
-            ( () ($($it2)*) ),
-        }
-    }
-}
-
-macro_rules! __cfg_if_items {
-    (($($not:meta,)*) ; ) => {};
-    (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
-        __cfg_if_apply! { cfg(all(not(any($($not),*)), $($m,)*)), $($it)* }
-        __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* }
-    }
-}
-
-macro_rules! __cfg_if_apply {
-    ($m:meta, $($it:item)*) => {
-        $(#[$m] $it)*
-    }
-}
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index e7923e381f1..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)
     }
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index 7f9f3b91a60..6b504056e5f 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -502,12 +502,19 @@ impl Ipv4Addr {
     ///
     /// The following return false:
     ///
-    /// - private address (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16)
-    /// - the loopback address (127.0.0.0/8)
-    /// - the link-local address (169.254.0.0/16)
-    /// - the broadcast address (255.255.255.255/32)
-    /// - test addresses used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24)
-    /// - the unspecified address (0.0.0.0)
+    /// - private addresses (see [`is_private()`](#method.is_private))
+    /// - the loopback address (see [`is_loopback()`](#method.is_loopback))
+    /// - the link-local address (see [`is_link_local()`](#method.is_link_local))
+    /// - the broadcast address (see [`is_broadcast()`](#method.is_broadcast))
+    /// - addresses used for documentation (see [`is_documentation()`](#method.is_documentation))
+    /// - the unspecified address (see [`is_unspecified()`](#method.is_unspecified)), and the whole
+    ///   0.0.0.0/8 block
+    /// - addresses reserved for future protocols (see
+    /// [`is_ietf_protocol_assignment()`](#method.is_ietf_protocol_assignment), except
+    /// `192.0.0.9/32` and `192.0.0.10/32` which are globally routable
+    /// - addresses reserved for future use (see [`is_reserved()`](#method.is_reserved)
+    /// - addresses reserved for networking devices benchmarking (see
+    /// [`is_benchmarking`](#method.is_benchmarking))
     ///
     /// [ipv4-sr]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
     /// [`true`]: ../../std/primitive.bool.html
@@ -520,16 +527,181 @@ impl Ipv4Addr {
     /// use std::net::Ipv4Addr;
     ///
     /// fn main() {
+    ///     // private addresses are not global
     ///     assert_eq!(Ipv4Addr::new(10, 254, 0, 0).is_global(), false);
     ///     assert_eq!(Ipv4Addr::new(192, 168, 10, 65).is_global(), false);
     ///     assert_eq!(Ipv4Addr::new(172, 16, 10, 65).is_global(), false);
+    ///
+    ///     // the 0.0.0.0/8 block is not global
+    ///     assert_eq!(Ipv4Addr::new(0, 1, 2, 3).is_global(), false);
+    ///     // in particular, the unspecified address is not global
     ///     assert_eq!(Ipv4Addr::new(0, 0, 0, 0).is_global(), false);
+    ///
+    ///     // the loopback address is not global
+    ///     assert_eq!(Ipv4Addr::new(127, 0, 0, 1).is_global(), false);
+    ///
+    ///     // link local addresses are not global
+    ///     assert_eq!(Ipv4Addr::new(169, 254, 45, 1).is_global(), false);
+    ///
+    ///     // the broadcast address is not global
+    ///     assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_global(), false);
+    ///
+    ///     // the broadcast address is not global
+    ///     assert_eq!(Ipv4Addr::new(192, 0, 2, 255).is_global(), false);
+    ///     assert_eq!(Ipv4Addr::new(198, 51, 100, 65).is_global(), false);
+    ///     assert_eq!(Ipv4Addr::new(203, 0, 113, 6).is_global(), false);
+    ///
+    ///     // shared addresses are not global
+    ///     assert_eq!(Ipv4Addr::new(100, 100, 0, 0).is_global(), false);
+    ///
+    ///     // addresses reserved for protocol assignment are not global
+    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_global(), false);
+    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_global(), false);
+    ///
+    ///     // addresses reserved for future use are not global
+    ///     assert_eq!(Ipv4Addr::new(250, 10, 20, 30).is_global(), false);
+    ///
+    ///     // addresses reserved for network devices benchmarking are not global
+    ///     assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_global(), false);
+    ///
+    ///     // All the other addresses are global
+    ///     assert_eq!(Ipv4Addr::new(1, 1, 1, 1).is_global(), true);
     ///     assert_eq!(Ipv4Addr::new(80, 9, 12, 3).is_global(), true);
     /// }
     /// ```
     pub fn is_global(&self) -> bool {
-        !self.is_private() && !self.is_loopback() && !self.is_link_local() &&
-        !self.is_broadcast() && !self.is_documentation() && !self.is_unspecified()
+        // check if this address is 192.0.0.9 or 192.0.0.10. These addresses are the only two
+        // globally routable addresses in the 192.0.0.0/24 range.
+        if u32::from(*self) == 0xc0000009 || u32::from(*self) == 0xc000000a {
+            return true;
+        }
+        !self.is_private()
+            && !self.is_loopback()
+            && !self.is_link_local()
+            && !self.is_broadcast()
+            && !self.is_documentation()
+            && !self.is_shared()
+            && !self.is_ietf_protocol_assignment()
+            && !self.is_reserved()
+            && !self.is_benchmarking()
+            // Make sure the address is not in 0.0.0.0/8
+            && self.octets()[0] != 0
+    }
+
+    /// Returns [`true`] if this address is part of the Shared Address Space defined in
+    /// [IETF RFC 6598] (`100.64.0.0/10`).
+    ///
+    /// [IETF RFC 6598]: https://tools.ietf.org/html/rfc6598
+    /// [`true`]: ../../std/primitive.bool.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip)]
+    /// use std::net::Ipv4Addr;
+    ///
+    /// fn main() {
+    ///     assert_eq!(Ipv4Addr::new(100, 64, 0, 0).is_shared(), true);
+    ///     assert_eq!(Ipv4Addr::new(100, 127, 255, 255).is_shared(), true);
+    ///     assert_eq!(Ipv4Addr::new(100, 128, 0, 0).is_shared(), false);
+    /// }
+    /// ```
+    pub fn is_shared(&self) -> bool {
+        self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
+    }
+
+    /// Returns [`true`] if this address is part of `192.0.0.0/24`, which is reserved to
+    /// IANA for IETF protocol assignments, as documented in [IETF RFC 6890].
+    ///
+    /// Note that parts of this block are in use:
+    ///
+    /// - `192.0.0.8/32` is the "IPv4 dummy address" (see [IETF RFC 7600])
+    /// - `192.0.0.9/32` is the "Port Control Protocol Anycast" (see [IETF RFC 7723])
+    /// - `192.0.0.10/32` is used for NAT traversal (see [IETF RFC 8155])
+    ///
+    /// [IETF RFC 6890]: https://tools.ietf.org/html/rfc6890
+    /// [IETF RFC 7600]: https://tools.ietf.org/html/rfc7600
+    /// [IETF RFC 7723]: https://tools.ietf.org/html/rfc7723
+    /// [IETF RFC 8155]: https://tools.ietf.org/html/rfc8155
+    /// [`true`]: ../../std/primitive.bool.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip)]
+    /// use std::net::Ipv4Addr;
+    ///
+    /// fn main() {
+    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 0).is_ietf_protocol_assignment(), true);
+    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 8).is_ietf_protocol_assignment(), true);
+    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 9).is_ietf_protocol_assignment(), true);
+    ///     assert_eq!(Ipv4Addr::new(192, 0, 0, 255).is_ietf_protocol_assignment(), true);
+    ///     assert_eq!(Ipv4Addr::new(192, 0, 1, 0).is_ietf_protocol_assignment(), false);
+    ///     assert_eq!(Ipv4Addr::new(191, 255, 255, 255).is_ietf_protocol_assignment(), false);
+    /// }
+    /// ```
+    pub fn is_ietf_protocol_assignment(&self) -> bool {
+        self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0
+    }
+
+    /// Returns [`true`] if this address part of the `198.18.0.0/15` range, which is reserved for
+    /// network devices benchmarking. This range is defined in [IETF RFC 2544] as `192.18.0.0`
+    /// through `198.19.255.255` but [errata 423] corrects it to `198.18.0.0/15`.
+    ///
+    /// [IETF RFC 1112]: https://tools.ietf.org/html/rfc1112
+    /// [errate 423]: https://www.rfc-editor.org/errata/eid423
+    /// [`true`]: ../../std/primitive.bool.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip)]
+    /// use std::net::Ipv4Addr;
+    ///
+    /// fn main() {
+    ///     assert_eq!(Ipv4Addr::new(198, 17, 255, 255).is_benchmarking(), false);
+    ///     assert_eq!(Ipv4Addr::new(198, 18, 0, 0).is_benchmarking(), true);
+    ///     assert_eq!(Ipv4Addr::new(198, 19, 255, 255).is_benchmarking(), true);
+    ///     assert_eq!(Ipv4Addr::new(198, 20, 0, 0).is_benchmarking(), false);
+    /// }
+    /// ```
+    pub fn is_benchmarking(&self) -> bool {
+        self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18
+    }
+
+    /// Returns [`true`] if this address is reserved by IANA for future use. [IETF RFC 1112]
+    /// defines the block of reserved addresses as `240.0.0.0/4`. This range normally includes the
+    /// broadcast address `255.255.255.255`, but this implementation explicitely excludes it, since
+    /// it is obviously not reserved for future use.
+    ///
+    /// [IETF RFC 1112]: https://tools.ietf.org/html/rfc1112
+    /// [`true`]: ../../std/primitive.bool.html
+    ///
+    /// # Warning
+    ///
+    /// As IANA assigns new addresses, this method will be
+    /// updated. This may result in non-reserved addresses being
+    /// treated as reserved in code that relies on an outdated version
+    /// of this method.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip)]
+    /// use std::net::Ipv4Addr;
+    ///
+    /// fn main() {
+    ///     assert_eq!(Ipv4Addr::new(240, 0, 0, 0).is_reserved(), true);
+    ///     assert_eq!(Ipv4Addr::new(255, 255, 255, 254).is_reserved(), true);
+    ///
+    ///     assert_eq!(Ipv4Addr::new(239, 255, 255, 255).is_reserved(), false);
+    ///     // The broadcast address is not considered as reserved for future use by this
+    ///     // implementation
+    ///     assert_eq!(Ipv4Addr::new(255, 255, 255, 255).is_reserved(), false);
+    /// }
+    /// ```
+    pub fn is_reserved(&self) -> bool {
+        self.octets()[0] & 240 == 240 && !self.is_broadcast()
     }
 
     /// Returns [`true`] if this is a multicast address (224.0.0.0/4).
@@ -1003,7 +1175,7 @@ impl Ipv6Addr {
         }
     }
 
-    /// Returns [`true`] if this is a unique local address (fc00::/7).
+    /// Returns [`true`] if this is a unique local address (`fc00::/7`).
     ///
     /// This property is defined in [IETF RFC 4193].
     ///
@@ -1027,12 +1199,83 @@ impl Ipv6Addr {
         (self.segments()[0] & 0xfe00) == 0xfc00
     }
 
-    /// Returns [`true`] if the address is unicast and link-local (fe80::/10).
+    /// Returns [`true`] if the address is a unicast link-local address (`fe80::/64`).
     ///
-    /// This property is defined in [IETF RFC 4291].
+    /// A common mis-conception is to think that "unicast link-local addresses start with
+    /// `fe80::`", but the [IETF RFC 4291] actually defines a stricter format for these addresses:
+    ///
+    /// ```no_rust
+    /// |   10     |
+    /// |  bits    |         54 bits         |          64 bits           |
+    /// +----------+-------------------------+----------------------------+
+    /// |1111111010|           0             |       interface ID         |
+    /// +----------+-------------------------+----------------------------+
+    /// ```
+    ///
+    /// This method validates the format defined in the RFC and won't recognize the following
+    /// addresses such as `fe80:0:0:1::` or `fe81::` as unicast link-local addresses for example.
+    /// If you need a less strict validation use [`is_unicast_link_local()`] instead.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ip)]
+    ///
+    /// use std::net::Ipv6Addr;
+    ///
+    /// fn main() {
+    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0);
+    ///     assert!(ip.is_unicast_link_local_strict());
+    ///
+    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff);
+    ///     assert!(ip.is_unicast_link_local_strict());
+    ///
+    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0);
+    ///     assert!(!ip.is_unicast_link_local_strict());
+    ///     assert!(ip.is_unicast_link_local());
+    ///
+    ///     let ip = Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0);
+    ///     assert!(!ip.is_unicast_link_local_strict());
+    ///     assert!(ip.is_unicast_link_local());
+    /// }
+    /// ```
+    ///
+    /// # See also
+    ///
+    /// - [IETF RFC 4291 section 2.5.6]
+    /// - [RFC 4291 errata 4406]
+    /// - [`is_unicast_link_local()`]
     ///
     /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [IETF RFC 4291 section 2.5.6]: https://tools.ietf.org/html/rfc4291#section-2.5.6
     /// [`true`]: ../../std/primitive.bool.html
+    /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406
+    /// [`is_unicast_link_local()`]: ../../std/net/struct.Ipv6Addr.html#method.is_unicast_link_local
+    ///
+    pub fn is_unicast_link_local_strict(&self) -> bool {
+        (self.segments()[0] & 0xffff) == 0xfe80
+            && (self.segments()[1] & 0xffff) == 0
+            && (self.segments()[2] & 0xffff) == 0
+            && (self.segments()[3] & 0xffff) == 0
+    }
+
+    /// Returns [`true`] if the address is a unicast link-local address (`fe80::/10`).
+    ///
+    /// This method returns [`true`] for addresses in the range reserved by [RFC 4291 section 2.4],
+    /// i.e. addresses with the following format:
+    ///
+    /// ```no_rust
+    /// |   10     |
+    /// |  bits    |         54 bits         |          64 bits           |
+    /// +----------+-------------------------+----------------------------+
+    /// |1111111010|    arbitratry value     |       interface ID         |
+    /// +----------+-------------------------+----------------------------+
+    /// ```
+    ///
+    /// As a result, this method consider addresses such as `fe80:0:0:1::` or `fe81::` to be
+    /// unicast link-local addresses, whereas [`is_unicast_link_local_strict()`] does not. If you
+    /// need a strict validation fully compliant with the RFC, use
+    /// [`is_unicast_link_local_strict()`].
     ///
     /// # Examples
     ///
@@ -1042,19 +1285,49 @@ impl Ipv6Addr {
     /// use std::net::Ipv6Addr;
     ///
     /// fn main() {
-    ///     assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unicast_link_local(),
-    ///                false);
-    ///     assert_eq!(Ipv6Addr::new(0xfe8a, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local(), true);
+    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 0);
+    ///     assert!(ip.is_unicast_link_local());
+    ///
+    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 0, 0xffff, 0xffff, 0xffff, 0xffff);
+    ///     assert!(ip.is_unicast_link_local());
+    ///
+    ///     let ip = Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0);
+    ///     assert!(ip.is_unicast_link_local());
+    ///     assert!(!ip.is_unicast_link_local_strict());
+    ///
+    ///     let ip = Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0);
+    ///     assert!(ip.is_unicast_link_local());
+    ///     assert!(!ip.is_unicast_link_local_strict());
     /// }
     /// ```
+    ///
+    /// # See also
+    ///
+    /// - [IETF RFC 4291 section 2.4]
+    /// - [RFC 4291 errata 4406]
+    ///
+    /// [IETF RFC 4291 section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4
+    /// [`true`]: ../../std/primitive.bool.html
+    /// [RFC 4291 errata 4406]: https://www.rfc-editor.org/errata/eid4406
+    /// [`is_unicast_link_local_strict()`]: ../../std/net/struct.Ipv6Addr.html#method.is_unicast_link_local_strict
+    ///
     pub fn is_unicast_link_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfe80
     }
 
-    /// Returns [`true`] if this is a deprecated unicast site-local address
-    /// (fec0::/10).
+    /// Returns [`true`] if this is a deprecated unicast site-local address (fec0::/10). The
+    /// unicast site-local address format is defined in [RFC 4291 section 2.5.7] as:
+    ///
+    /// ```no_rust
+    /// |   10     |
+    /// |  bits    |         54 bits         |         64 bits            |
+    /// +----------+-------------------------+----------------------------+
+    /// |1111111011|        subnet ID        |       interface ID         |
+    /// +----------+-------------------------+----------------------------+
+    /// ```
     ///
     /// [`true`]: ../../std/primitive.bool.html
+    /// [RFC 4291 section 2.5.7]: https://tools.ietf.org/html/rfc4291#section-2.5.7
     ///
     /// # Examples
     ///
@@ -1069,6 +1342,14 @@ impl Ipv6Addr {
     ///     assert_eq!(Ipv6Addr::new(0xfec2, 0, 0, 0, 0, 0, 0, 0).is_unicast_site_local(), true);
     /// }
     /// ```
+    ///
+    /// # Warning
+    ///
+    /// As per [RFC 3879], the whole `FEC0::/10` prefix is
+    /// deprecated. New software must not support site-local
+    /// addresses.
+    ///
+    /// [RFC 3879]: https://tools.ietf.org/html/rfc3879
     pub fn is_unicast_site_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfec0
     }
@@ -1104,12 +1385,20 @@ impl Ipv6Addr {
     ///
     /// - the loopback address
     /// - the link-local addresses
-    /// - the (deprecated) site-local addresses
     /// - unique local addresses
     /// - the unspecified address
     /// - the address range reserved for documentation
     ///
+    /// This method returns [`true`] for site-local addresses as per [RFC 4291 section 2.5.7]
+    ///
+    /// ```no_rust
+    /// The special behavior of [the site-local unicast] prefix defined in [RFC3513] must no longer
+    /// be supported in new implementations (i.e., new implementations must treat this prefix as
+    /// Global Unicast).
+    /// ```
+    ///
     /// [`true`]: ../../std/primitive.bool.html
+    /// [RFC 4291 section 2.5.7]: https://tools.ietf.org/html/rfc4291#section-2.5.7
     ///
     /// # Examples
     ///
@@ -1126,9 +1415,11 @@ impl Ipv6Addr {
     /// ```
     pub fn is_unicast_global(&self) -> bool {
         !self.is_multicast()
-            && !self.is_loopback() && !self.is_unicast_link_local()
-            && !self.is_unicast_site_local() && !self.is_unique_local()
-            && !self.is_unspecified() && !self.is_documentation()
+            && !self.is_loopback()
+            && !self.is_unicast_link_local()
+            && !self.is_unique_local()
+            && !self.is_unspecified()
+            && !self.is_documentation()
     }
 
     /// Returns the address's multicast scope if the address is multicast.
@@ -1510,8 +1801,8 @@ impl From<[u16; 8]> for IpAddr {
 #[cfg(all(test, not(target_os = "emscripten")))]
 mod tests {
     use crate::net::*;
-    use crate::net::Ipv6MulticastScope::*;
     use crate::net::test::{tsa, sa6, sa4};
+    use crate::str::FromStr;
 
     #[test]
     fn test_from_str_ipv4() {
@@ -1675,164 +1966,491 @@ mod tests {
 
     #[test]
     fn ip_properties() {
-        fn check4(octets: &[u8; 4], unspec: bool, loopback: bool,
-                  global: bool, multicast: bool, documentation: bool) {
-            let ip = IpAddr::V4(Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]));
-            assert_eq!(ip.is_unspecified(), unspec);
-            assert_eq!(ip.is_loopback(), loopback);
-            assert_eq!(ip.is_global(), global);
-            assert_eq!(ip.is_multicast(), multicast);
-            assert_eq!(ip.is_documentation(), documentation);
+        macro_rules! ip {
+            ($s:expr) => {
+                IpAddr::from_str($s).unwrap()
+            }
         }
 
-        fn check6(str_addr: &str, unspec: bool, loopback: bool,
-                  global: bool, u_doc: bool, mcast: bool) {
-            let ip = IpAddr::V6(str_addr.parse().unwrap());
-            assert_eq!(ip.is_unspecified(), unspec);
-            assert_eq!(ip.is_loopback(), loopback);
-            assert_eq!(ip.is_global(), global);
-            assert_eq!(ip.is_documentation(), u_doc);
-            assert_eq!(ip.is_multicast(), mcast);
+        macro_rules! check {
+            ($s:expr) => {
+                check!($s, 0);
+            };
+
+            ($s:expr, $mask:expr) => {{
+                let unspec: u8 = 1 << 0;
+                let loopback: u8 = 1 << 1;
+                let global: u8 = 1 << 2;
+                let multicast: u8 = 1 << 3;
+                let doc: u8 = 1 << 4;
+
+                if ($mask & unspec) == unspec {
+                    assert!(ip!($s).is_unspecified());
+                } else {
+                    assert!(!ip!($s).is_unspecified());
+                }
+
+                if ($mask & loopback) == loopback {
+                    assert!(ip!($s).is_loopback());
+                } else {
+                    assert!(!ip!($s).is_loopback());
+                }
+
+                if ($mask & global) == global {
+                    assert!(ip!($s).is_global());
+                } else {
+                    assert!(!ip!($s).is_global());
+                }
+
+                if ($mask & multicast) == multicast {
+                    assert!(ip!($s).is_multicast());
+                } else {
+                    assert!(!ip!($s).is_multicast());
+                }
+
+                if ($mask & doc) == doc {
+                    assert!(ip!($s).is_documentation());
+                } else {
+                    assert!(!ip!($s).is_documentation());
+                }
+            }}
         }
 
-        //     address                unspec loopbk global multicast doc
-        check4(&[0, 0, 0, 0],         true,  false, false,  false,   false);
-        check4(&[0, 0, 0, 1],         false, false, true,   false,   false);
-        check4(&[0, 1, 0, 0],         false, false, true,   false,   false);
-        check4(&[10, 9, 8, 7],        false, false, false,  false,   false);
-        check4(&[127, 1, 2, 3],       false, true,  false,  false,   false);
-        check4(&[172, 31, 254, 253],  false, false, false,  false,   false);
-        check4(&[169, 254, 253, 242], false, false, false,  false,   false);
-        check4(&[192, 0, 2, 183],     false, false, false,  false,   true);
-        check4(&[192, 1, 2, 183],     false, false, true,   false,   false);
-        check4(&[192, 168, 254, 253], false, false, false,  false,   false);
-        check4(&[198, 51, 100, 0],    false, false, false,  false,   true);
-        check4(&[203, 0, 113, 0],     false, false, false,  false,   true);
-        check4(&[203, 2, 113, 0],     false, false, true,   false,   false);
-        check4(&[224, 0, 0, 0],       false, false, true,   true,    false);
-        check4(&[239, 255, 255, 255], false, false, true,   true,    false);
-        check4(&[255, 255, 255, 255], false, false, false,  false,   false);
-
-        //     address                            unspec loopbk global doc    mcast
-        check6("::",                              true,  false, false, false, false);
-        check6("::1",                             false, true,  false, false, false);
-        check6("::0.0.0.2",                       false, false, true,  false, false);
-        check6("1::",                             false, false, true,  false, false);
-        check6("fc00::",                          false, false, false, false, false);
-        check6("fdff:ffff::",                     false, false, false, false, false);
-        check6("fe80:ffff::",                     false, false, false, false, false);
-        check6("febf:ffff::",                     false, false, false, false, false);
-        check6("fec0::",                          false, false, false, false, false);
-        check6("ff01::",                          false, false, false, false, true);
-        check6("ff02::",                          false, false, false, false, true);
-        check6("ff03::",                          false, false, false, false, true);
-        check6("ff04::",                          false, false, false, false, true);
-        check6("ff05::",                          false, false, false, false, true);
-        check6("ff08::",                          false, false, false, false, true);
-        check6("ff0e::",                          false, false, true,  false, true);
-        check6("2001:db8:85a3::8a2e:370:7334",    false, false, false, true,  false);
-        check6("102:304:506:708:90a:b0c:d0e:f10", false, false, true,  false, false);
+        let unspec: u8 = 1 << 0;
+        let loopback: u8 = 1 << 1;
+        let global: u8 = 1 << 2;
+        let multicast: u8 = 1 << 3;
+        let doc: u8 = 1 << 4;
+
+        check!("0.0.0.0", unspec);
+        check!("0.0.0.1");
+        check!("0.1.0.0");
+        check!("10.9.8.7");
+        check!("127.1.2.3", loopback);
+        check!("172.31.254.253");
+        check!("169.254.253.242");
+        check!("192.0.2.183", doc);
+        check!("192.1.2.183", global);
+        check!("192.168.254.253");
+        check!("198.51.100.0", doc);
+        check!("203.0.113.0", doc);
+        check!("203.2.113.0", global);
+        check!("224.0.0.0", global|multicast);
+        check!("239.255.255.255", global|multicast);
+        check!("255.255.255.255");
+        // make sure benchmarking addresses are not global
+        check!("198.18.0.0");
+        check!("198.18.54.2");
+        check!("198.19.255.255");
+        // make sure addresses reserved for protocol assignment are not global
+        check!("192.0.0.0");
+        check!("192.0.0.255");
+        check!("192.0.0.100");
+        // make sure reserved addresses are not global
+        check!("240.0.0.0");
+        check!("251.54.1.76");
+        check!("254.255.255.255");
+        // make sure shared addresses are not global
+        check!("100.64.0.0");
+        check!("100.127.255.255");
+        check!("100.100.100.0");
+
+        check!("::", unspec);
+        check!("::1", loopback);
+        check!("::0.0.0.2", global);
+        check!("1::", global);
+        check!("fc00::");
+        check!("fdff:ffff::");
+        check!("fe80:ffff::");
+        check!("febf:ffff::");
+        check!("fec0::", global);
+        check!("ff01::", multicast);
+        check!("ff02::", multicast);
+        check!("ff03::", multicast);
+        check!("ff04::", multicast);
+        check!("ff05::", multicast);
+        check!("ff08::", multicast);
+        check!("ff0e::", global|multicast);
+        check!("2001:db8:85a3::8a2e:370:7334", doc);
+        check!("102:304:506:708:90a:b0c:d0e:f10", global);
     }
 
     #[test]
     fn ipv4_properties() {
-        fn check(octets: &[u8; 4], unspec: bool, loopback: bool,
-                 private: bool, link_local: bool, global: bool,
-                 multicast: bool, broadcast: bool, documentation: bool) {
-            let ip = Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]);
-            assert_eq!(octets, &ip.octets());
-
-            assert_eq!(ip.is_unspecified(), unspec);
-            assert_eq!(ip.is_loopback(), loopback);
-            assert_eq!(ip.is_private(), private);
-            assert_eq!(ip.is_link_local(), link_local);
-            assert_eq!(ip.is_global(), global);
-            assert_eq!(ip.is_multicast(), multicast);
-            assert_eq!(ip.is_broadcast(), broadcast);
-            assert_eq!(ip.is_documentation(), documentation);
+        macro_rules! ip {
+            ($s:expr) => {
+                Ipv4Addr::from_str($s).unwrap()
+            }
         }
 
-        //    address                unspec loopbk privt  linloc global multicast brdcast doc
-        check(&[0, 0, 0, 0],         true,  false, false, false, false,  false,    false,  false);
-        check(&[0, 0, 0, 1],         false, false, false, false, true,   false,    false,  false);
-        check(&[0, 1, 0, 0],         false, false, false, false, true,   false,    false,  false);
-        check(&[10, 9, 8, 7],        false, false, true,  false, false,  false,    false,  false);
-        check(&[127, 1, 2, 3],       false, true,  false, false, false,  false,    false,  false);
-        check(&[172, 31, 254, 253],  false, false, true,  false, false,  false,    false,  false);
-        check(&[169, 254, 253, 242], false, false, false, true,  false,  false,    false,  false);
-        check(&[192, 0, 2, 183],     false, false, false, false, false,  false,    false,  true);
-        check(&[192, 1, 2, 183],     false, false, false, false, true,   false,    false,  false);
-        check(&[192, 168, 254, 253], false, false, true,  false, false,  false,    false,  false);
-        check(&[198, 51, 100, 0],    false, false, false, false, false,  false,    false,  true);
-        check(&[203, 0, 113, 0],     false, false, false, false, false,  false,    false,  true);
-        check(&[203, 2, 113, 0],     false, false, false, false, true,   false,    false,  false);
-        check(&[224, 0, 0, 0],       false, false, false, false, true,   true,     false,  false);
-        check(&[239, 255, 255, 255], false, false, false, false, true,   true,     false,  false);
-        check(&[255, 255, 255, 255], false, false, false, false, false,  false,    true,   false);
+        macro_rules! check {
+            ($s:expr) => {
+                check!($s, 0);
+            };
+
+            ($s:expr, $mask:expr) => {{
+                let unspec: u16 = 1 << 0;
+                let loopback: u16 = 1 << 1;
+                let private: u16 = 1 << 2;
+                let link_local: u16 = 1 << 3;
+                let global: u16 = 1 << 4;
+                let multicast: u16 = 1 << 5;
+                let broadcast: u16 = 1 << 6;
+                let documentation: u16 = 1 << 7;
+                let benchmarking: u16 = 1 << 8;
+                let ietf_protocol_assignment: u16 = 1 << 9;
+                let reserved: u16 = 1 << 10;
+                let shared: u16 = 1 << 11;
+
+                if ($mask & unspec) == unspec {
+                    assert!(ip!($s).is_unspecified());
+                } else {
+                    assert!(!ip!($s).is_unspecified());
+                }
+
+                if ($mask & loopback) == loopback {
+                    assert!(ip!($s).is_loopback());
+                } else {
+                    assert!(!ip!($s).is_loopback());
+                }
+
+                if ($mask & private) == private {
+                    assert!(ip!($s).is_private());
+                } else {
+                    assert!(!ip!($s).is_private());
+                }
+
+                if ($mask & link_local) == link_local {
+                    assert!(ip!($s).is_link_local());
+                } else {
+                    assert!(!ip!($s).is_link_local());
+                }
+
+                if ($mask & global) == global {
+                    assert!(ip!($s).is_global());
+                } else {
+                    assert!(!ip!($s).is_global());
+                }
+
+                if ($mask & multicast) == multicast {
+                    assert!(ip!($s).is_multicast());
+                } else {
+                    assert!(!ip!($s).is_multicast());
+                }
+
+                if ($mask & broadcast) == broadcast {
+                    assert!(ip!($s).is_broadcast());
+                } else {
+                    assert!(!ip!($s).is_broadcast());
+                }
+
+                if ($mask & documentation) == documentation {
+                    assert!(ip!($s).is_documentation());
+                } else {
+                    assert!(!ip!($s).is_documentation());
+                }
+
+                if ($mask & benchmarking) == benchmarking {
+                    assert!(ip!($s).is_benchmarking());
+                } else {
+                    assert!(!ip!($s).is_benchmarking());
+                }
+
+                if ($mask & ietf_protocol_assignment) == ietf_protocol_assignment {
+                    assert!(ip!($s).is_ietf_protocol_assignment());
+                } else {
+                    assert!(!ip!($s).is_ietf_protocol_assignment());
+                }
+
+                if ($mask & reserved) == reserved {
+                    assert!(ip!($s).is_reserved());
+                } else {
+                    assert!(!ip!($s).is_reserved());
+                }
+
+                if ($mask & shared) == shared {
+                    assert!(ip!($s).is_shared());
+                } else {
+                    assert!(!ip!($s).is_shared());
+                }
+            }}
+        }
+
+        let unspec: u16 = 1 << 0;
+        let loopback: u16 = 1 << 1;
+        let private: u16 = 1 << 2;
+        let link_local: u16 = 1 << 3;
+        let global: u16 = 1 << 4;
+        let multicast: u16 = 1 << 5;
+        let broadcast: u16 = 1 << 6;
+        let documentation: u16 = 1 << 7;
+        let benchmarking: u16 = 1 << 8;
+        let ietf_protocol_assignment: u16 = 1 << 9;
+        let reserved: u16 = 1 << 10;
+        let shared: u16 = 1 << 11;
+
+        check!("0.0.0.0", unspec);
+        check!("0.0.0.1");
+        check!("0.1.0.0");
+        check!("10.9.8.7", private);
+        check!("127.1.2.3", loopback);
+        check!("172.31.254.253", private);
+        check!("169.254.253.242", link_local);
+        check!("192.0.2.183", documentation);
+        check!("192.1.2.183", global);
+        check!("192.168.254.253", private);
+        check!("198.51.100.0", documentation);
+        check!("203.0.113.0", documentation);
+        check!("203.2.113.0", global);
+        check!("224.0.0.0", global|multicast);
+        check!("239.255.255.255", global|multicast);
+        check!("255.255.255.255", broadcast);
+        check!("198.18.0.0", benchmarking);
+        check!("198.18.54.2", benchmarking);
+        check!("198.19.255.255", benchmarking);
+        check!("192.0.0.0", ietf_protocol_assignment);
+        check!("192.0.0.255", ietf_protocol_assignment);
+        check!("192.0.0.100", ietf_protocol_assignment);
+        check!("240.0.0.0", reserved);
+        check!("251.54.1.76", reserved);
+        check!("254.255.255.255", reserved);
+        check!("100.64.0.0", shared);
+        check!("100.127.255.255", shared);
+        check!("100.100.100.0", shared);
     }
 
     #[test]
     fn ipv6_properties() {
-        fn check(str_addr: &str, octets: &[u8; 16], unspec: bool, loopback: bool,
-                 unique_local: bool, global: bool,
-                 u_link_local: bool, u_site_local: bool, u_global: bool, u_doc: bool,
-                 m_scope: Option<Ipv6MulticastScope>) {
-            let ip: Ipv6Addr = str_addr.parse().unwrap();
-            assert_eq!(str_addr, ip.to_string());
-            assert_eq!(&ip.octets(), octets);
-            assert_eq!(Ipv6Addr::from(*octets), ip);
-
-            assert_eq!(ip.is_unspecified(), unspec);
-            assert_eq!(ip.is_loopback(), loopback);
-            assert_eq!(ip.is_unique_local(), unique_local);
-            assert_eq!(ip.is_global(), global);
-            assert_eq!(ip.is_unicast_link_local(), u_link_local);
-            assert_eq!(ip.is_unicast_site_local(), u_site_local);
-            assert_eq!(ip.is_unicast_global(), u_global);
-            assert_eq!(ip.is_documentation(), u_doc);
-            assert_eq!(ip.multicast_scope(), m_scope);
-            assert_eq!(ip.is_multicast(), m_scope.is_some());
+        macro_rules! ip {
+            ($s:expr) => {
+                Ipv6Addr::from_str($s).unwrap()
+            }
+        }
+
+        macro_rules! check {
+            ($s:expr, &[$($octet:expr),*], $mask:expr) => {
+                assert_eq!($s, ip!($s).to_string());
+                let octets = &[$($octet),*];
+                assert_eq!(&ip!($s).octets(), octets);
+                assert_eq!(Ipv6Addr::from(*octets), ip!($s));
+
+                let unspecified: u16 = 1 << 0;
+                let loopback: u16 = 1 << 1;
+                let unique_local: u16 = 1 << 2;
+                let global: u16 = 1 << 3;
+                let unicast_link_local: u16 = 1 << 4;
+                let unicast_link_local_strict: u16 = 1 << 5;
+                let unicast_site_local: u16 = 1 << 6;
+                let unicast_global: u16 = 1 << 7;
+                let documentation: u16 = 1 << 8;
+                let multicast_interface_local: u16 = 1 << 9;
+                let multicast_link_local: u16 = 1 << 10;
+                let multicast_realm_local: u16 = 1 << 11;
+                let multicast_admin_local: u16 = 1 << 12;
+                let multicast_site_local: u16 = 1 << 13;
+                let multicast_organization_local: u16 = 1 << 14;
+                let multicast_global: u16 = 1 << 15;
+                let multicast: u16 = multicast_interface_local
+                    | multicast_admin_local
+                    | multicast_global
+                    | multicast_link_local
+                    | multicast_realm_local
+                    | multicast_site_local
+                    | multicast_organization_local;
+
+                if ($mask & unspecified) == unspecified {
+                    assert!(ip!($s).is_unspecified());
+                } else {
+                    assert!(!ip!($s).is_unspecified());
+                }
+                if ($mask & loopback) == loopback {
+                    assert!(ip!($s).is_loopback());
+                } else {
+                    assert!(!ip!($s).is_loopback());
+                }
+                if ($mask & unique_local) == unique_local {
+                    assert!(ip!($s).is_unique_local());
+                } else {
+                    assert!(!ip!($s).is_unique_local());
+                }
+                if ($mask & global) == global {
+                    assert!(ip!($s).is_global());
+                } else {
+                    assert!(!ip!($s).is_global());
+                }
+                if ($mask & unicast_link_local) == unicast_link_local {
+                    assert!(ip!($s).is_unicast_link_local());
+                } else {
+                    assert!(!ip!($s).is_unicast_link_local());
+                }
+                if ($mask & unicast_link_local_strict) == unicast_link_local_strict {
+                    assert!(ip!($s).is_unicast_link_local_strict());
+                } else {
+                    assert!(!ip!($s).is_unicast_link_local_strict());
+                }
+                if ($mask & unicast_site_local) == unicast_site_local {
+                    assert!(ip!($s).is_unicast_site_local());
+                } else {
+                    assert!(!ip!($s).is_unicast_site_local());
+                }
+                if ($mask & unicast_global) == unicast_global {
+                    assert!(ip!($s).is_unicast_global());
+                } else {
+                    assert!(!ip!($s).is_unicast_global());
+                }
+                if ($mask & documentation) == documentation {
+                    assert!(ip!($s).is_documentation());
+                } else {
+                    assert!(!ip!($s).is_documentation());
+                }
+                if ($mask & multicast) != 0 {
+                    assert!(ip!($s).multicast_scope().is_some());
+                    assert!(ip!($s).is_multicast());
+                } else {
+                    assert!(ip!($s).multicast_scope().is_none());
+                    assert!(!ip!($s).is_multicast());
+                }
+                if ($mask & multicast_interface_local) == multicast_interface_local {
+                    assert_eq!(ip!($s).multicast_scope().unwrap(),
+                               Ipv6MulticastScope::InterfaceLocal);
+                }
+                if ($mask & multicast_link_local) == multicast_link_local {
+                    assert_eq!(ip!($s).multicast_scope().unwrap(),
+                               Ipv6MulticastScope::LinkLocal);
+                }
+                if ($mask & multicast_realm_local) == multicast_realm_local {
+                    assert_eq!(ip!($s).multicast_scope().unwrap(),
+                               Ipv6MulticastScope::RealmLocal);
+                }
+                if ($mask & multicast_admin_local) == multicast_admin_local {
+                    assert_eq!(ip!($s).multicast_scope().unwrap(),
+                               Ipv6MulticastScope::AdminLocal);
+                }
+                if ($mask & multicast_site_local) == multicast_site_local {
+                    assert_eq!(ip!($s).multicast_scope().unwrap(),
+                               Ipv6MulticastScope::SiteLocal);
+                }
+                if ($mask & multicast_organization_local) == multicast_organization_local {
+                    assert_eq!(ip!($s).multicast_scope().unwrap(),
+                               Ipv6MulticastScope::OrganizationLocal);
+                }
+                if ($mask & multicast_global) == multicast_global {
+                    assert_eq!(ip!($s).multicast_scope().unwrap(),
+                               Ipv6MulticastScope::Global);
+                }
+            }
         }
 
-        //    unspec loopbk uniqlo global unill  unisl  uniglo doc    mscope
-        check("::", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              true,  false, false, false, false, false, false, false, None);
-        check("::1", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
-              false, true,  false, false, false, false, false, false, None);
-        check("::0.0.0.2", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
-              false, false, false, true,  false, false, true,  false, None);
-        check("1::", &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, false, true,  false, false, true,  false, None);
-        check("fc00::", &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, true,  false, false, false, false, false, None);
-        check("fdff:ffff::", &[0xfd, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, true,  false, false, false, false, false, None);
-        check("fe80:ffff::", &[0xfe, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, false, false, true,  false, false, false, None);
-        check("febf:ffff::", &[0xfe, 0xbf, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, false, false, true,  false, false, false, None);
-        check("fec0::", &[0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, false, false, false, true,  false, false, None);
-        check("ff01::", &[0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, false, false, false, false, false, false, Some(InterfaceLocal));
-        check("ff02::", &[0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, false, false, false, false, false, false, Some(LinkLocal));
-        check("ff03::", &[0xff, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, false, false, false, false, false, false, Some(RealmLocal));
-        check("ff04::", &[0xff, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, false, false, false, false, false, false, Some(AdminLocal));
-        check("ff05::", &[0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, false, false, false, false, false, false, Some(SiteLocal));
-        check("ff08::", &[0xff, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, false, false, false, false, false, false, Some(OrganizationLocal));
-        check("ff0e::", &[0xff, 0xe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
-              false, false, false, true,  false, false, false, false, Some(Global));
-        check("2001:db8:85a3::8a2e:370:7334",
-              &[0x20, 1, 0xd, 0xb8, 0x85, 0xa3, 0, 0, 0, 0, 0x8a, 0x2e, 3, 0x70, 0x73, 0x34],
-              false, false, false, false, false, false, false, true, None);
-        check("102:304:506:708:90a:b0c:d0e:f10",
-              &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
-              false, false, false, true,  false, false, true,  false, None);
+        let unspecified: u16 = 1 << 0;
+        let loopback: u16 = 1 << 1;
+        let unique_local: u16 = 1 << 2;
+        let global: u16 = 1 << 3;
+        let unicast_link_local: u16 = 1 << 4;
+        let unicast_link_local_strict: u16 = 1 << 5;
+        let unicast_site_local: u16 = 1 << 6;
+        let unicast_global: u16 = 1 << 7;
+        let documentation: u16 = 1 << 8;
+        let multicast_interface_local: u16 = 1 << 9;
+        let multicast_link_local: u16 = 1 << 10;
+        let multicast_realm_local: u16 = 1 << 11;
+        let multicast_admin_local: u16 = 1 << 12;
+        let multicast_site_local: u16 = 1 << 13;
+        let multicast_organization_local: u16 = 1 << 14;
+        let multicast_global: u16 = 1 << 15;
+
+        check!("::",
+               &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               unspecified);
+
+        check!("::1",
+               &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+               loopback);
+
+        check!("::0.0.0.2",
+               &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2],
+               global | unicast_global);
+
+        check!("1::",
+               &[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               global | unicast_global);
+
+        check!("fc00::",
+               &[0xfc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               unique_local);
+
+        check!("fdff:ffff::",
+               &[0xfd, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               unique_local);
+
+        check!("fe80:ffff::",
+               &[0xfe, 0x80, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               unicast_link_local);
+
+        check!("fe80::",
+               &[0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               unicast_link_local|unicast_link_local_strict);
+
+        check!("febf:ffff::",
+               &[0xfe, 0xbf, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               unicast_link_local);
+
+        check!("febf::",
+               &[0xfe, 0xbf, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               unicast_link_local);
+
+        check!("febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
+               &[0xfe, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
+               unicast_link_local);
+
+        check!("fe80::ffff:ffff:ffff:ffff",
+               &[0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
+               unicast_link_local|unicast_link_local_strict);
+
+        check!("fe80:0:0:1::",
+               &[0xfe, 0x80, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
+               unicast_link_local);
+
+        check!("fec0::",
+               &[0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               unicast_site_local|unicast_global|global);
+
+        check!("ff01::",
+               &[0xff, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               multicast_interface_local);
+
+        check!("ff02::",
+               &[0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               multicast_link_local);
+
+        check!("ff03::",
+               &[0xff, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               multicast_realm_local);
+
+        check!("ff04::",
+               &[0xff, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               multicast_admin_local);
+
+        check!("ff05::",
+               &[0xff, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               multicast_site_local);
+
+        check!("ff08::",
+               &[0xff, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               multicast_organization_local);
+
+        check!("ff0e::",
+               &[0xff, 0xe, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+               multicast_global | global);
+
+        check!("2001:db8:85a3::8a2e:370:7334",
+               &[0x20, 1, 0xd, 0xb8, 0x85, 0xa3, 0, 0, 0, 0, 0x8a, 0x2e, 3, 0x70, 0x73, 0x34],
+               documentation);
+
+        check!("102:304:506:708:90a:b0c:d0e:f10",
+               &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
+               global| unicast_global);
     }
 
     #[test]
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index 61d9149952e..c430e103951 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -422,7 +422,7 @@ impl UdpSocket {
     /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
     ///
     /// If enabled, multicast packets will be looped back to the local socket.
-    /// Note that this may not have any affect on IPv6 sockets.
+    /// Note that this may not have any effect on IPv6 sockets.
     ///
     /// # Examples
     ///
@@ -464,7 +464,7 @@ impl UdpSocket {
     /// this socket. The default value is 1 which means that multicast packets
     /// don't leave the local network unless explicitly requested.
     ///
-    /// Note that this may not have any affect on IPv6 sockets.
+    /// Note that this may not have any effect on IPv6 sockets.
     ///
     /// # Examples
     ///
diff --git a/src/libstd/os/linux/fs.rs b/src/libstd/os/linux/fs.rs
index ec5e9837076..78321ac3185 100644
--- a/src/libstd/os/linux/fs.rs
+++ b/src/libstd/os/linux/fs.rs
@@ -34,9 +34,10 @@ pub trait MetadataExt {
     /// }
     /// ```
     #[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")]
+    #[rustc_deprecated(
+        since = "1.8.0",
+        reason = "other methods of this trait are now prefered"
+    )]
     #[allow(deprecated)]
     fn as_raw_stat(&self) -> &raw::stat;
 
diff --git a/src/libstd/os/linux/raw.rs b/src/libstd/os/linux/raw.rs
index 77eeacb4b47..21e1cf8a22b 100644
--- a/src/libstd/os/linux/raw.rs
+++ b/src/libstd/os/linux/raw.rs
@@ -147,6 +147,62 @@ mod arch {
     }
 }
 
+#[cfg(target_arch = "hexagon")]
+mod arch {
+    use crate::os::raw::{c_long, c_int, c_longlong, culonglong};
+
+    #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = c_longlong;
+    #[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = c_long;
+    #[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = c_ulonglong;
+    #[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = c_uint;
+    #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = c_longlong;
+    #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = c_long;
+
+    #[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_dev: ::dev_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ino: ::c_ulonglong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mode: ::c_uint,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_nlink: ::c_uint,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_uid: ::c_uint,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_gid: ::c_uint,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_rdev: ::c_ulonglong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub __pad1: ::c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_size: ::c_longlong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_blksize: ::blksize_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub __pad2: ::c_int,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_blocks: ::blkcnt_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_atime: ::time_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_atime_nsec: ::c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mtime: ::time_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mtime_nsec: ::c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ctime: ::time_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ctime_nsec: ::c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub __pad3: [::c_int;2],
+    }
+}
+
 #[cfg(any(target_arch = "mips64",
           target_arch = "s390x",
           target_arch = "sparc64"))]
diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs
index 44cbc180b8b..fcd81f0a1b2 100644
--- a/src/libstd/os/mod.rs
+++ b/src/libstd/os/mod.rs
@@ -3,7 +3,7 @@
 #![stable(feature = "os", since = "1.0.0")]
 #![allow(missing_docs, nonstandard_style, missing_debug_implementations)]
 
-cfg_if! {
+cfg_if::cfg_if! {
     if #[cfg(rustdoc)] {
 
         // When documenting libstd we want to show unix/windows/linux modules as
@@ -24,7 +24,7 @@ cfg_if! {
         // If we're not documenting libstd then we just expose the main modules
         // as we otherwise would.
 
-        #[cfg(any(target_os = "redox", unix))]
+        #[cfg(any(target_os = "redox", unix, target_os = "vxworks"))]
         #[stable(feature = "rust1", since = "1.0.0")]
         pub use crate::sys::ext as unix;
 
@@ -50,7 +50,9 @@ cfg_if! {
 #[cfg(target_os = "emscripten")] pub mod emscripten;
 #[cfg(target_os = "fuchsia")]    pub mod fuchsia;
 #[cfg(target_os = "hermit")]     pub mod hermit;
+#[cfg(target_os = "redox")]      pub mod redox;
 #[cfg(target_os = "wasi")]       pub mod wasi;
+#[cfg(target_os = "vxworks")]    pub mod vxworks;
 #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] pub mod fortanix_sgx;
 
 pub mod raw;
diff --git a/src/libstd/os/raw/mod.rs b/src/libstd/os/raw/mod.rs
index e9043b4b40d..611a1709c8d 100644
--- a/src/libstd/os/raw/mod.rs
+++ b/src/libstd/os/raw/mod.rs
@@ -8,9 +8,10 @@
 
 #![stable(feature = "raw_os", since = "1.1.0")]
 
-#[doc(include = "os/raw/char.md")]
+#[doc(include = "char.md")]
 #[cfg(any(all(target_os = "linux", any(target_arch = "aarch64",
                                        target_arch = "arm",
+                                       target_arch = "hexagon",
                                        target_arch = "powerpc",
                                        target_arch = "powerpc64",
                                        target_arch = "s390x")),
@@ -25,11 +26,16 @@
                                         target_arch = "arm",
                                         target_arch = "powerpc")),
           all(target_os = "openbsd", target_arch = "aarch64"),
+          all(target_os = "vxworks", any(target_arch = "aarch64",
+                                         target_arch = "arm",
+                                         target_arch = "powerpc64",
+                                         target_arch = "powerpc")),
           all(target_os = "fuchsia", target_arch = "aarch64")))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8;
-#[doc(include = "os/raw/char.md")]
+#[doc(include = "char.md")]
 #[cfg(not(any(all(target_os = "linux", any(target_arch = "aarch64",
                                            target_arch = "arm",
+                                           target_arch = "hexagon",
                                            target_arch = "powerpc",
                                            target_arch = "powerpc64",
                                            target_arch = "s390x")),
@@ -44,39 +50,43 @@
                                             target_arch = "arm",
                                             target_arch = "powerpc")),
               all(target_os = "openbsd", target_arch = "aarch64"),
+              all(target_os = "vxworks", any(target_arch = "aarch64",
+                                             target_arch = "arm",
+                                             target_arch = "powerpc64",
+                                             target_arch = "powerpc")),
               all(target_os = "fuchsia", target_arch = "aarch64"))))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8;
-#[doc(include = "os/raw/schar.md")]
+#[doc(include = "schar.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8;
-#[doc(include = "os/raw/uchar.md")]
+#[doc(include = "uchar.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8;
-#[doc(include = "os/raw/short.md")]
+#[doc(include = "short.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_short = i16;
-#[doc(include = "os/raw/ushort.md")]
+#[doc(include = "ushort.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ushort = u16;
-#[doc(include = "os/raw/int.md")]
+#[doc(include = "int.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_int = i32;
-#[doc(include = "os/raw/uint.md")]
+#[doc(include = "uint.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uint = u32;
-#[doc(include = "os/raw/long.md")]
+#[doc(include = "long.md")]
 #[cfg(any(target_pointer_width = "32", windows))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i32;
-#[doc(include = "os/raw/ulong.md")]
+#[doc(include = "ulong.md")]
 #[cfg(any(target_pointer_width = "32", windows))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u32;
-#[doc(include = "os/raw/long.md")]
+#[doc(include = "long.md")]
 #[cfg(all(target_pointer_width = "64", not(windows)))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i64;
-#[doc(include = "os/raw/ulong.md")]
+#[doc(include = "ulong.md")]
 #[cfg(all(target_pointer_width = "64", not(windows)))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u64;
-#[doc(include = "os/raw/longlong.md")]
+#[doc(include = "longlong.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_longlong = i64;
-#[doc(include = "os/raw/ulonglong.md")]
+#[doc(include = "ulonglong.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulonglong = u64;
-#[doc(include = "os/raw/float.md")]
+#[doc(include = "float.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_float = f32;
-#[doc(include = "os/raw/double.md")]
+#[doc(include = "double.md")]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_double = f64;
 
 #[stable(feature = "raw_os", since = "1.1.0")]
diff --git a/src/libstd/os/redox/fs.rs b/src/libstd/os/redox/fs.rs
new file mode 100644
index 00000000000..80a12907619
--- /dev/null
+++ b/src/libstd/os/redox/fs.rs
@@ -0,0 +1,383 @@
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use crate::fs::Metadata;
+use crate::sys_common::AsInner;
+
+#[allow(deprecated)]
+use crate::os::redox::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.
+    ///
+    /// [`stat`]: ../../../../std/os/redox/raw/struct.stat.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let stat = meta.as_raw_stat();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[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;
+
+    /// Returns the device ID on which this file resides.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_dev());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_dev(&self) -> u64;
+    /// Returns the inode number.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ino());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ino(&self) -> u64;
+    /// Returns the file type and mode.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mode());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mode(&self) -> u32;
+    /// Returns the number of hard links to file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_nlink());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_nlink(&self) -> u64;
+    /// Returns the user ID of the file owner.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_uid());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_uid(&self) -> u32;
+    /// Returns the group ID of the file owner.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_gid());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gid(&self) -> u32;
+    /// Returns the device ID that this file represents. Only relevant for special file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_rdev());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_rdev(&self) -> u64;
+    /// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
+    ///
+    /// The size of a symbolic link is the length of the pathname it contains,
+    /// without a terminating null byte.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_size());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_size(&self) -> u64;
+    /// Returns the last access time of the file, in seconds since Unix Epoch.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_atime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime(&self) -> i64;
+    /// Returns the last access time of the file, in nanoseconds since [`st_atime`].
+    ///
+    /// [`st_atime`]: #tymethod.st_atime
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_atime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime_nsec(&self) -> i64;
+    /// Returns the last modification time of the file, in seconds since Unix Epoch.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mtime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime(&self) -> i64;
+    /// Returns the last modification time of the file, in nanoseconds since [`st_mtime`].
+    ///
+    /// [`st_mtime`]: #tymethod.st_mtime
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_mtime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime_nsec(&self) -> i64;
+    /// Returns the last status change time of the file, in seconds since Unix Epoch.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ctime());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime(&self) -> i64;
+    /// Returns the last status change time of the file, in nanoseconds since [`st_ctime`].
+    ///
+    /// [`st_ctime`]: #tymethod.st_ctime
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_ctime_nsec());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime_nsec(&self) -> i64;
+    /// Returns the "preferred" blocksize for efficient filesystem I/O.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_blksize());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blksize(&self) -> u64;
+    /// Returns the number of blocks allocated to the file, 512-byte units.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::io;
+    /// use std::os::redox::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     println!("{}", meta.st_blocks());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blocks(&self) -> u64;
+}
+
+#[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_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
+    }
+}
diff --git a/src/libstd/os/redox/mod.rs b/src/libstd/os/redox/mod.rs
new file mode 100644
index 00000000000..c60da5926da
--- /dev/null
+++ b/src/libstd/os/redox/mod.rs
@@ -0,0 +1,6 @@
+//! Redox-specific definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+
+pub mod raw;
+pub mod fs;
diff --git a/src/libstd/os/redox/raw.rs b/src/libstd/os/redox/raw.rs
new file mode 100644
index 00000000000..23d8ff7694b
--- /dev/null
+++ b/src/libstd/os/redox/raw.rs
@@ -0,0 +1,67 @@
+//! Redox-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)]
+#![allow(missing_debug_implementations)]
+
+use crate::os::raw::{c_char, c_int, c_long, c_ulong, c_void};
+
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = c_long;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type gid_t = c_int;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = c_int;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type uid_t = c_int;
+
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = *mut c_void;
+
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = c_ulong;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = c_ulong;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type ino_t = c_ulong;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type nlink_t = c_ulong;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = c_long;
+#[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = c_long;
+
+#[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_dev: dev_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ino: ino_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_nlink: nlink_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mode: mode_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_uid: uid_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_gid: gid_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_rdev: dev_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_size: off_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blksize: blksize_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blocks: blkcnt_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_atime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_atime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mtime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mtime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ctime: time_t,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ctime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub _pad: [c_char; 24],
+}
diff --git a/src/libstd/os/vxworks/fs.rs b/src/libstd/os/vxworks/fs.rs
new file mode 100644
index 00000000000..57ab4fb943e
--- /dev/null
+++ b/src/libstd/os/vxworks/fs.rs
@@ -0,0 +1,84 @@
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use crate::fs::Metadata;
+use crate::sys_common::AsInner;
+
+///
+/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+pub trait MetadataExt {
+    #[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_mtime(&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_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_attrib(&self) -> u8;
+}
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+impl MetadataExt for Metadata {
+    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_mtime(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime as i64
+    }
+    fn st_ctime(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime 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_attrib(&self) -> u8 {
+        self.as_inner().as_inner().st_attrib as u8
+    }
+}
diff --git a/src/libstd/os/vxworks/mod.rs b/src/libstd/os/vxworks/mod.rs
new file mode 100644
index 00000000000..2255a103d35
--- /dev/null
+++ b/src/libstd/os/vxworks/mod.rs
@@ -0,0 +1,6 @@
+//! VxWorks-specific definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+
+pub mod raw;
+pub mod fs;
diff --git a/src/libstd/os/vxworks/raw.rs b/src/libstd/os/vxworks/raw.rs
new file mode 100644
index 00000000000..ae0560a5a92
--- /dev/null
+++ b/src/libstd/os/vxworks/raw.rs
@@ -0,0 +1,7 @@
+//! VxWorks-specific raw type definitions
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use crate::os::raw::{c_ulong};
+
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = c_ulong;
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 7a3b5d30500..1d4fd98dd75 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -4,6 +4,7 @@
 
 use crate::any::Any;
 use crate::cell::UnsafeCell;
+use crate::collections;
 use crate::fmt;
 use crate::future::Future;
 use crate::pin::Pin;
@@ -285,6 +286,11 @@ impl RefUnwindSafe for atomic::AtomicBool {}
 #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")]
 impl<T> RefUnwindSafe for atomic::AtomicPtr<T> {}
 
+// https://github.com/rust-lang/rust/issues/62301
+#[stable(feature = "hashbrown", since = "1.36.0")]
+impl<K, V, S> UnwindSafe for collections::HashMap<K, V, S>
+    where K: UnwindSafe, V: UnwindSafe, S: UnwindSafe {}
+
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T> Deref for AssertUnwindSafe<T> {
     type Target = T;
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 27b8a110ca7..952fd9ebfdf 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -103,7 +103,9 @@ pub fn set_hook(hook: Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send>) {
         HOOK_LOCK.write_unlock();
 
         if let Hook::Custom(ptr) = old_hook {
-            Box::from_raw(ptr);
+            #[allow(unused_must_use)] {
+                Box::from_raw(ptr);
+            }
         }
     }
 }
@@ -171,7 +173,8 @@ fn default_hook(info: &PanicInfo<'_>) {
         }
     };
 
-    let location = info.location().unwrap();  // The current implementation always returns Some
+    // The current implementation always returns `Some`.
+    let location = info.location().unwrap();
 
     let msg = match info.payload().downcast_ref::<&'static str>() {
         Some(s) => *s,
@@ -196,7 +199,7 @@ fn default_hook(info: &PanicInfo<'_>) {
             if let Some(format) = log_backtrace {
                 let _ = backtrace::print(err, format);
             } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) {
-                let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` \
+                let _ = writeln!(err, "note: run with `RUST_BACKTRACE=1` \
                                        environment variable to display a backtrace.");
             }
         }
@@ -361,7 +364,7 @@ fn continue_panic_fmt(info: &PanicInfo<'_>) -> ! {
 
     unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
         fn box_me_up(&mut self) -> *mut (dyn Any + Send) {
-            let contents = mem::replace(self.fill(), String::new());
+            let contents = mem::take(self.fill());
             Box::into_raw(Box::new(contents))
         }
 
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 59f9e439add..fd6ff1032bb 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -317,7 +317,7 @@ unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
 
 // Detect scheme on Redox
 fn has_redox_scheme(s: &[u8]) -> bool {
-    cfg!(target_os = "redox") && s.split(|b| *b == b'/').next().unwrap_or(b"").contains(&b':')
+    cfg!(target_os = "redox") && s.contains(&b':')
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -888,11 +888,6 @@ 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")]
@@ -956,11 +951,6 @@ 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")]
@@ -1133,6 +1123,12 @@ impl FusedIterator for Ancestors<'_> {}
 /// Which method works best depends on what kind of situation you're in.
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
+// FIXME:
+// `PathBuf::as_mut_vec` current implementation relies
+// on `PathBuf` being layout-compatible with `Vec<u8>`.
+// When attribute privacy is implemented, `PathBuf` should be annotated as `#[repr(transparent)]`.
+// Anyway, `PathBuf` representation and layout are considered implementation detail, are
+// not documented and must not be relied upon.
 pub struct PathBuf {
     inner: OsString,
 }
@@ -1755,6 +1751,12 @@ impl AsRef<OsStr> for PathBuf {
 /// assert_eq!(extension, Some(OsStr::new("txt")));
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+// FIXME:
+// `Path::new` current implementation relies
+// on `Path` being layout-compatible with `OsStr`.
+// When attribute privacy is implemented, `Path` should be annotated as `#[repr(transparent)]`.
+// Anyway, `Path` representation and layout are considered implementation detail, are
+// not documented and must not be relied upon.
 pub struct Path {
     inner: OsStr,
 }
@@ -1829,6 +1831,8 @@ impl Path {
     /// Yields a [`&str`] slice if the `Path` is valid unicode.
     ///
     /// This conversion may entail doing a check for UTF-8 validity.
+    /// Note that validation is performed because non-UTF-8 strings are
+    /// perfectly valid for some OS.
     ///
     /// [`&str`]: ../primitive.str.html
     ///
diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs
index 551e982a3c6..3085c3d8296 100644
--- a/src/libstd/prelude/mod.rs
+++ b/src/libstd/prelude/mod.rs
@@ -71,9 +71,6 @@
 //! * [`std::result`]::[`Result`]::{`self`, `Ok`, `Err`}. A type for functions
 //!   that may succeed or fail. Like [`Option`], its variants are exported as
 //!   well.
-//! * [`std::slice`]::[`SliceConcatExt`], a trait that exists for technical
-//!   reasons, but shouldn't have to exist. It provides a few useful methods on
-//!   slices.
 //! * [`std::string`]::{[`String`], [`ToString`]}, heap allocated strings.
 //! * [`std::vec`]::[`Vec`](../vec/struct.Vec.html), a growable, heap-allocated
 //!   vector.
diff --git a/src/libstd/prelude/v1.rs b/src/libstd/prelude/v1.rs
index ce1e8e3319c..3e4cf91127f 100644
--- a/src/libstd/prelude/v1.rs
+++ b/src/libstd/prelude/v1.rs
@@ -9,7 +9,7 @@
 // Re-exported core operators
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
-pub use crate::marker::{Copy, Send, Sized, Sync, Unpin};
+pub use crate::marker::{Send, Sized, Sync, Unpin};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
 pub use crate::ops::{Drop, Fn, FnMut, FnOnce};
@@ -22,18 +22,9 @@ pub use crate::mem::drop;
 // Re-exported types and traits
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
-pub use crate::clone::Clone;
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)]
-pub use crate::cmp::{PartialEq, PartialOrd, Eq, Ord};
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)]
 pub use crate::convert::{AsRef, AsMut, Into, From};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
-pub use crate::default::Default;
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)]
 pub use crate::iter::{Iterator, Extend, IntoIterator};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
@@ -45,6 +36,55 @@ pub use crate::option::Option::{self, Some, None};
 #[doc(no_inline)]
 pub use crate::result::Result::{self, Ok, Err};
 
+// Re-exported built-in macros
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[doc(no_inline)]
+pub use core::prelude::v1::{
+    asm,
+    assert,
+    cfg,
+    column,
+    compile_error,
+    concat,
+    concat_idents,
+    env,
+    file,
+    format_args,
+    format_args_nl,
+    global_asm,
+    include,
+    include_bytes,
+    include_str,
+    line,
+    log_syntax,
+    module_path,
+    option_env,
+    stringify,
+    trace_macros,
+};
+
+// FIXME: Attribute and derive macros are not documented because for them rustdoc generates
+// dead links which fail link checker testing.
+#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
+#[allow(deprecated)]
+#[doc(hidden)]
+pub use core::prelude::v1::{
+    Clone,
+    Copy,
+    Debug,
+    Default,
+    Eq,
+    Hash,
+    Ord,
+    PartialEq,
+    PartialOrd,
+    RustcDecodable,
+    RustcEncodable,
+    bench,
+    global_allocator,
+    test,
+    test_case,
+};
 
 // The file so far is equivalent to src/libcore/prelude/v1.rs,
 // and below to src/liballoc/prelude.rs.
@@ -60,9 +100,6 @@ pub use crate::boxed::Box;
 pub use crate::borrow::ToOwned;
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
-pub use crate::slice::SliceConcatExt;
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(no_inline)]
 pub use crate::string::{String, ToString};
 #[stable(feature = "rust1", since = "1.0.0")]
 #[doc(no_inline)]
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index 24f728158c4..d9a3da66a67 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -120,7 +120,7 @@ mod prim_bool { }
 /// When implementing this trait for [`String`] we need to pick a type for [`Err`]. And since
 /// converting a string into a string will never result in an error, the appropriate type is `!`.
 /// (Currently the type actually used is an enum with no variants, though this is only because `!`
-/// was added to Rust at a later date and it may change in the future). With an [`Err`] type of
+/// was added to Rust at a later date and it may change in the future.) With an [`Err`] type of
 /// `!`, if we have to call [`String::from_str`] for some reason the result will be a
 /// [`Result<String, !>`] which we can unpack like this:
 ///
@@ -362,8 +362,13 @@ mod prim_unit { }
 ///
 /// *[See also the `std::ptr` module](ptr/index.html).*
 ///
-/// Working with raw pointers in Rust is uncommon,
-/// typically limited to a few patterns.
+/// Working with raw pointers in Rust is uncommon, typically limited to a few patterns.
+/// Raw pointers can be unaligned or [`null`]. However, when a raw pointer is
+/// dereferenced (using the `*` operator), it must be non-null and aligned.
+///
+/// Storing through a raw pointer using `*ptr = data` calls `drop` on the old value, so
+/// [`write`] must be used if the type has drop glue and memory is not already
+/// initialized - otherwise `drop` would be called on the uninitialized memory.
 ///
 /// Use the [`null`] and [`null_mut`] functions to create null pointers, and the
 /// [`is_null`] method of the `*const T` and `*mut T` types to check for null.
@@ -442,6 +447,7 @@ mod prim_unit { }
 /// [`offset`]: ../std/primitive.pointer.html#method.offset
 /// [`into_raw`]: ../std/boxed/struct.Box.html#method.into_raw
 /// [`drop`]: ../std/mem/fn.drop.html
+/// [`write`]: ../std/ptr/fn.write.html
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_pointer { }
 
@@ -482,8 +488,8 @@ mod prim_pointer { }
 /// an array. Indeed, this provides most of the API for working with arrays.
 /// Slices have a dynamic size and do not coerce to arrays.
 ///
-/// There is no way to move elements out of an array. See [`mem::replace`][replace]
-/// for an alternative.
+/// You can move elements out of an array with a slice pattern. If you want
+/// one element, see [`mem::replace`][replace].
 ///
 /// # Examples
 ///
@@ -525,6 +531,16 @@ mod prim_pointer { }
 /// for x in &array { }
 /// ```
 ///
+/// You can use a slice pattern to move elements out of an array:
+///
+/// ```
+/// fn move_away(_: String) { /* Do interesting things. */ }
+///
+/// let [john, roa] = ["John".to_string(), "Roa".to_string()];
+/// move_away(john);
+/// move_away(roa);
+/// ```
+///
 /// [slice]: primitive.slice.html
 /// [copy]: marker/trait.Copy.html
 /// [clone]: clone/trait.Clone.html
@@ -683,6 +699,10 @@ mod prim_str { }
 /// assert_eq!(tuple.2, 'c');
 /// ```
 ///
+/// The sequential nature of the tuple applies to its implementations of various
+/// traits.  For example, in `PartialOrd` and `Ord`, the elements are compared
+/// sequentially until the first non-equal set is found.
+///
 /// For more about tuples, see [the book](../book/ch03-02-data-types.html#the-tuple-type).
 ///
 /// # Trait implementations
@@ -877,9 +897,13 @@ mod prim_usize { }
 /// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut`
 /// operators on a value, or by using a `ref` or `ref mut` pattern.
 ///
-/// For those familiar with pointers, a reference is just a pointer that is assumed to not be null.
-/// In fact, `Option<&T>` has the same memory representation as a nullable pointer, and can be
-/// passed across FFI boundaries as such.
+/// For those familiar with pointers, a reference is just a pointer that is assumed to be
+/// aligned, not null, and pointing to memory containing a valid value of `T` - for example,
+/// `&bool` can only point to an allocation containing the integer values `1` (`true`) or `0`
+/// (`false`), but creating a `&bool` that points to an allocation containing
+/// the value `3` causes undefined behaviour.
+/// In fact, `Option<&T>` has the same memory representation as a
+/// nullable but aligned pointer, and can be passed across FFI boundaries as such.
 ///
 /// In most cases, references can be used much like the original value. Field access, method
 /// calling, and indexing work the same (save for mutability rules, of course). In addition, the
@@ -1022,6 +1046,11 @@ mod prim_ref { }
 /// [`FnMut`]: ops/trait.FnMut.html
 /// [`FnOnce`]: ops/trait.FnOnce.html
 ///
+/// Function pointers are pointers that point to *code*, not data. They can be called
+/// just like functions. Like references, function pointers are, among other things, assumed to
+/// not be null, so if you want to pass a function pointer over FFI and be able to accommodate null
+/// pointers, make your type `Option<fn()>` with your required signature.
+///
 /// Plain function pointers are obtained by casting either plain functions, or closures that don't
 /// capture an environment:
 ///
@@ -1077,10 +1106,6 @@ mod prim_ref { }
 ///
 /// These markers can be combined, so `unsafe extern "stdcall" fn()` is a valid type.
 ///
-/// Like references in rust, function pointers are assumed to not be null, so if you want to pass a
-/// function pointer over FFI and be able to accommodate null pointers, make your type
-/// `Option<fn()>` with your required signature.
-///
 /// Function pointers implement the following traits:
 ///
 /// * [`Clone`]
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 6e4c6e4c366..000f80f99e7 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -1153,10 +1153,13 @@ impl From<fs::File> for Stdio {
 ///
 /// This `struct` is used to represent the exit status of a child process.
 /// Child processes are created via the [`Command`] struct and their exit
-/// status is exposed through the [`status`] method.
+/// status is exposed through the [`status`] method, or the [`wait`] method
+/// of a [`Child`] process.
 ///
 /// [`Command`]: struct.Command.html
+/// [`Child`]: struct.Child.html
 /// [`status`]: struct.Command.html#method.status
+/// [`wait`]: struct.Child.html#method.wait
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ExitStatus(imp::ExitStatus);
@@ -1762,33 +1765,6 @@ mod tests {
         assert_eq!(out, "foobar\n");
     }
 
-
-    #[test]
-    #[cfg_attr(target_os = "android", ignore)]
-    #[cfg(unix)]
-    fn uid_works() {
-        use crate::os::unix::prelude::*;
-
-        let mut p = Command::new("/bin/sh")
-                            .arg("-c").arg("true")
-                            .uid(unsafe { libc::getuid() })
-                            .gid(unsafe { libc::getgid() })
-                            .spawn().unwrap();
-        assert!(p.wait().unwrap().success());
-    }
-
-    #[test]
-    #[cfg_attr(target_os = "android", ignore)]
-    #[cfg(unix)]
-    fn uid_to_root_fails() {
-        use crate::os::unix::prelude::*;
-
-        // if we're already root, this isn't a valid test. Most of the bots run
-        // as non-root though (android is an exception).
-        if unsafe { libc::getuid() == 0 } { return }
-        assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err());
-    }
-
     #[test]
     #[cfg_attr(target_os = "android", ignore)]
     fn test_process_status() {
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index ffb9ce1c81a..aeff57716e8 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -36,7 +36,7 @@ impl WaitTimeoutResult {
     /// let pair2 = pair.clone();
     ///
     /// thread::spawn(move|| {
-    ///     let &(ref lock, ref cvar) = &*pair2;
+    ///     let (lock, cvar) = &*pair2;
     ///
     ///     // Let's wait 20 milliseconds before notifying the condvar.
     ///     thread::sleep(Duration::from_millis(20));
@@ -48,7 +48,7 @@ impl WaitTimeoutResult {
     /// });
     ///
     /// // Wait for the thread to start up.
-    /// let &(ref lock, ref cvar) = &*pair;
+    /// let (lock, cvar) = &*pair;
     /// let mut started = lock.lock().unwrap();
     /// loop {
     ///     // Let's put a timeout on the condvar's wait.
@@ -94,7 +94,7 @@ impl WaitTimeoutResult {
 ///
 /// // Inside of our lock, spawn a new thread, and then wait for it to start.
 /// thread::spawn(move|| {
-///     let &(ref lock, ref cvar) = &*pair2;
+///     let (lock, cvar) = &*pair2;
 ///     let mut started = lock.lock().unwrap();
 ///     *started = true;
 ///     // We notify the condvar that the value has changed.
@@ -102,7 +102,7 @@ impl WaitTimeoutResult {
 /// });
 ///
 /// // Wait for the thread to start up.
-/// let &(ref lock, ref cvar) = &*pair;
+/// let (lock, cvar) = &*pair;
 /// let mut started = lock.lock().unwrap();
 /// while !*started {
 ///     started = cvar.wait(started).unwrap();
@@ -180,7 +180,7 @@ impl Condvar {
     /// let pair2 = pair.clone();
     ///
     /// thread::spawn(move|| {
-    ///     let &(ref lock, ref cvar) = &*pair2;
+    ///     let (lock, cvar) = &*pair2;
     ///     let mut started = lock.lock().unwrap();
     ///     *started = true;
     ///     // We notify the condvar that the value has changed.
@@ -188,7 +188,7 @@ impl Condvar {
     /// });
     ///
     /// // Wait for the thread to start up.
-    /// let &(ref lock, ref cvar) = &*pair;
+    /// let (lock, cvar) = &*pair;
     /// let mut started = lock.lock().unwrap();
     /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
     /// while !*started {
@@ -245,7 +245,7 @@ impl Condvar {
     /// let pair2 = pair.clone();
     ///
     /// thread::spawn(move|| {
-    ///     let &(ref lock, ref cvar) = &*pair2;
+    ///     let (lock, cvar) = &*pair2;
     ///     let mut started = lock.lock().unwrap();
     ///     *started = true;
     ///     // We notify the condvar that the value has changed.
@@ -253,7 +253,7 @@ impl Condvar {
     /// });
     ///
     /// // Wait for the thread to start up.
-    /// let &(ref lock, ref cvar) = &*pair;
+    /// let (lock, cvar) = &*pair;
     /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
     /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap();
     /// ```
@@ -301,7 +301,7 @@ impl Condvar {
     /// let pair2 = pair.clone();
     ///
     /// thread::spawn(move|| {
-    ///     let &(ref lock, ref cvar) = &*pair2;
+    ///     let (lock, cvar) = &*pair2;
     ///     let mut started = lock.lock().unwrap();
     ///     *started = true;
     ///     // We notify the condvar that the value has changed.
@@ -309,7 +309,7 @@ impl Condvar {
     /// });
     ///
     /// // Wait for the thread to start up.
-    /// let &(ref lock, ref cvar) = &*pair;
+    /// let (lock, cvar) = &*pair;
     /// let mut started = lock.lock().unwrap();
     /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
     /// loop {
@@ -374,7 +374,7 @@ impl Condvar {
     /// let pair2 = pair.clone();
     ///
     /// thread::spawn(move|| {
-    ///     let &(ref lock, ref cvar) = &*pair2;
+    ///     let (lock, cvar) = &*pair2;
     ///     let mut started = lock.lock().unwrap();
     ///     *started = true;
     ///     // We notify the condvar that the value has changed.
@@ -382,7 +382,7 @@ impl Condvar {
     /// });
     ///
     /// // wait for the thread to start up
-    /// let &(ref lock, ref cvar) = &*pair;
+    /// let (lock, cvar) = &*pair;
     /// let mut started = lock.lock().unwrap();
     /// // as long as the value inside the `Mutex<bool>` is `false`, we wait
     /// loop {
@@ -449,7 +449,7 @@ impl Condvar {
     /// let pair2 = pair.clone();
     ///
     /// thread::spawn(move|| {
-    ///     let &(ref lock, ref cvar) = &*pair2;
+    ///     let (lock, cvar) = &*pair2;
     ///     let mut started = lock.lock().unwrap();
     ///     *started = true;
     ///     // We notify the condvar that the value has changed.
@@ -457,7 +457,7 @@ impl Condvar {
     /// });
     ///
     /// // wait for the thread to start up
-    /// let &(ref lock, ref cvar) = &*pair;
+    /// let (lock, cvar) = &*pair;
     /// let result = cvar.wait_timeout_until(
     ///     lock.lock().unwrap(),
     ///     Duration::from_millis(100),
@@ -508,7 +508,7 @@ impl Condvar {
     /// let pair2 = pair.clone();
     ///
     /// thread::spawn(move|| {
-    ///     let &(ref lock, ref cvar) = &*pair2;
+    ///     let (lock, cvar) = &*pair2;
     ///     let mut started = lock.lock().unwrap();
     ///     *started = true;
     ///     // We notify the condvar that the value has changed.
@@ -516,7 +516,7 @@ impl Condvar {
     /// });
     ///
     /// // Wait for the thread to start up.
-    /// let &(ref lock, ref cvar) = &*pair;
+    /// let (lock, cvar) = &*pair;
     /// let mut started = lock.lock().unwrap();
     /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
     /// while !*started {
@@ -548,7 +548,7 @@ impl Condvar {
     /// let pair2 = pair.clone();
     ///
     /// thread::spawn(move|| {
-    ///     let &(ref lock, ref cvar) = &*pair2;
+    ///     let (lock, cvar) = &*pair2;
     ///     let mut started = lock.lock().unwrap();
     ///     *started = true;
     ///     // We notify the condvar that the value has changed.
@@ -556,7 +556,7 @@ impl Condvar {
     /// });
     ///
     /// // Wait for the thread to start up.
-    /// let &(ref lock, ref cvar) = &*pair;
+    /// let (lock, cvar) = &*pair;
     /// let mut started = lock.lock().unwrap();
     /// // As long as the value inside the `Mutex<bool>` is `false`, we wait.
     /// while !*started {
diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs
index 809ee882698..fd6e46fd61d 100644
--- a/src/libstd/sync/mod.rs
+++ b/src/libstd/sync/mod.rs
@@ -163,6 +163,7 @@ pub use self::condvar::{Condvar, WaitTimeoutResult};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::mutex::{Mutex, MutexGuard};
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 pub use self::once::{Once, OnceState, ONCE_INIT};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use crate::sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
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..58a4b716afb 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;
 
@@ -141,7 +140,7 @@ fn wait_timeout_receiver<'a, 'b, T>(lock: &'a Mutex<State<T>>,
     new_guard
 }
 
-fn abort_selection<'a, T>(guard: &mut MutexGuard<'a , State<T>>) -> bool {
+fn abort_selection<T>(guard: &mut MutexGuard<'_, State<T>>) -> bool {
     match mem::replace(&mut guard.blocker, NoneBlocked) {
         NoneBlocked => true,
         BlockedSender(token) => {
@@ -161,20 +160,20 @@ fn wakeup<T>(token: SignalToken, guard: MutexGuard<'_, State<T>>) {
 }
 
 impl<T> Packet<T> {
-    pub fn new(cap: usize) -> Packet<T> {
+    pub fn new(capacity: usize) -> Packet<T> {
         Packet {
             channels: AtomicUsize::new(1),
             lock: Mutex::new(State {
                 disconnected: false,
                 blocker: NoneBlocked,
-                cap,
+                cap: capacity,
                 canceled: None,
                 queue: Queue {
                     head: ptr::null_mut(),
                     tail: ptr::null_mut(),
                 },
                 buf: Buffer {
-                    buf: (0..cap + if cap == 0 {1} else {0}).map(|_| None).collect(),
+                    buf: (0..capacity + if capacity == 0 {1} else {0}).map(|_| None).collect(),
                     start: 0,
                     size: 0,
                 },
@@ -189,7 +188,7 @@ impl<T> Packet<T> {
         loop {
             let mut guard = self.lock.lock().unwrap();
             // are we ready to go?
-            if guard.disconnected || guard.buf.size() < guard.buf.cap() {
+            if guard.disconnected || guard.buf.size() < guard.buf.capacity() {
                 return guard;
             }
             // no room; actually block
@@ -231,7 +230,7 @@ impl<T> Packet<T> {
         let mut guard = self.lock.lock().unwrap();
         if guard.disconnected {
             Err(super::TrySendError::Disconnected(t))
-        } else if guard.buf.size() == guard.buf.cap() {
+        } else if guard.buf.size() == guard.buf.capacity() {
             Err(super::TrySendError::Full(t))
         } else if guard.cap == 0 {
             // With capacity 0, even though we have buffer space we can't
@@ -249,7 +248,7 @@ impl<T> Packet<T> {
             // If the buffer has some space and the capacity isn't 0, then we
             // just enqueue the data for later retrieval, ensuring to wake up
             // any blocked receiver if there is one.
-            assert!(guard.buf.size() < guard.buf.cap());
+            assert!(guard.buf.size() < guard.buf.capacity());
             guard.buf.enqueue(t);
             match mem::replace(&mut guard.blocker, NoneBlocked) {
                 BlockedReceiver(token) => wakeup(token, guard),
@@ -384,7 +383,7 @@ impl<T> Packet<T> {
         // needs to be careful to destroy the data *outside* of the lock to
         // prevent deadlock.
         let _data = if guard.cap != 0 {
-            mem::replace(&mut guard.buf.buf, Vec::new())
+            mem::take(&mut guard.buf.buf)
         } else {
             Vec::new()
         };
@@ -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> {
@@ -475,7 +438,7 @@ impl<T> Buffer<T> {
     }
 
     fn size(&self) -> usize { self.size }
-    fn cap(&self) -> usize { self.buf.len() }
+    fn capacity(&self) -> usize { self.buf.len() }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
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/once.rs b/src/libstd/sync/once.rs
index 0c912494024..e529b8c4227 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -115,6 +115,11 @@ pub struct OnceState {
 /// static START: Once = ONCE_INIT;
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_deprecated(
+    since = "1.38.0",
+    reason = "the `new` function is now preferred",
+    suggestion = "Once::new()",
+)]
 pub const ONCE_INIT: Once = Once::new();
 
 // Four states that a Once can be in, encoded into the lower bits of `state` in
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/cloudabi/abi/cloudabi.rs b/src/libstd/sys/cloudabi/abi/cloudabi.rs
index 2307e2167c5..38db4dd5165 100644
--- a/src/libstd/sys/cloudabi/abi/cloudabi.rs
+++ b/src/libstd/sys/cloudabi/abi/cloudabi.rs
@@ -115,6 +115,7 @@
 
 #![no_std]
 #![allow(non_camel_case_types)]
+#![allow(deprecated)] // FIXME: using `mem::uninitialized()`
 
 include!("bitflags.rs");
 
@@ -1884,7 +1885,7 @@ pub unsafe fn clock_res_get(clock_id_: clockid, resolution_: &mut timestamp) ->
 /// **time**:
 /// The time value of the clock.
 #[inline]
-pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: &mut timestamp) -> errno {
+pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: *mut timestamp) -> errno {
   cloudabi_sys_clock_time_get(clock_id_, precision_, time_)
 }
 
@@ -2643,7 +2644,7 @@ pub unsafe fn mem_unmap(mapping_: &mut [u8]) -> errno {
 /// **nevents**:
 /// The number of events stored.
 #[inline]
-pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: &mut usize) -> errno {
+pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: *mut usize) -> errno {
   cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_)
 }
 
diff --git a/src/libstd/sys/cloudabi/backtrace.rs b/src/libstd/sys/cloudabi/backtrace.rs
deleted file mode 100644
index 17719a29b6e..00000000000
--- a/src/libstd/sys/cloudabi/backtrace.rs
+++ /dev/null
@@ -1,116 +0,0 @@
-use crate::error::Error;
-use crate::ffi::CStr;
-use crate::fmt;
-use crate::intrinsics;
-use crate::io;
-use crate::sys_common::backtrace::Frame;
-
-use unwind as uw;
-
-pub struct BacktraceContext;
-
-struct Context<'a> {
-    idx: usize,
-    frames: &'a mut [Frame],
-}
-
-#[derive(Debug)]
-struct UnwindError(uw::_Unwind_Reason_Code);
-
-impl Error for UnwindError {
-    fn description(&self) -> &'static str {
-        "unexpected return value while unwinding"
-    }
-}
-
-impl fmt::Display for UnwindError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}: {:?}", self.description(), self.0)
-    }
-}
-
-#[inline(never)] // if we know this is a function call, we can skip it when
-                 // tracing
-pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> {
-    let mut cx = Context { idx: 0, frames };
-    let result_unwind = unsafe {
-        uw::_Unwind_Backtrace(trace_fn, &mut cx as *mut Context<'_> as *mut libc::c_void)
-    };
-    // See libunwind:src/unwind/Backtrace.c for the return values.
-    // No, there is no doc.
-    match result_unwind {
-        // These return codes seem to be benign and need to be ignored for backtraces
-        // to show up properly on all tested platforms.
-        uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
-            Ok((cx.idx, BacktraceContext))
-        }
-        _ => Err(io::Error::new(
-            io::ErrorKind::Other,
-            UnwindError(result_unwind),
-        )),
-    }
-}
-
-extern "C" fn trace_fn(
-    ctx: *mut uw::_Unwind_Context,
-    arg: *mut libc::c_void,
-) -> uw::_Unwind_Reason_Code {
-    let cx = unsafe { &mut *(arg as *mut Context<'_>) };
-    if cx.idx >= cx.frames.len() {
-        return uw::_URC_NORMAL_STOP;
-    }
-
-    let mut ip_before_insn = 0;
-    let mut ip = unsafe { uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void };
-    if !ip.is_null() && ip_before_insn == 0 {
-        // this is a non-signaling frame, so `ip` refers to the address
-        // after the calling instruction. account for that.
-        ip = (ip as usize - 1) as *mut _;
-    }
-
-    let symaddr = unsafe { uw::_Unwind_FindEnclosingFunction(ip) };
-    cx.frames[cx.idx] = Frame {
-        symbol_addr: symaddr as *mut u8,
-        exact_position: ip as *mut u8,
-        inline_context: 0,
-    };
-    cx.idx += 1;
-
-    uw::_URC_NO_REASON
-}
-
-pub fn foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool>
-where
-    F: FnMut(&[u8], u32) -> io::Result<()>,
-{
-    // No way to obtain this information on CloudABI.
-    Ok(false)
-}
-
-pub fn resolve_symname<F>(frame: Frame, callback: F, _: &BacktraceContext) -> io::Result<()>
-where
-    F: FnOnce(Option<&str>) -> io::Result<()>,
-{
-    unsafe {
-        let mut info: Dl_info = intrinsics::init();
-        let symname =
-            if dladdr(frame.exact_position as *mut _, &mut info) == 0 || info.dli_sname.is_null() {
-                None
-            } else {
-                CStr::from_ptr(info.dli_sname).to_str().ok()
-            };
-        callback(symname)
-    }
-}
-
-#[repr(C)]
-struct Dl_info {
-    dli_fname: *const libc::c_char,
-    dli_fbase: *mut libc::c_void,
-    dli_sname: *const libc::c_char,
-    dli_saddr: *mut libc::c_void,
-}
-
-extern "C" {
-    fn dladdr(addr: *const libc::c_void, info: *mut Dl_info) -> libc::c_int;
-}
diff --git a/src/libstd/sys/cloudabi/condvar.rs b/src/libstd/sys/cloudabi/condvar.rs
index 7aa0b0b6f49..ec1fca7805a 100644
--- a/src/libstd/sys/cloudabi/condvar.rs
+++ b/src/libstd/sys/cloudabi/condvar.rs
@@ -79,16 +79,21 @@ impl Condvar {
             },
             ..mem::zeroed()
         };
-        let mut event: abi::event = mem::uninitialized();
-        let mut nevents: usize = mem::uninitialized();
-        let ret = abi::poll(&subscription, &mut event, 1, &mut nevents);
+        let mut event: mem::MaybeUninit<abi::event> = mem::MaybeUninit::uninit();
+        let mut nevents: mem::MaybeUninit<usize> = mem::MaybeUninit::uninit();
+        let ret = abi::poll(
+            &subscription,
+            event.as_mut_ptr(),
+            1,
+            nevents.as_mut_ptr()
+        );
         assert_eq!(
             ret,
             abi::errno::SUCCESS,
             "Failed to wait on condition variable"
         );
         assert_eq!(
-            event.error,
+            event.assume_init().error,
             abi::errno::SUCCESS,
             "Failed to wait on condition variable"
         );
@@ -131,21 +136,27 @@ impl Condvar {
                 ..mem::zeroed()
             },
         ];
-        let mut events: [abi::event; 2] = mem::uninitialized();
-        let mut nevents: usize = mem::uninitialized();
-        let ret = abi::poll(subscriptions.as_ptr(), events.as_mut_ptr(), 2, &mut nevents);
+        let mut events: [mem::MaybeUninit<abi::event>; 2] = [mem::MaybeUninit::uninit(); 2];
+        let mut nevents: mem::MaybeUninit<usize> = mem::MaybeUninit::uninit();
+        let ret = abi::poll(
+            subscriptions.as_ptr(),
+            mem::MaybeUninit::first_ptr_mut(&mut events),
+            2,
+            nevents.as_mut_ptr()
+        );
         assert_eq!(
             ret,
             abi::errno::SUCCESS,
             "Failed to wait on condition variable"
         );
+        let nevents = nevents.assume_init();
         for i in 0..nevents {
             assert_eq!(
-                events[i].error,
+                events[i].assume_init().error,
                 abi::errno::SUCCESS,
                 "Failed to wait on condition variable"
             );
-            if events[i].type_ == abi::eventtype::CONDVAR {
+            if events[i].assume_init().type_ == abi::eventtype::CONDVAR {
                 return true;
             }
         }
diff --git a/src/libstd/sys/cloudabi/io.rs b/src/libstd/sys/cloudabi/io.rs
index 4b423a5cbc1..976e122463d 100644
--- a/src/libstd/sys/cloudabi/io.rs
+++ b/src/libstd/sys/cloudabi/io.rs
@@ -1,3 +1,5 @@
+use crate::mem;
+
 pub struct IoSlice<'a>(&'a [u8]);
 
 impl<'a> IoSlice<'a> {
@@ -7,6 +9,11 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        self.0 = &self.0[n..]
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         self.0
     }
@@ -21,6 +28,13 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        let slice = mem::replace(&mut self.0, &mut []);
+        let (_, remaining) = slice.split_at_mut(n);
+        self.0 = remaining;
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         self.0
     }
diff --git a/src/libstd/sys/cloudabi/mod.rs b/src/libstd/sys/cloudabi/mod.rs
index 3f8e67a7af8..2fb10cc370a 100644
--- a/src/libstd/sys/cloudabi/mod.rs
+++ b/src/libstd/sys/cloudabi/mod.rs
@@ -4,8 +4,6 @@ use crate::mem;
 #[path = "../unix/alloc.rs"]
 pub mod alloc;
 pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 #[path = "../unix/cmath.rs"]
 pub mod cmath;
 pub mod condvar;
@@ -61,8 +59,11 @@ pub use libc::strlen;
 
 pub fn hashmap_random_keys() -> (u64, u64) {
     unsafe {
-        let mut v = mem::uninitialized();
-        libc::arc4random_buf(&mut v as *mut _ as *mut libc::c_void, mem::size_of_val(&v));
-        v
+        let mut v: mem::MaybeUninit<(u64, u64)> = mem::MaybeUninit::uninit();
+        libc::arc4random_buf(
+            v.as_mut_ptr() as *mut libc::c_void,
+            mem::size_of_val(&v)
+        );
+        v.assume_init()
     }
 }
diff --git a/src/libstd/sys/cloudabi/mutex.rs b/src/libstd/sys/cloudabi/mutex.rs
index 5e191e31d5f..0e30d3a1c6c 100644
--- a/src/libstd/sys/cloudabi/mutex.rs
+++ b/src/libstd/sys/cloudabi/mutex.rs
@@ -1,5 +1,6 @@
 use crate::cell::UnsafeCell;
 use crate::mem;
+use crate::mem::MaybeUninit;
 use crate::sync::atomic::{AtomicU32, Ordering};
 use crate::sys::cloudabi::abi;
 use crate::sys::rwlock::{self, RWLock};
@@ -47,24 +48,27 @@ impl Mutex {
 }
 
 pub struct ReentrantMutex {
-    lock: UnsafeCell<AtomicU32>,
-    recursion: UnsafeCell<u32>,
+    lock: UnsafeCell<MaybeUninit<AtomicU32>>,
+    recursion: UnsafeCell<MaybeUninit<u32>>,
 }
 
 impl ReentrantMutex {
     pub unsafe fn uninitialized() -> ReentrantMutex {
-        mem::uninitialized()
+        ReentrantMutex {
+            lock: UnsafeCell::new(MaybeUninit::uninit()),
+            recursion: UnsafeCell::new(MaybeUninit::uninit())
+        }
     }
 
     pub unsafe fn init(&mut self) {
-        self.lock = UnsafeCell::new(AtomicU32::new(abi::LOCK_UNLOCKED.0));
-        self.recursion = UnsafeCell::new(0);
+        self.lock = UnsafeCell::new(MaybeUninit::new(AtomicU32::new(abi::LOCK_UNLOCKED.0)));
+        self.recursion = UnsafeCell::new(MaybeUninit::new(0));
     }
 
     pub unsafe fn try_lock(&self) -> bool {
         // Attempt to acquire the lock.
-        let lock = self.lock.get();
-        let recursion = self.recursion.get();
+        let lock = (*self.lock.get()).as_mut_ptr();
+        let recursion = (*self.recursion.get()).as_mut_ptr();
         if let Err(old) = (*lock).compare_exchange(
             abi::LOCK_UNLOCKED.0,
             __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
@@ -100,17 +104,18 @@ impl ReentrantMutex {
                 },
                 ..mem::zeroed()
             };
-            let mut event: abi::event = mem::uninitialized();
-            let mut nevents: usize = mem::uninitialized();
-            let ret = abi::poll(&subscription, &mut event, 1, &mut nevents);
+            let mut event = MaybeUninit::<abi::event>::uninit();
+            let mut nevents = MaybeUninit::<usize>::uninit();
+            let ret = abi::poll(&subscription, event.as_mut_ptr(), 1, nevents.as_mut_ptr());
             assert_eq!(ret, abi::errno::SUCCESS, "Failed to acquire mutex");
+            let event = event.assume_init();
             assert_eq!(event.error, abi::errno::SUCCESS, "Failed to acquire mutex");
         }
     }
 
     pub unsafe fn unlock(&self) {
-        let lock = self.lock.get();
-        let recursion = self.recursion.get();
+        let lock = (*self.lock.get()).as_mut_ptr();
+        let recursion = (*self.recursion.get()).as_mut_ptr();
         assert_eq!(
             (*lock).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0,
             __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0,
@@ -136,8 +141,8 @@ impl ReentrantMutex {
     }
 
     pub unsafe fn destroy(&self) {
-        let lock = self.lock.get();
-        let recursion = self.recursion.get();
+        let lock = (*self.lock.get()).as_mut_ptr();
+        let recursion = (*self.recursion.get()).as_mut_ptr();
         assert_eq!(
             (*lock).load(Ordering::Relaxed),
             abi::LOCK_UNLOCKED.0,
diff --git a/src/libstd/sys/cloudabi/rwlock.rs b/src/libstd/sys/cloudabi/rwlock.rs
index 6da3f3841b6..73499d65a06 100644
--- a/src/libstd/sys/cloudabi/rwlock.rs
+++ b/src/libstd/sys/cloudabi/rwlock.rs
@@ -1,5 +1,6 @@
 use crate::cell::UnsafeCell;
 use crate::mem;
+use crate::mem::MaybeUninit;
 use crate::sync::atomic::{AtomicU32, Ordering};
 use crate::sys::cloudabi::abi;
 
@@ -73,10 +74,11 @@ impl RWLock {
                 },
                 ..mem::zeroed()
             };
-            let mut event: abi::event = mem::uninitialized();
-            let mut nevents: usize = mem::uninitialized();
-            let ret = abi::poll(&subscription, &mut event, 1, &mut nevents);
+            let mut event = MaybeUninit::<abi::event>::uninit();
+            let mut nevents = MaybeUninit::<usize>::uninit();
+            let ret = abi::poll(&subscription, event.as_mut_ptr(), 1, nevents.as_mut_ptr());
             assert_eq!(ret, abi::errno::SUCCESS, "Failed to acquire read lock");
+            let event = event.assume_init();
             assert_eq!(
                 event.error,
                 abi::errno::SUCCESS,
@@ -182,10 +184,11 @@ impl RWLock {
                 },
                 ..mem::zeroed()
             };
-            let mut event: abi::event = mem::uninitialized();
-            let mut nevents: usize = mem::uninitialized();
-            let ret = abi::poll(&subscription, &mut event, 1, &mut nevents);
+            let mut event = MaybeUninit::<abi::event>::uninit();
+            let mut nevents = MaybeUninit::<usize>::uninit();
+            let ret = abi::poll(&subscription, event.as_mut_ptr(), 1, nevents.as_mut_ptr());
             assert_eq!(ret, abi::errno::SUCCESS, "Failed to acquire write lock");
+            let event = event.assume_init();
             assert_eq!(
                 event.error,
                 abi::errno::SUCCESS,
diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs
index 7da16c4d247..240b6ea9e57 100644
--- a/src/libstd/sys/cloudabi/thread.rs
+++ b/src/libstd/sys/cloudabi/thread.rs
@@ -72,10 +72,11 @@ impl Thread {
                 },
                 ..mem::zeroed()
             };
-            let mut event: abi::event = mem::uninitialized();
-            let mut nevents: usize = mem::uninitialized();
-            let ret = abi::poll(&subscription, &mut event, 1, &mut nevents);
+            let mut event = mem::MaybeUninit::<abi::event>::uninit();
+            let mut nevents = mem::MaybeUninit::<usize>::uninit();
+            let ret = abi::poll(&subscription, event.as_mut_ptr(), 1, nevents.as_mut_ptr());
             assert_eq!(ret, abi::errno::SUCCESS);
+            let event = event.assume_init();
             assert_eq!(event.error, abi::errno::SUCCESS);
         }
     }
diff --git a/src/libstd/sys/cloudabi/time.rs b/src/libstd/sys/cloudabi/time.rs
index 49a234e1158..5e502dcb2ba 100644
--- a/src/libstd/sys/cloudabi/time.rs
+++ b/src/libstd/sys/cloudabi/time.rs
@@ -18,10 +18,10 @@ pub fn checked_dur2intervals(dur: &Duration) -> Option<abi::timestamp> {
 impl Instant {
     pub fn now() -> Instant {
         unsafe {
-            let mut t = mem::uninitialized();
-            let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, &mut t);
+            let mut t: mem::MaybeUninit<abi::timestamp> = mem::MaybeUninit::uninit();
+            let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, t.as_mut_ptr());
             assert_eq!(ret, abi::errno::SUCCESS);
-            Instant { t }
+            Instant { t: t.assume_init() }
         }
     }
 
@@ -59,10 +59,10 @@ pub struct SystemTime {
 impl SystemTime {
     pub fn now() -> SystemTime {
         unsafe {
-            let mut t = mem::uninitialized();
-            let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, &mut t);
+            let mut t: mem::MaybeUninit<abi::timestamp> = mem::MaybeUninit::uninit();
+            let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, t.as_mut_ptr());
             assert_eq!(ret, abi::errno::SUCCESS);
-            SystemTime { t }
+            SystemTime { t: t.assume_init() }
         }
     }
 
diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs
index 3f3cedc53b7..5a5859a6ad8 100644
--- a/src/libstd/sys/mod.rs
+++ b/src/libstd/sys/mod.rs
@@ -22,8 +22,11 @@
 
 #![allow(missing_debug_implementations)]
 
-cfg_if! {
-    if #[cfg(unix)] {
+cfg_if::cfg_if! {
+    if #[cfg(target_os = "vxworks")] {
+        mod vxworks;
+        pub use self::vxworks::*;
+    } else if #[cfg(unix)] {
         mod unix;
         pub use self::unix::*;
     } else if #[cfg(windows)] {
@@ -32,9 +35,6 @@ cfg_if! {
     } else if #[cfg(target_os = "cloudabi")] {
         mod cloudabi;
         pub use self::cloudabi::*;
-    } else if #[cfg(target_os = "redox")] {
-        mod redox;
-        pub use self::redox::*;
     } else if #[cfg(target_os = "wasi")] {
         mod wasi;
         pub use self::wasi::*;
@@ -54,8 +54,8 @@ cfg_if! {
 // Windows when we're compiling for Linux.
 
 #[cfg(rustdoc)]
-cfg_if! {
-    if #[cfg(any(unix, target_os = "redox"))] {
+cfg_if::cfg_if! {
+    if #[cfg(unix)] {
         // On unix we'll document what's already available
         #[stable(feature = "rust1", since = "1.0.0")]
         pub use self::ext as unix_ext;
@@ -77,7 +77,7 @@ cfg_if! {
 }
 
 #[cfg(rustdoc)]
-cfg_if! {
+cfg_if::cfg_if! {
     if #[cfg(windows)] {
         // On windows we'll just be documenting what's already available
         #[allow(missing_docs)]
diff --git a/src/libstd/sys/redox/backtrace/mod.rs b/src/libstd/sys/redox/backtrace/mod.rs
deleted file mode 100644
index 8ea2783580a..00000000000
--- a/src/libstd/sys/redox/backtrace/mod.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-/// See sys/unix/backtrace/mod.rs for an explanation of the method used here.
-
-pub use self::tracing::unwind_backtrace;
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-
-// tracing impls:
-mod tracing;
-// symbol resolvers:
-mod printing;
-
-pub mod gnu {
-    use crate::io;
-    use crate::fs;
-    use crate::vec::Vec;
-    use crate::ffi::OsStr;
-    use crate::os::unix::ffi::OsStrExt;
-    use crate::io::Read;
-    use libc::c_char;
-
-    pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
-        let mut exefile = fs::File::open("sys:exe")?;
-        let mut exename = Vec::new();
-        exefile.read_to_end(&mut exename)?;
-        if exename.last() == Some(&b'\n') {
-            exename.pop();
-        }
-        let file = fs::File::open(OsStr::from_bytes(&exename))?;
-        Ok((exename.into_iter().map(|c| c as c_char).collect(), file))
-    }
-}
-
-pub struct BacktraceContext;
diff --git a/src/libstd/sys/redox/backtrace/printing.rs b/src/libstd/sys/redox/backtrace/printing.rs
deleted file mode 100644
index 489eed4562d..00000000000
--- a/src/libstd/sys/redox/backtrace/printing.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub use crate::sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
diff --git a/src/libstd/sys/redox/backtrace/tracing.rs b/src/libstd/sys/redox/backtrace/tracing.rs
deleted file mode 100644
index 13f34338fd3..00000000000
--- a/src/libstd/sys/redox/backtrace/tracing.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use crate::error::Error;
-use crate::fmt;
-use crate::io;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-use unwind as uw;
-
-struct Context<'a> {
-    idx: usize,
-    frames: &'a mut [Frame],
-}
-
-#[derive(Debug)]
-struct UnwindError(uw::_Unwind_Reason_Code);
-
-impl Error for UnwindError {
-    fn description(&self) -> &'static str {
-        "unexpected return value while unwinding"
-    }
-}
-
-impl fmt::Display for UnwindError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}: {:?}", self.description(), self.0)
-    }
-}
-
-#[inline(never)] // if we know this is a function call, we can skip it when
-                 // tracing
-pub fn unwind_backtrace(frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    let mut cx = Context {
-        idx: 0,
-        frames: frames,
-    };
-    let result_unwind = unsafe {
-        uw::_Unwind_Backtrace(trace_fn,
-                              &mut cx as *mut Context<'_>
-                              as *mut libc::c_void)
-    };
-    // See libunwind:src/unwind/Backtrace.c for the return values.
-    // No, there is no doc.
-    match result_unwind {
-        // These return codes seem to be benign and need to be ignored for backtraces
-        // to show up properly on all tested platforms.
-        uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
-            Ok((cx.idx, BacktraceContext))
-        }
-        _ => {
-            Err(io::Error::new(io::ErrorKind::Other,
-                               UnwindError(result_unwind)))
-        }
-    }
-}
-
-extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
-                   arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
-    let cx = unsafe { &mut *(arg as *mut Context<'_>) };
-    if cx.idx >= cx.frames.len() {
-        return uw::_URC_NORMAL_STOP;
-    }
-
-    let mut ip_before_insn = 0;
-    let mut ip = unsafe {
-        uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void
-    };
-    if !ip.is_null() && ip_before_insn == 0 {
-        // this is a non-signaling frame, so `ip` refers to the address
-        // after the calling instruction. account for that.
-        ip = (ip as usize - 1) as *mut _;
-    }
-
-    // dladdr() on osx gets whiny when we use FindEnclosingFunction, and
-    // it appears to work fine without it, so we only use
-    // FindEnclosingFunction on non-osx platforms. In doing so, we get a
-    // slightly more accurate stack trace in the process.
-    //
-    // This is often because panic involves the last instruction of a
-    // function being "call std::rt::begin_unwind", with no ret
-    // instructions after it. This means that the return instruction
-    // pointer points *outside* of the calling function, and by
-    // unwinding it we go back to the original function.
-    let symaddr = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
-        ip
-    } else {
-        unsafe { uw::_Unwind_FindEnclosingFunction(ip) }
-    };
-
-    cx.frames[cx.idx] = Frame {
-        symbol_addr: symaddr as *mut u8,
-        exact_position: ip as *mut u8,
-        inline_context: 0,
-    };
-    cx.idx += 1;
-
-    uw::_URC_NO_REASON
-}
diff --git a/src/libstd/sys/redox/condvar.rs b/src/libstd/sys/redox/condvar.rs
deleted file mode 100644
index a6365cac23e..00000000000
--- a/src/libstd/sys/redox/condvar.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-use crate::cell::UnsafeCell;
-use crate::intrinsics::{atomic_cxchg, atomic_load, atomic_xadd, atomic_xchg};
-use crate::ptr;
-use crate::time::Duration;
-
-use crate::sys::mutex::{mutex_unlock, Mutex};
-use crate::sys::syscall::{futex, TimeSpec, FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE};
-
-pub struct Condvar {
-    lock: UnsafeCell<*mut i32>,
-    seq: UnsafeCell<i32>
-}
-
-impl Condvar {
-    pub const fn new() -> Condvar {
-        Condvar {
-            lock: UnsafeCell::new(ptr::null_mut()),
-            seq: UnsafeCell::new(0)
-        }
-    }
-
-    #[inline]
-    pub unsafe fn init(&self) {
-        *self.lock.get() = ptr::null_mut();
-        *self.seq.get() = 0;
-    }
-
-    #[inline]
-    pub fn notify_one(&self) {
-        unsafe {
-            let seq = self.seq.get();
-
-            atomic_xadd(seq, 1);
-
-            let _ = futex(seq, FUTEX_WAKE, 1, 0, ptr::null_mut());
-        }
-    }
-
-    #[inline]
-    pub fn notify_all(&self) {
-        unsafe {
-            let lock = self.lock.get();
-            let seq = self.seq.get();
-
-            if *lock == ptr::null_mut() {
-                return;
-            }
-
-            atomic_xadd(seq, 1);
-
-            let _ = futex(seq, FUTEX_REQUEUE, 1, crate::usize::MAX, *lock);
-        }
-    }
-
-    #[inline]
-    unsafe fn wait_inner(&self, mutex: &Mutex, timeout_ptr: *const TimeSpec) -> bool {
-        let lock = self.lock.get();
-        let seq = self.seq.get();
-
-        if *lock != mutex.lock.get() {
-            if *lock != ptr::null_mut() {
-                panic!("Condvar used with more than one Mutex");
-            }
-
-            atomic_cxchg(lock as *mut usize, 0, mutex.lock.get() as usize);
-        }
-
-        mutex_unlock(*lock);
-
-        let seq_before = atomic_load(seq);
-
-        let _ = futex(seq, FUTEX_WAIT, seq_before, timeout_ptr as usize, ptr::null_mut());
-
-        let seq_after = atomic_load(seq);
-
-        while atomic_xchg(*lock, 2) != 0 {
-            let _ = futex(*lock, FUTEX_WAIT, 2, 0, ptr::null_mut());
-        }
-
-        seq_before != seq_after
-    }
-
-    #[inline]
-    pub fn wait(&self, mutex: &Mutex) {
-        unsafe {
-            assert!(self.wait_inner(mutex, ptr::null()));
-        }
-    }
-
-    #[inline]
-    pub fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
-        unsafe {
-            let timeout = TimeSpec {
-                tv_sec: dur.as_secs() as i64,
-                tv_nsec: dur.subsec_nanos() as i32
-            };
-
-            self.wait_inner(mutex, &timeout as *const TimeSpec)
-        }
-    }
-
-    #[inline]
-    pub unsafe fn destroy(&self) {
-        *self.lock.get() = ptr::null_mut();
-        *self.seq.get() = 0;
-    }
-}
-
-unsafe impl Send for Condvar {}
-
-unsafe impl Sync for Condvar {}
diff --git a/src/libstd/sys/redox/ext/fs.rs b/src/libstd/sys/redox/ext/fs.rs
deleted file mode 100644
index 53b9dd68f73..00000000000
--- a/src/libstd/sys/redox/ext/fs.rs
+++ /dev/null
@@ -1,339 +0,0 @@
-//! Redox-specific extensions to primitives in the `std::fs` module.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use crate::fs::{self, Permissions, OpenOptions};
-use crate::io;
-use crate::path::Path;
-use crate::sys;
-use crate::sys_common::{FromInner, AsInner, AsInnerMut};
-
-/// Redox-specific extensions to [`fs::Permissions`].
-///
-/// [`fs::Permissions`]: ../../../../std/fs/struct.Permissions.html
-#[stable(feature = "fs_ext", since = "1.1.0")]
-pub trait PermissionsExt {
-    /// Returns the underlying raw `mode_t` bits that are the standard Redox
-    /// permissions for this file.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::fs::File;
-    /// use std::os::redox::fs::PermissionsExt;
-    ///
-    /// fn main() -> std::io::Result<()> {
-    ///     let f = File::create("foo.txt")?;
-    ///     let metadata = f.metadata()?;
-    ///     let permissions = metadata.permissions();
-    ///
-    ///     println!("permissions: {}", permissions.mode());
-    ///     Ok(())
-    /// }
-    /// ```
-    #[stable(feature = "fs_ext", since = "1.1.0")]
-    fn mode(&self) -> u32;
-
-    /// Sets the underlying raw bits for this set of permissions.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::fs::File;
-    /// use std::os::redox::fs::PermissionsExt;
-    ///
-    /// fn main() -> std::io::Result<()> {
-    ///     let f = File::create("foo.txt")?;
-    ///     let metadata = f.metadata()?;
-    ///     let mut permissions = metadata.permissions();
-    ///
-    ///     permissions.set_mode(0o644); // Read/write for owner and read for others.
-    ///     assert_eq!(permissions.mode(), 0o644);
-    ///     Ok(())
-    /// }
-    /// ```
-    #[stable(feature = "fs_ext", since = "1.1.0")]
-    fn set_mode(&mut self, mode: u32);
-
-    /// Creates a new instance of `Permissions` from the given set of Redox
-    /// permission bits.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::fs::Permissions;
-    /// use std::os::redox::fs::PermissionsExt;
-    ///
-    /// // Read/write for owner and read for others.
-    /// let permissions = Permissions::from_mode(0o644);
-    /// assert_eq!(permissions.mode(), 0o644);
-    /// ```
-    #[stable(feature = "fs_ext", since = "1.1.0")]
-    fn from_mode(mode: u32) -> Self;
-}
-
-#[stable(feature = "fs_ext", since = "1.1.0")]
-impl PermissionsExt for Permissions {
-    fn mode(&self) -> u32 {
-        self.as_inner().mode()
-    }
-
-    fn set_mode(&mut self, mode: u32) {
-        *self = Permissions::from_inner(FromInner::from_inner(mode));
-    }
-
-    fn from_mode(mode: u32) -> Permissions {
-        Permissions::from_inner(FromInner::from_inner(mode))
-    }
-}
-
-/// Redox-specific extensions to [`fs::OpenOptions`].
-///
-/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html
-#[stable(feature = "fs_ext", since = "1.1.0")]
-pub trait OpenOptionsExt {
-    /// Sets the mode bits that a new file will be created with.
-    ///
-    /// If a new file is created as part of a `File::open_opts` call then this
-    /// specified `mode` will be used as the permission bits for the new file.
-    /// If no `mode` is set, the default of `0o666` will be used.
-    /// The operating system masks out bits with the systems `umask`, to produce
-    /// the final permissions.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// # #![feature(libc)]
-    /// extern crate libc;
-    /// use std::fs::OpenOptions;
-    /// use std::os::redox::fs::OpenOptionsExt;
-    ///
-    /// # fn main() {
-    /// let mut options = OpenOptions::new();
-    /// options.mode(0o644); // Give read/write for owner and read for others.
-    /// let file = options.open("foo.txt");
-    /// # }
-    /// ```
-    #[stable(feature = "fs_ext", since = "1.1.0")]
-    fn mode(&mut self, mode: u32) -> &mut Self;
-
-    /// Passes custom flags to the `flags` argument of `open`.
-    ///
-    /// The bits that define the access mode are masked out with `O_ACCMODE`, to
-    /// ensure they do not interfere with the access mode set by Rusts options.
-    ///
-    /// Custom flags can only set flags, not remove flags set by Rusts options.
-    /// This options overwrites any previously set custom flags.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// # #![feature(libc)]
-    /// extern crate libc;
-    /// use std::fs::OpenOptions;
-    /// use std::os::redox::fs::OpenOptionsExt;
-    ///
-    /// # fn main() {
-    /// let mut options = OpenOptions::new();
-    /// options.write(true);
-    /// if cfg!(target_os = "redox") {
-    ///     options.custom_flags(libc::O_NOFOLLOW);
-    /// }
-    /// let file = options.open("foo.txt");
-    /// # }
-    /// ```
-    #[stable(feature = "open_options_ext", since = "1.10.0")]
-    fn custom_flags(&mut self, flags: i32) -> &mut Self;
-}
-
-#[stable(feature = "fs_ext", since = "1.1.0")]
-impl OpenOptionsExt for OpenOptions {
-    fn mode(&mut self, mode: u32) -> &mut OpenOptions {
-        self.as_inner_mut().mode(mode); self
-    }
-
-    fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
-        self.as_inner_mut().custom_flags(flags); self
-    }
-}
-
-/// Redox-specific extensions to [`fs::Metadata`].
-///
-/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
-#[stable(feature = "metadata_ext", since = "1.1.0")]
-pub trait MetadataExt {
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn dev(&self) -> u64;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn ino(&self) -> u64;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn mode(&self) -> u32;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn nlink(&self) -> u64;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn uid(&self) -> u32;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn gid(&self) -> u32;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn size(&self) -> u64;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn atime(&self) -> i64;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn atime_nsec(&self) -> i64;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn mtime(&self) -> i64;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn mtime_nsec(&self) -> i64;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn ctime(&self) -> i64;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn ctime_nsec(&self) -> i64;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn blksize(&self) -> u64;
-    #[stable(feature = "metadata_ext", since = "1.1.0")]
-    fn blocks(&self) -> u64;
-}
-
-// Hm, why are there casts here to the returned type, shouldn't the types always
-// be the same? Right you are! Turns out, however, on android at least the types
-// in the raw `stat` structure are not the same as the types being returned. Who
-// knew!
-//
-// As a result to make sure this compiles for all platforms we do the manual
-// casts and rely on manual lowering to `stat` if the raw type is desired.
-#[stable(feature = "metadata_ext", since = "1.1.0")]
-impl MetadataExt for fs::Metadata {
-    fn dev(&self) -> u64 {
-        self.as_inner().as_inner().st_dev as u64
-    }
-    fn ino(&self) -> u64 {
-        self.as_inner().as_inner().st_ino as u64
-    }
-    fn mode(&self) -> u32 {
-        self.as_inner().as_inner().st_mode as u32
-    }
-    fn nlink(&self) -> u64 {
-        self.as_inner().as_inner().st_nlink as u64
-    }
-    fn uid(&self) -> u32 {
-        self.as_inner().as_inner().st_uid as u32
-    }
-    fn gid(&self) -> u32 {
-        self.as_inner().as_inner().st_gid as u32
-    }
-    fn size(&self) -> u64 {
-        self.as_inner().as_inner().st_size as u64
-    }
-    fn atime(&self) -> i64 {
-        self.as_inner().as_inner().st_atime as i64
-    }
-    fn atime_nsec(&self) -> i64 {
-        self.as_inner().as_inner().st_atime_nsec as i64
-    }
-    fn mtime(&self) -> i64 {
-        self.as_inner().as_inner().st_mtime as i64
-    }
-    fn mtime_nsec(&self) -> i64 {
-        self.as_inner().as_inner().st_mtime_nsec as i64
-    }
-    fn ctime(&self) -> i64 {
-        self.as_inner().as_inner().st_ctime as i64
-    }
-    fn ctime_nsec(&self) -> i64 {
-        self.as_inner().as_inner().st_ctime_nsec as i64
-    }
-    fn blksize(&self) -> u64 {
-        self.as_inner().as_inner().st_blksize as u64
-    }
-    fn blocks(&self) -> u64 {
-        self.as_inner().as_inner().st_blocks as u64
-    }
-}
-
-/// Redox-specific extensions for [`FileType`].
-///
-/// Adds support for special Unix file types such as block/character devices,
-/// pipes, and sockets.
-///
-/// [`FileType`]: ../../../../std/fs/struct.FileType.html
-#[stable(feature = "file_type_ext", since = "1.5.0")]
-pub trait FileTypeExt {
-    /// Returns whether this file type is a block device.
-    #[stable(feature = "file_type_ext", since = "1.5.0")]
-    fn is_block_device(&self) -> bool;
-    /// Returns whether this file type is a char device.
-    #[stable(feature = "file_type_ext", since = "1.5.0")]
-    fn is_char_device(&self) -> bool;
-    /// Returns whether this file type is a fifo.
-    #[stable(feature = "file_type_ext", since = "1.5.0")]
-    fn is_fifo(&self) -> bool;
-    /// Returns whether this file type is a socket.
-    #[stable(feature = "file_type_ext", since = "1.5.0")]
-    fn is_socket(&self) -> bool;
-}
-
-#[stable(feature = "file_type_ext", since = "1.5.0")]
-impl FileTypeExt for fs::FileType {
-    fn is_block_device(&self) -> bool { false /*FIXME: Implement block device mode*/ }
-    fn is_char_device(&self) -> bool { false /*FIXME: Implement char device mode*/ }
-    fn is_fifo(&self) -> bool { false /*FIXME: Implement fifo mode*/ }
-    fn is_socket(&self) -> bool { false /*FIXME: Implement socket mode*/ }
-}
-
-/// Creates a new symbolic link on the filesystem.
-///
-/// The `dst` path will be a symbolic link pointing to the `src` path.
-///
-/// # Note
-///
-/// On Windows, you must specify whether a symbolic link points to a file
-/// or directory. Use `os::windows::fs::symlink_file` to create a
-/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
-/// symbolic link to a directory. Additionally, the process must have
-/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
-/// symbolic link.
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::os::redox::fs;
-///
-/// fn main() -> std::io::Result<()> {
-///     fs::symlink("a.txt", "b.txt")?;
-///     Ok(())
-/// }
-/// ```
-#[stable(feature = "symlink", since = "1.1.0")]
-pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
-{
-    sys::fs::symlink(src.as_ref(), dst.as_ref())
-}
-
-/// Redox-specific extensions to [`fs::DirBuilder`].
-///
-/// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html
-#[stable(feature = "dir_builder", since = "1.6.0")]
-pub trait DirBuilderExt {
-    /// Sets the mode to create new directories with. This option defaults to
-    /// 0o777.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::fs::DirBuilder;
-    /// use std::os::redox::fs::DirBuilderExt;
-    ///
-    /// let mut builder = DirBuilder::new();
-    /// builder.mode(0o755);
-    /// ```
-    #[stable(feature = "dir_builder", since = "1.6.0")]
-    fn mode(&mut self, mode: u32) -> &mut Self;
-}
-
-#[stable(feature = "dir_builder", since = "1.6.0")]
-impl DirBuilderExt for fs::DirBuilder {
-    fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder {
-        self.as_inner_mut().set_mode(mode);
-        self
-    }
-}
diff --git a/src/libstd/sys/redox/ext/mod.rs b/src/libstd/sys/redox/ext/mod.rs
deleted file mode 100644
index 8a2d243c7ff..00000000000
--- a/src/libstd/sys/redox/ext/mod.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-//! Experimental extensions to `std` for Unix platforms.
-//!
-//! For now, this module is limited to extracting file descriptors,
-//! but its functionality will grow over time.
-//!
-//! # Examples
-//!
-//! ```no_run
-//! use std::fs::File;
-//! use std::os::unix::prelude::*;
-//!
-//! fn main() {
-//!     let f = File::create("foo.txt").unwrap();
-//!     let fd = f.as_raw_fd();
-//!
-//!     // use fd with native unix bindings
-//! }
-//! ```
-
-#![stable(feature = "rust1", since = "1.0.0")]
-#![doc(cfg(target_os = "redox"))]
-
-pub mod ffi;
-pub mod fs;
-pub mod io;
-pub mod net;
-pub mod process;
-pub mod thread;
-
-/// A prelude for conveniently writing platform-specific code.
-///
-/// Includes all extension traits, and some important type definitions.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub mod prelude {
-    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
-    pub use super::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
-    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
-    pub use super::ffi::{OsStrExt, OsStringExt};
-    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
-    pub use super::fs::{FileTypeExt, PermissionsExt, OpenOptionsExt, MetadataExt};
-    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
-    pub use super::thread::JoinHandleExt;
-    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
-    pub use super::process::{CommandExt, ExitStatusExt};
-}
diff --git a/src/libstd/sys/redox/ext/net.rs b/src/libstd/sys/redox/ext/net.rs
deleted file mode 100644
index b3ef5f3064c..00000000000
--- a/src/libstd/sys/redox/ext/net.rs
+++ /dev/null
@@ -1,759 +0,0 @@
-#![stable(feature = "unix_socket_redox", since = "1.29.0")]
-
-//! Unix-specific networking functionality
-
-use crate::fmt;
-use crate::io::{self, Error, ErrorKind, Initializer};
-use crate::net::Shutdown;
-use crate::os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
-use crate::path::Path;
-use crate::time::Duration;
-use crate::sys::{cvt, fd::FileDesc, syscall};
-
-/// An address associated with a Unix socket.
-///
-/// # Examples
-///
-/// ```
-/// use std::os::unix::net::UnixListener;
-///
-/// let socket = match UnixListener::bind("/tmp/sock") {
-///     Ok(sock) => sock,
-///     Err(e) => {
-///         println!("Couldn't bind: {:?}", e);
-///         return
-///     }
-/// };
-/// let addr = socket.local_addr().expect("Couldn't get local address");
-/// ```
-#[derive(Clone)]
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-pub struct SocketAddr(());
-
-impl SocketAddr {
-    /// Returns the contents of this address if it is a `pathname` address.
-    ///
-    /// # Examples
-    ///
-    /// With a pathname:
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixListener;
-    /// use std::path::Path;
-    ///
-    /// let socket = UnixListener::bind("/tmp/sock").unwrap();
-    /// let addr = socket.local_addr().expect("Couldn't get local address");
-    /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
-    /// ```
-    ///
-    /// Without a pathname:
-    ///
-    /// ```
-    /// use std::os::unix::net::UnixDatagram;
-    ///
-    /// let socket = UnixDatagram::unbound().unwrap();
-    /// let addr = socket.local_addr().expect("Couldn't get local address");
-    /// assert_eq!(addr.as_pathname(), None);
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn as_pathname(&self) -> Option<&Path> {
-        None
-    }
-
-    /// Returns `true` if the address is unnamed.
-    ///
-    /// # Examples
-    ///
-    /// A named address:
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixListener;
-    ///
-    /// let socket = UnixListener::bind("/tmp/sock").unwrap();
-    /// let addr = socket.local_addr().expect("Couldn't get local address");
-    /// assert_eq!(addr.is_unnamed(), false);
-    /// ```
-    ///
-    /// An unnamed address:
-    ///
-    /// ```
-    /// use std::os::unix::net::UnixDatagram;
-    ///
-    /// let socket = UnixDatagram::unbound().unwrap();
-    /// let addr = socket.local_addr().expect("Couldn't get local address");
-    /// assert_eq!(addr.is_unnamed(), true);
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn is_unnamed(&self) -> bool {
-        false
-    }
-}
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl fmt::Debug for SocketAddr {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(fmt, "SocketAddr")
-    }
-}
-
-/// A Unix stream socket.
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::os::unix::net::UnixStream;
-/// use std::io::prelude::*;
-///
-/// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap();
-/// stream.write_all(b"hello world").unwrap();
-/// let mut response = String::new();
-/// stream.read_to_string(&mut response).unwrap();
-/// println!("{}", response);
-/// ```
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-pub struct UnixStream(FileDesc);
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl fmt::Debug for UnixStream {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let mut builder = fmt.debug_struct("UnixStream");
-        builder.field("fd", &self.0.raw());
-        if let Ok(addr) = self.local_addr() {
-            builder.field("local", &addr);
-        }
-        if let Ok(addr) = self.peer_addr() {
-            builder.field("peer", &addr);
-        }
-        builder.finish()
-    }
-}
-
-impl UnixStream {
-    /// Connects to the socket named by `path`.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    ///
-    /// let socket = match UnixStream::connect("/tmp/sock") {
-    ///     Ok(sock) => sock,
-    ///     Err(e) => {
-    ///         println!("Couldn't connect: {:?}", e);
-    ///         return
-    ///     }
-    /// };
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
-        if let Some(s) = path.as_ref().to_str() {
-            cvt(syscall::open(format!("chan:{}", s), syscall::O_CLOEXEC))
-                .map(FileDesc::new)
-                .map(UnixStream)
-        } else {
-            Err(Error::new(
-                ErrorKind::Other,
-                "UnixStream::connect: non-utf8 paths not supported on redox"
-            ))
-        }
-    }
-
-    /// Creates an unnamed pair of connected sockets.
-    ///
-    /// Returns two `UnixStream`s which are connected to each other.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    ///
-    /// let (sock1, sock2) = match UnixStream::pair() {
-    ///     Ok((sock1, sock2)) => (sock1, sock2),
-    ///     Err(e) => {
-    ///         println!("Couldn't create a pair of sockets: {:?}", e);
-    ///         return
-    ///     }
-    /// };
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
-        let server = cvt(syscall::open("chan:", syscall::O_CREAT | syscall::O_CLOEXEC))
-            .map(FileDesc::new)?;
-        let client = server.duplicate_path(b"connect")?;
-        let stream = server.duplicate_path(b"listen")?;
-        Ok((UnixStream(client), UnixStream(stream)))
-    }
-
-    /// Creates a new independently owned handle to the underlying socket.
-    ///
-    /// The returned `UnixStream` is a reference to the same stream that this
-    /// object references. Both handles will read and write the same stream of
-    /// data, and options set on one stream will be propagated to the other
-    /// stream.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    ///
-    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
-    /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn try_clone(&self) -> io::Result<UnixStream> {
-        self.0.duplicate().map(UnixStream)
-    }
-
-    /// Returns the socket address of the local half of this connection.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    ///
-    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
-    /// let addr = socket.local_addr().expect("Couldn't get local address");
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn local_addr(&self) -> io::Result<SocketAddr> {
-        Err(Error::new(ErrorKind::Other, "UnixStream::local_addr unimplemented on redox"))
-    }
-
-    /// Returns the socket address of the remote half of this connection.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    ///
-    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
-    /// let addr = socket.peer_addr().expect("Couldn't get peer address");
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-        Err(Error::new(ErrorKind::Other, "UnixStream::peer_addr unimplemented on redox"))
-    }
-
-    /// Sets the read timeout for the socket.
-    ///
-    /// If the provided value is [`None`], then [`read`] calls will block
-    /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
-    /// method.
-    ///
-    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-    /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
-    /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
-    /// [`Duration`]: ../../../../std/time/struct.Duration.html
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    /// use std::time::Duration;
-    ///
-    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
-    /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
-    /// ```
-    ///
-    /// An [`Err`] is returned if the zero [`Duration`] is passed to this
-    /// method:
-    ///
-    /// ```no_run
-    /// use std::io;
-    /// use std::os::unix::net::UnixStream;
-    /// use std::time::Duration;
-    ///
-    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
-    /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
-    /// let err = result.unwrap_err();
-    /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn set_read_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
-        Err(Error::new(ErrorKind::Other, "UnixStream::set_read_timeout unimplemented on redox"))
-    }
-
-    /// Sets the write timeout for the socket.
-    ///
-    /// If the provided value is [`None`], then [`write`] calls will block
-    /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
-    /// passed to this method.
-    ///
-    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-    /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
-    /// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write
-    /// [`Duration`]: ../../../../std/time/struct.Duration.html
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    /// use std::time::Duration;
-    ///
-    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
-    /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
-    /// ```
-    ///
-    /// An [`Err`] is returned if the zero [`Duration`] is passed to this
-    /// method:
-    ///
-    /// ```no_run
-    /// use std::io;
-    /// use std::net::UdpSocket;
-    /// use std::time::Duration;
-    ///
-    /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
-    /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
-    /// let err = result.unwrap_err();
-    /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn set_write_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
-        Err(Error::new(ErrorKind::Other, "UnixStream::set_write_timeout unimplemented on redox"))
-    }
-
-    /// Returns the read timeout of this socket.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    /// use std::time::Duration;
-    ///
-    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
-    /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
-    /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-        Err(Error::new(ErrorKind::Other, "UnixStream::read_timeout unimplemented on redox"))
-    }
-
-    /// Returns the write timeout of this socket.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    /// use std::time::Duration;
-    ///
-    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
-    /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
-    /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-        Err(Error::new(ErrorKind::Other, "UnixStream::write_timeout unimplemented on redox"))
-    }
-
-    /// Moves the socket into or out of nonblocking mode.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    ///
-    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
-    /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
-        self.0.set_nonblocking(nonblocking)
-    }
-
-    /// Returns the value of the `SO_ERROR` option.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    ///
-    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
-    /// if let Ok(Some(err)) = socket.take_error() {
-    ///     println!("Got error: {:?}", err);
-    /// }
-    /// ```
-    ///
-    /// # Platform specific
-    /// On Redox this always returns `None`.
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        Ok(None)
-    }
-
-    /// Shuts down the read, write, or both halves of this connection.
-    ///
-    /// This function will cause all pending and future I/O calls on the
-    /// specified portions to immediately return with an appropriate value
-    /// (see the documentation of [`Shutdown`]).
-    ///
-    /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixStream;
-    /// use std::net::Shutdown;
-    ///
-    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
-    /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> {
-        Err(Error::new(ErrorKind::Other, "UnixStream::shutdown unimplemented on redox"))
-    }
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl io::Read for UnixStream {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        io::Read::read(&mut &*self, buf)
-    }
-
-    #[inline]
-    unsafe fn initializer(&self) -> Initializer {
-        Initializer::nop()
-    }
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl<'a> io::Read for &'a UnixStream {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        self.0.read(buf)
-    }
-
-    #[inline]
-    unsafe fn initializer(&self) -> Initializer {
-        Initializer::nop()
-    }
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl io::Write for UnixStream {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        io::Write::write(&mut &*self, buf)
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        io::Write::flush(&mut &*self)
-    }
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl<'a> io::Write for &'a UnixStream {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.0.write(buf)
-    }
-
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl AsRawFd for UnixStream {
-    fn as_raw_fd(&self) -> RawFd {
-        self.0.raw()
-    }
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl FromRawFd for UnixStream {
-    unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
-        UnixStream(FileDesc::new(fd))
-    }
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl IntoRawFd for UnixStream {
-    fn into_raw_fd(self) -> RawFd {
-        self.0.into_raw()
-    }
-}
-
-/// A structure representing a Unix domain socket server.
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::thread;
-/// use std::os::unix::net::{UnixStream, UnixListener};
-///
-/// fn handle_client(stream: UnixStream) {
-///     // ...
-/// }
-///
-/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
-///
-/// // accept connections and process them, spawning a new thread for each one
-/// for stream in listener.incoming() {
-///     match stream {
-///         Ok(stream) => {
-///             /* connection succeeded */
-///             thread::spawn(|| handle_client(stream));
-///         }
-///         Err(err) => {
-///             /* connection failed */
-///             break;
-///         }
-///     }
-/// }
-/// ```
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-pub struct UnixListener(FileDesc);
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl fmt::Debug for UnixListener {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let mut builder = fmt.debug_struct("UnixListener");
-        builder.field("fd", &self.0.raw());
-        if let Ok(addr) = self.local_addr() {
-            builder.field("local", &addr);
-        }
-        builder.finish()
-    }
-}
-
-impl UnixListener {
-    /// Creates a new `UnixListener` bound to the specified socket.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixListener;
-    ///
-    /// let listener = match UnixListener::bind("/path/to/the/socket") {
-    ///     Ok(sock) => sock,
-    ///     Err(e) => {
-    ///         println!("Couldn't connect: {:?}", e);
-    ///         return
-    ///     }
-    /// };
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
-        if let Some(s) = path.as_ref().to_str() {
-            cvt(syscall::open(format!("chan:{}", s), syscall::O_CREAT | syscall::O_CLOEXEC))
-                .map(FileDesc::new)
-                .map(UnixListener)
-        } else {
-            Err(Error::new(
-                ErrorKind::Other,
-                "UnixListener::bind: non-utf8 paths not supported on redox"
-            ))
-        }
-    }
-
-    /// Accepts a new incoming connection to this listener.
-    ///
-    /// This function will block the calling thread until a new Unix connection
-    /// is established. When established, the corresponding [`UnixStream`] and
-    /// the remote peer's address will be returned.
-    ///
-    /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixListener;
-    ///
-    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
-    ///
-    /// match listener.accept() {
-    ///     Ok((socket, addr)) => println!("Got a client: {:?}", addr),
-    ///     Err(e) => println!("accept function failed: {:?}", e),
-    /// }
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
-        self.0.duplicate_path(b"listen").map(|fd| (UnixStream(fd), SocketAddr(())))
-    }
-
-    /// Creates a new independently owned handle to the underlying socket.
-    ///
-    /// The returned `UnixListener` is a reference to the same socket that this
-    /// object references. Both handles can be used to accept incoming
-    /// connections and options set on one listener will affect the other.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixListener;
-    ///
-    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
-    ///
-    /// let listener_copy = listener.try_clone().expect("try_clone failed");
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn try_clone(&self) -> io::Result<UnixListener> {
-        self.0.duplicate().map(UnixListener)
-    }
-
-    /// Returns the local socket address of this listener.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixListener;
-    ///
-    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
-    ///
-    /// let addr = listener.local_addr().expect("Couldn't get local address");
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn local_addr(&self) -> io::Result<SocketAddr> {
-        Err(Error::new(ErrorKind::Other, "UnixListener::local_addr unimplemented on redox"))
-    }
-
-    /// Moves the socket into or out of nonblocking mode.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixListener;
-    ///
-    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
-    ///
-    /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
-        self.0.set_nonblocking(nonblocking)
-    }
-
-    /// Returns the value of the `SO_ERROR` option.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::os::unix::net::UnixListener;
-    ///
-    /// let listener = UnixListener::bind("/tmp/sock").unwrap();
-    ///
-    /// if let Ok(Some(err)) = listener.take_error() {
-    ///     println!("Got error: {:?}", err);
-    /// }
-    /// ```
-    ///
-    /// # Platform specific
-    /// On Redox this always returns `None`.
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-        Ok(None)
-    }
-
-    /// Returns an iterator over incoming connections.
-    ///
-    /// The iterator will never return [`None`] and will also not yield the
-    /// peer's [`SocketAddr`] structure.
-    ///
-    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-    /// [`SocketAddr`]: struct.SocketAddr.html
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// use std::thread;
-    /// use std::os::unix::net::{UnixStream, UnixListener};
-    ///
-    /// fn handle_client(stream: UnixStream) {
-    ///     // ...
-    /// }
-    ///
-    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
-    ///
-    /// for stream in listener.incoming() {
-    ///     match stream {
-    ///         Ok(stream) => {
-    ///             thread::spawn(|| handle_client(stream));
-    ///         }
-    ///         Err(err) => {
-    ///             break;
-    ///         }
-    ///     }
-    /// }
-    /// ```
-    #[stable(feature = "unix_socket_redox", since = "1.29.0")]
-    pub fn incoming<'a>(&'a self) -> Incoming<'a> {
-        Incoming { listener: self }
-    }
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl AsRawFd for UnixListener {
-    fn as_raw_fd(&self) -> RawFd {
-        self.0.raw()
-    }
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl FromRawFd for UnixListener {
-    unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
-        UnixListener(FileDesc::new(fd))
-    }
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl IntoRawFd for UnixListener {
-    fn into_raw_fd(self) -> RawFd {
-        self.0.into_raw()
-    }
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl<'a> IntoIterator for &'a UnixListener {
-    type Item = io::Result<UnixStream>;
-    type IntoIter = Incoming<'a>;
-
-    fn into_iter(self) -> Incoming<'a> {
-        self.incoming()
-    }
-}
-
-/// An iterator over incoming connections to a [`UnixListener`].
-///
-/// It will never return [`None`].
-///
-/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-/// [`UnixListener`]: struct.UnixListener.html
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::thread;
-/// use std::os::unix::net::{UnixStream, UnixListener};
-///
-/// fn handle_client(stream: UnixStream) {
-///     // ...
-/// }
-///
-/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
-///
-/// for stream in listener.incoming() {
-///     match stream {
-///         Ok(stream) => {
-///             thread::spawn(|| handle_client(stream));
-///         }
-///         Err(err) => {
-///             break;
-///         }
-///     }
-/// }
-/// ```
-#[derive(Debug)]
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-pub struct Incoming<'a> {
-    listener: &'a UnixListener,
-}
-
-#[stable(feature = "unix_socket_redox", since = "1.29.0")]
-impl<'a> Iterator for Incoming<'a> {
-    type Item = io::Result<UnixStream>;
-
-    fn next(&mut self) -> Option<io::Result<UnixStream>> {
-        Some(self.listener.accept().map(|s| s.0))
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (usize::max_value(), None)
-    }
-}
diff --git a/src/libstd/sys/redox/ext/thread.rs b/src/libstd/sys/redox/ext/thread.rs
deleted file mode 100644
index 629eaef04ce..00000000000
--- a/src/libstd/sys/redox/ext/thread.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-//! Redox-specific extensions to primitives in the `std::thread` module.
-
-#![stable(feature = "thread_extensions", since = "1.9.0")]
-
-use crate::sys_common::{AsInner, IntoInner};
-use crate::thread::JoinHandle;
-
-#[stable(feature = "thread_extensions", since = "1.9.0")]
-#[allow(deprecated)]
-pub type RawPthread = usize;
-
-/// Redox-specific extensions to [`thread::JoinHandle`].
-///
-/// [`thread::JoinHandle`]: ../../../../std/thread/struct.JoinHandle.html
-#[stable(feature = "thread_extensions", since = "1.9.0")]
-pub trait JoinHandleExt {
-    /// Extracts the raw pthread_t without taking ownership
-    #[stable(feature = "thread_extensions", since = "1.9.0")]
-    fn as_pthread_t(&self) -> RawPthread;
-
-    /// Consumes the thread, returning the raw pthread_t
-    ///
-    /// This function **transfers ownership** of the underlying pthread_t to
-    /// the caller. Callers are then the unique owners of the pthread_t and
-    /// must either detach or join the pthread_t once it's no longer needed.
-    #[stable(feature = "thread_extensions", since = "1.9.0")]
-    fn into_pthread_t(self) -> RawPthread;
-}
-
-#[stable(feature = "thread_extensions", since = "1.9.0")]
-impl<T> JoinHandleExt for JoinHandle<T> {
-    fn as_pthread_t(&self) -> RawPthread {
-        self.as_inner().id() as RawPthread
-    }
-
-    fn into_pthread_t(self) -> RawPthread {
-        self.into_inner().into_id() as RawPthread
-    }
-}
diff --git a/src/libstd/sys/redox/fast_thread_local.rs b/src/libstd/sys/redox/fast_thread_local.rs
deleted file mode 100644
index 1202708a476..00000000000
--- a/src/libstd/sys/redox/fast_thread_local.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-#![cfg(target_thread_local)]
-#![unstable(feature = "thread_local_internals", issue = "0")]
-
-use crate::cell::{Cell, UnsafeCell};
-use crate::mem;
-use crate::ptr;
-
-
-pub struct Key<T> {
-    inner: UnsafeCell<Option<T>>,
-
-    // Metadata to keep track of the state of the destructor. Remember that
-    // these variables are thread-local, not global.
-    dtor_registered: Cell<bool>,
-    dtor_running: Cell<bool>,
-}
-
-unsafe impl<T> Sync for Key<T> { }
-
-impl<T> Key<T> {
-    pub const fn new() -> Key<T> {
-        Key {
-            inner: UnsafeCell::new(None),
-            dtor_registered: Cell::new(false),
-            dtor_running: Cell::new(false)
-        }
-    }
-
-    pub fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
-        unsafe {
-            if mem::needs_drop::<T>() && self.dtor_running.get() {
-                return None
-            }
-            self.register_dtor();
-        }
-        Some(&self.inner)
-    }
-
-    unsafe fn register_dtor(&self) {
-        if !mem::needs_drop::<T>() || self.dtor_registered.get() {
-            return
-        }
-
-        register_dtor(self as *const _ as *mut u8,
-                      destroy_value::<T>);
-        self.dtor_registered.set(true);
-    }
-}
-
-pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
-    // The fallback implementation uses a vanilla OS-based TLS key to track
-    // the list of destructors that need to be run for this thread. The key
-    // then has its own destructor which runs all the other destructors.
-    //
-    // The destructor for DTORS is a little special in that it has a `while`
-    // loop to continuously drain the list of registered destructors. It
-    // *should* be the case that this loop always terminates because we
-    // provide the guarantee that a TLS key cannot be set after it is
-    // flagged for destruction.
-    use crate::sys_common::thread_local as os;
-
-    static DTORS: os::StaticKey = os::StaticKey::new(Some(run_dtors));
-    type List = Vec<(*mut u8, unsafe extern fn(*mut u8))>;
-    if DTORS.get().is_null() {
-        let v: Box<List> = box Vec::new();
-        DTORS.set(Box::into_raw(v) as *mut u8);
-    }
-    let list: &mut List = &mut *(DTORS.get() as *mut List);
-    list.push((t, dtor));
-
-    unsafe extern fn run_dtors(mut ptr: *mut u8) {
-        while !ptr.is_null() {
-            let list: Box<List> = Box::from_raw(ptr as *mut List);
-            for (ptr, dtor) in list.into_iter() {
-                dtor(ptr);
-            }
-            ptr = DTORS.get();
-            DTORS.set(ptr::null_mut());
-        }
-    }
-}
-
-pub unsafe extern fn destroy_value<T>(ptr: *mut u8) {
-    let ptr = ptr as *mut Key<T>;
-    // Right before we run the user destructor be sure to flag the
-    // destructor as running for this thread so calls to `get` will return
-    // `None`.
-    (*ptr).dtor_running.set(true);
-
-    // The macOS implementation of TLS apparently had an odd aspect to it
-    // where the pointer we have may be overwritten while this destructor
-    // is running. Specifically if a TLS destructor re-accesses TLS it may
-    // trigger a re-initialization of all TLS variables, paving over at
-    // least some destroyed ones with initial values.
-    //
-    // This means that if we drop a TLS value in place on macOS that we could
-    // revert the value to its original state halfway through the
-    // destructor, which would be bad!
-    //
-    // Hence, we use `ptr::read` on macOS (to move to a "safe" location)
-    // instead of drop_in_place.
-    if cfg!(target_os = "macos") {
-        ptr::read((*ptr).inner.get());
-    } else {
-        ptr::drop_in_place((*ptr).inner.get());
-    }
-}
-
-pub fn requires_move_before_drop() -> bool {
-    false
-}
diff --git a/src/libstd/sys/redox/fd.rs b/src/libstd/sys/redox/fd.rs
deleted file mode 100644
index a42e486db22..00000000000
--- a/src/libstd/sys/redox/fd.rs
+++ /dev/null
@@ -1,88 +0,0 @@
-#![unstable(reason = "not public", issue = "0", feature = "fd")]
-
-use crate::io::{self, Read};
-use crate::mem;
-use crate::sys::{cvt, syscall};
-use crate::sys_common::AsInner;
-
-pub struct FileDesc {
-    fd: usize,
-}
-
-impl FileDesc {
-    pub fn new(fd: usize) -> FileDesc {
-        FileDesc { fd }
-    }
-
-    pub fn raw(&self) -> usize { self.fd }
-
-    /// Extracts the actual file descriptor without closing it.
-    pub fn into_raw(self) -> usize {
-        let fd = self.fd;
-        mem::forget(self);
-        fd
-    }
-
-    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
-        cvt(syscall::read(self.fd, buf))
-    }
-
-    pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
-        let mut me = self;
-        (&mut me).read_to_end(buf)
-    }
-
-    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
-        cvt(syscall::write(self.fd, buf))
-    }
-
-    pub fn duplicate(&self) -> io::Result<FileDesc> {
-        self.duplicate_path(&[])
-    }
-    pub fn duplicate_path(&self, path: &[u8]) -> io::Result<FileDesc> {
-        let new_fd = cvt(syscall::dup(self.fd, path))?;
-        Ok(FileDesc::new(new_fd))
-    }
-
-    pub fn nonblocking(&self) -> io::Result<bool> {
-        let flags = cvt(syscall::fcntl(self.fd, syscall::F_GETFL, 0))?;
-        Ok(flags & syscall::O_NONBLOCK == syscall::O_NONBLOCK)
-    }
-
-    pub fn set_cloexec(&self) -> io::Result<()> {
-        let mut flags = cvt(syscall::fcntl(self.fd, syscall::F_GETFD, 0))?;
-        flags |= syscall::O_CLOEXEC;
-        cvt(syscall::fcntl(self.fd, syscall::F_SETFD, flags)).and(Ok(()))
-    }
-
-    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
-        let mut flags = cvt(syscall::fcntl(self.fd, syscall::F_GETFL, 0))?;
-        if nonblocking {
-            flags |= syscall::O_NONBLOCK;
-        } else {
-            flags &= !syscall::O_NONBLOCK;
-        }
-        cvt(syscall::fcntl(self.fd, syscall::F_SETFL, flags)).and(Ok(()))
-    }
-}
-
-impl<'a> Read for &'a FileDesc {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        (**self).read(buf)
-    }
-}
-
-impl AsInner<usize> for FileDesc {
-    fn as_inner(&self) -> &usize { &self.fd }
-}
-
-impl Drop for FileDesc {
-    fn drop(&mut self) {
-        // Note that errors are ignored when closing a file descriptor. The
-        // reason for this is that if an error occurs we don't actually know if
-        // the file descriptor was closed or not, and if we retried (for
-        // something like EINTR), we might close another valid file descriptor
-        // (opened after we closed ours.
-        let _ = syscall::close(self.fd);
-    }
-}
diff --git a/src/libstd/sys/redox/fs.rs b/src/libstd/sys/redox/fs.rs
deleted file mode 100644
index b80a1a349e3..00000000000
--- a/src/libstd/sys/redox/fs.rs
+++ /dev/null
@@ -1,447 +0,0 @@
-use crate::os::unix::prelude::*;
-
-use crate::ffi::{OsString, OsStr};
-use crate::fmt;
-use crate::io::{self, Error, SeekFrom, IoSlice, IoSliceMut};
-use crate::path::{Path, PathBuf};
-use crate::sync::Arc;
-use crate::sys::fd::FileDesc;
-use crate::sys::time::SystemTime;
-use crate::sys::{cvt, syscall};
-use crate::sys_common::{AsInner, FromInner};
-
-pub use crate::sys_common::fs::copy;
-pub use crate::sys_common::fs::remove_dir_all;
-
-pub struct File(FileDesc);
-
-#[derive(Clone)]
-pub struct FileAttr {
-    stat: syscall::Stat,
-}
-
-pub struct ReadDir {
-    data: Vec<u8>,
-    i: usize,
-    root: Arc<PathBuf>,
-}
-
-struct Dir(FileDesc);
-
-unsafe impl Send for Dir {}
-unsafe impl Sync for Dir {}
-
-pub struct DirEntry {
-    root: Arc<PathBuf>,
-    name: Box<[u8]>
-}
-
-#[derive(Clone, Debug)]
-pub struct OpenOptions {
-    // generic
-    read: bool,
-    write: bool,
-    append: bool,
-    truncate: bool,
-    create: bool,
-    create_new: bool,
-    // system-specific
-    custom_flags: i32,
-    mode: u16,
-}
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct FilePermissions { mode: u16 }
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
-pub struct FileType { mode: u16 }
-
-#[derive(Debug)]
-pub struct DirBuilder { mode: u16 }
-
-impl FileAttr {
-    pub fn size(&self) -> u64 { self.stat.st_size as u64 }
-    pub fn perm(&self) -> FilePermissions {
-        FilePermissions { mode: (self.stat.st_mode as u16) & 0o777 }
-    }
-
-    pub fn file_type(&self) -> FileType {
-        FileType { mode: self.stat.st_mode as u16 }
-    }
-}
-
-impl FileAttr {
-    pub fn modified(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(syscall::TimeSpec {
-            tv_sec: self.stat.st_mtime as i64,
-            tv_nsec: self.stat.st_mtime_nsec as i32,
-        }))
-    }
-
-    pub fn accessed(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(syscall::TimeSpec {
-            tv_sec: self.stat.st_atime as i64,
-            tv_nsec: self.stat.st_atime_nsec as i32,
-        }))
-    }
-
-    pub fn created(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(syscall::TimeSpec {
-            tv_sec: self.stat.st_ctime as i64,
-            tv_nsec: self.stat.st_ctime_nsec as i32,
-        }))
-    }
-}
-
-impl AsInner<syscall::Stat> for FileAttr {
-    fn as_inner(&self) -> &syscall::Stat { &self.stat }
-}
-
-impl FilePermissions {
-    pub fn readonly(&self) -> bool { self.mode & 0o222 == 0 }
-    pub fn set_readonly(&mut self, readonly: bool) {
-        if readonly {
-            self.mode &= !0o222;
-        } else {
-            self.mode |= 0o222;
-        }
-    }
-    pub fn mode(&self) -> u32 { self.mode as u32 }
-}
-
-impl FileType {
-    pub fn is_dir(&self) -> bool { self.is(syscall::MODE_DIR) }
-    pub fn is_file(&self) -> bool { self.is(syscall::MODE_FILE) }
-    pub fn is_symlink(&self) -> bool { self.is(syscall::MODE_SYMLINK) }
-
-    pub fn is(&self, mode: u16) -> bool {
-        self.mode & syscall::MODE_TYPE == mode
-    }
-}
-
-impl FromInner<u32> for FilePermissions {
-    fn from_inner(mode: u32) -> FilePermissions {
-        FilePermissions { mode: mode as u16 }
-    }
-}
-
-impl fmt::Debug for ReadDir {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame.
-        // Thus the result will be e g 'ReadDir("/home")'
-        fmt::Debug::fmt(&*self.root, f)
-    }
-}
-
-impl Iterator for ReadDir {
-    type Item = io::Result<DirEntry>;
-
-    fn next(&mut self) -> Option<io::Result<DirEntry>> {
-        loop {
-            let start = self.i;
-            let mut i = self.i;
-            while i < self.data.len() {
-                self.i += 1;
-                if self.data[i] == b'\n' {
-                    break;
-                }
-                i += 1;
-            }
-            if start < self.i {
-                let ret = DirEntry {
-                    name: self.data[start .. i].to_owned().into_boxed_slice(),
-                    root: self.root.clone()
-                };
-                if ret.name_bytes() != b"." && ret.name_bytes() != b".." {
-                    return Some(Ok(ret))
-                }
-            } else {
-                return None;
-            }
-        }
-    }
-}
-
-impl DirEntry {
-    pub fn path(&self) -> PathBuf {
-        self.root.join(OsStr::from_bytes(self.name_bytes()))
-    }
-
-    pub fn file_name(&self) -> OsString {
-        OsStr::from_bytes(self.name_bytes()).to_os_string()
-    }
-
-    pub fn metadata(&self) -> io::Result<FileAttr> {
-        lstat(&self.path())
-    }
-
-    pub fn file_type(&self) -> io::Result<FileType> {
-        lstat(&self.path()).map(|m| m.file_type())
-    }
-
-    fn name_bytes(&self) -> &[u8] {
-        &*self.name
-    }
-}
-
-impl OpenOptions {
-    pub fn new() -> OpenOptions {
-        OpenOptions {
-            // generic
-            read: false,
-            write: false,
-            append: false,
-            truncate: false,
-            create: false,
-            create_new: false,
-            // system-specific
-            custom_flags: 0,
-            mode: 0o666,
-        }
-    }
-
-    pub fn read(&mut self, read: bool) { self.read = read; }
-    pub fn write(&mut self, write: bool) { self.write = write; }
-    pub fn append(&mut self, append: bool) { self.append = append; }
-    pub fn truncate(&mut self, truncate: bool) { self.truncate = truncate; }
-    pub fn create(&mut self, create: bool) { self.create = create; }
-    pub fn create_new(&mut self, create_new: bool) { self.create_new = create_new; }
-
-    pub fn custom_flags(&mut self, flags: i32) { self.custom_flags = flags; }
-    pub fn mode(&mut self, mode: u32) { self.mode = mode as u16; }
-
-    fn get_access_mode(&self) -> io::Result<usize> {
-        match (self.read, self.write, self.append) {
-            (true,  false, false) => Ok(syscall::O_RDONLY),
-            (false, true,  false) => Ok(syscall::O_WRONLY),
-            (true,  true,  false) => Ok(syscall::O_RDWR),
-            (false, _,     true)  => Ok(syscall::O_WRONLY | syscall::O_APPEND),
-            (true,  _,     true)  => Ok(syscall::O_RDWR | syscall::O_APPEND),
-            (false, false, false) => Err(Error::from_raw_os_error(syscall::EINVAL)),
-        }
-    }
-
-    fn get_creation_mode(&self) -> io::Result<usize> {
-        match (self.write, self.append) {
-            (true, false) => {}
-            (false, false) =>
-                if self.truncate || self.create || self.create_new {
-                    return Err(Error::from_raw_os_error(syscall::EINVAL));
-                },
-            (_, true) =>
-                if self.truncate && !self.create_new {
-                    return Err(Error::from_raw_os_error(syscall::EINVAL));
-                },
-        }
-
-        Ok(match (self.create, self.truncate, self.create_new) {
-                (false, false, false) => 0,
-                (true,  false, false) => syscall::O_CREAT,
-                (false, true,  false) => syscall::O_TRUNC,
-                (true,  true,  false) => syscall::O_CREAT | syscall::O_TRUNC,
-                (_,      _,    true)  => syscall::O_CREAT | syscall::O_EXCL,
-           })
-    }
-}
-
-impl File {
-    pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
-        let flags = syscall::O_CLOEXEC |
-                    opts.get_access_mode()? as usize |
-                    opts.get_creation_mode()? as usize |
-                    (opts.custom_flags as usize & !syscall::O_ACCMODE);
-        let fd = cvt(syscall::open(path.to_str().unwrap(), flags | opts.mode as usize))?;
-        Ok(File(FileDesc::new(fd)))
-    }
-
-    pub fn file_attr(&self) -> io::Result<FileAttr> {
-        let mut stat = syscall::Stat::default();
-        cvt(syscall::fstat(self.0.raw(), &mut stat))?;
-        Ok(FileAttr { stat })
-    }
-
-    pub fn fsync(&self) -> io::Result<()> {
-        cvt(syscall::fsync(self.0.raw()))?;
-        Ok(())
-    }
-
-    pub fn datasync(&self) -> io::Result<()> {
-        self.fsync()
-    }
-
-    pub fn truncate(&self, size: u64) -> io::Result<()> {
-        cvt(syscall::ftruncate(self.0.raw(), size as usize))?;
-        Ok(())
-    }
-
-    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
-        self.0.read(buf)
-    }
-
-    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        crate::io::default_read_vectored(|buf| self.read(buf), bufs)
-    }
-
-    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
-        self.0.write(buf)
-    }
-
-    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        crate::io::default_write_vectored(|buf| self.write(buf), bufs)
-    }
-
-    pub fn flush(&self) -> io::Result<()> { Ok(()) }
-
-    pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
-        let (whence, pos) = match pos {
-            // Casting to `i64` is fine, too large values will end up as
-            // negative which will cause an error in `lseek64`.
-            SeekFrom::Start(off) => (syscall::SEEK_SET, off as i64),
-            SeekFrom::End(off) => (syscall::SEEK_END, off),
-            SeekFrom::Current(off) => (syscall::SEEK_CUR, off),
-        };
-        let n = cvt(syscall::lseek(self.0.raw(), pos as isize, whence))?;
-        Ok(n as u64)
-    }
-
-    pub fn duplicate(&self) -> io::Result<File> {
-        self.0.duplicate().map(File)
-    }
-
-    pub fn dup(&self, buf: &[u8]) -> io::Result<File> {
-        let fd = cvt(syscall::dup(*self.fd().as_inner() as usize, buf))?;
-        Ok(File(FileDesc::new(fd)))
-    }
-
-    pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> {
-        set_perm(&self.path()?, perm)
-    }
-
-    pub fn path(&self) -> io::Result<PathBuf> {
-        let mut buf: [u8; 4096] = [0; 4096];
-        let count = cvt(syscall::fpath(*self.fd().as_inner() as usize, &mut buf))?;
-        Ok(PathBuf::from(unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) }))
-    }
-
-    pub fn fd(&self) -> &FileDesc { &self.0 }
-
-    pub fn into_fd(self) -> FileDesc { self.0 }
-}
-
-impl DirBuilder {
-    pub fn new() -> DirBuilder {
-        DirBuilder { mode: 0o777 }
-    }
-
-    pub fn mkdir(&self, p: &Path) -> io::Result<()> {
-        let flags = syscall::O_CREAT | syscall::O_CLOEXEC | syscall::O_DIRECTORY | syscall::O_EXCL;
-        let fd = cvt(syscall::open(p.to_str().unwrap(), flags | (self.mode as usize & 0o777)))?;
-        let _ = syscall::close(fd);
-        Ok(())
-    }
-
-    pub fn set_mode(&mut self, mode: u32) {
-        self.mode = mode as u16;
-    }
-}
-
-impl FromInner<usize> for File {
-    fn from_inner(fd: usize) -> File {
-        File(FileDesc::new(fd))
-    }
-}
-
-impl fmt::Debug for File {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let mut b = f.debug_struct("File");
-        b.field("fd", &self.0.raw());
-        if let Ok(path) = self.path() {
-            b.field("path", &path);
-        }
-        /*
-        if let Some((read, write)) = get_mode(fd) {
-            b.field("read", &read).field("write", &write);
-        }
-        */
-        b.finish()
-    }
-}
-
-pub fn readdir(p: &Path) -> io::Result<ReadDir> {
-    let root = Arc::new(p.to_path_buf());
-
-    let flags = syscall::O_CLOEXEC | syscall::O_RDONLY | syscall::O_DIRECTORY;
-    let fd = cvt(syscall::open(p.to_str().unwrap(), flags))?;
-    let file = FileDesc::new(fd);
-    let mut data = Vec::new();
-    file.read_to_end(&mut data)?;
-
-    Ok(ReadDir { data: data, i: 0, root: root })
-}
-
-pub fn unlink(p: &Path) -> io::Result<()> {
-    cvt(syscall::unlink(p.to_str().unwrap()))?;
-    Ok(())
-}
-
-pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
-    let fd = cvt(syscall::open(old.to_str().unwrap(),
-                               syscall::O_CLOEXEC | syscall::O_STAT | syscall::O_NOFOLLOW))?;
-    let res = cvt(syscall::frename(fd, new.to_str().unwrap()));
-    cvt(syscall::close(fd))?;
-    res?;
-    Ok(())
-}
-
-pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
-    cvt(syscall::chmod(p.to_str().unwrap(), perm.mode as usize))?;
-    Ok(())
-}
-
-pub fn rmdir(p: &Path) -> io::Result<()> {
-    cvt(syscall::rmdir(p.to_str().unwrap()))?;
-    Ok(())
-}
-
-pub fn readlink(p: &Path) -> io::Result<PathBuf> {
-    let fd = cvt(syscall::open(p.to_str().unwrap(),
-                               syscall::O_CLOEXEC | syscall::O_SYMLINK | syscall::O_RDONLY))?;
-    let mut buf: [u8; 4096] = [0; 4096];
-    let res = cvt(syscall::read(fd, &mut buf));
-    cvt(syscall::close(fd))?;
-    let count = res?;
-    Ok(PathBuf::from(unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) }))
-}
-
-pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
-    let fd = cvt(syscall::open(dst.to_str().unwrap(),
-                               syscall::O_CLOEXEC | syscall::O_SYMLINK |
-                               syscall::O_CREAT | syscall::O_WRONLY | 0o777))?;
-    let res = cvt(syscall::write(fd, src.to_str().unwrap().as_bytes()));
-    cvt(syscall::close(fd))?;
-    res?;
-    Ok(())
-}
-
-pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
-    Err(Error::from_raw_os_error(syscall::ENOSYS))
-}
-
-pub fn stat(p: &Path) -> io::Result<FileAttr> {
-    let fd = cvt(syscall::open(p.to_str().unwrap(), syscall::O_CLOEXEC | syscall::O_STAT))?;
-    let file = File(FileDesc::new(fd));
-    file.file_attr()
-}
-
-pub fn lstat(p: &Path) -> io::Result<FileAttr> {
-    let fd = cvt(syscall::open(p.to_str().unwrap(),
-                               syscall::O_CLOEXEC | syscall::O_STAT | syscall::O_NOFOLLOW))?;
-    let file = File(FileDesc::new(fd));
-    file.file_attr()
-}
-
-pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
-    let fd = cvt(syscall::open(p.to_str().unwrap(), syscall::O_CLOEXEC | syscall::O_STAT))?;
-    let file = File(FileDesc::new(fd));
-    file.path()
-}
diff --git a/src/libstd/sys/redox/io.rs b/src/libstd/sys/redox/io.rs
deleted file mode 100644
index 4b423a5cbc1..00000000000
--- a/src/libstd/sys/redox/io.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-pub struct IoSlice<'a>(&'a [u8]);
-
-impl<'a> IoSlice<'a> {
-    #[inline]
-    pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
-        IoSlice(buf)
-    }
-
-    #[inline]
-    pub fn as_slice(&self) -> &[u8] {
-        self.0
-    }
-}
-
-pub struct IoSliceMut<'a>(&'a mut [u8]);
-
-impl<'a> IoSliceMut<'a> {
-    #[inline]
-    pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
-        IoSliceMut(buf)
-    }
-
-    #[inline]
-    pub fn as_slice(&self) -> &[u8] {
-        self.0
-    }
-
-    #[inline]
-    pub fn as_mut_slice(&mut self) -> &mut [u8] {
-        self.0
-    }
-}
diff --git a/src/libstd/sys/redox/memchr.rs b/src/libstd/sys/redox/memchr.rs
deleted file mode 100644
index d2bfcce86f4..00000000000
--- a/src/libstd/sys/redox/memchr.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-// Original implementation taken from rust-memchr.
-// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
-
-pub use core::slice::memchr::{memchr, memrchr};
diff --git a/src/libstd/sys/redox/mod.rs b/src/libstd/sys/redox/mod.rs
deleted file mode 100644
index 0e8ed8e303d..00000000000
--- a/src/libstd/sys/redox/mod.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-#![allow(dead_code, missing_docs, nonstandard_style)]
-
-use crate::io::ErrorKind;
-
-pub use libc::strlen;
-pub use self::rand::hashmap_random_keys;
-
-#[path = "../unix/alloc.rs"]
-pub mod alloc;
-pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
-pub mod cmath;
-pub mod condvar;
-pub mod env;
-pub mod ext;
-pub mod fast_thread_local;
-pub mod fd;
-pub mod fs;
-pub mod io;
-pub mod memchr;
-pub mod mutex;
-pub mod net;
-pub mod os;
-pub mod path;
-pub mod pipe;
-pub mod process;
-pub mod rand;
-pub mod rwlock;
-pub mod stack_overflow;
-pub mod stdio;
-pub mod syscall;
-pub mod thread;
-pub mod thread_local;
-pub mod time;
-
-pub use crate::sys_common::os_str_bytes as os_str;
-
-#[cfg(not(test))]
-pub fn init() {}
-
-pub fn decode_error_kind(errno: i32) -> ErrorKind {
-    match errno {
-        syscall::ECONNREFUSED => ErrorKind::ConnectionRefused,
-        syscall::ECONNRESET => ErrorKind::ConnectionReset,
-        syscall::EPERM | syscall::EACCES => ErrorKind::PermissionDenied,
-        syscall::EPIPE => ErrorKind::BrokenPipe,
-        syscall::ENOTCONN => ErrorKind::NotConnected,
-        syscall::ECONNABORTED => ErrorKind::ConnectionAborted,
-        syscall::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
-        syscall::EADDRINUSE => ErrorKind::AddrInUse,
-        syscall::ENOENT => ErrorKind::NotFound,
-        syscall::EINTR => ErrorKind::Interrupted,
-        syscall::EINVAL => ErrorKind::InvalidInput,
-        syscall::ETIMEDOUT => ErrorKind::TimedOut,
-        syscall::EEXIST => ErrorKind::AlreadyExists,
-
-        // These two constants can have the same value on some systems,
-        // but different values on others, so we can't use a match
-        // clause
-        x if x == syscall::EAGAIN || x == syscall::EWOULDBLOCK =>
-            ErrorKind::WouldBlock,
-
-        _ => ErrorKind::Other,
-    }
-}
-
-pub fn cvt(result: Result<usize, syscall::Error>) -> crate::io::Result<usize> {
-    result.map_err(|err| crate::io::Error::from_raw_os_error(err.errno))
-}
-
-#[doc(hidden)]
-pub trait IsMinusOne {
-    fn is_minus_one(&self) -> bool;
-}
-
-macro_rules! impl_is_minus_one {
-    ($($t:ident)*) => ($(impl IsMinusOne for $t {
-        fn is_minus_one(&self) -> bool {
-            *self == -1
-        }
-    })*)
-}
-
-impl_is_minus_one! { i8 i16 i32 i64 isize }
-
-pub fn cvt_libc<T: IsMinusOne>(t: T) -> crate::io::Result<T> {
-    if t.is_minus_one() {
-        Err(crate::io::Error::last_os_error())
-    } else {
-        Ok(t)
-    }
-}
-
-/// On Redox, use an illegal instruction to abort
-pub unsafe fn abort_internal() -> ! {
-    core::intrinsics::abort();
-}
diff --git a/src/libstd/sys/redox/mutex.rs b/src/libstd/sys/redox/mutex.rs
deleted file mode 100644
index 59399df0294..00000000000
--- a/src/libstd/sys/redox/mutex.rs
+++ /dev/null
@@ -1,169 +0,0 @@
-use crate::cell::UnsafeCell;
-use crate::intrinsics::{atomic_cxchg, atomic_xchg};
-use crate::ptr;
-
-use crate::sys::syscall::{futex, getpid, FUTEX_WAIT, FUTEX_WAKE};
-
-pub unsafe fn mutex_try_lock(m: *mut i32) -> bool {
-    atomic_cxchg(m, 0, 1).0 == 0
-}
-
-pub unsafe fn mutex_lock(m: *mut i32) {
-    let mut c = 0;
-    //Set to larger value for longer spin test
-    for _i in 0..100 {
-        c = atomic_cxchg(m, 0, 1).0;
-        if c == 0 {
-            break;
-        }
-        //cpu_relax()
-    }
-    if c == 1 {
-        c = atomic_xchg(m, 2);
-    }
-    while c != 0 {
-        let _ = futex(m, FUTEX_WAIT, 2, 0, ptr::null_mut());
-        c = atomic_xchg(m, 2);
-    }
-}
-
-pub unsafe fn mutex_unlock(m: *mut i32) {
-    if *m == 2 {
-        *m = 0;
-    } else if atomic_xchg(m, 0) == 1 {
-        return;
-    }
-    //Set to larger value for longer spin test
-    for _i in 0..100 {
-        if *m != 0 {
-            if atomic_cxchg(m, 1, 2).0 != 0 {
-                return;
-            }
-        }
-        //cpu_relax()
-    }
-    let _ = futex(m, FUTEX_WAKE, 1, 0, ptr::null_mut());
-}
-
-pub struct Mutex {
-    pub lock: UnsafeCell<i32>,
-}
-
-impl Mutex {
-    /// Creates a new mutex.
-    pub const fn new() -> Self {
-        Mutex {
-            lock: UnsafeCell::new(0),
-        }
-    }
-
-    #[inline]
-    pub unsafe fn init(&self) {
-        *self.lock.get() = 0;
-    }
-
-    /// Try to lock the mutex
-    #[inline]
-    pub unsafe fn try_lock(&self) -> bool {
-        mutex_try_lock(self.lock.get())
-    }
-
-    /// Lock the mutex
-    #[inline]
-    pub unsafe fn lock(&self) {
-        mutex_lock(self.lock.get());
-    }
-
-    /// Unlock the mutex
-    #[inline]
-    pub unsafe fn unlock(&self) {
-        mutex_unlock(self.lock.get());
-    }
-
-    #[inline]
-    pub unsafe fn destroy(&self) {
-        *self.lock.get() = 0;
-    }
-}
-
-unsafe impl Send for Mutex {}
-
-unsafe impl Sync for Mutex {}
-
-pub struct ReentrantMutex {
-    pub lock: UnsafeCell<i32>,
-    pub owner: UnsafeCell<usize>,
-    pub own_count: UnsafeCell<usize>,
-}
-
-impl ReentrantMutex {
-    pub const fn uninitialized() -> Self {
-        ReentrantMutex {
-            lock: UnsafeCell::new(0),
-            owner: UnsafeCell::new(0),
-            own_count: UnsafeCell::new(0),
-        }
-    }
-
-    #[inline]
-    pub unsafe fn init(&mut self) {
-        *self.lock.get() = 0;
-        *self.owner.get() = 0;
-        *self.own_count.get() = 0;
-    }
-
-    /// Try to lock the mutex
-    #[inline]
-    pub unsafe fn try_lock(&self) -> bool {
-        let pid = getpid().unwrap();
-        if *self.own_count.get() > 0 && *self.owner.get() == pid {
-            *self.own_count.get() += 1;
-            true
-        } else {
-            if mutex_try_lock(self.lock.get()) {
-                *self.owner.get() = pid;
-                *self.own_count.get() = 1;
-                true
-            } else {
-                false
-            }
-        }
-    }
-
-    /// Lock the mutex
-    #[inline]
-    pub unsafe fn lock(&self) {
-        let pid = getpid().unwrap();
-        if *self.own_count.get() > 0 && *self.owner.get() == pid {
-            *self.own_count.get() += 1;
-        } else {
-            mutex_lock(self.lock.get());
-            *self.owner.get() = pid;
-            *self.own_count.get() = 1;
-        }
-    }
-
-    /// Unlock the mutex
-    #[inline]
-    pub unsafe fn unlock(&self) {
-        let pid = getpid().unwrap();
-        if *self.own_count.get() > 0 && *self.owner.get() == pid {
-            *self.own_count.get() -= 1;
-            if *self.own_count.get() == 0 {
-                *self.owner.get() = 0;
-                mutex_unlock(self.lock.get());
-            }
-        }
-    }
-
-    #[inline]
-    pub unsafe fn destroy(&self) {
-        *self.lock.get() = 0;
-        *self.owner.get() = 0;
-        *self.own_count.get() = 0;
-    }
-}
-
-unsafe impl Send for ReentrantMutex {}
-
-unsafe impl Sync for ReentrantMutex {}
diff --git a/src/libstd/sys/redox/net/dns/answer.rs b/src/libstd/sys/redox/net/dns/answer.rs
deleted file mode 100644
index e9b406bc685..00000000000
--- a/src/libstd/sys/redox/net/dns/answer.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-use crate::string::String;
-use crate::vec::Vec;
-
-#[derive(Clone, Debug)]
-pub struct DnsAnswer {
-    pub name: String,
-    pub a_type: u16,
-    pub a_class: u16,
-    pub ttl_a: u16,
-    pub ttl_b: u16,
-    pub data: Vec<u8>
-}
diff --git a/src/libstd/sys/redox/net/dns/mod.rs b/src/libstd/sys/redox/net/dns/mod.rs
deleted file mode 100644
index 6533e0d5efb..00000000000
--- a/src/libstd/sys/redox/net/dns/mod.rs
+++ /dev/null
@@ -1,205 +0,0 @@
-pub use self::answer::DnsAnswer;
-pub use self::query::DnsQuery;
-
-use crate::slice;
-use crate::u16;
-use crate::string::String;
-use crate::vec::Vec;
-
-mod answer;
-mod query;
-
-#[unstable(feature = "n16", issue="0")]
-#[allow(non_camel_case_types)]
-#[derive(Copy, Clone, Debug, Default)]
-#[repr(packed)]
-pub struct n16 {
-    inner: u16
-}
-
-impl n16 {
-    #[unstable(feature = "n16", issue="0")]
-    pub fn as_bytes(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts((&self.inner as *const u16) as *const u8, 2) }
-    }
-
-    #[unstable(feature = "n16", issue="0")]
-    pub fn from_bytes(bytes: &[u8]) -> Self {
-        n16 {
-            inner: unsafe { slice::from_raw_parts(bytes.as_ptr() as *const u16, bytes.len()/2)[0] }
-        }
-    }
-}
-
-#[unstable(feature = "n16", issue="0")]
-impl From<u16> for n16 {
-    fn from(value: u16) -> Self {
-        n16 {
-            inner: value.to_be()
-        }
-    }
-}
-
-#[unstable(feature = "n16", issue="0")]
-impl From<n16> for u16 {
-    fn from(value: n16) -> Self {
-        u16::from_be(value.inner)
-    }
-}
-
-#[derive(Clone, Debug)]
-pub struct Dns {
-    pub transaction_id: u16,
-    pub flags: u16,
-    pub queries: Vec<DnsQuery>,
-    pub answers: Vec<DnsAnswer>
-}
-
-impl Dns {
-    pub fn compile(&self) -> Vec<u8> {
-        let mut data = Vec::new();
-
-        macro_rules! push_u8 {
-            ($value:expr) => {
-                data.push($value);
-            };
-        };
-
-        macro_rules! push_n16 {
-            ($value:expr) => {
-                data.extend_from_slice(n16::from($value).as_bytes());
-            };
-        };
-
-        push_n16!(self.transaction_id);
-        push_n16!(self.flags);
-        push_n16!(self.queries.len() as u16);
-        push_n16!(self.answers.len() as u16);
-        push_n16!(0);
-        push_n16!(0);
-
-        for query in self.queries.iter() {
-            for part in query.name.split('.') {
-                push_u8!(part.len() as u8);
-                data.extend_from_slice(part.as_bytes());
-            }
-            push_u8!(0);
-            push_n16!(query.q_type);
-            push_n16!(query.q_class);
-        }
-
-        data
-    }
-
-    pub fn parse(data: &[u8]) -> Result<Self, String> {
-        let name_ind = 0b11000000;
-        let mut i = 0;
-
-        macro_rules! pop_u8 {
-            () => {
-                {
-                    i += 1;
-                    if i > data.len() {
-                        return Err(format!("{}: {}: pop_u8", file!(), line!()));
-                    }
-                    data[i - 1]
-                }
-            };
-        };
-
-        macro_rules! pop_n16 {
-            () => {
-                {
-                    i += 2;
-                    if i > data.len() {
-                        return Err(format!("{}: {}: pop_n16", file!(), line!()));
-                    }
-                    u16::from(n16::from_bytes(&data[i - 2 .. i]))
-                }
-            };
-        };
-
-        macro_rules! pop_data {
-            () => {
-                {
-                    let mut data = Vec::new();
-
-                    let data_len = pop_n16!();
-                    for _data_i in 0..data_len {
-                        data.push(pop_u8!());
-                    }
-
-                    data
-                }
-            };
-        };
-
-        macro_rules! pop_name {
-            () => {
-                {
-                    let mut name = String::new();
-                    let old_i = i;
-
-                    loop {
-                        let name_len = pop_u8!();
-                        if name_len & name_ind == name_ind {
-                            i -= 1;
-                            i = (pop_n16!() - ((name_ind as u16) << 8)) as usize;
-                            continue;
-                        }
-                        if name_len == 0 {
-                            break;
-                        }
-                        if ! name.is_empty() {
-                            name.push('.');
-                        }
-                        for _name_i in 0..name_len {
-                            name.push(pop_u8!() as char);
-                        }
-                    }
-
-                    if i <= old_i {
-                        i = old_i + 2;
-                    }
-
-                    name
-                }
-            };
-        };
-
-        let transaction_id = pop_n16!();
-        let flags = pop_n16!();
-        let queries_len = pop_n16!();
-        let answers_len = pop_n16!();
-        pop_n16!();
-        pop_n16!();
-
-        let mut queries = Vec::new();
-        for _query_i in 0..queries_len {
-            queries.push(DnsQuery {
-                name: pop_name!(),
-                q_type: pop_n16!(),
-                q_class: pop_n16!()
-            });
-        }
-
-        let mut answers = Vec::new();
-        for _answer_i in 0..answers_len {
-            answers.push(DnsAnswer {
-                name: pop_name!(),
-                a_type: pop_n16!(),
-                a_class: pop_n16!(),
-                ttl_a: pop_n16!(),
-                ttl_b: pop_n16!(),
-                data: pop_data!()
-            });
-        }
-
-        Ok(Dns {
-            transaction_id,
-            flags,
-            queries,
-            answers,
-        })
-    }
-}
diff --git a/src/libstd/sys/redox/net/dns/query.rs b/src/libstd/sys/redox/net/dns/query.rs
deleted file mode 100644
index 65fb241b037..00000000000
--- a/src/libstd/sys/redox/net/dns/query.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-use crate::string::String;
-
-#[derive(Clone, Debug)]
-pub struct DnsQuery {
-    pub name: String,
-    pub q_type: u16,
-    pub q_class: u16
-}
diff --git a/src/libstd/sys/redox/net/mod.rs b/src/libstd/sys/redox/net/mod.rs
deleted file mode 100644
index dbaa140ed8a..00000000000
--- a/src/libstd/sys/redox/net/mod.rs
+++ /dev/null
@@ -1,140 +0,0 @@
-use crate::fs::File;
-use crate::io::{Error, Read, self};
-use crate::iter::Iterator;
-use crate::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
-use crate::str::FromStr;
-use crate::string::{String, ToString};
-use crate::sys::syscall::EINVAL;
-use crate::time::{self, Duration};
-use crate::vec::{IntoIter, Vec};
-use crate::convert::{TryFrom, TryInto};
-
-use self::dns::{Dns, DnsQuery};
-
-pub use self::tcp::{TcpStream, TcpListener};
-pub use self::udp::UdpSocket;
-
-pub mod netc;
-
-mod dns;
-mod tcp;
-mod udp;
-
-pub struct LookupHost(IntoIter<SocketAddr>, u16);
-
-impl LookupHost {
-    pub fn port(&self) -> u16 {
-        self.1
-    }
-}
-
-impl Iterator for LookupHost {
-    type Item = SocketAddr;
-    fn next(&mut self) -> Option<Self::Item> {
-        self.0.next()
-    }
-}
-
-impl TryFrom<&str> for LookupHost {
-    type Error = io::Error;
-
-    fn try_from(s: &str) -> io::Result<LookupHost> {
-        macro_rules! try_opt {
-            ($e:expr, $msg:expr) => (
-                match $e {
-                    Some(r) => r,
-                    None => return Err(io::Error::new(io::ErrorKind::InvalidInput,
-                                                      $msg)),
-                }
-            )
-        }
-
-        // split the string by ':' and convert the second part to u16
-        let mut parts_iter = s.rsplitn(2, ':');
-        let port_str = try_opt!(parts_iter.next(), "invalid socket address");
-        let host = try_opt!(parts_iter.next(), "invalid socket address");
-        let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
-
-        (host, port).try_into()
-    }
-}
-
-impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
-    type Error = io::Error;
-
-    fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
-        let mut ip_string = String::new();
-        File::open("/etc/net/ip")?.read_to_string(&mut ip_string)?;
-        let ip: Vec<u8> = ip_string.trim().split('.').map(|part| part.parse::<u8>()
-                                   .unwrap_or(0)).collect();
-
-        let mut dns_string = String::new();
-        File::open("/etc/net/dns")?.read_to_string(&mut dns_string)?;
-        let dns: Vec<u8> = dns_string.trim().split('.').map(|part| part.parse::<u8>()
-                                     .unwrap_or(0)).collect();
-
-        if ip.len() == 4 && dns.len() == 4 {
-            let time = time::SystemTime::now().duration_since(time::UNIX_EPOCH).unwrap();
-            let tid = (time.subsec_nanos() >> 16) as u16;
-
-            let packet = Dns {
-                transaction_id: tid,
-                flags: 0x0100,
-                queries: vec![DnsQuery {
-                    name: host.to_string(),
-                    q_type: 0x0001,
-                    q_class: 0x0001,
-                }],
-                answers: vec![]
-            };
-
-            let packet_data = packet.compile();
-
-            let my_ip = Ipv4Addr::new(ip[0], ip[1], ip[2], ip[3]);
-            let dns_ip = Ipv4Addr::new(dns[0], dns[1], dns[2], dns[3]);
-            let socket = UdpSocket::bind(Ok(&SocketAddr::V4(SocketAddrV4::new(my_ip, 0))))?;
-            socket.set_read_timeout(Some(Duration::new(5, 0)))?;
-            socket.set_write_timeout(Some(Duration::new(5, 0)))?;
-            socket.connect(Ok(&SocketAddr::V4(SocketAddrV4::new(dns_ip, 53))))?;
-            socket.send(&packet_data)?;
-
-            let mut buf = [0; 65536];
-            let count = socket.recv(&mut buf)?;
-
-            match Dns::parse(&buf[.. count]) {
-                Ok(response) => {
-                    let mut addrs = vec![];
-                    for answer in response.answers.iter() {
-                        if answer.a_type == 0x0001 && answer.a_class == 0x0001
-                           && answer.data.len() == 4
-                        {
-                            let answer_ip = Ipv4Addr::new(answer.data[0],
-                                                          answer.data[1],
-                                                          answer.data[2],
-                                                          answer.data[3]);
-                            addrs.push(SocketAddr::V4(SocketAddrV4::new(answer_ip, 0)));
-                        }
-                    }
-                    Ok(LookupHost(addrs.into_iter(), port))
-                },
-                Err(_err) => Err(Error::from_raw_os_error(EINVAL))
-            }
-        } else {
-            Err(Error::from_raw_os_error(EINVAL))
-        }
-    }
-}
-
-fn path_to_peer_addr(path_str: &str) -> SocketAddr {
-    let mut parts = path_str.split('/').next().unwrap_or("").split(':').skip(1);
-    let host = Ipv4Addr::from_str(parts.next().unwrap_or("")).unwrap_or(Ipv4Addr::new(0, 0, 0, 0));
-    let port = parts.next().unwrap_or("").parse::<u16>().unwrap_or(0);
-    SocketAddr::V4(SocketAddrV4::new(host, port))
-}
-
-fn path_to_local_addr(path_str: &str) -> SocketAddr {
-    let mut parts = path_str.split('/').nth(1).unwrap_or("").split(':');
-    let host = Ipv4Addr::from_str(parts.next().unwrap_or("")).unwrap_or(Ipv4Addr::new(0, 0, 0, 0));
-    let port = parts.next().unwrap_or("").parse::<u16>().unwrap_or(0);
-    SocketAddr::V4(SocketAddrV4::new(host, port))
-}
diff --git a/src/libstd/sys/redox/net/netc.rs b/src/libstd/sys/redox/net/netc.rs
deleted file mode 100644
index 420a15a4063..00000000000
--- a/src/libstd/sys/redox/net/netc.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-pub type in_addr_t = u32;
-pub type in_port_t = u16;
-
-pub type socklen_t = u32;
-pub type sa_family_t = u16;
-
-pub const AF_INET: sa_family_t = 2;
-pub const AF_INET6: sa_family_t = 23;
-
-#[derive(Copy, Clone)]
-#[repr(C)]
-pub struct in_addr {
-    pub s_addr: in_addr_t,
-}
-
-#[derive(Copy, Clone)]
-#[repr(align(4))]
-#[repr(C)]
-pub struct in6_addr {
-    pub s6_addr: [u8; 16],
-}
-
-#[derive(Copy, Clone)]
-#[repr(C)]
-pub struct sockaddr {
-    pub sa_family: sa_family_t,
-    pub sa_data: [u8; 14],
-}
-
-#[derive(Copy, Clone)]
-#[repr(C)]
-pub struct sockaddr_in {
-    pub sin_family: sa_family_t,
-    pub sin_port: in_port_t,
-    pub sin_addr: in_addr,
-    pub sin_zero: [u8; 8],
-}
-
-#[derive(Copy, Clone)]
-#[repr(C)]
-pub struct sockaddr_in6 {
-    pub sin6_family: sa_family_t,
-    pub sin6_port: in_port_t,
-    pub sin6_flowinfo: u32,
-    pub sin6_addr: in6_addr,
-    pub sin6_scope_id: u32,
-}
diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs
deleted file mode 100644
index 494f943c96b..00000000000
--- a/src/libstd/sys/redox/net/tcp.rs
+++ /dev/null
@@ -1,251 +0,0 @@
-use crate::cmp;
-use crate::io::{self, Error, ErrorKind, Result, IoSlice, IoSliceMut};
-use crate::mem;
-use crate::net::{SocketAddr, Shutdown};
-use crate::path::Path;
-use crate::sys::fs::{File, OpenOptions};
-use crate::sys::syscall::TimeSpec;
-use crate::sys_common::{AsInner, FromInner, IntoInner};
-use crate::time::Duration;
-
-use super::{path_to_peer_addr, path_to_local_addr};
-
-#[derive(Debug)]
-pub struct TcpStream(File);
-
-impl TcpStream {
-    pub fn connect(addr: Result<&SocketAddr>) -> Result<TcpStream> {
-        let path = format!("tcp:{}", addr?);
-        let mut options = OpenOptions::new();
-        options.read(true);
-        options.write(true);
-        Ok(TcpStream(File::open(Path::new(path.as_str()), &options)?))
-    }
-
-    pub fn connect_timeout(_addr: &SocketAddr, _timeout: Duration) -> Result<TcpStream> {
-        Err(Error::new(ErrorKind::Other, "TcpStream::connect_timeout not implemented"))
-    }
-
-    pub fn duplicate(&self) -> Result<TcpStream> {
-        Ok(TcpStream(self.0.dup(&[])?))
-    }
-
-    pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
-        self.0.read(buf)
-    }
-
-    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        io::default_read_vectored(|b| self.read(b), bufs)
-    }
-
-    pub fn write(&self, buf: &[u8]) -> Result<usize> {
-        self.0.write(buf)
-    }
-
-    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        io::default_write_vectored(|b| self.write(b), bufs)
-    }
-
-    pub fn take_error(&self) -> Result<Option<Error>> {
-        Ok(None)
-    }
-
-    pub fn peer_addr(&self) -> Result<SocketAddr> {
-        let path = self.0.path()?;
-        Ok(path_to_peer_addr(path.to_str().unwrap_or("")))
-    }
-
-    pub fn socket_addr(&self) -> Result<SocketAddr> {
-        let path = self.0.path()?;
-        Ok(path_to_local_addr(path.to_str().unwrap_or("")))
-    }
-
-    pub fn peek(&self, _buf: &mut [u8]) -> Result<usize> {
-        Err(Error::new(ErrorKind::Other, "TcpStream::peek not implemented"))
-    }
-
-    pub fn shutdown(&self, _how: Shutdown) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "TcpStream::shutdown not implemented"))
-    }
-
-    pub fn nodelay(&self) -> Result<bool> {
-        Err(Error::new(ErrorKind::Other, "TcpStream::nodelay not implemented"))
-    }
-
-    pub fn nonblocking(&self) -> Result<bool> {
-        self.0.fd().nonblocking()
-    }
-
-    pub fn only_v6(&self) -> Result<bool> {
-        Err(Error::new(ErrorKind::Other, "TcpStream::only_v6 not implemented"))
-    }
-
-    pub fn ttl(&self) -> Result<u32> {
-        let mut ttl = [0];
-        let file = self.0.dup(b"ttl")?;
-        file.read(&mut ttl)?;
-        Ok(ttl[0] as u32)
-    }
-
-    pub fn read_timeout(&self) -> Result<Option<Duration>> {
-        let mut time = TimeSpec::default();
-        let file = self.0.dup(b"read_timeout")?;
-        if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
-            Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
-        } else {
-            Ok(None)
-        }
-    }
-
-    pub fn write_timeout(&self) -> Result<Option<Duration>> {
-        let mut time = TimeSpec::default();
-        let file = self.0.dup(b"write_timeout")?;
-        if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
-            Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
-        } else {
-            Ok(None)
-        }
-    }
-
-    pub fn set_nodelay(&self, _nodelay: bool) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "TcpStream::set_nodelay not implemented"))
-    }
-
-    pub fn set_nonblocking(&self, nonblocking: bool) -> Result<()> {
-        self.0.fd().set_nonblocking(nonblocking)
-    }
-
-    pub fn set_only_v6(&self, _only_v6: bool) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "TcpStream::set_only_v6 not implemented"))
-    }
-
-    pub fn set_ttl(&self, ttl: u32) -> Result<()> {
-        let file = self.0.dup(b"ttl")?;
-        file.write(&[cmp::min(ttl, 255) as u8])?;
-        Ok(())
-    }
-
-    pub fn set_read_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
-        let file = self.0.dup(b"read_timeout")?;
-        if let Some(duration) = duration_option {
-            if duration.as_secs() == 0 && duration.subsec_nanos() == 0 {
-                return Err(io::Error::new(io::ErrorKind::InvalidInput,
-                                          "cannot set a 0 duration timeout"));
-            }
-            file.write(&TimeSpec {
-                tv_sec: duration.as_secs() as i64,
-                tv_nsec: duration.subsec_nanos() as i32
-            })?;
-        } else {
-            file.write(&[])?;
-        }
-        Ok(())
-    }
-
-    pub fn set_write_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
-        let file = self.0.dup(b"write_timeout")?;
-        if let Some(duration) = duration_option {
-            if duration.as_secs() == 0 && duration.subsec_nanos() == 0 {
-                return Err(io::Error::new(io::ErrorKind::InvalidInput,
-                                          "cannot set a 0 duration timeout"));
-            }
-            file.write(&TimeSpec {
-                tv_sec: duration.as_secs() as i64,
-                tv_nsec: duration.subsec_nanos() as i32
-            })?;
-        } else {
-            file.write(&[])?;
-        }
-        Ok(())
-    }
-}
-
-impl AsInner<File> for TcpStream {
-    fn as_inner(&self) -> &File { &self.0 }
-}
-
-impl FromInner<File> for TcpStream {
-    fn from_inner(file: File) -> TcpStream {
-        TcpStream(file)
-    }
-}
-
-impl IntoInner<File> for TcpStream {
-    fn into_inner(self) -> File { self.0 }
-}
-
-#[derive(Debug)]
-pub struct TcpListener(File);
-
-impl TcpListener {
-    pub fn bind(addr: Result<&SocketAddr>) -> Result<TcpListener> {
-        let path = format!("tcp:/{}", addr?);
-        let mut options = OpenOptions::new();
-        options.read(true);
-        options.write(true);
-        Ok(TcpListener(File::open(Path::new(path.as_str()), &options)?))
-    }
-
-    pub fn accept(&self) -> Result<(TcpStream, SocketAddr)> {
-        let file = self.0.dup(b"listen")?;
-        let path = file.path()?;
-        let peer_addr = path_to_peer_addr(path.to_str().unwrap_or(""));
-        Ok((TcpStream(file), peer_addr))
-    }
-
-    pub fn duplicate(&self) -> Result<TcpListener> {
-        Ok(TcpListener(self.0.dup(&[])?))
-    }
-
-    pub fn take_error(&self) -> Result<Option<Error>> {
-        Ok(None)
-    }
-
-    pub fn socket_addr(&self) -> Result<SocketAddr> {
-        let path = self.0.path()?;
-        Ok(path_to_local_addr(path.to_str().unwrap_or("")))
-    }
-
-    pub fn nonblocking(&self) -> Result<bool> {
-        Err(Error::new(ErrorKind::Other, "TcpListener::nonblocking not implemented"))
-    }
-
-    pub fn only_v6(&self) -> Result<bool> {
-        Err(Error::new(ErrorKind::Other, "TcpListener::only_v6 not implemented"))
-    }
-
-    pub fn ttl(&self) -> Result<u32> {
-        let mut ttl = [0];
-        let file = self.0.dup(b"ttl")?;
-        file.read(&mut ttl)?;
-        Ok(ttl[0] as u32)
-    }
-
-    pub fn set_nonblocking(&self, _nonblocking: bool) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "TcpListener::set_nonblocking not implemented"))
-    }
-
-    pub fn set_only_v6(&self, _only_v6: bool) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "TcpListener::set_only_v6 not implemented"))
-    }
-
-    pub fn set_ttl(&self, ttl: u32) -> Result<()> {
-        let file = self.0.dup(b"ttl")?;
-        file.write(&[cmp::min(ttl, 255) as u8])?;
-        Ok(())
-    }
-}
-
-impl AsInner<File> for TcpListener {
-    fn as_inner(&self) -> &File { &self.0 }
-}
-
-impl FromInner<File> for TcpListener {
-    fn from_inner(file: File) -> TcpListener {
-        TcpListener(file)
-    }
-}
-
-impl IntoInner<File> for TcpListener {
-    fn into_inner(self) -> File { self.0 }
-}
diff --git a/src/libstd/sys/redox/net/udp.rs b/src/libstd/sys/redox/net/udp.rs
deleted file mode 100644
index 274123dce4b..00000000000
--- a/src/libstd/sys/redox/net/udp.rs
+++ /dev/null
@@ -1,237 +0,0 @@
-use crate::cell::UnsafeCell;
-use crate::cmp;
-use crate::io::{self, Error, ErrorKind, Result};
-use crate::mem;
-use crate::net::{SocketAddr, Ipv4Addr, Ipv6Addr};
-use crate::path::Path;
-use crate::sys::fs::{File, OpenOptions};
-use crate::sys::syscall::TimeSpec;
-use crate::sys_common::{AsInner, FromInner, IntoInner};
-use crate::time::Duration;
-
-use super::{path_to_peer_addr, path_to_local_addr};
-
-#[derive(Debug)]
-pub struct UdpSocket(File, UnsafeCell<Option<SocketAddr>>);
-
-impl UdpSocket {
-    pub fn bind(addr: Result<&SocketAddr>) -> Result<UdpSocket> {
-        let path = format!("udp:/{}", addr?);
-        let mut options = OpenOptions::new();
-        options.read(true);
-        options.write(true);
-        Ok(UdpSocket(File::open(Path::new(path.as_str()), &options)?, UnsafeCell::new(None)))
-    }
-
-    fn get_conn(&self) -> &mut Option<SocketAddr> {
-        unsafe { &mut *(self.1.get()) }
-    }
-
-    pub fn connect(&self, addr: Result<&SocketAddr>) -> Result<()> {
-        unsafe { *self.1.get() = Some(*addr?) };
-        Ok(())
-    }
-
-    pub fn duplicate(&self) -> Result<UdpSocket> {
-        let new_bind = self.0.dup(&[])?;
-        let new_conn = *self.get_conn();
-        Ok(UdpSocket(new_bind, UnsafeCell::new(new_conn)))
-    }
-
-    pub fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)> {
-        let from = self.0.dup(b"listen")?;
-        let path = from.path()?;
-        let peer_addr = path_to_peer_addr(path.to_str().unwrap_or(""));
-        let count = from.read(buf)?;
-        Ok((count, peer_addr))
-    }
-
-    pub fn recv(&self, buf: &mut [u8]) -> Result<usize> {
-        if let Some(addr) = *self.get_conn() {
-            let from = self.0.dup(addr.to_string().as_bytes())?;
-            from.read(buf)
-        } else {
-            Err(Error::new(ErrorKind::Other, "UdpSocket::recv not connected"))
-        }
-    }
-
-    pub fn send_to(&self, buf: &[u8], addr: &SocketAddr) -> Result<usize> {
-        let to = self.0.dup(format!("{}", addr).as_bytes())?;
-        to.write(buf)
-    }
-
-    pub fn send(&self, buf: &[u8]) -> Result<usize> {
-        if let Some(addr) = *self.get_conn() {
-            self.send_to(buf, &addr)
-        } else {
-            Err(Error::new(ErrorKind::Other, "UdpSocket::send not connected"))
-        }
-    }
-
-    pub fn take_error(&self) -> Result<Option<Error>> {
-        Ok(None)
-    }
-
-    pub fn peer_addr(&self) -> Result<SocketAddr> {
-        let path = self.0.path()?;
-        Ok(path_to_peer_addr(path.to_str().unwrap_or("")))
-    }
-
-    pub fn socket_addr(&self) -> Result<SocketAddr> {
-        let path = self.0.path()?;
-        Ok(path_to_local_addr(path.to_str().unwrap_or("")))
-    }
-
-    pub fn peek(&self, _buf: &mut [u8]) -> Result<usize> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::peek not implemented"))
-    }
-
-    pub fn peek_from(&self, _buf: &mut [u8]) -> Result<(usize, SocketAddr)> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::peek_from not implemented"))
-    }
-
-    pub fn broadcast(&self) -> Result<bool> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::broadcast not implemented"))
-    }
-
-    pub fn multicast_loop_v4(&self) -> Result<bool> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::multicast_loop_v4 not implemented"))
-    }
-
-    pub fn multicast_loop_v6(&self) -> Result<bool> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::multicast_loop_v6 not implemented"))
-    }
-
-    pub fn multicast_ttl_v4(&self) -> Result<u32> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::multicast_ttl_v4 not implemented"))
-    }
-
-    pub fn nonblocking(&self) -> Result<bool> {
-        self.0.fd().nonblocking()
-    }
-
-    pub fn only_v6(&self) -> Result<bool> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::only_v6 not implemented"))
-    }
-
-    pub fn ttl(&self) -> Result<u32> {
-        let mut ttl = [0];
-        let file = self.0.dup(b"ttl")?;
-        file.read(&mut ttl)?;
-        Ok(ttl[0] as u32)
-    }
-
-    pub fn read_timeout(&self) -> Result<Option<Duration>> {
-        let mut time = TimeSpec::default();
-        let file = self.0.dup(b"read_timeout")?;
-        if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
-            Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
-        } else {
-            Ok(None)
-        }
-    }
-
-    pub fn write_timeout(&self) -> Result<Option<Duration>> {
-        let mut time = TimeSpec::default();
-        let file = self.0.dup(b"write_timeout")?;
-        if file.read(&mut time)? >= mem::size_of::<TimeSpec>() {
-            Ok(Some(Duration::new(time.tv_sec as u64, time.tv_nsec as u32)))
-        } else {
-            Ok(None)
-        }
-    }
-
-    pub fn set_broadcast(&self, _broadcast: bool) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::set_broadcast not implemented"))
-    }
-
-    pub fn set_multicast_loop_v4(&self, _multicast_loop_v4: bool) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::set_multicast_loop_v4 not implemented"))
-    }
-
-    pub fn set_multicast_loop_v6(&self, _multicast_loop_v6: bool) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::set_multicast_loop_v6 not implemented"))
-    }
-
-    pub fn set_multicast_ttl_v4(&self, _multicast_ttl_v4: u32) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::set_multicast_ttl_v4 not implemented"))
-    }
-
-    pub fn set_nonblocking(&self, nonblocking: bool) -> Result<()> {
-        self.0.fd().set_nonblocking(nonblocking)
-    }
-
-    pub fn set_only_v6(&self, _only_v6: bool) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::set_only_v6 not implemented"))
-    }
-
-    pub fn set_ttl(&self, ttl: u32) -> Result<()> {
-        let file = self.0.dup(b"ttl")?;
-        file.write(&[cmp::min(ttl, 255) as u8])?;
-        Ok(())
-    }
-
-    pub fn set_read_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
-        let file = self.0.dup(b"read_timeout")?;
-        if let Some(duration) = duration_option {
-            if duration.as_secs() == 0 && duration.subsec_nanos() == 0 {
-                return Err(io::Error::new(io::ErrorKind::InvalidInput,
-                                          "cannot set a 0 duration timeout"));
-            }
-            file.write(&TimeSpec {
-                tv_sec: duration.as_secs() as i64,
-                tv_nsec: duration.subsec_nanos() as i32
-            })?;
-        } else {
-            file.write(&[])?;
-        }
-        Ok(())
-    }
-
-    pub fn set_write_timeout(&self, duration_option: Option<Duration>) -> Result<()> {
-        let file = self.0.dup(b"write_timeout")?;
-        if let Some(duration) = duration_option {
-            if duration.as_secs() == 0 && duration.subsec_nanos() == 0 {
-                return Err(io::Error::new(io::ErrorKind::InvalidInput,
-                                          "cannot set a 0 duration timeout"));
-            }
-            file.write(&TimeSpec {
-                tv_sec: duration.as_secs() as i64,
-                tv_nsec: duration.subsec_nanos() as i32
-            })?;
-        } else {
-            file.write(&[])?;
-        }
-        Ok(())
-    }
-
-    pub fn join_multicast_v4(&self, _multiaddr: &Ipv4Addr, _interface: &Ipv4Addr) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::join_multicast_v4 not implemented"))
-    }
-
-    pub fn join_multicast_v6(&self, _multiaddr: &Ipv6Addr, _interface: u32) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::join_multicast_v6 not implemented"))
-    }
-
-    pub fn leave_multicast_v4(&self, _multiaddr: &Ipv4Addr, _interface: &Ipv4Addr) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::leave_multicast_v4 not implemented"))
-    }
-
-    pub fn leave_multicast_v6(&self, _multiaddr: &Ipv6Addr, _interface: u32) -> Result<()> {
-        Err(Error::new(ErrorKind::Other, "UdpSocket::leave_multicast_v6 not implemented"))
-    }
-}
-
-impl AsInner<File> for UdpSocket {
-    fn as_inner(&self) -> &File { &self.0 }
-}
-
-impl FromInner<File> for UdpSocket {
-    fn from_inner(file: File) -> UdpSocket {
-        UdpSocket(file, UnsafeCell::new(None))
-    }
-}
-
-impl IntoInner<File> for UdpSocket {
-    fn into_inner(self) -> File { self.0 }
-}
diff --git a/src/libstd/sys/redox/path.rs b/src/libstd/sys/redox/path.rs
deleted file mode 100644
index b62d6c98782..00000000000
--- a/src/libstd/sys/redox/path.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-use crate::ffi::OsStr;
-use crate::path::Prefix;
-
-#[inline]
-pub fn is_sep_byte(b: u8) -> bool {
-    b == b'/'
-}
-
-#[inline]
-pub fn is_verbatim_sep(b: u8) -> bool {
-    b == b'/'
-}
-
-pub fn parse_prefix(path: &OsStr) -> Option<Prefix<'_>> {
-    if let Some(path_str) = path.to_str() {
-        if let Some(_i) = path_str.find(':') {
-            // FIXME: Redox specific prefix
-            // Some(Prefix::Verbatim(OsStr::new(&path_str[..i])))
-            None
-        } else {
-            None
-        }
-    } else {
-        None
-    }
-}
-
-pub const MAIN_SEP_STR: &str = "/";
-pub const MAIN_SEP: char = '/';
diff --git a/src/libstd/sys/redox/pipe.rs b/src/libstd/sys/redox/pipe.rs
deleted file mode 100644
index 29cacb6d562..00000000000
--- a/src/libstd/sys/redox/pipe.rs
+++ /dev/null
@@ -1,101 +0,0 @@
-use crate::io::{self, IoSlice, IoSliceMut};
-use crate::sys::{cvt, syscall};
-use crate::sys::fd::FileDesc;
-
-////////////////////////////////////////////////////////////////////////////////
-// Anonymous pipes
-////////////////////////////////////////////////////////////////////////////////
-
-pub struct AnonPipe(FileDesc);
-
-pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
-    let mut fds = [0; 2];
-    cvt(syscall::pipe2(&mut fds, syscall::O_CLOEXEC))?;
-    Ok((AnonPipe(FileDesc::new(fds[0])), AnonPipe(FileDesc::new(fds[1]))))
-}
-
-impl AnonPipe {
-    pub fn from_fd(fd: FileDesc) -> io::Result<AnonPipe> {
-        fd.set_cloexec()?;
-        Ok(AnonPipe(fd))
-    }
-
-    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
-        self.0.read(buf)
-    }
-
-    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        crate::io::default_read_vectored(|buf| self.read(buf), bufs)
-    }
-
-    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
-        self.0.write(buf)
-    }
-
-    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        crate::io::default_write_vectored(|buf| self.write(buf), bufs)
-    }
-
-    pub fn fd(&self) -> &FileDesc { &self.0 }
-    pub fn into_fd(self) -> FileDesc { self.0 }
-}
-
-pub fn read2(p1: AnonPipe,
-             v1: &mut Vec<u8>,
-             p2: AnonPipe,
-             v2: &mut Vec<u8>) -> io::Result<()> {
-    //FIXME: Use event based I/O multiplexing
-    //unimplemented!()
-
-    p1.0.read_to_end(v1)?;
-    p2.0.read_to_end(v2)?;
-
-    Ok(())
-
-    /*
-    // Set both pipes into nonblocking mode as we're gonna be reading from both
-    // in the `select` loop below, and we wouldn't want one to block the other!
-    let p1 = p1.into_fd();
-    let p2 = p2.into_fd();
-    p1.set_nonblocking(true)?;
-    p2.set_nonblocking(true)?;
-
-    loop {
-        // wait for either pipe to become readable using `select`
-        cvt_r(|| unsafe {
-            let mut read: libc::fd_set = mem::zeroed();
-            libc::FD_SET(p1.raw(), &mut read);
-            libc::FD_SET(p2.raw(), &mut read);
-            libc::select(max + 1, &mut read, ptr::null_mut(), ptr::null_mut(),
-                         ptr::null_mut())
-        })?;
-
-        // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
-        // EAGAIN. If we hit EOF, then this will happen because the underlying
-        // reader will return Ok(0), in which case we'll see `Ok` ourselves. In
-        // this case we flip the other fd back into blocking mode and read
-        // whatever's leftover on that file descriptor.
-        let read = |fd: &FileDesc, dst: &mut Vec<u8>| {
-            match fd.read_to_end(dst) {
-                Ok(_) => Ok(true),
-                Err(e) => {
-                    if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
-                       e.raw_os_error() == Some(libc::EAGAIN) {
-                        Ok(false)
-                    } else {
-                        Err(e)
-                    }
-                }
-            }
-        };
-        if read(&p1, v1)? {
-            p2.set_nonblocking(false)?;
-            return p2.read_to_end(v2).map(|_| ());
-        }
-        if read(&p2, v2)? {
-            p1.set_nonblocking(false)?;
-            return p1.read_to_end(v1).map(|_| ());
-        }
-    }
-    */
-}
diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs
deleted file mode 100644
index 8e6f50773ab..00000000000
--- a/src/libstd/sys/redox/process.rs
+++ /dev/null
@@ -1,614 +0,0 @@
-use crate::env::{self, split_paths};
-use crate::ffi::{CStr, OsStr};
-use crate::fmt;
-use crate::fs::File;
-use crate::io::{self, prelude::*, BufReader, Error, ErrorKind, SeekFrom};
-use crate::os::unix::ffi::OsStrExt;
-use crate::path::{Path, PathBuf};
-use crate::ptr;
-use crate::sys::ext::fs::MetadataExt;
-use crate::sys::ext::io::AsRawFd;
-use crate::sys::fd::FileDesc;
-use crate::sys::fs::{File as SysFile, OpenOptions};
-use crate::sys::os::{ENV_LOCK, environ};
-use crate::sys::pipe::{self, AnonPipe};
-use crate::sys::{cvt, syscall};
-use crate::sys_common::process::{CommandEnv, DefaultEnvKey};
-
-use libc::{EXIT_SUCCESS, EXIT_FAILURE};
-
-////////////////////////////////////////////////////////////////////////////////
-// Command
-////////////////////////////////////////////////////////////////////////////////
-
-pub struct Command {
-    // Currently we try hard to ensure that the call to `.exec()` doesn't
-    // actually allocate any memory. While many platforms try to ensure that
-    // memory allocation works after a fork in a multithreaded process, it's
-    // been observed to be buggy and somewhat unreliable, so we do our best to
-    // just not do it at all!
-    //
-    // Along those lines, the `argv` and `envp` raw pointers here are exactly
-    // what's gonna get passed to `execvp`. The `argv` array starts with the
-    // `program` and ends with a NULL, and the `envp` pointer, if present, is
-    // also null-terminated.
-    //
-    // Right now we don't support removing arguments, so there's no much fancy
-    // support there, but we support adding and removing environment variables,
-    // so a side table is used to track where in the `envp` array each key is
-    // located. Whenever we add a key we update it in place if it's already
-    // present, and whenever we remove a key we update the locations of all
-    // other keys.
-    program: String,
-    args: Vec<String>,
-    env: CommandEnv<DefaultEnvKey>,
-
-    cwd: Option<String>,
-    uid: Option<u32>,
-    gid: Option<u32>,
-    saw_nul: bool,
-    closures: Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>>,
-    stdin: Option<Stdio>,
-    stdout: Option<Stdio>,
-    stderr: Option<Stdio>,
-}
-
-// passed back to std::process with the pipes connected to the child, if any
-// were requested
-pub struct StdioPipes {
-    pub stdin: Option<AnonPipe>,
-    pub stdout: Option<AnonPipe>,
-    pub stderr: Option<AnonPipe>,
-}
-
-// passed to do_exec() with configuration of what the child stdio should look
-// like
-struct ChildPipes {
-    stdin: ChildStdio,
-    stdout: ChildStdio,
-    stderr: ChildStdio,
-}
-
-enum ChildStdio {
-    Inherit,
-    Explicit(usize),
-    Owned(FileDesc),
-}
-
-pub enum Stdio {
-    Inherit,
-    Null,
-    MakePipe,
-    Fd(FileDesc),
-}
-
-impl Command {
-    pub fn new(program: &OsStr) -> Command {
-        Command {
-            program: program.to_str().unwrap().to_owned(),
-            args: Vec::new(),
-            env: Default::default(),
-            cwd: None,
-            uid: None,
-            gid: None,
-            saw_nul: false,
-            closures: Vec::new(),
-            stdin: None,
-            stdout: None,
-            stderr: None,
-        }
-    }
-
-    pub fn arg(&mut self, arg: &OsStr) {
-        self.args.push(arg.to_str().unwrap().to_owned());
-    }
-
-    pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
-        &mut self.env
-    }
-
-    pub fn cwd(&mut self, dir: &OsStr) {
-        self.cwd = Some(dir.to_str().unwrap().to_owned());
-    }
-    pub fn uid(&mut self, id: u32) {
-        self.uid = Some(id);
-    }
-    pub fn gid(&mut self, id: u32) {
-        self.gid = Some(id);
-    }
-
-    pub unsafe fn pre_exec(
-        &mut self,
-        f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>,
-    ) {
-        self.closures.push(f);
-    }
-
-    pub fn stdin(&mut self, stdin: Stdio) {
-        self.stdin = Some(stdin);
-    }
-    pub fn stdout(&mut self, stdout: Stdio) {
-        self.stdout = Some(stdout);
-    }
-    pub fn stderr(&mut self, stderr: Stdio) {
-        self.stderr = Some(stderr);
-    }
-
-    pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
-                 -> io::Result<(Process, StdioPipes)> {
-         const CLOEXEC_MSG_FOOTER: &[u8] = b"NOEX";
-
-         if self.saw_nul {
-             return Err(io::Error::new(ErrorKind::InvalidInput,
-                                       "nul byte found in provided data"));
-         }
-
-         let (ours, theirs) = self.setup_io(default, needs_stdin)?;
-         let (input, output) = pipe::anon_pipe()?;
-
-         let pid = unsafe {
-             match cvt(syscall::clone(0))? {
-                 0 => {
-                     drop(input);
-                     let err = self.do_exec(theirs);
-                     let errno = err.raw_os_error().unwrap_or(syscall::EINVAL) as u32;
-                     let bytes = [
-                         (errno >> 24) as u8,
-                         (errno >> 16) as u8,
-                         (errno >>  8) as u8,
-                         (errno >>  0) as u8,
-                         CLOEXEC_MSG_FOOTER[0], CLOEXEC_MSG_FOOTER[1],
-                         CLOEXEC_MSG_FOOTER[2], CLOEXEC_MSG_FOOTER[3]
-                     ];
-                     // pipe I/O up to PIPE_BUF bytes should be atomic, and then
-                     // we want to be sure we *don't* run at_exit destructors as
-                     // we're being torn down regardless
-                     assert!(output.write(&bytes).is_ok());
-                     let _ = syscall::exit(1);
-                     panic!("failed to exit");
-                 }
-                 n => n,
-             }
-         };
-
-         let mut p = Process { pid: pid, status: None };
-         drop(output);
-         let mut bytes = [0; 8];
-
-         // loop to handle EINTR
-         loop {
-             match input.read(&mut bytes) {
-                 Ok(0) => return Ok((p, ours)),
-                 Ok(8) => {
-                     assert!(combine(CLOEXEC_MSG_FOOTER) == combine(&bytes[4.. 8]),
-                             "Validation on the CLOEXEC pipe failed: {:?}", bytes);
-                     let errno = combine(&bytes[0.. 4]);
-                     assert!(p.wait().is_ok(),
-                             "wait() should either return Ok or panic");
-                     return Err(Error::from_raw_os_error(errno))
-                 }
-                 Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
-                 Err(e) => {
-                     assert!(p.wait().is_ok(),
-                             "wait() should either return Ok or panic");
-                     panic!("the CLOEXEC pipe failed: {:?}", e)
-                 },
-                 Ok(..) => { // pipe I/O up to PIPE_BUF bytes should be atomic
-                     assert!(p.wait().is_ok(),
-                             "wait() should either return Ok or panic");
-                     panic!("short read on the CLOEXEC pipe")
-                 }
-             }
-         }
-
-         fn combine(arr: &[u8]) -> i32 {
-             let a = arr[0] as u32;
-             let b = arr[1] as u32;
-             let c = arr[2] as u32;
-             let d = arr[3] as u32;
-
-             ((a << 24) | (b << 16) | (c << 8) | (d << 0)) as i32
-         }
-    }
-
-    pub fn exec(&mut self, default: Stdio) -> io::Error {
-        if self.saw_nul {
-            return io::Error::new(ErrorKind::InvalidInput,
-                                  "nul byte found in provided data")
-        }
-
-        match self.setup_io(default, true) {
-            Ok((_, theirs)) => unsafe { self.do_exec(theirs) },
-            Err(e) => e,
-        }
-    }
-
-    // And at this point we've reached a special time in the life of the
-    // child. The child must now be considered hamstrung and unable to
-    // do anything other than syscalls really. Consider the following
-    // scenario:
-    //
-    //      1. Thread A of process 1 grabs the malloc() mutex
-    //      2. Thread B of process 1 forks(), creating thread C
-    //      3. Thread C of process 2 then attempts to malloc()
-    //      4. The memory of process 2 is the same as the memory of
-    //         process 1, so the mutex is locked.
-    //
-    // This situation looks a lot like deadlock, right? It turns out
-    // that this is what pthread_atfork() takes care of, which is
-    // presumably implemented across platforms. The first thing that
-    // threads to *before* forking is to do things like grab the malloc
-    // mutex, and then after the fork they unlock it.
-    //
-    // Despite this information, libnative's spawn has been witnessed to
-    // deadlock on both macOS and FreeBSD. I'm not entirely sure why, but
-    // all collected backtraces point at malloc/free traffic in the
-    // child spawned process.
-    //
-    // For this reason, the block of code below should contain 0
-    // invocations of either malloc of free (or their related friends).
-    //
-    // As an example of not having malloc/free traffic, we don't close
-    // this file descriptor by dropping the FileDesc (which contains an
-    // allocation). Instead we just close it manually. This will never
-    // have the drop glue anyway because this code never returns (the
-    // child will either exec() or invoke syscall::exit)
-    unsafe fn do_exec(&mut self, stdio: ChildPipes) -> io::Error {
-        macro_rules! t {
-            ($e:expr) => (match $e {
-                Ok(e) => e,
-                Err(e) => return e,
-            })
-        }
-
-        if let Some(fd) = stdio.stderr.fd() {
-            t!(cvt(syscall::dup2(fd, 2, &[])));
-            let mut flags = t!(cvt(syscall::fcntl(2, syscall::F_GETFD, 0)));
-            flags &= ! syscall::O_CLOEXEC;
-            t!(cvt(syscall::fcntl(2, syscall::F_SETFD, flags)));
-        }
-        if let Some(fd) = stdio.stdout.fd() {
-            t!(cvt(syscall::dup2(fd, 1, &[])));
-            let mut flags = t!(cvt(syscall::fcntl(1, syscall::F_GETFD, 0)));
-            flags &= ! syscall::O_CLOEXEC;
-            t!(cvt(syscall::fcntl(1, syscall::F_SETFD, flags)));
-        }
-        if let Some(fd) = stdio.stdin.fd() {
-            t!(cvt(syscall::dup2(fd, 0, &[])));
-            let mut flags = t!(cvt(syscall::fcntl(0, syscall::F_GETFD, 0)));
-            flags &= ! syscall::O_CLOEXEC;
-            t!(cvt(syscall::fcntl(0, syscall::F_SETFD, flags)));
-        }
-
-        if let Some(g) = self.gid {
-            t!(cvt(syscall::setregid(g as usize, g as usize)));
-        }
-        if let Some(u) = self.uid {
-            t!(cvt(syscall::setreuid(u as usize, u as usize)));
-        }
-        if let Some(ref cwd) = self.cwd {
-            t!(cvt(syscall::chdir(cwd)));
-        }
-
-        for callback in self.closures.iter_mut() {
-            t!(callback());
-        }
-
-        self.env.apply();
-
-        let program = if self.program.contains(':') || self.program.contains('/') {
-            Some(PathBuf::from(&self.program))
-        } else if let Ok(path_env) = env::var("PATH") {
-            let mut program = None;
-            for mut path in split_paths(&path_env) {
-                path.push(&self.program);
-                if path.exists() {
-                    program = Some(path);
-                    break;
-                }
-            }
-            program
-        } else {
-            None
-        };
-
-        let mut file = if let Some(program) = program {
-            t!(File::open(program.as_os_str()))
-        } else {
-            return io::Error::from_raw_os_error(syscall::ENOENT);
-        };
-
-        // Push all the arguments
-        let mut args: Vec<[usize; 2]> = Vec::with_capacity(1 + self.args.len());
-
-        let interpreter = {
-            let mut reader = BufReader::new(&file);
-
-            let mut shebang = [0; 2];
-            let mut read = 0;
-            loop {
-                match t!(reader.read(&mut shebang[read..])) {
-                    0 => break,
-                    n => read += n,
-                }
-            }
-
-            if &shebang == b"#!" {
-                // This is an interpreted script.
-                // First of all, since we'll be passing another file to
-                // fexec(), we need to manually check that we have permission
-                // to execute this file:
-                let uid = t!(cvt(syscall::getuid()));
-                let gid = t!(cvt(syscall::getgid()));
-                let meta = t!(file.metadata());
-
-                let mode = if uid == meta.uid() as usize {
-                    meta.mode() >> 3*2 & 0o7
-                } else if gid == meta.gid() as usize {
-                    meta.mode() >> 3*1 & 0o7
-                } else {
-                    meta.mode() & 0o7
-                };
-                if mode & 1 == 0 {
-                    return io::Error::from_raw_os_error(syscall::EPERM);
-                }
-
-                // Second of all, we need to actually read which interpreter it wants
-                let mut interpreter = Vec::new();
-                t!(reader.read_until(b'\n', &mut interpreter));
-                // Pop one trailing newline, if any
-                if interpreter.ends_with(&[b'\n']) {
-                    interpreter.pop().unwrap();
-                }
-
-                // FIXME: Here we could just reassign `file` directly, if it
-                // wasn't for lexical lifetimes. Remove the whole `let
-                // interpreter = { ... };` hack once NLL lands.
-                // NOTE: Although DO REMEMBER to make sure the interpreter path
-                // still lives long enough to reach fexec.
-                Some(interpreter)
-            } else {
-                None
-            }
-        };
-        if let Some(ref interpreter) = interpreter {
-            let path: &OsStr = OsStr::from_bytes(&interpreter);
-            file = t!(File::open(path));
-
-            args.push([interpreter.as_ptr() as usize, interpreter.len()]);
-        } else {
-            t!(file.seek(SeekFrom::Start(0)));
-        }
-
-        args.push([self.program.as_ptr() as usize, self.program.len()]);
-        args.extend(self.args.iter().map(|arg| [arg.as_ptr() as usize, arg.len()]));
-
-        // Push all the variables
-        let mut vars: Vec<[usize; 2]> = Vec::new();
-        {
-            let _guard = ENV_LOCK.lock();
-            let mut environ = *environ();
-            while *environ != ptr::null() {
-                let var = CStr::from_ptr(*environ).to_bytes();
-                vars.push([var.as_ptr() as usize, var.len()]);
-                environ = environ.offset(1);
-            }
-        }
-
-        if let Err(err) = syscall::fexec(file.as_raw_fd(), &args, &vars) {
-            io::Error::from_raw_os_error(err.errno as i32)
-        } else {
-            panic!("return from exec without err");
-        }
-    }
-
-
-    fn setup_io(&self, default: Stdio, needs_stdin: bool)
-                -> io::Result<(StdioPipes, ChildPipes)> {
-        let null = Stdio::Null;
-        let default_stdin = if needs_stdin {&default} else {&null};
-        let stdin = self.stdin.as_ref().unwrap_or(default_stdin);
-        let stdout = self.stdout.as_ref().unwrap_or(&default);
-        let stderr = self.stderr.as_ref().unwrap_or(&default);
-        let (their_stdin, our_stdin) = stdin.to_child_stdio(true)?;
-        let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?;
-        let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?;
-        let ours = StdioPipes {
-            stdin: our_stdin,
-            stdout: our_stdout,
-            stderr: our_stderr,
-        };
-        let theirs = ChildPipes {
-            stdin: their_stdin,
-            stdout: their_stdout,
-            stderr: their_stderr,
-        };
-        Ok((ours, theirs))
-    }
-}
-
-impl Stdio {
-    fn to_child_stdio(&self, readable: bool)
-                      -> io::Result<(ChildStdio, Option<AnonPipe>)> {
-        match *self {
-            Stdio::Inherit => Ok((ChildStdio::Inherit, None)),
-
-            // Make sure that the source descriptors are not an stdio
-            // descriptor, otherwise the order which we set the child's
-            // descriptors may blow away a descriptor which we are hoping to
-            // save. For example, suppose we want the child's stderr to be the
-            // parent's stdout, and the child's stdout to be the parent's
-            // stderr. No matter which we dup first, the second will get
-            // overwritten prematurely.
-            Stdio::Fd(ref fd) => {
-                if fd.raw() <= 2 {
-                    Ok((ChildStdio::Owned(fd.duplicate()?), None))
-                } else {
-                    Ok((ChildStdio::Explicit(fd.raw()), None))
-                }
-            }
-
-            Stdio::MakePipe => {
-                let (reader, writer) = pipe::anon_pipe()?;
-                let (ours, theirs) = if readable {
-                    (writer, reader)
-                } else {
-                    (reader, writer)
-                };
-                Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours)))
-            }
-
-            Stdio::Null => {
-                let mut opts = OpenOptions::new();
-                opts.read(readable);
-                opts.write(!readable);
-                let fd = SysFile::open(Path::new("null:"), &opts)?;
-                Ok((ChildStdio::Owned(fd.into_fd()), None))
-            }
-        }
-    }
-}
-
-impl From<AnonPipe> for Stdio {
-    fn from(pipe: AnonPipe) -> Stdio {
-        Stdio::Fd(pipe.into_fd())
-    }
-}
-
-impl From<SysFile> for Stdio {
-    fn from(file: SysFile) -> Stdio {
-        Stdio::Fd(file.into_fd())
-    }
-}
-
-impl ChildStdio {
-    fn fd(&self) -> Option<usize> {
-        match *self {
-            ChildStdio::Inherit => None,
-            ChildStdio::Explicit(fd) => Some(fd),
-            ChildStdio::Owned(ref fd) => Some(fd.raw()),
-        }
-    }
-}
-
-impl fmt::Debug for Command {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{:?}", self.program)?;
-        for arg in &self.args {
-            write!(f, " {:?}", arg)?;
-        }
-        Ok(())
-    }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Processes
-////////////////////////////////////////////////////////////////////////////////
-
-/// Unix exit statuses
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitStatus(i32);
-
-impl ExitStatus {
-    fn exited(&self) -> bool {
-        self.0 & 0x7F == 0
-    }
-
-    pub fn success(&self) -> bool {
-        self.code() == Some(0)
-    }
-
-    pub fn code(&self) -> Option<i32> {
-        if self.exited() {
-            Some((self.0 >> 8) & 0xFF)
-        } else {
-            None
-        }
-    }
-
-    pub fn signal(&self) -> Option<i32> {
-        if !self.exited() {
-            Some(self.0 & 0x7F)
-        } else {
-            None
-        }
-    }
-}
-
-impl From<i32> for ExitStatus {
-    fn from(a: i32) -> ExitStatus {
-        ExitStatus(a)
-    }
-}
-
-impl fmt::Display for ExitStatus {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if let Some(code) = self.code() {
-            write!(f, "exit code: {}", code)
-        } else {
-            let signal = self.signal().unwrap();
-            write!(f, "signal: {}", signal)
-        }
-    }
-}
-
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitCode(u8);
-
-impl ExitCode {
-    pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
-    pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);
-
-    pub fn as_i32(&self) -> i32 {
-        self.0 as i32
-    }
-}
-
-/// The unique ID of the process (this should never be negative).
-pub struct Process {
-    pid: usize,
-    status: Option<ExitStatus>,
-}
-
-impl Process {
-    pub fn id(&self) -> u32 {
-        self.pid as u32
-    }
-
-    pub fn kill(&mut self) -> io::Result<()> {
-        // If we've already waited on this process then the pid can be recycled
-        // and used for another process, and we probably shouldn't be killing
-        // random processes, so just return an error.
-        if self.status.is_some() {
-            Err(Error::new(ErrorKind::InvalidInput,
-                           "invalid argument: can't kill an exited process"))
-        } else {
-            cvt(syscall::kill(self.pid, syscall::SIGKILL))?;
-            Ok(())
-        }
-    }
-
-    pub fn wait(&mut self) -> io::Result<ExitStatus> {
-        if let Some(status) = self.status {
-            return Ok(status)
-        }
-        let mut status = 0;
-        cvt(syscall::waitpid(self.pid, &mut status, 0))?;
-        self.status = Some(ExitStatus(status as i32));
-        Ok(ExitStatus(status as i32))
-    }
-
-    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
-        if let Some(status) = self.status {
-            return Ok(Some(status))
-        }
-        let mut status = 0;
-        let pid = cvt(syscall::waitpid(self.pid, &mut status, syscall::WNOHANG))?;
-        if pid == 0 {
-            Ok(None)
-        } else {
-            self.status = Some(ExitStatus(status as i32));
-            Ok(Some(ExitStatus(status as i32)))
-        }
-    }
-}
diff --git a/src/libstd/sys/redox/rand.rs b/src/libstd/sys/redox/rand.rs
deleted file mode 100644
index 5b58d1782bf..00000000000
--- a/src/libstd/sys/redox/rand.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-pub fn hashmap_random_keys() -> (u64, u64) {
-    (0, 0)
-}
diff --git a/src/libstd/sys/redox/rwlock.rs b/src/libstd/sys/redox/rwlock.rs
deleted file mode 100644
index 990e7551114..00000000000
--- a/src/libstd/sys/redox/rwlock.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-use super::mutex::Mutex;
-
-pub struct RWLock {
-    mutex: Mutex
-}
-
-unsafe impl Send for RWLock {}
-unsafe impl Sync for RWLock {}
-
-impl RWLock {
-    pub const fn new() -> RWLock {
-        RWLock {
-            mutex: Mutex::new()
-        }
-    }
-
-    #[inline]
-    pub unsafe fn read(&self) {
-        self.mutex.lock();
-    }
-
-    #[inline]
-    pub unsafe fn try_read(&self) -> bool {
-        self.mutex.try_lock()
-    }
-
-    #[inline]
-    pub unsafe fn write(&self) {
-        self.mutex.lock();
-    }
-
-    #[inline]
-    pub unsafe fn try_write(&self) -> bool {
-        self.mutex.try_lock()
-    }
-
-    #[inline]
-    pub unsafe fn read_unlock(&self) {
-        self.mutex.unlock();
-    }
-
-    #[inline]
-    pub unsafe fn write_unlock(&self) {
-        self.mutex.unlock();
-    }
-
-    #[inline]
-    pub unsafe fn destroy(&self) {
-        self.mutex.destroy();
-    }
-}
diff --git a/src/libstd/sys/redox/syscall/arch/arm.rs b/src/libstd/sys/redox/syscall/arch/arm.rs
deleted file mode 100644
index e640f7ed376..00000000000
--- a/src/libstd/sys/redox/syscall/arch/arm.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-use super::error::{Error, Result};
-
-pub unsafe fn syscall0(mut a: usize) -> Result<usize> {
-    asm!("swi $$0"
-        : "={r0}"(a)
-        : "{r7}"(a)
-        : "memory"
-        : "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall1(mut a: usize, b: usize) -> Result<usize> {
-    asm!("swi $$0"
-        : "={r0}"(a)
-        : "{r7}"(a), "{r0}"(b)
-        : "memory"
-        : "volatile");
-
-    Error::demux(a)
-}
-
-// Clobbers all registers - special for clone
-pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result<usize> {
-    asm!("swi $$0"
-        : "={r0}"(a)
-        : "{r7}"(a), "{r0}"(b)
-        : "memory", "r0", "r1", "r2", "r3", "r4"
-        : "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result<usize> {
-    asm!("swi $$0"
-        : "={r0}"(a)
-        : "{r7}"(a), "{r0}"(b), "{r1}"(c)
-        : "memory"
-        : "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result<usize> {
-    asm!("swi $$0"
-        : "={r0}"(a)
-        : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d)
-        : "memory"
-        : "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result<usize> {
-    asm!("swi $$0"
-        : "={r0}"(a)
-        : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d), "{r3}"(e)
-        : "memory"
-        : "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize)
-                       -> Result<usize> {
-    asm!("swi $$0"
-        : "={r0}"(a)
-        : "{r7}"(a), "{r0}"(b), "{r1}"(c), "{r2}"(d), "{r3}"(e), "{r4}"(f)
-        : "memory"
-        : "volatile");
-
-    Error::demux(a)
-}
diff --git a/src/libstd/sys/redox/syscall/arch/x86.rs b/src/libstd/sys/redox/syscall/arch/x86.rs
deleted file mode 100644
index 0cd6409bb06..00000000000
--- a/src/libstd/sys/redox/syscall/arch/x86.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-use super::error::{Error, Result};
-
-pub unsafe fn syscall0(mut a: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={eax}"(a)
-        : "{eax}"(a)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall1(mut a: usize, b: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={eax}"(a)
-        : "{eax}"(a), "{ebx}"(b)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-// Clobbers all registers - special for clone
-pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={eax}"(a)
-        : "{eax}"(a), "{ebx}"(b)
-        : "memory", "ebx", "ecx", "edx", "esi", "edi"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={eax}"(a)
-        : "{eax}"(a), "{ebx}"(b), "{ecx}"(c)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={eax}"(a)
-        : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={eax}"(a)
-        : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d), "{esi}"(e)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize)
-                       -> Result<usize> {
-    asm!("int 0x80"
-        : "={eax}"(a)
-        : "{eax}"(a), "{ebx}"(b), "{ecx}"(c), "{edx}"(d), "{esi}"(e), "{edi}"(f)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
diff --git a/src/libstd/sys/redox/syscall/arch/x86_64.rs b/src/libstd/sys/redox/syscall/arch/x86_64.rs
deleted file mode 100644
index 52ad01bd4a8..00000000000
--- a/src/libstd/sys/redox/syscall/arch/x86_64.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-use super::error::{Error, Result};
-
-pub unsafe fn syscall0(mut a: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={rax}"(a)
-        : "{rax}"(a)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall1(mut a: usize, b: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={rax}"(a)
-        : "{rax}"(a), "{rbx}"(b)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-// Clobbers all registers - special for clone
-pub unsafe fn syscall1_clobber(mut a: usize, b: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={rax}"(a)
-        : "{rax}"(a), "{rbx}"(b)
-        : "memory", "rbx", "rcx", "rdx", "rsi", "rdi", "r8",
-          "r9", "r10", "r11", "r12", "r13", "r14", "r15"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall2(mut a: usize, b: usize, c: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={rax}"(a)
-        : "{rax}"(a), "{rbx}"(b), "{rcx}"(c)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall3(mut a: usize, b: usize, c: usize, d: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={rax}"(a)
-        : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall4(mut a: usize, b: usize, c: usize, d: usize, e: usize) -> Result<usize> {
-    asm!("int 0x80"
-        : "={rax}"(a)
-        : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d), "{rsi}"(e)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
-
-pub unsafe fn syscall5(mut a: usize, b: usize, c: usize, d: usize, e: usize, f: usize)
-                       -> Result<usize> {
-    asm!("int 0x80"
-        : "={rax}"(a)
-        : "{rax}"(a), "{rbx}"(b), "{rcx}"(c), "{rdx}"(d), "{rsi}"(e), "{rdi}"(f)
-        : "memory"
-        : "intel", "volatile");
-
-    Error::demux(a)
-}
diff --git a/src/libstd/sys/redox/syscall/call.rs b/src/libstd/sys/redox/syscall/call.rs
deleted file mode 100644
index b9abb48a8d3..00000000000
--- a/src/libstd/sys/redox/syscall/call.rs
+++ /dev/null
@@ -1,348 +0,0 @@
-use super::arch::*;
-use super::data::{SigAction, Stat, StatVfs, TimeSpec};
-use super::error::Result;
-use super::number::*;
-
-use core::{mem, ptr};
-
-// Signal restorer
-extern "C" fn restorer() -> ! {
-    sigreturn().unwrap();
-    unreachable!();
-}
-
-/// Set the end of the process's heap
-///
-/// When `addr` is `0`, this function will return the current break.
-///
-/// When `addr` is nonzero, this function will attempt to set the end of the process's
-/// heap to `addr` and return the new program break. The new program break should be
-/// checked by the allocator, it may not be exactly `addr`, as it may be aligned to a page
-/// boundary.
-///
-/// On error, `Err(ENOMEM)` will be returned indicating that no memory is available
-pub unsafe fn brk(addr: usize) -> Result<usize> {
-    syscall1(SYS_BRK, addr)
-}
-
-/// Changes the process's working directory.
-///
-/// This function will attempt to set the process's working directory to `path`, which can be
-/// either a relative, scheme relative, or absolute path.
-///
-/// On success, `Ok(0)` will be returned. On error, one of the following errors will be returned.
-///
-/// # Errors
-///
-/// * `EACCES` - permission is denied for one of the components of `path`, or `path`
-/// * `EFAULT` - `path` does not point to the process's addressable memory
-/// * `EIO` - an I/O error occurred
-/// * `ENOENT` - `path` does not exit
-/// * `ENOTDIR` - `path` is not a directory
-pub fn chdir<T: AsRef<[u8]>>(path: T) -> Result<usize> {
-    unsafe { syscall2(SYS_CHDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) }
-}
-
-pub fn chmod<T: AsRef<[u8]>>(path: T, mode: usize) -> Result<usize> {
-    unsafe { syscall3(SYS_CHMOD, path.as_ref().as_ptr() as usize, path.as_ref().len(), mode) }
-}
-
-/// Produces a fork of the current process, or a new process thread.
-pub unsafe fn clone(flags: usize) -> Result<usize> {
-    syscall1_clobber(SYS_CLONE, flags)
-}
-
-/// Closes a file.
-pub fn close(fd: usize) -> Result<usize> {
-    unsafe { syscall1(SYS_CLOSE, fd) }
-}
-
-/// Gets the current system time.
-pub fn clock_gettime(clock: usize, tp: &mut TimeSpec) -> Result<usize> {
-    unsafe { syscall2(SYS_CLOCK_GETTIME, clock, tp as *mut TimeSpec as usize) }
-}
-
-/// Copies and transforms a file descriptor.
-pub fn dup(fd: usize, buf: &[u8]) -> Result<usize> {
-    unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) }
-}
-
-/// Copies and transforms a file descriptor.
-pub fn dup2(fd: usize, newfd: usize, buf: &[u8]) -> Result<usize> {
-    unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) }
-}
-
-/// Exits the current process.
-pub fn exit(status: usize) -> Result<usize> {
-    unsafe { syscall1(SYS_EXIT, status) }
-}
-
-/// Changes file permissions.
-pub fn fchmod(fd: usize, mode: u16) -> Result<usize> {
-    unsafe { syscall2(SYS_FCHMOD, fd, mode as usize) }
-
-}
-
-/// Changes file ownership.
-pub fn fchown(fd: usize, uid: u32, gid: u32) -> Result<usize> {
-    unsafe { syscall3(SYS_FCHOWN, fd, uid as usize, gid as usize) }
-
-}
-
-/// Changes file descriptor flags.
-pub fn fcntl(fd: usize, cmd: usize, arg: usize) -> Result<usize> {
-    unsafe { syscall3(SYS_FCNTL, fd, cmd, arg) }
-}
-
-/// Replaces the current process with a new executable.
-pub fn fexec(fd: usize, args: &[[usize; 2]], vars: &[[usize; 2]]) -> Result<usize> {
-    unsafe { syscall5(SYS_FEXEC, fd, args.as_ptr() as usize, args.len(),
-                      vars.as_ptr() as usize, vars.len()) }
-}
-
-/// Maps a file into memory.
-pub unsafe fn fmap(fd: usize, offset: usize, size: usize) -> Result<usize> {
-    syscall3(SYS_FMAP, fd, offset, size)
-}
-
-/// Unmaps a memory-mapped file.
-pub unsafe fn funmap(addr: usize) -> Result<usize> {
-    syscall1(SYS_FUNMAP, addr)
-}
-
-/// Retrieves the canonical path of a file.
-pub fn fpath(fd: usize, buf: &mut [u8]) -> Result<usize> {
-    unsafe { syscall3(SYS_FPATH, fd, buf.as_mut_ptr() as usize, buf.len()) }
-}
-
-/// Renames a file.
-pub fn frename<T: AsRef<[u8]>>(fd: usize, path: T) -> Result<usize> {
-    unsafe { syscall3(SYS_FRENAME, fd, path.as_ref().as_ptr() as usize, path.as_ref().len()) }
-}
-
-/// Gets metadata about a file.
-pub fn fstat(fd: usize, stat: &mut Stat) -> Result<usize> {
-    unsafe { syscall3(SYS_FSTAT, fd, stat as *mut Stat as usize, mem::size_of::<Stat>()) }
-}
-
-/// Gets metadata about a filesystem.
-pub fn fstatvfs(fd: usize, stat: &mut StatVfs) -> Result<usize> {
-    unsafe { syscall3(SYS_FSTATVFS, fd, stat as *mut StatVfs as usize, mem::size_of::<StatVfs>()) }
-}
-
-/// Syncs a file descriptor to its underlying medium.
-pub fn fsync(fd: usize) -> Result<usize> {
-    unsafe { syscall1(SYS_FSYNC, fd) }
-}
-
-/// Truncate or extend a file to a specified length
-pub fn ftruncate(fd: usize, len: usize) -> Result<usize> {
-    unsafe { syscall2(SYS_FTRUNCATE, fd, len) }
-}
-
-// Change modify and/or access times
-pub fn futimens(fd: usize, times: &[TimeSpec]) -> Result<usize> {
-    unsafe { syscall3(SYS_FUTIMENS, fd, times.as_ptr() as usize,
-                      times.len() * mem::size_of::<TimeSpec>()) }
-}
-
-/// Fast userspace mutex
-pub unsafe fn futex(addr: *mut i32, op: usize, val: i32, val2: usize, addr2: *mut i32)
-                    -> Result<usize> {
-    syscall5(SYS_FUTEX, addr as usize, op, (val as isize) as usize, val2, addr2 as usize)
-}
-
-/// Gets the current working directory.
-pub fn getcwd(buf: &mut [u8]) -> Result<usize> {
-    unsafe { syscall2(SYS_GETCWD, buf.as_mut_ptr() as usize, buf.len()) }
-}
-
-/// Gets the effective group ID.
-pub fn getegid() -> Result<usize> {
-    unsafe { syscall0(SYS_GETEGID) }
-}
-
-/// Gets the effective namespace.
-pub fn getens() -> Result<usize> {
-    unsafe { syscall0(SYS_GETENS) }
-}
-
-/// Gets the effective user ID.
-pub fn geteuid() -> Result<usize> {
-    unsafe { syscall0(SYS_GETEUID) }
-}
-
-/// Gets the current group ID.
-pub fn getgid() -> Result<usize> {
-    unsafe { syscall0(SYS_GETGID) }
-}
-
-/// Gets the current namespace.
-pub fn getns() -> Result<usize> {
-    unsafe { syscall0(SYS_GETNS) }
-}
-
-/// Gets the current process ID.
-pub fn getpid() -> Result<usize> {
-    unsafe { syscall0(SYS_GETPID) }
-}
-
-/// Gets the process group ID.
-pub fn getpgid(pid: usize) -> Result<usize> {
-    unsafe { syscall1(SYS_GETPGID, pid) }
-}
-
-/// Gets the parent process ID.
-pub fn getppid() -> Result<usize> {
-    unsafe { syscall0(SYS_GETPPID) }
-}
-
-/// Gets the current user ID.
-pub fn getuid() -> Result<usize> {
-    unsafe { syscall0(SYS_GETUID) }
-}
-
-/// Sets the I/O privilege level
-pub unsafe fn iopl(level: usize) -> Result<usize> {
-    syscall1(SYS_IOPL, level)
-}
-
-/// Sends a signal `sig` to the process identified by `pid`.
-pub fn kill(pid: usize, sig: usize) -> Result<usize> {
-    unsafe { syscall2(SYS_KILL, pid, sig) }
-}
-
-/// Creates a link to a file.
-pub unsafe fn link(old: *const u8, new: *const u8) -> Result<usize> {
-    syscall2(SYS_LINK, old as usize, new as usize)
-}
-
-/// Seeks to `offset` bytes in a file descriptor.
-pub fn lseek(fd: usize, offset: isize, whence: usize) -> Result<usize> {
-    unsafe { syscall3(SYS_LSEEK, fd, offset as usize, whence) }
-}
-
-/// Makes a new scheme namespace.
-pub fn mkns(schemes: &[[usize; 2]]) -> Result<usize> {
-    unsafe { syscall2(SYS_MKNS, schemes.as_ptr() as usize, schemes.len()) }
-}
-
-/// Sleeps for the time specified in `req`.
-pub fn nanosleep(req: &TimeSpec, rem: &mut TimeSpec) -> Result<usize> {
-    unsafe { syscall2(SYS_NANOSLEEP, req as *const TimeSpec as usize,
-                                     rem as *mut TimeSpec as usize) }
-}
-
-/// Opens a file.
-pub fn open<T: AsRef<[u8]>>(path: T, flags: usize) -> Result<usize> {
-    unsafe { syscall3(SYS_OPEN, path.as_ref().as_ptr() as usize, path.as_ref().len(), flags) }
-}
-
-/// Allocates pages, linearly in physical memory.
-pub unsafe fn physalloc(size: usize) -> Result<usize> {
-    syscall1(SYS_PHYSALLOC, size)
-}
-
-/// Frees physically allocated pages.
-pub unsafe fn physfree(physical_address: usize, size: usize) -> Result<usize> {
-    syscall2(SYS_PHYSFREE, physical_address, size)
-}
-
-/// Maps physical memory to virtual memory.
-pub unsafe fn physmap(physical_address: usize, size: usize, flags: usize) -> Result<usize> {
-    syscall3(SYS_PHYSMAP, physical_address, size, flags)
-}
-
-/// Unmaps previously mapped physical memory.
-pub unsafe fn physunmap(virtual_address: usize) -> Result<usize> {
-    syscall1(SYS_PHYSUNMAP, virtual_address)
-}
-
-/// Creates a pair of file descriptors referencing the read and write ends of a pipe.
-pub fn pipe2(fds: &mut [usize; 2], flags: usize) -> Result<usize> {
-    unsafe { syscall2(SYS_PIPE2, fds.as_ptr() as usize, flags) }
-}
-
-/// Read from a file descriptor into a buffer
-pub fn read(fd: usize, buf: &mut [u8]) -> Result<usize> {
-    unsafe { syscall3(SYS_READ, fd, buf.as_mut_ptr() as usize, buf.len()) }
-}
-
-/// Removes a directory.
-pub fn rmdir<T: AsRef<[u8]>>(path: T) -> Result<usize> {
-    unsafe { syscall2(SYS_RMDIR, path.as_ref().as_ptr() as usize, path.as_ref().len()) }
-}
-
-/// Sets the process group ID.
-pub fn setpgid(pid: usize, pgid: usize) -> Result<usize> {
-    unsafe { syscall2(SYS_SETPGID, pid, pgid) }
-}
-
-/// Sets the current process group IDs.
-pub fn setregid(rgid: usize, egid: usize) -> Result<usize> {
-    unsafe { syscall2(SYS_SETREGID, rgid, egid) }
-}
-
-/// Makes a new scheme namespace.
-pub fn setrens(rns: usize, ens: usize) -> Result<usize> {
-    unsafe { syscall2(SYS_SETRENS, rns, ens) }
-}
-
-/// Sets the current process user IDs.
-pub fn setreuid(ruid: usize, euid: usize) -> Result<usize> {
-    unsafe { syscall2(SYS_SETREUID, ruid, euid) }
-}
-
-/// Sets up a signal handler.
-pub fn sigaction(sig: usize, act: Option<&SigAction>, oldact: Option<&mut SigAction>)
--> Result<usize> {
-    unsafe { syscall4(SYS_SIGACTION, sig,
-                      act.map(|x| x as *const _).unwrap_or_else(ptr::null) as usize,
-                      oldact.map(|x| x as *mut _).unwrap_or_else(ptr::null_mut) as usize,
-                      restorer as usize) }
-}
-
-/// Returns from signal handler.
-pub fn sigreturn() -> Result<usize> {
-    unsafe { syscall0(SYS_SIGRETURN) }
-}
-
-/// Removes a file.
-pub fn unlink<T: AsRef<[u8]>>(path: T) -> Result<usize> {
-    unsafe { syscall2(SYS_UNLINK, path.as_ref().as_ptr() as usize, path.as_ref().len()) }
-}
-
-/// Converts a virtual address to a physical one.
-pub unsafe fn virttophys(virtual_address: usize) -> Result<usize> {
-    syscall1(SYS_VIRTTOPHYS, virtual_address)
-}
-
-/// Checks if a child process has exited or received a signal.
-pub fn waitpid(pid: usize, status: &mut usize, options: usize) -> Result<usize> {
-    unsafe { syscall3(SYS_WAITPID, pid, status as *mut usize as usize, options) }
-}
-
-/// Writes a buffer to a file descriptor.
-///
-/// The kernel will attempt to write the bytes in `buf` to the file descriptor `fd`, returning
-/// either an `Err`, explained below, or `Ok(count)` where `count` is the number of bytes which
-/// were written.
-///
-/// # Errors
-///
-/// * `EAGAIN` - the file descriptor was opened with `O_NONBLOCK` and writing would block
-/// * `EBADF` - the file descriptor is not valid or is not open for writing
-/// * `EFAULT` - `buf` does not point to the process's addressable memory
-/// * `EIO` - an I/O error occurred
-/// * `ENOSPC` - the device containing the file descriptor has no room for data
-/// * `EPIPE` - the file descriptor refers to a pipe or socket whose reading end is closed
-pub fn write(fd: usize, buf: &[u8]) -> Result<usize> {
-    unsafe { syscall3(SYS_WRITE, fd, buf.as_ptr() as usize, buf.len()) }
-}
-
-/// Yields the process's time slice to the kernel.
-///
-/// This function will return Ok(0) on success
-pub fn sched_yield() -> Result<usize> {
-    unsafe { syscall0(SYS_YIELD) }
-}
diff --git a/src/libstd/sys/redox/syscall/data.rs b/src/libstd/sys/redox/syscall/data.rs
deleted file mode 100644
index 0b458ea89b8..00000000000
--- a/src/libstd/sys/redox/syscall/data.rs
+++ /dev/null
@@ -1,191 +0,0 @@
-use core::ops::{Deref, DerefMut};
-use core::{mem, slice};
-
-#[derive(Copy, Clone, Debug, Default)]
-pub struct Event {
-    pub id: usize,
-    pub flags: usize,
-    pub data: usize
-}
-
-impl Deref for Event {
-    type Target = [u8];
-    fn deref(&self) -> &[u8] {
-        unsafe {
-            slice::from_raw_parts(
-                self as *const Event as *const u8,
-                mem::size_of::<Event>()
-            ) as &[u8]
-        }
-    }
-}
-
-impl DerefMut for Event {
-    fn deref_mut(&mut self) -> &mut [u8] {
-        unsafe {
-            slice::from_raw_parts_mut(
-                self as *mut Event as *mut u8,
-                mem::size_of::<Event>()
-            ) as &mut [u8]
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug, Default)]
-#[repr(C)]
-pub struct Packet {
-    pub id: u64,
-    pub pid: usize,
-    pub uid: u32,
-    pub gid: u32,
-    pub a: usize,
-    pub b: usize,
-    pub c: usize,
-    pub d: usize
-}
-
-impl Deref for Packet {
-    type Target = [u8];
-    fn deref(&self) -> &[u8] {
-        unsafe {
-            slice::from_raw_parts(
-                self as *const Packet as *const u8,
-                mem::size_of::<Packet>()
-            ) as &[u8]
-        }
-    }
-}
-
-impl DerefMut for Packet {
-    fn deref_mut(&mut self) -> &mut [u8] {
-        unsafe {
-            slice::from_raw_parts_mut(
-                self as *mut Packet as *mut u8,
-                mem::size_of::<Packet>()
-            ) as &mut [u8]
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug)]
-#[repr(C)]
-pub struct SigAction {
-    pub sa_handler: extern "C" fn(usize),
-    pub sa_mask: [u64; 2],
-    pub sa_flags: usize,
-}
-
-impl Default for SigAction {
-    fn default() -> Self {
-        Self {
-            sa_handler: unsafe { mem::transmute(0usize) },
-            sa_mask: [0; 2],
-            sa_flags: 0,
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug, Default)]
-#[repr(C)]
-pub struct Stat {
-    pub st_dev: u64,
-    pub st_ino: u64,
-    pub st_mode: u16,
-    pub st_nlink: u32,
-    pub st_uid: u32,
-    pub st_gid: u32,
-    pub st_size: u64,
-    pub st_blksize: u32,
-    pub st_blocks: u64,
-    pub st_mtime: u64,
-    pub st_mtime_nsec: u32,
-    pub st_atime: u64,
-    pub st_atime_nsec: u32,
-    pub st_ctime: u64,
-    pub st_ctime_nsec: u32,
-}
-
-impl Deref for Stat {
-    type Target = [u8];
-    fn deref(&self) -> &[u8] {
-        unsafe {
-            slice::from_raw_parts(
-                self as *const Stat as *const u8,
-                mem::size_of::<Stat>()
-            ) as &[u8]
-        }
-    }
-}
-
-impl DerefMut for Stat {
-    fn deref_mut(&mut self) -> &mut [u8] {
-        unsafe {
-            slice::from_raw_parts_mut(
-                self as *mut Stat as *mut u8,
-                mem::size_of::<Stat>()
-            ) as &mut [u8]
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug, Default)]
-#[repr(C)]
-pub struct StatVfs {
-    pub f_bsize: u32,
-    pub f_blocks: u64,
-    pub f_bfree: u64,
-    pub f_bavail: u64,
-}
-
-impl Deref for StatVfs {
-    type Target = [u8];
-    fn deref(&self) -> &[u8] {
-        unsafe {
-            slice::from_raw_parts(
-                self as *const StatVfs as *const u8,
-                mem::size_of::<StatVfs>()
-            ) as &[u8]
-        }
-    }
-}
-
-impl DerefMut for StatVfs {
-    fn deref_mut(&mut self) -> &mut [u8] {
-        unsafe {
-            slice::from_raw_parts_mut(
-                self as *mut StatVfs as *mut u8,
-                mem::size_of::<StatVfs>()
-            ) as &mut [u8]
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug, Default)]
-#[repr(C)]
-pub struct TimeSpec {
-    pub tv_sec: i64,
-    pub tv_nsec: i32,
-}
-
-impl Deref for TimeSpec {
-    type Target = [u8];
-    fn deref(&self) -> &[u8] {
-        unsafe {
-            slice::from_raw_parts(
-                self as *const TimeSpec as *const u8,
-                mem::size_of::<TimeSpec>()
-            ) as &[u8]
-        }
-    }
-}
-
-impl DerefMut for TimeSpec {
-    fn deref_mut(&mut self) -> &mut [u8] {
-        unsafe {
-            slice::from_raw_parts_mut(
-                self as *mut TimeSpec as *mut u8,
-                mem::size_of::<TimeSpec>()
-            ) as &mut [u8]
-        }
-    }
-}
diff --git a/src/libstd/sys/redox/syscall/error.rs b/src/libstd/sys/redox/syscall/error.rs
deleted file mode 100644
index da84ffb0423..00000000000
--- a/src/libstd/sys/redox/syscall/error.rs
+++ /dev/null
@@ -1,315 +0,0 @@
-use core::{fmt, result};
-
-#[derive(Eq, PartialEq)]
-pub struct Error {
-    pub errno: i32,
-}
-
-pub type Result<T> = result::Result<T, Error>;
-
-impl Error {
-    pub fn new(errno: i32) -> Error {
-        Error { errno }
-    }
-
-    pub fn mux(result: Result<usize>) -> usize {
-        match result {
-            Ok(value) => value,
-            Err(error) => -error.errno as usize,
-        }
-    }
-
-    pub fn demux(value: usize) -> Result<usize> {
-        let errno = -(value as i32);
-        if errno >= 1 && errno < STR_ERROR.len() as i32 {
-            Err(Error::new(errno))
-        } else {
-            Ok(value)
-        }
-    }
-
-    pub fn text(&self) -> &str {
-        if let Some(description) = STR_ERROR.get(self.errno as usize) {
-            description
-        } else {
-            "Unknown Error"
-        }
-    }
-}
-
-impl fmt::Debug for Error {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(self.text())
-    }
-}
-
-impl fmt::Display for Error {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(self.text())
-    }
-}
-
-pub const EPERM: i32 = 1;  /* Operation not permitted */
-pub const ENOENT: i32 = 2;  /* No such file or directory */
-pub const ESRCH: i32 = 3;  /* No such process */
-pub const EINTR: i32 = 4;  /* Interrupted system call */
-pub const EIO: i32 = 5;  /* I/O error */
-pub const ENXIO: i32 = 6;  /* No such device or address */
-pub const E2BIG: i32 = 7;  /* Argument list too long */
-pub const ENOEXEC: i32 = 8;  /* Exec format error */
-pub const EBADF: i32 = 9;  /* Bad file number */
-pub const ECHILD: i32 = 10;  /* No child processes */
-pub const EAGAIN: i32 = 11;  /* Try again */
-pub const ENOMEM: i32 = 12;  /* Out of memory */
-pub const EACCES: i32 = 13;  /* Permission denied */
-pub const EFAULT: i32 = 14;  /* Bad address */
-pub const ENOTBLK: i32 = 15;  /* Block device required */
-pub const EBUSY: i32 = 16;  /* Device or resource busy */
-pub const EEXIST: i32 = 17;  /* File exists */
-pub const EXDEV: i32 = 18;  /* Cross-device link */
-pub const ENODEV: i32 = 19;  /* No such device */
-pub const ENOTDIR: i32 = 20;  /* Not a directory */
-pub const EISDIR: i32 = 21;  /* Is a directory */
-pub const EINVAL: i32 = 22;  /* Invalid argument */
-pub const ENFILE: i32 = 23;  /* File table overflow */
-pub const EMFILE: i32 = 24;  /* Too many open files */
-pub const ENOTTY: i32 = 25;  /* Not a typewriter */
-pub const ETXTBSY: i32 = 26;  /* Text file busy */
-pub const EFBIG: i32 = 27;  /* File too large */
-pub const ENOSPC: i32 = 28;  /* No space left on device */
-pub const ESPIPE: i32 = 29;  /* Illegal seek */
-pub const EROFS: i32 = 30;  /* Read-only file system */
-pub const EMLINK: i32 = 31;  /* Too many links */
-pub const EPIPE: i32 = 32;  /* Broken pipe */
-pub const EDOM: i32 = 33;  /* Math argument out of domain of func */
-pub const ERANGE: i32 = 34;  /* Math result not representable */
-pub const EDEADLK: i32 = 35;  /* Resource deadlock would occur */
-pub const ENAMETOOLONG: i32 = 36;  /* File name too long */
-pub const ENOLCK: i32 = 37;  /* No record locks available */
-pub const ENOSYS: i32 = 38;  /* Function not implemented */
-pub const ENOTEMPTY: i32 = 39;  /* Directory not empty */
-pub const ELOOP: i32 = 40;  /* Too many symbolic links encountered */
-pub const EWOULDBLOCK: i32 = 41;  /* Operation would block */
-pub const ENOMSG: i32 = 42;  /* No message of desired type */
-pub const EIDRM: i32 = 43;  /* Identifier removed */
-pub const ECHRNG: i32 = 44;  /* Channel number out of range */
-pub const EL2NSYNC: i32 = 45;  /* Level 2 not synchronized */
-pub const EL3HLT: i32 = 46;  /* Level 3 halted */
-pub const EL3RST: i32 = 47;  /* Level 3 reset */
-pub const ELNRNG: i32 = 48;  /* Link number out of range */
-pub const EUNATCH: i32 = 49;  /* Protocol driver not attached */
-pub const ENOCSI: i32 = 50;  /* No CSI structure available */
-pub const EL2HLT: i32 = 51;  /* Level 2 halted */
-pub const EBADE: i32 = 52;  /* Invalid exchange */
-pub const EBADR: i32 = 53;  /* Invalid request descriptor */
-pub const EXFULL: i32 = 54;  /* Exchange full */
-pub const ENOANO: i32 = 55;  /* No anode */
-pub const EBADRQC: i32 = 56;  /* Invalid request code */
-pub const EBADSLT: i32 = 57;  /* Invalid slot */
-pub const EDEADLOCK: i32 = 58; /* Resource deadlock would occur */
-pub const EBFONT: i32 = 59;  /* Bad font file format */
-pub const ENOSTR: i32 = 60;  /* Device not a stream */
-pub const ENODATA: i32 = 61;  /* No data available */
-pub const ETIME: i32 = 62;  /* Timer expired */
-pub const ENOSR: i32 = 63;  /* Out of streams resources */
-pub const ENONET: i32 = 64;  /* Machine is not on the network */
-pub const ENOPKG: i32 = 65;  /* Package not installed */
-pub const EREMOTE: i32 = 66;  /* Object is remote */
-pub const ENOLINK: i32 = 67;  /* Link has been severed */
-pub const EADV: i32 = 68;  /* Advertise error */
-pub const ESRMNT: i32 = 69;  /* Srmount error */
-pub const ECOMM: i32 = 70;  /* Communication error on send */
-pub const EPROTO: i32 = 71;  /* Protocol error */
-pub const EMULTIHOP: i32 = 72;  /* Multihop attempted */
-pub const EDOTDOT: i32 = 73;  /* RFS specific error */
-pub const EBADMSG: i32 = 74;  /* Not a data message */
-pub const EOVERFLOW: i32 = 75;  /* Value too large for defined data type */
-pub const ENOTUNIQ: i32 = 76;  /* Name not unique on network */
-pub const EBADFD: i32 = 77;  /* File descriptor in bad state */
-pub const EREMCHG: i32 = 78;  /* Remote address changed */
-pub const ELIBACC: i32 = 79;  /* Can not access a needed shared library */
-pub const ELIBBAD: i32 = 80;  /* Accessing a corrupted shared library */
-pub const ELIBSCN: i32 = 81;  /* .lib section in a.out corrupted */
-pub const ELIBMAX: i32 = 82;  /* Attempting to link in too many shared libraries */
-pub const ELIBEXEC: i32 = 83;  /* Cannot exec a shared library directly */
-pub const EILSEQ: i32 = 84;  /* Illegal byte sequence */
-pub const ERESTART: i32 = 85;  /* Interrupted system call should be restarted */
-pub const ESTRPIPE: i32 = 86;  /* Streams pipe error */
-pub const EUSERS: i32 = 87;  /* Too many users */
-pub const ENOTSOCK: i32 = 88;  /* Socket operation on non-socket */
-pub const EDESTADDRREQ: i32 = 89;  /* Destination address required */
-pub const EMSGSIZE: i32 = 90;  /* Message too long */
-pub const EPROTOTYPE: i32 = 91;  /* Protocol wrong type for socket */
-pub const ENOPROTOOPT: i32 = 92;  /* Protocol not available */
-pub const EPROTONOSUPPORT: i32 = 93;  /* Protocol not supported */
-pub const ESOCKTNOSUPPORT: i32 = 94;  /* Socket type not supported */
-pub const EOPNOTSUPP: i32 = 95;  /* Operation not supported on transport endpoint */
-pub const EPFNOSUPPORT: i32 = 96;  /* Protocol family not supported */
-pub const EAFNOSUPPORT: i32 = 97;  /* Address family not supported by protocol */
-pub const EADDRINUSE: i32 = 98;  /* Address already in use */
-pub const EADDRNOTAVAIL: i32 = 99;  /* Cannot assign requested address */
-pub const ENETDOWN: i32 = 100; /* Network is down */
-pub const ENETUNREACH: i32 = 101; /* Network is unreachable */
-pub const ENETRESET: i32 = 102; /* Network dropped connection because of reset */
-pub const ECONNABORTED: i32 = 103; /* Software caused connection abort */
-pub const ECONNRESET: i32 = 104; /* Connection reset by peer */
-pub const ENOBUFS: i32 = 105; /* No buffer space available */
-pub const EISCONN: i32 = 106; /* Transport endpoint is already connected */
-pub const ENOTCONN: i32 = 107; /* Transport endpoint is not connected */
-pub const ESHUTDOWN: i32 = 108; /* Cannot send after transport endpoint shutdown */
-pub const ETOOMANYREFS: i32 = 109; /* Too many references: cannot splice */
-pub const ETIMEDOUT: i32 = 110; /* Connection timed out */
-pub const ECONNREFUSED: i32 = 111; /* Connection refused */
-pub const EHOSTDOWN: i32 = 112; /* Host is down */
-pub const EHOSTUNREACH: i32 = 113; /* No route to host */
-pub const EALREADY: i32 = 114; /* Operation already in progress */
-pub const EINPROGRESS: i32 = 115; /* Operation now in progress */
-pub const ESTALE: i32 = 116; /* Stale NFS file handle */
-pub const EUCLEAN: i32 = 117; /* Structure needs cleaning */
-pub const ENOTNAM: i32 = 118; /* Not a XENIX named type file */
-pub const ENAVAIL: i32 = 119; /* No XENIX semaphores available */
-pub const EISNAM: i32 = 120; /* Is a named type file */
-pub const EREMOTEIO: i32 = 121; /* Remote I/O error */
-pub const EDQUOT: i32 = 122; /* Quota exceeded */
-pub const ENOMEDIUM: i32 = 123; /* No medium found */
-pub const EMEDIUMTYPE: i32 = 124; /* Wrong medium type */
-pub const ECANCELED: i32 = 125; /* Operation Canceled */
-pub const ENOKEY: i32 = 126; /* Required key not available */
-pub const EKEYEXPIRED: i32 = 127; /* Key has expired */
-pub const EKEYREVOKED: i32 = 128; /* Key has been revoked */
-pub const EKEYREJECTED: i32 = 129; /* Key was rejected by service */
-pub const EOWNERDEAD: i32 = 130; /* Owner died */
-pub const ENOTRECOVERABLE: i32 = 131; /* State not recoverable */
-
-pub static STR_ERROR: [&'static str; 132] = ["Success",
-                                             "Operation not permitted",
-                                             "No such file or directory",
-                                             "No such process",
-                                             "Interrupted system call",
-                                             "I/O error",
-                                             "No such device or address",
-                                             "Argument list too long",
-                                             "Exec format error",
-                                             "Bad file number",
-                                             "No child processes",
-                                             "Try again",
-                                             "Out of memory",
-                                             "Permission denied",
-                                             "Bad address",
-                                             "Block device required",
-                                             "Device or resource busy",
-                                             "File exists",
-                                             "Cross-device link",
-                                             "No such device",
-                                             "Not a directory",
-                                             "Is a directory",
-                                             "Invalid argument",
-                                             "File table overflow",
-                                             "Too many open files",
-                                             "Not a typewriter",
-                                             "Text file busy",
-                                             "File too large",
-                                             "No space left on device",
-                                             "Illegal seek",
-                                             "Read-only file system",
-                                             "Too many links",
-                                             "Broken pipe",
-                                             "Math argument out of domain of func",
-                                             "Math result not representable",
-                                             "Resource deadlock would occur",
-                                             "File name too long",
-                                             "No record locks available",
-                                             "Function not implemented",
-                                             "Directory not empty",
-                                             "Too many symbolic links encountered",
-                                             "Operation would block",
-                                             "No message of desired type",
-                                             "Identifier removed",
-                                             "Channel number out of range",
-                                             "Level 2 not synchronized",
-                                             "Level 3 halted",
-                                             "Level 3 reset",
-                                             "Link number out of range",
-                                             "Protocol driver not attached",
-                                             "No CSI structure available",
-                                             "Level 2 halted",
-                                             "Invalid exchange",
-                                             "Invalid request descriptor",
-                                             "Exchange full",
-                                             "No anode",
-                                             "Invalid request code",
-                                             "Invalid slot",
-                                             "Resource deadlock would occur",
-                                             "Bad font file format",
-                                             "Device not a stream",
-                                             "No data available",
-                                             "Timer expired",
-                                             "Out of streams resources",
-                                             "Machine is not on the network",
-                                             "Package not installed",
-                                             "Object is remote",
-                                             "Link has been severed",
-                                             "Advertise error",
-                                             "Srmount error",
-                                             "Communication error on send",
-                                             "Protocol error",
-                                             "Multihop attempted",
-                                             "RFS specific error",
-                                             "Not a data message",
-                                             "Value too large for defined data type",
-                                             "Name not unique on network",
-                                             "File descriptor in bad state",
-                                             "Remote address changed",
-                                             "Can not access a needed shared library",
-                                             "Accessing a corrupted shared library",
-                                             ".lib section in a.out corrupted",
-                                             "Attempting to link in too many shared libraries",
-                                             "Cannot exec a shared library directly",
-                                             "Illegal byte sequence",
-                                             "Interrupted system call should be restarted",
-                                             "Streams pipe error",
-                                             "Too many users",
-                                             "Socket operation on non-socket",
-                                             "Destination address required",
-                                             "Message too long",
-                                             "Protocol wrong type for socket",
-                                             "Protocol not available",
-                                             "Protocol not supported",
-                                             "Socket type not supported",
-                                             "Operation not supported on transport endpoint",
-                                             "Protocol family not supported",
-                                             "Address family not supported by protocol",
-                                             "Address already in use",
-                                             "Cannot assign requested address",
-                                             "Network is down",
-                                             "Network is unreachable",
-                                             "Network dropped connection because of reset",
-                                             "Software caused connection abort",
-                                             "Connection reset by peer",
-                                             "No buffer space available",
-                                             "Transport endpoint is already connected",
-                                             "Transport endpoint is not connected",
-                                             "Cannot send after transport endpoint shutdown",
-                                             "Too many references: cannot splice",
-                                             "Connection timed out",
-                                             "Connection refused",
-                                             "Host is down",
-                                             "No route to host",
-                                             "Operation already in progress",
-                                             "Operation now in progress",
-                                             "Stale NFS file handle",
-                                             "Structure needs cleaning",
-                                             "Not a XENIX named type file",
-                                             "No XENIX semaphores available",
-                                             "Is a named type file",
-                                             "Remote I/O error",
-                                             "Quota exceeded",
-                                             "No medium found",
-                                             "Wrong medium type",
-                                             "Operation Canceled",
-                                             "Required key not available",
-                                             "Key has expired",
-                                             "Key has been revoked",
-                                             "Key was rejected by service",
-                                             "Owner died",
-                                             "State not recoverable"];
diff --git a/src/libstd/sys/redox/syscall/flag.rs b/src/libstd/sys/redox/syscall/flag.rs
deleted file mode 100644
index 5820f1ad03a..00000000000
--- a/src/libstd/sys/redox/syscall/flag.rs
+++ /dev/null
@@ -1,148 +0,0 @@
-pub const CLONE_VM: usize = 0x100;
-pub const CLONE_FS: usize = 0x200;
-pub const CLONE_FILES: usize = 0x400;
-pub const CLONE_SIGHAND: usize = 0x800;
-pub const CLONE_VFORK: usize = 0x4000;
-pub const CLONE_THREAD: usize = 0x10000;
-
-pub const CLOCK_REALTIME: usize = 1;
-pub const CLOCK_MONOTONIC: usize = 4;
-
-pub const EVENT_NONE: usize = 0;
-pub const EVENT_READ: usize = 1;
-pub const EVENT_WRITE: usize = 2;
-
-pub const F_DUPFD: usize = 0;
-pub const F_GETFD: usize = 1;
-pub const F_SETFD: usize = 2;
-pub const F_GETFL: usize = 3;
-pub const F_SETFL: usize = 4;
-
-pub const FUTEX_WAIT: usize = 0;
-pub const FUTEX_WAKE: usize = 1;
-pub const FUTEX_REQUEUE: usize = 2;
-
-pub const MAP_WRITE: usize = 1;
-pub const MAP_WRITE_COMBINE: usize = 2;
-
-pub const MODE_TYPE: u16 = 0xF000;
-pub const MODE_DIR: u16 = 0x4000;
-pub const MODE_FILE: u16 = 0x8000;
-pub const MODE_SYMLINK: u16 = 0xA000;
-pub const MODE_FIFO: u16 = 0x1000;
-pub const MODE_CHR: u16 = 0x2000;
-
-pub const MODE_PERM: u16 = 0x0FFF;
-pub const MODE_SETUID: u16 = 0o4000;
-pub const MODE_SETGID: u16 = 0o2000;
-
-pub const O_RDONLY: usize =     0x0001_0000;
-pub const O_WRONLY: usize =     0x0002_0000;
-pub const O_RDWR: usize =       0x0003_0000;
-pub const O_NONBLOCK: usize =   0x0004_0000;
-pub const O_APPEND: usize =     0x0008_0000;
-pub const O_SHLOCK: usize =     0x0010_0000;
-pub const O_EXLOCK: usize =     0x0020_0000;
-pub const O_ASYNC: usize =      0x0040_0000;
-pub const O_FSYNC: usize =      0x0080_0000;
-pub const O_CLOEXEC: usize =    0x0100_0000;
-pub const O_CREAT: usize =      0x0200_0000;
-pub const O_TRUNC: usize =      0x0400_0000;
-pub const O_EXCL: usize =       0x0800_0000;
-pub const O_DIRECTORY: usize =  0x1000_0000;
-pub const O_STAT: usize =       0x2000_0000;
-pub const O_SYMLINK: usize =    0x4000_0000;
-pub const O_NOFOLLOW: usize =   0x8000_0000;
-pub const O_ACCMODE: usize =    O_RDONLY | O_WRONLY | O_RDWR;
-
-pub const SEEK_SET: usize = 0;
-pub const SEEK_CUR: usize = 1;
-pub const SEEK_END: usize = 2;
-
-pub const SIGHUP: usize =   1;
-pub const SIGINT: usize =   2;
-pub const SIGQUIT: usize =  3;
-pub const SIGILL: usize =   4;
-pub const SIGTRAP: usize =  5;
-pub const SIGABRT: usize =  6;
-pub const SIGBUS: usize =   7;
-pub const SIGFPE: usize =   8;
-pub const SIGKILL: usize =  9;
-pub const SIGUSR1: usize =  10;
-pub const SIGSEGV: usize =  11;
-pub const SIGUSR2: usize =  12;
-pub const SIGPIPE: usize =  13;
-pub const SIGALRM: usize =  14;
-pub const SIGTERM: usize =  15;
-pub const SIGSTKFLT: usize= 16;
-pub const SIGCHLD: usize =  17;
-pub const SIGCONT: usize =  18;
-pub const SIGSTOP: usize =  19;
-pub const SIGTSTP: usize =  20;
-pub const SIGTTIN: usize =  21;
-pub const SIGTTOU: usize =  22;
-pub const SIGURG: usize =   23;
-pub const SIGXCPU: usize =  24;
-pub const SIGXFSZ: usize =  25;
-pub const SIGVTALRM: usize= 26;
-pub const SIGPROF: usize =  27;
-pub const SIGWINCH: usize = 28;
-pub const SIGIO: usize =    29;
-pub const SIGPWR: usize =   30;
-pub const SIGSYS: usize =   31;
-
-pub const SIG_DFL: usize = 0;
-pub const SIG_IGN: usize = 1;
-
-pub const SA_NOCLDSTOP: usize = 0x00000001;
-pub const SA_NOCLDWAIT: usize = 0x00000002;
-pub const SA_SIGINFO: usize =   0x00000004;
-pub const SA_RESTORER: usize =  0x04000000;
-pub const SA_ONSTACK: usize =   0x08000000;
-pub const SA_RESTART: usize =   0x10000000;
-pub const SA_NODEFER: usize =   0x40000000;
-pub const SA_RESETHAND: usize = 0x80000000;
-
-pub const WNOHANG: usize =    0x01;
-pub const WUNTRACED: usize =  0x02;
-pub const WCONTINUED: usize = 0x08;
-
-/// Returns `true` if status indicates the child is stopped.
-pub fn wifstopped(status: usize) -> bool {
-    (status & 0xff) == 0x7f
-}
-
-/// If wifstopped(status), returns the signal that stopped the child.
-pub fn wstopsig(status: usize) -> usize {
-    (status >> 8) & 0xff
-}
-
-/// Returns `true` if status indicates the child continued after a stop.
-pub fn wifcontinued(status: usize) -> bool {
-    status == 0xffff
-}
-
-/// Returns `true` if status indicates termination by a signal.
-pub fn wifsignaled(status: usize) -> bool {
-    ((status & 0x7f) + 1) as i8 >= 2
-}
-
-/// If wifsignaled(status), returns the terminating signal.
-pub fn wtermsig(status: usize) -> usize {
-    status & 0x7f
-}
-
-/// Returns `true` if status indicates normal termination.
-pub fn wifexited(status: usize) -> bool {
-    wtermsig(status) == 0
-}
-
-/// If wifexited(status), returns the exit status.
-pub fn wexitstatus(status: usize) -> usize {
-    (status >> 8) & 0xff
-}
-
-/// Returns `true` if status indicates a core dump was created.
-pub fn wcoredump(status: usize) -> bool {
-    (status & 0x80) != 0
-}
diff --git a/src/libstd/sys/redox/syscall/mod.rs b/src/libstd/sys/redox/syscall/mod.rs
deleted file mode 100644
index b16f5dbd918..00000000000
--- a/src/libstd/sys/redox/syscall/mod.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-pub use self::arch::*;
-pub use self::call::*;
-pub use self::data::*;
-pub use self::error::*;
-pub use self::flag::*;
-pub use self::number::*;
-
-#[cfg(target_arch = "arm")]
-#[path="arch/arm.rs"]
-mod arch;
-
-#[cfg(target_arch = "x86")]
-#[path="arch/x86.rs"]
-mod arch;
-
-#[cfg(target_arch = "x86_64")]
-#[path="arch/x86_64.rs"]
-mod arch;
-
-/// Function definitions
-pub mod call;
-
-/// Complex structures that are used for some system calls
-pub mod data;
-
-/// All errors that can be generated by a system call
-pub mod error;
-
-/// Flags used as an argument to many system calls
-pub mod flag;
-
-/// Call numbers used by each system call
-pub mod number;
diff --git a/src/libstd/sys/redox/syscall/number.rs b/src/libstd/sys/redox/syscall/number.rs
deleted file mode 100644
index f8884aa2ed8..00000000000
--- a/src/libstd/sys/redox/syscall/number.rs
+++ /dev/null
@@ -1,73 +0,0 @@
-pub const SYS_CLASS: usize =    0xF000_0000;
-pub const SYS_CLASS_PATH: usize=0x1000_0000;
-pub const SYS_CLASS_FILE: usize=0x2000_0000;
-
-pub const SYS_ARG: usize =      0x0F00_0000;
-pub const SYS_ARG_SLICE: usize =0x0100_0000;
-pub const SYS_ARG_MSLICE: usize=0x0200_0000;
-pub const SYS_ARG_PATH: usize = 0x0300_0000;
-
-pub const SYS_RET: usize =      0x00F0_0000;
-pub const SYS_RET_FILE: usize = 0x0010_0000;
-
-pub const SYS_LINK: usize =     SYS_CLASS_PATH | SYS_ARG_PATH | 9;
-pub const SYS_OPEN: usize =     SYS_CLASS_PATH | SYS_RET_FILE | 5;
-pub const SYS_CHMOD: usize =    SYS_CLASS_PATH | 15;
-pub const SYS_RMDIR: usize =    SYS_CLASS_PATH | 84;
-pub const SYS_UNLINK: usize =   SYS_CLASS_PATH | 10;
-
-pub const SYS_CLOSE: usize =    SYS_CLASS_FILE | 6;
-pub const SYS_DUP: usize =      SYS_CLASS_FILE | SYS_RET_FILE | 41;
-pub const SYS_DUP2: usize =     SYS_CLASS_FILE | SYS_RET_FILE | 63;
-pub const SYS_READ: usize =     SYS_CLASS_FILE | SYS_ARG_MSLICE | 3;
-pub const SYS_WRITE: usize =    SYS_CLASS_FILE | SYS_ARG_SLICE | 4;
-pub const SYS_LSEEK: usize =    SYS_CLASS_FILE | 19;
-pub const SYS_FCHMOD: usize =   SYS_CLASS_FILE | 94;
-pub const SYS_FCHOWN: usize =   SYS_CLASS_FILE | 207;
-pub const SYS_FCNTL: usize =    SYS_CLASS_FILE | 55;
-pub const SYS_FEVENT: usize =   SYS_CLASS_FILE | 927;
-pub const SYS_FEXEC: usize =    SYS_CLASS_FILE | 11;
-pub const SYS_FMAP: usize =     SYS_CLASS_FILE | 90;
-pub const SYS_FUNMAP: usize =   SYS_CLASS_FILE | 91;
-pub const SYS_FPATH: usize =    SYS_CLASS_FILE | SYS_ARG_MSLICE | 928;
-pub const SYS_FRENAME: usize =  SYS_CLASS_FILE | SYS_ARG_PATH | 38;
-pub const SYS_FSTAT: usize =    SYS_CLASS_FILE | SYS_ARG_MSLICE | 28;
-pub const SYS_FSTATVFS: usize = SYS_CLASS_FILE | SYS_ARG_MSLICE | 100;
-pub const SYS_FSYNC: usize =    SYS_CLASS_FILE | 118;
-pub const SYS_FTRUNCATE: usize =SYS_CLASS_FILE | 93;
-pub const SYS_FUTIMENS: usize = SYS_CLASS_FILE | SYS_ARG_SLICE | 320;
-
-pub const SYS_BRK: usize =      45;
-pub const SYS_CHDIR: usize =    12;
-pub const SYS_CLOCK_GETTIME: usize = 265;
-pub const SYS_CLONE: usize =    120;
-pub const SYS_EXIT: usize =     1;
-pub const SYS_FUTEX: usize =    240;
-pub const SYS_GETCWD: usize =   183;
-pub const SYS_GETEGID: usize =  202;
-pub const SYS_GETENS: usize =   951;
-pub const SYS_GETEUID: usize =  201;
-pub const SYS_GETGID: usize =   200;
-pub const SYS_GETNS: usize =    950;
-pub const SYS_GETPID: usize =   20;
-pub const SYS_GETPGID: usize =  132;
-pub const SYS_GETPPID: usize =  64;
-pub const SYS_GETUID: usize =   199;
-pub const SYS_IOPL: usize =     110;
-pub const SYS_KILL: usize =     37;
-pub const SYS_MKNS: usize =     984;
-pub const SYS_NANOSLEEP: usize =162;
-pub const SYS_PHYSALLOC: usize =945;
-pub const SYS_PHYSFREE: usize = 946;
-pub const SYS_PHYSMAP: usize =  947;
-pub const SYS_PHYSUNMAP: usize =948;
-pub const SYS_VIRTTOPHYS: usize=949;
-pub const SYS_PIPE2: usize =    331;
-pub const SYS_SETPGID: usize =  57;
-pub const SYS_SETREGID: usize = 204;
-pub const SYS_SETRENS: usize =  952;
-pub const SYS_SETREUID: usize = 203;
-pub const SYS_SIGACTION: usize =67;
-pub const SYS_SIGRETURN: usize =119;
-pub const SYS_WAITPID: usize =  7;
-pub const SYS_YIELD: usize =    158;
diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs
deleted file mode 100644
index 9d40a7e8bb8..00000000000
--- a/src/libstd/sys/redox/thread.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-use crate::ffi::CStr;
-use crate::io;
-use crate::mem;
-use crate::sys_common::thread::start_thread;
-use crate::sys::{cvt, syscall};
-use crate::time::Duration;
-
-pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
-
-pub struct Thread {
-    id: usize,
-}
-
-// Some platforms may have pthread_t as a pointer in which case we still want
-// a thread to be Send/Sync
-unsafe impl Send for Thread {}
-unsafe impl Sync for Thread {}
-
-impl Thread {
-    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
-    pub unsafe fn new(_stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
-        let p = box p;
-
-        let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?;
-        if id == 0 {
-            start_thread(&*p as *const _ as *mut _);
-            let _ = syscall::exit(0);
-            panic!("thread failed to exit");
-        } else {
-            mem::forget(p);
-            Ok(Thread { id })
-        }
-    }
-
-    pub fn yield_now() {
-        let ret = syscall::sched_yield().expect("failed to sched_yield");
-        debug_assert_eq!(ret, 0);
-    }
-
-    pub fn set_name(_name: &CStr) {
-
-    }
-
-    pub fn sleep(dur: Duration) {
-        let mut secs = dur.as_secs();
-        let mut nsecs = dur.subsec_nanos() as i32;
-
-        // If we're awoken with a signal then the return value will be -1 and
-        // nanosleep will fill in `ts` with the remaining time.
-        while secs > 0 || nsecs > 0 {
-            let req = syscall::TimeSpec {
-                tv_sec: secs as i64,
-                tv_nsec: nsecs,
-            };
-            secs -= req.tv_sec as u64;
-            let mut rem = syscall::TimeSpec::default();
-            if syscall::nanosleep(&req, &mut rem).is_err() {
-                secs += rem.tv_sec as u64;
-                nsecs = rem.tv_nsec;
-            } else {
-                nsecs = 0;
-            }
-        }
-    }
-
-    pub fn join(self) {
-        let mut status = 0;
-        syscall::waitpid(self.id, &mut status, 0).unwrap();
-    }
-
-    pub fn id(&self) -> usize { self.id }
-
-    pub fn into_id(self) -> usize {
-        let id = self.id;
-        mem::forget(self);
-        id
-    }
-}
-
-pub mod guard {
-    pub type Guard = !;
-    pub unsafe fn current() -> Option<Guard> { None }
-    pub unsafe fn init() -> Option<Guard> { None }
-}
diff --git a/src/libstd/sys/redox/thread_local.rs b/src/libstd/sys/redox/thread_local.rs
deleted file mode 100644
index 4bc8c4d5883..00000000000
--- a/src/libstd/sys/redox/thread_local.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-#![allow(dead_code)] // not used on all platforms
-
-use crate::collections::BTreeMap;
-use crate::ptr;
-use crate::sync::atomic::{AtomicUsize, Ordering};
-
-pub type Key = usize;
-
-type Dtor = unsafe extern fn(*mut u8);
-
-static NEXT_KEY: AtomicUsize = AtomicUsize::new(0);
-
-static mut KEYS: *mut BTreeMap<Key, Option<Dtor>> = ptr::null_mut();
-
-#[thread_local]
-static mut LOCALS: *mut BTreeMap<Key, *mut u8> = ptr::null_mut();
-
-unsafe fn keys() -> &'static mut BTreeMap<Key, Option<Dtor>> {
-    if KEYS == ptr::null_mut() {
-        KEYS = Box::into_raw(Box::new(BTreeMap::new()));
-    }
-    &mut *KEYS
-}
-
-unsafe fn locals() -> &'static mut BTreeMap<Key, *mut u8> {
-    if LOCALS == ptr::null_mut() {
-        LOCALS = Box::into_raw(Box::new(BTreeMap::new()));
-    }
-    &mut *LOCALS
-}
-
-#[inline]
-pub unsafe fn create(dtor: Option<Dtor>) -> Key {
-    let key = NEXT_KEY.fetch_add(1, Ordering::SeqCst);
-    keys().insert(key, dtor);
-    key
-}
-
-#[inline]
-pub unsafe fn get(key: Key) -> *mut u8 {
-    if let Some(&entry) = locals().get(&key) {
-        entry
-    } else {
-        ptr::null_mut()
-    }
-}
-
-#[inline]
-pub unsafe fn set(key: Key, value: *mut u8) {
-    locals().insert(key, value);
-}
-
-#[inline]
-pub unsafe fn destroy(key: Key) {
-    keys().remove(&key);
-}
-
-#[inline]
-pub fn requires_synchronized_create() -> bool {
-    false
-}
diff --git a/src/libstd/sys/redox/time.rs b/src/libstd/sys/redox/time.rs
deleted file mode 100644
index 081437459cc..00000000000
--- a/src/libstd/sys/redox/time.rs
+++ /dev/null
@@ -1,207 +0,0 @@
-use crate::cmp::Ordering;
-use crate::fmt;
-use crate::sys::{cvt, syscall};
-use crate::time::Duration;
-use crate::convert::TryInto;
-
-use core::hash::{Hash, Hasher};
-
-const NSEC_PER_SEC: u64 = 1_000_000_000;
-
-#[derive(Copy, Clone)]
-struct Timespec {
-    t: syscall::TimeSpec,
-}
-
-impl Timespec {
-    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
-        if self >= other {
-            Ok(if self.t.tv_nsec >= other.t.tv_nsec {
-                Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
-                              (self.t.tv_nsec - other.t.tv_nsec) as u32)
-            } else {
-                Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
-                              self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
-                              other.t.tv_nsec as u32)
-            })
-        } else {
-            match other.sub_timespec(self) {
-                Ok(d) => Err(d),
-                Err(d) => Ok(d),
-            }
-        }
-    }
-
-    fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
-        let mut secs = other
-            .as_secs()
-            .try_into() // <- target type would be `i64`
-            .ok()
-            .and_then(|secs| self.t.tv_sec.checked_add(secs))?;
-
-        // Nano calculations can't overflow because nanos are <1B which fit
-        // in a u32.
-        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
-        if nsec >= NSEC_PER_SEC as u32 {
-            nsec -= NSEC_PER_SEC as u32;
-            secs = secs.checked_add(1)?;
-        }
-        Some(Timespec {
-            t: syscall::TimeSpec {
-                tv_sec: secs,
-                tv_nsec: nsec as i32,
-            },
-        })
-    }
-
-    fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
-        let mut secs = other
-            .as_secs()
-            .try_into() // <- target type would be `i64`
-            .ok()
-            .and_then(|secs| self.t.tv_sec.checked_sub(secs))?;
-
-        // Similar to above, nanos can't overflow.
-        let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
-        if nsec < 0 {
-            nsec += NSEC_PER_SEC as i32;
-            secs = secs.checked_sub(1)?;
-        }
-        Some(Timespec {
-            t: syscall::TimeSpec {
-                tv_sec: secs,
-                tv_nsec: nsec as i32,
-            },
-        })
-    }
-}
-
-impl PartialEq for Timespec {
-    fn eq(&self, other: &Timespec) -> bool {
-        self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
-    }
-}
-
-impl Eq for Timespec {}
-
-impl PartialOrd for Timespec {
-    fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-impl Ord for Timespec {
-    fn cmp(&self, other: &Timespec) -> Ordering {
-        let me = (self.t.tv_sec, self.t.tv_nsec);
-        let other = (other.t.tv_sec, other.t.tv_nsec);
-        me.cmp(&other)
-    }
-}
-
-impl Hash for Timespec {
-    fn hash<H : Hasher>(&self, state: &mut H) {
-        self.t.tv_sec.hash(state);
-        self.t.tv_nsec.hash(state);
-    }
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct Instant {
-    t: Timespec,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct SystemTime {
-    t: Timespec,
-}
-
-pub const UNIX_EPOCH: SystemTime = SystemTime {
-    t: Timespec {
-        t: syscall::TimeSpec {
-            tv_sec: 0,
-            tv_nsec: 0,
-        },
-    },
-};
-
-impl Instant {
-    pub fn now() -> Instant {
-        Instant { t: now(syscall::CLOCK_MONOTONIC) }
-    }
-
-    pub const fn zero() -> Instant {
-        Instant { t: Timespec { t: syscall::TimeSpec { tv_sec: 0, tv_nsec: 0 } } }
-    }
-
-    pub fn actually_monotonic() -> bool {
-        false
-    }
-
-    pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
-        self.t.sub_timespec(&other.t).ok()
-    }
-
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
-        Some(Instant { t: self.t.checked_add_duration(other)? })
-    }
-
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
-        Some(Instant { t: self.t.checked_sub_duration(other)? })
-    }
-}
-
-impl fmt::Debug for Instant {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Instant")
-         .field("tv_sec", &self.t.t.tv_sec)
-         .field("tv_nsec", &self.t.t.tv_nsec)
-         .finish()
-    }
-}
-
-impl SystemTime {
-    pub fn now() -> SystemTime {
-        SystemTime { t: now(syscall::CLOCK_REALTIME) }
-    }
-
-    pub fn sub_time(&self, other: &SystemTime)
-                    -> Result<Duration, Duration> {
-        self.t.sub_timespec(&other.t)
-    }
-
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-        Some(SystemTime { t: self.t.checked_add_duration(other)? })
-    }
-
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
-        Some(SystemTime { t: self.t.checked_sub_duration(other)? })
-    }
-}
-
-impl From<syscall::TimeSpec> for SystemTime {
-    fn from(t: syscall::TimeSpec) -> SystemTime {
-        SystemTime { t: Timespec { t } }
-    }
-}
-
-impl fmt::Debug for SystemTime {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("SystemTime")
-         .field("tv_sec", &self.t.t.tv_sec)
-         .field("tv_nsec", &self.t.t.tv_nsec)
-         .finish()
-    }
-}
-
-pub type clock_t = usize;
-
-fn now(clock: clock_t) -> Timespec {
-    let mut t = Timespec {
-        t: syscall::TimeSpec {
-            tv_sec: 0,
-            tv_nsec: 0,
-        }
-    };
-    cvt(syscall::clock_gettime(clock, &mut t.t)).unwrap();
-    t
-}
diff --git a/src/libstd/sys/sgx/abi/usercalls/alloc.rs b/src/libstd/sys/sgx/abi/usercalls/alloc.rs
index c9ff53d0a4f..75dd0d429c2 100644
--- a/src/libstd/sys/sgx/abi/usercalls/alloc.rs
+++ b/src/libstd/sys/sgx/abi/usercalls/alloc.rs
@@ -522,7 +522,11 @@ impl<T: ?Sized> Drop for User<T> where T: UserSafe {
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<UserRef<U>> for UserRef<T> {}
 
 #[unstable(feature = "sgx_platform", issue = "56975")]
-impl<T, I: SliceIndex<[T]>> Index<I> for UserRef<[T]> where [T]: UserSafe, I::Output: UserSafe {
+impl<T, I> Index<I> for UserRef<[T]>
+where
+    [T]: UserSafe,
+    I: SliceIndex<[T], Output: UserSafe>,
+{
     type Output = UserRef<I::Output>;
 
     #[inline]
@@ -538,7 +542,11 @@ impl<T, I: SliceIndex<[T]>> Index<I> for UserRef<[T]> where [T]: UserSafe, I::Ou
 }
 
 #[unstable(feature = "sgx_platform", issue = "56975")]
-impl<T, I: SliceIndex<[T]>> IndexMut<I> for UserRef<[T]> where [T]: UserSafe, I::Output: UserSafe {
+impl<T, I> IndexMut<I> for UserRef<[T]>
+where
+    [T]: UserSafe,
+    I: SliceIndex<[T], Output: UserSafe>,
+{
     #[inline]
     fn index_mut(&mut self, index: I) -> &mut UserRef<I::Output> {
         unsafe {
diff --git a/src/libstd/sys/sgx/backtrace.rs b/src/libstd/sys/sgx/backtrace.rs
deleted file mode 100644
index 326737a2418..00000000000
--- a/src/libstd/sys/sgx/backtrace.rs
+++ /dev/null
@@ -1,98 +0,0 @@
-use crate::io;
-use crate::error::Error;
-use crate::fmt;
-use crate::sys_common::backtrace::Frame;
-use crate::sys::sgx::abi::mem::image_base;
-
-use unwind as uw;
-
-pub struct BacktraceContext;
-
-struct Context<'a> {
-    idx: usize,
-    frames: &'a mut [Frame],
-}
-
-#[derive(Debug)]
-struct UnwindError(uw::_Unwind_Reason_Code);
-
-impl Error for UnwindError {
-    fn description(&self) -> &'static str {
-        "unexpected return value while unwinding"
-    }
-}
-
-impl fmt::Display for UnwindError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}: {:?}", self.description(), self.0)
-    }
-}
-
-#[inline(never)] // this function call can be skipped it when tracing.
-pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> {
-    let mut cx = Context { idx: 0, frames };
-    let result_unwind = unsafe {
-        uw::_Unwind_Backtrace(trace_fn, &mut cx as *mut Context<'_> as *mut libc::c_void)
-    };
-    // See libunwind:src/unwind/Backtrace.c for the return values.
-    // No, there is no doc.
-    let res = match result_unwind {
-        // These return codes seem to be benign and need to be ignored for backtraces
-        // to show up properly on all tested platforms.
-        uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
-            Ok((cx.idx, BacktraceContext))
-        }
-        _ => Err(io::Error::new(
-            io::ErrorKind::Other,
-            UnwindError(result_unwind),
-        )),
-    };
-    res
-}
-
-extern "C" fn trace_fn(
-    ctx: *mut uw::_Unwind_Context,
-    arg: *mut libc::c_void,
-) -> uw::_Unwind_Reason_Code {
-    let cx = unsafe { &mut *(arg as *mut Context<'_>) };
-    if cx.idx >= cx.frames.len() {
-        return uw::_URC_NORMAL_STOP;
-    }
-
-    let mut ip_before_insn = 0;
-    let mut ip = unsafe { uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void };
-    if !ip.is_null() && ip_before_insn == 0 {
-        // this is a non-signaling frame, so `ip` refers to the address
-        // after the calling instruction. account for that.
-        ip = (ip as usize - 1) as *mut _;
-    }
-
-    let symaddr = unsafe { uw::_Unwind_FindEnclosingFunction(ip) };
-    cx.frames[cx.idx] = Frame {
-        symbol_addr: symaddr as *mut u8,
-        exact_position: ip as *mut u8,
-        inline_context: 0,
-    };
-    cx.idx += 1;
-
-    uw::_URC_NO_REASON
-}
-
-// To reduce TCB size in Sgx enclave, we do not want to implement resolve_symname functionality.
-// Rather, we print the offset of the address here, which could be later mapped to correct function.
-pub fn resolve_symname<F>(frame: Frame,
-                          callback: F,
-                          _: &BacktraceContext) -> io::Result<()>
-    where F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    callback(Some(&format!("0x{:x}",
-            (frame.symbol_addr.wrapping_offset_from(image_base() as _)))))
-}
-
-pub fn foreach_symbol_fileline<F>(_: Frame,
-                                  _: F,
-                                  _: &BacktraceContext) -> io::Result<bool>
-    where F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    Ok(false)
-}
diff --git a/src/libstd/sys/sgx/io.rs b/src/libstd/sys/sgx/io.rs
index 4b423a5cbc1..976e122463d 100644
--- a/src/libstd/sys/sgx/io.rs
+++ b/src/libstd/sys/sgx/io.rs
@@ -1,3 +1,5 @@
+use crate::mem;
+
 pub struct IoSlice<'a>(&'a [u8]);
 
 impl<'a> IoSlice<'a> {
@@ -7,6 +9,11 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        self.0 = &self.0[n..]
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         self.0
     }
@@ -21,6 +28,13 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        let slice = mem::replace(&mut self.0, &mut []);
+        let (_, remaining) = slice.split_at_mut(n);
+        self.0 = remaining;
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         self.0
     }
diff --git a/src/libstd/sys/sgx/mod.rs b/src/libstd/sys/sgx/mod.rs
index a99a534f41e..601957acd5c 100644
--- a/src/libstd/sys/sgx/mod.rs
+++ b/src/libstd/sys/sgx/mod.rs
@@ -12,8 +12,6 @@ mod waitqueue;
 
 pub mod alloc;
 pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 pub mod cmath;
 pub mod condvar;
 pub mod env;
@@ -142,7 +140,7 @@ pub unsafe extern "C" fn __rust_abort() {
 pub fn hashmap_random_keys() -> (u64, u64) {
     fn rdrand64() -> u64 {
         unsafe {
-            let mut ret: u64 = crate::mem::uninitialized();
+            let mut ret: u64 = 0;
             for _ in 0..10 {
                 if crate::arch::x86_64::_rdrand64_step(&mut ret) == 1 {
                     return ret;
diff --git a/src/libstd/sys/unix/alloc.rs b/src/libstd/sys/unix/alloc.rs
index 8e8f5017da7..f47dc92d2de 100644
--- a/src/libstd/sys/unix/alloc.rs
+++ b/src/libstd/sys/unix/alloc.rs
@@ -6,6 +6,10 @@ use crate::alloc::{GlobalAlloc, Layout, System};
 unsafe impl GlobalAlloc for System {
     #[inline]
     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        // jemalloc provides alignment less than MIN_ALIGN for small allocations.
+        // So only rely on MIN_ALIGN if size >= align.
+        // Also see <https://github.com/rust-lang/rust/issues/45955> and
+        // <https://github.com/rust-lang/rust/issues/62251#issuecomment-507580914>.
         if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
             libc::malloc(layout.size()) as *mut u8
         } else {
@@ -21,10 +25,11 @@ unsafe impl GlobalAlloc for System {
 
     #[inline]
     unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+        // See the comment above in `alloc` for why this check looks the way it does.
         if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
             libc::calloc(layout.size(), 1) as *mut u8
         } else {
-            let ptr = self.alloc(layout.clone());
+            let ptr = self.alloc(layout);
             if !ptr.is_null() {
                 ptr::write_bytes(ptr, 0, layout.size());
             }
@@ -80,7 +85,10 @@ unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
 #[inline]
 unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
     let mut out = ptr::null_mut();
-    let ret = libc::posix_memalign(&mut out, layout.align(), layout.size());
+    // posix_memalign requires that the alignment be a multiple of `sizeof(void*)`.
+    // Since these are all powers of 2, we can just use max.
+    let align = layout.align().max(crate::mem::size_of::<usize>());
+    let ret = libc::posix_memalign(&mut out, align, layout.size());
     if ret != 0 {
         ptr::null_mut()
     } else {
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs
index 6ba947d4598..288e9b5c126 100644
--- a/src/libstd/sys/unix/args.rs
+++ b/src/libstd/sys/unix/args.rs
@@ -35,8 +35,6 @@ 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 {
@@ -58,7 +56,8 @@ impl DoubleEndedIterator for Args {
           target_os = "haiku",
           target_os = "l4re",
           target_os = "fuchsia",
-          target_os = "hermit"))]
+          target_os = "hermit",
+          target_os = "redox"))]
 mod imp {
     use crate::os::unix::prelude::*;
     use crate::ptr;
diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs
index 47fb6792f08..0a93fbf8ea7 100644
--- a/src/libstd/sys/unix/condvar.rs
+++ b/src/libstd/sys/unix/condvar.rs
@@ -31,24 +31,26 @@ impl Condvar {
               target_os = "ios",
               target_os = "l4re",
               target_os = "android",
-              target_os = "hermit"))]
+              target_os = "hermit",
+              target_os = "redox"))]
     pub unsafe fn init(&mut self) {}
 
     #[cfg(not(any(target_os = "macos",
                   target_os = "ios",
                   target_os = "l4re",
                   target_os = "android",
-                  target_os = "hermit")))]
+                  target_os = "hermit",
+                  target_os = "redox")))]
     pub unsafe fn init(&mut self) {
-        use crate::mem;
-        let mut attr: libc::pthread_condattr_t = mem::uninitialized();
-        let r = libc::pthread_condattr_init(&mut attr);
+        use crate::mem::MaybeUninit;
+        let mut attr = MaybeUninit::<libc::pthread_condattr_t>::uninit();
+        let r = libc::pthread_condattr_init(attr.as_mut_ptr());
         assert_eq!(r, 0);
-        let r = libc::pthread_condattr_setclock(&mut attr, libc::CLOCK_MONOTONIC);
+        let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC);
         assert_eq!(r, 0);
-        let r = libc::pthread_cond_init(self.inner.get(), &attr);
+        let r = libc::pthread_cond_init(self.inner.get(), attr.as_ptr());
         assert_eq!(r, 0);
-        let r = libc::pthread_condattr_destroy(&mut attr);
+        let r = libc::pthread_condattr_destroy(attr.as_mut_ptr());
         assert_eq!(r, 0);
     }
 
diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs
index 891013406a1..d724eeb8b3f 100644
--- a/src/libstd/sys/unix/env.rs
+++ b/src/libstd/sys/unix/env.rs
@@ -162,3 +162,14 @@ pub mod os {
     pub const EXE_SUFFIX: &str = "";
     pub const EXE_EXTENSION: &str = "";
 }
+
+#[cfg(target_os = "redox")]
+pub mod os {
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "redox";
+    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 = "";
+}
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index d9baac993c4..c033c60cbe9 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -238,7 +238,7 @@ pub trait PermissionsExt {
     ///     let metadata = f.metadata()?;
     ///     let permissions = metadata.permissions();
     ///
-    ///     println!("permissions: {}", permissions.mode());
+    ///     println!("permissions: {:o}", permissions.mode());
     ///     Ok(()) }
     /// ```
     #[stable(feature = "fs_ext", since = "1.1.0")]
diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs
index 3ccb0a1b1ab..42edd5dbbea 100644
--- a/src/libstd/sys/unix/ext/net.rs
+++ b/src/libstd/sys/unix/ext/net.rs
@@ -40,10 +40,9 @@ use libc::MSG_NOSIGNAL;
               target_os = "haiku")))]
 const MSG_NOSIGNAL: libc::c_int = 0x0;
 
-fn sun_path_offset() -> usize {
+fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
     // Work with an actual instance of the type since using a null pointer is UB
-    let addr: libc::sockaddr_un = unsafe { mem::uninitialized() };
-    let base = &addr as *const _ as usize;
+    let base = addr as *const _ as usize;
     let path = &addr.sun_path as *const _ as usize;
     path - base
 }
@@ -69,7 +68,7 @@ unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::sockl
     // null byte for pathname addresses is already there because we zeroed the
     // struct
 
-    let mut len = sun_path_offset() + bytes.len();
+    let mut len = sun_path_offset(&addr) + bytes.len();
     match bytes.get(0) {
         Some(&0) | None => {}
         Some(_) => len += 1,
@@ -122,7 +121,7 @@ impl SocketAddr {
         if len == 0 {
             // When there is a datagram from unnamed unix socket
             // linux returns zero bytes of address
-            len = sun_path_offset() as libc::socklen_t;  // i.e., zero-length address
+            len = sun_path_offset(&addr) as libc::socklen_t;  // i.e., zero-length address
         } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
             return Err(io::Error::new(io::ErrorKind::InvalidInput,
                                       "file descriptor did not correspond to a Unix socket"));
@@ -199,8 +198,8 @@ impl SocketAddr {
         }
     }
 
-    fn address<'a>(&'a self) -> AddressKind<'a> {
-        let len = self.len as usize - sun_path_offset();
+    fn address(&self) -> AddressKind<'_> {
+        let len = self.len as usize - sun_path_offset(&self.addr);
         let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
 
         // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
@@ -895,7 +894,7 @@ impl UnixListener {
     /// }
     /// ```
     #[stable(feature = "unix_socket", since = "1.10.0")]
-    pub fn incoming<'a>(&'a self) -> Incoming<'a> {
+    pub fn incoming(&self) -> Incoming<'_> {
         Incoming { listener: self }
     }
 }
diff --git a/src/libstd/sys/unix/fast_thread_local.rs b/src/libstd/sys/unix/fast_thread_local.rs
index 17478dce4fe..952ba40ee87 100644
--- a/src/libstd/sys/unix/fast_thread_local.rs
+++ b/src/libstd/sys/unix/fast_thread_local.rs
@@ -10,7 +10,7 @@
 // fallback implementation to use as well.
 //
 // Due to rust-lang/rust#18804, make sure this is not generic!
-#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "hermit"))]
+#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "hermit", target_os = "redox"))]
 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
     use crate::mem;
     use crate::sys_common::thread_local::register_dtor_fallback;
@@ -82,7 +82,3 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
         }
     }
 }
-
-pub fn requires_move_before_drop() -> bool {
-    false
-}
diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs
index 6d23963e141..ac43526b50f 100644
--- a/src/libstd/sys/unix/fd.rs
+++ b/src/libstd/sys/unix/fd.rs
@@ -175,7 +175,9 @@ impl FileDesc {
                   target_os = "emscripten",
                   target_os = "fuchsia",
                   target_os = "l4re",
-                  target_os = "haiku")))]
+                  target_os = "linux",
+                  target_os = "haiku",
+                  target_os = "redox")))]
     pub fn set_cloexec(&self) -> io::Result<()> {
         unsafe {
             cvt(libc::ioctl(self.fd, libc::FIOCLEX))?;
@@ -187,7 +189,9 @@ impl FileDesc {
               target_os = "emscripten",
               target_os = "fuchsia",
               target_os = "l4re",
-              target_os = "haiku"))]
+              target_os = "linux",
+              target_os = "haiku",
+              target_os = "redox"))]
     pub fn set_cloexec(&self) -> io::Result<()> {
         unsafe {
             let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?;
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index cc1f0790d43..3b1eb86b84f 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -33,7 +33,8 @@ use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, off_t as off64_t,
               target_os = "emscripten",
               target_os = "solaris",
               target_os = "l4re",
-              target_os = "fuchsia")))]
+              target_os = "fuchsia",
+              target_os = "redox")))]
 use libc::{readdir_r as readdir64_r};
 
 pub use crate::sys_common::fs::remove_dir_all;
@@ -69,7 +70,7 @@ pub struct DirEntry {
     // on Solaris and Fuchsia because a) it uses a zero-length
     // array to store the name, b) its lifetime between readdir
     // calls is not guaranteed.
-    #[cfg(any(target_os = "solaris", target_os = "fuchsia"))]
+    #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))]
     name: Box<[u8]>
 }
 
@@ -216,7 +217,7 @@ impl fmt::Debug for ReadDir {
 impl Iterator for ReadDir {
     type Item = io::Result<DirEntry>;
 
-    #[cfg(any(target_os = "solaris", target_os = "fuchsia"))]
+    #[cfg(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox"))]
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
         use crate::slice;
 
@@ -253,7 +254,7 @@ impl Iterator for ReadDir {
         }
     }
 
-    #[cfg(not(any(target_os = "solaris", target_os = "fuchsia")))]
+    #[cfg(not(any(target_os = "solaris", target_os = "fuchsia", target_os = "redox")))]
     fn next(&mut self) -> Option<io::Result<DirEntry>> {
         if self.end_of_stream {
             return None;
@@ -346,7 +347,8 @@ impl DirEntry {
               target_os = "haiku",
               target_os = "l4re",
               target_os = "fuchsia",
-              target_os = "hermit"))]
+              target_os = "hermit",
+              target_os = "redox"))]
     pub fn ino(&self) -> u64 {
         self.entry.d_ino as u64
     }
@@ -384,7 +386,8 @@ impl DirEntry {
         }
     }
     #[cfg(any(target_os = "solaris",
-              target_os = "fuchsia"))]
+              target_os = "fuchsia",
+              target_os = "redox"))]
     fn name_bytes(&self) -> &[u8] {
         &*self.name
     }
@@ -554,9 +557,15 @@ impl File {
         return crate::sys::android::ftruncate64(self.0.raw(), size);
 
         #[cfg(not(target_os = "android"))]
-        return cvt_r(|| unsafe {
-            ftruncate64(self.0.raw(), size as off64_t)
-        }).map(|_| ());
+        {
+            use crate::convert::TryInto;
+            let size: off64_t = size
+                .try_into()
+                .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;
+            cvt_r(|| unsafe {
+                ftruncate64(self.0.raw(), size)
+            }).map(|_| ())
+        }
     }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
diff --git a/src/libstd/sys/unix/io.rs b/src/libstd/sys/unix/io.rs
index 72954ff20ef..a3a72919176 100644
--- a/src/libstd/sys/unix/io.rs
+++ b/src/libstd/sys/unix/io.rs
@@ -22,6 +22,18 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        if self.vec.iov_len < n {
+            panic!("advancing IoSlice beyond its length");
+        }
+
+        unsafe {
+            self.vec.iov_len -= n;
+            self.vec.iov_base = self.vec.iov_base.add(n);
+        }
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         unsafe {
             slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
@@ -29,6 +41,7 @@ impl<'a> IoSlice<'a> {
     }
 }
 
+#[repr(transparent)]
 pub struct IoSliceMut<'a> {
     vec: iovec,
     _p: PhantomData<&'a mut [u8]>,
@@ -47,6 +60,18 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        if self.vec.iov_len < n {
+            panic!("advancing IoSliceMut beyond its length");
+        }
+
+        unsafe {
+            self.vec.iov_len -= n;
+            self.vec.iov_base = self.vec.iov_base.add(n);
+        }
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         unsafe {
             slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index c2b264ff8de..b1f7aac8b4b 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -17,6 +17,7 @@ use crate::io::ErrorKind;
 #[cfg(all(not(rustdoc), target_os = "fuchsia"))]   pub use crate::os::fuchsia as platform;
 #[cfg(all(not(rustdoc), target_os = "l4re"))]      pub use crate::os::linux as platform;
 #[cfg(all(not(rustdoc), target_os = "hermit"))]    pub use crate::os::hermit as platform;
+#[cfg(all(not(rustdoc), target_os = "redox"))]      pub use crate::os::redox as platform;
 
 pub use self::rand::hashmap_random_keys;
 pub use libc::strlen;
@@ -27,8 +28,6 @@ pub mod weak;
 pub mod alloc;
 pub mod args;
 pub mod android;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 pub mod cmath;
 pub mod condvar;
 pub mod env;
diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs
index b6a22e1962a..b43af8fdcaa 100644
--- a/src/libstd/sys/unix/mutex.rs
+++ b/src/libstd/sys/unix/mutex.rs
@@ -1,5 +1,5 @@
 use crate::cell::UnsafeCell;
-use crate::mem;
+use crate::mem::MaybeUninit;
 
 pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t> }
 
@@ -40,14 +40,14 @@ impl Mutex {
         // references, we instead create the mutex with type
         // PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to
         // re-lock it from the same thread, thus avoiding undefined behavior.
-        let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
-        let r = libc::pthread_mutexattr_init(&mut attr);
+        let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
+        let r = libc::pthread_mutexattr_init(attr.as_mut_ptr());
         debug_assert_eq!(r, 0);
-        let r = libc::pthread_mutexattr_settype(&mut attr, libc::PTHREAD_MUTEX_NORMAL);
+        let r = libc::pthread_mutexattr_settype(attr.as_mut_ptr(), libc::PTHREAD_MUTEX_NORMAL);
         debug_assert_eq!(r, 0);
-        let r = libc::pthread_mutex_init(self.inner.get(), &attr);
+        let r = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
         debug_assert_eq!(r, 0);
-        let r = libc::pthread_mutexattr_destroy(&mut attr);
+        let r = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
         debug_assert_eq!(r, 0);
     }
     #[inline]
@@ -89,19 +89,19 @@ unsafe impl Sync for ReentrantMutex {}
 
 impl ReentrantMutex {
     pub unsafe fn uninitialized() -> ReentrantMutex {
-        ReentrantMutex { inner: mem::uninitialized() }
+        ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
     }
 
     pub unsafe fn init(&mut self) {
-        let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
-        let result = libc::pthread_mutexattr_init(&mut attr as *mut _);
+        let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
+        let result = libc::pthread_mutexattr_init(attr.as_mut_ptr());
         debug_assert_eq!(result, 0);
-        let result = libc::pthread_mutexattr_settype(&mut attr as *mut _,
+        let result = libc::pthread_mutexattr_settype(attr.as_mut_ptr(),
                                                     libc::PTHREAD_MUTEX_RECURSIVE);
         debug_assert_eq!(result, 0);
-        let result = libc::pthread_mutex_init(self.inner.get(), &attr as *const _);
+        let result = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
         debug_assert_eq!(result, 0);
-        let result = libc::pthread_mutexattr_destroy(&mut attr as *mut _);
+        let result = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
         debug_assert_eq!(result, 0);
     }
 
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index dad19eabf7d..169bb57ef78 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -25,6 +25,13 @@ use libc::{c_int, c_char, c_void};
 
 const TMPBUF_SZ: usize = 128;
 
+cfg_if::cfg_if! {
+    if #[cfg(target_os = "redox")] {
+        const PATH_SEPARATOR: u8 = b';';
+    } else {
+        const PATH_SEPARATOR: u8 = b':';
+    }
+}
 
 extern {
     #[cfg(not(target_os = "dragonfly"))]
@@ -37,6 +44,7 @@ extern {
                    target_os = "openbsd",
                    target_os = "android",
                    target_os = "hermit",
+                   target_os = "redox",
                    target_env = "newlib"),
                link_name = "__errno")]
     #[cfg_attr(target_os = "solaris", link_name = "___errno")]
@@ -155,10 +163,10 @@ pub fn split_paths(unparsed: &OsStr) -> SplitPaths<'_> {
     fn bytes_to_path(b: &[u8]) -> PathBuf {
         PathBuf::from(<OsStr as OsStrExt>::from_bytes(b))
     }
-    fn is_colon(b: &u8) -> bool { *b == b':' }
+    fn is_separator(b: &u8) -> bool { *b == PATH_SEPARATOR }
     let unparsed = unparsed.as_bytes();
     SplitPaths {
-        iter: unparsed.split(is_colon as fn(&u8) -> bool)
+        iter: unparsed.split(is_separator as fn(&u8) -> bool)
                       .map(bytes_to_path as fn(&[u8]) -> PathBuf)
     }
 }
@@ -176,12 +184,11 @@ pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
     where I: Iterator<Item=T>, T: AsRef<OsStr>
 {
     let mut joined = Vec::new();
-    let sep = b':';
 
     for (i, path) in paths.enumerate() {
         let path = path.as_ref().as_bytes();
-        if i > 0 { joined.push(sep) }
-        if path.contains(&sep) {
+        if i > 0 { joined.push(PATH_SEPARATOR) }
+        if path.contains(&PATH_SEPARATOR) {
             return Err(JoinPathsError)
         }
         joined.extend_from_slice(path);
@@ -191,7 +198,7 @@ pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
 
 impl fmt::Display for JoinPathsError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        "path segment contains separator `:`".fmt(f)
+        write!(f, "path segment contains separator `{}`", PATH_SEPARATOR)
     }
 }
 
@@ -382,6 +389,11 @@ pub fn current_exe() -> io::Result<PathBuf> {
     }
 }
 
+#[cfg(target_os = "redox")]
+pub fn current_exe() -> io::Result<PathBuf> {
+    crate::fs::read_to_string("sys:exe").map(PathBuf::from)
+}
+
 #[cfg(any(target_os = "fuchsia", target_os = "l4re", target_os = "hermit"))]
 pub fn current_exe() -> io::Result<PathBuf> {
     use crate::io::ErrorKind;
@@ -511,11 +523,13 @@ pub fn home_dir() -> Option<PathBuf> {
 
     #[cfg(any(target_os = "android",
               target_os = "ios",
-              target_os = "emscripten"))]
+              target_os = "emscripten",
+              target_os = "redox"))]
     unsafe fn fallback() -> Option<OsString> { None }
     #[cfg(not(any(target_os = "android",
                   target_os = "ios",
-                  target_os = "emscripten")))]
+                  target_os = "emscripten",
+                  target_os = "redox")))]
     unsafe fn fallback() -> Option<OsString> {
         let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) {
             n if n < 0 => 512 as usize,
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index d36e94df63f..029f4216b7e 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -26,7 +26,8 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
                 target_os = "freebsd",
                 target_os = "linux",
                 target_os = "netbsd",
-                target_os = "openbsd")) &&
+                target_os = "openbsd",
+                target_os = "redox")) &&
        !INVALID.load(Ordering::SeqCst)
     {
 
diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index f6a12a16396..6bb20bbe087 100644
--- a/src/libstd/sys/unix/process/process_common.rs
+++ b/src/libstd/sys/unix/process/process_common.rs
@@ -12,6 +12,14 @@ use crate::collections::BTreeMap;
 
 use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
 
+cfg_if::cfg_if! {
+    if #[cfg(target_os = "redox")] {
+        const DEV_NULL: &'static str = "null:\0";
+    } else {
+        const DEV_NULL: &'static str = "/dev/null\0";
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Command
 ////////////////////////////////////////////////////////////////////////////////
@@ -298,7 +306,7 @@ impl Stdio {
                 opts.read(readable);
                 opts.write(!readable);
                 let path = unsafe {
-                    CStr::from_ptr("/dev/null\0".as_ptr() as *const _)
+                    CStr::from_ptr(DEV_NULL.as_ptr() as *const _)
                 };
                 let fd = File::open_c(&path, &opts)?;
                 Ok((ChildStdio::Owned(fd.into_fd()), None))
@@ -437,7 +445,7 @@ mod tests {
 
     #[cfg(target_os = "android")]
     unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
-        libc::memset(set as *mut _, 0, mem::size_of::<libc::sigset_t>());
+        set.write_bytes(0u8, 1);
         return 0;
     }
 
@@ -466,11 +474,11 @@ mod tests {
             // Test to make sure that a signal mask does not get inherited.
             let mut cmd = Command::new(OsStr::new("cat"));
 
-            let mut set: libc::sigset_t = mem::uninitialized();
-            let mut old_set: libc::sigset_t = mem::uninitialized();
-            t!(cvt(sigemptyset(&mut set)));
-            t!(cvt(sigaddset(&mut set, libc::SIGINT)));
-            t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set)));
+            let mut set = mem::MaybeUninit::<libc::sigset_t>::uninit();
+            let mut old_set = mem::MaybeUninit::<libc::sigset_t>::uninit();
+            t!(cvt(sigemptyset(set.as_mut_ptr())));
+            t!(cvt(sigaddset(set.as_mut_ptr(), libc::SIGINT)));
+            t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), old_set.as_mut_ptr())));
 
             cmd.stdin(Stdio::MakePipe);
             cmd.stdout(Stdio::MakePipe);
@@ -479,7 +487,7 @@ mod tests {
             let stdin_write = pipes.stdin.take().unwrap();
             let stdout_read = pipes.stdout.take().unwrap();
 
-            t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &old_set,
+            t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, old_set.as_ptr(),
                                          ptr::null_mut())));
 
             t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index 220b1fd4531..327d82e60cf 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -47,7 +47,7 @@ impl Command {
             match result {
                 0 => {
                     drop(input);
-                    let err = self.do_exec(theirs, envp.as_ref());
+                    let Err(err) = self.do_exec(theirs, envp.as_ref());
                     let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
                     let bytes = [
                         (errno >> 24) as u8,
@@ -123,7 +123,8 @@ impl Command {
                     // environment lock before we try to exec.
                     let _lock = sys::os::env_lock();
 
-                    self.do_exec(theirs, envp.as_ref())
+                    let Err(e) = self.do_exec(theirs, envp.as_ref());
+                    e
                 }
             }
             Err(e) => e,
@@ -164,51 +165,47 @@ impl Command {
         &mut self,
         stdio: ChildPipes,
         maybe_envp: Option<&CStringArray>
-    ) -> io::Error {
+    ) -> Result<!, io::Error> {
         use crate::sys::{self, cvt_r};
 
-        macro_rules! t {
-            ($e:expr) => (match $e {
-                Ok(e) => e,
-                Err(e) => return e,
-            })
-        }
-
         if let Some(fd) = stdio.stdin.fd() {
-            t!(cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO)));
+            cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO))?;
         }
         if let Some(fd) = stdio.stdout.fd() {
-            t!(cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO)));
+            cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO))?;
         }
         if let Some(fd) = stdio.stderr.fd() {
-            t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO)));
+            cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?;
         }
 
         if cfg!(not(any(target_os = "l4re"))) {
             if let Some(u) = self.get_gid() {
-                t!(cvt(libc::setgid(u as gid_t)));
+                cvt(libc::setgid(u as gid_t))?;
             }
             if let Some(u) = self.get_uid() {
-                // When dropping privileges from root, the `setgroups` call
-                // will remove any extraneous groups. If we don't call this,
-                // then even though our uid has dropped, we may still have
-                // groups that enable us to do super-user things. This will
-                // fail if we aren't root, so don't bother checking the
-                // return value, this is just done as an optimistic
-                // privilege dropping function.
-                let _ = libc::setgroups(0, ptr::null());
-
-                t!(cvt(libc::setuid(u as uid_t)));
+                //FIXME: Redox kernel does not support setgroups yet
+                if cfg!(not(target_os = "redox")) {
+                    // When dropping privileges from root, the `setgroups` call
+                    // will remove any extraneous groups. If we don't call this,
+                    // then even though our uid has dropped, we may still have
+                    // groups that enable us to do super-user things. This will
+                    // fail if we aren't root, so don't bother checking the
+                    // return value, this is just done as an optimistic
+                    // privilege dropping function.
+                    let _ = libc::setgroups(0, ptr::null());
+                }
+
+                cvt(libc::setuid(u as uid_t))?;
             }
         }
         if let Some(ref cwd) = *self.get_cwd() {
-            t!(cvt(libc::chdir(cwd.as_ptr())));
+            cvt(libc::chdir(cwd.as_ptr()))?;
         }
 
         // emscripten has no signal support.
         #[cfg(not(any(target_os = "emscripten")))]
         {
-            use crate::mem;
+            use crate::mem::MaybeUninit;
             // Reset signal handling so the child process starts in a
             // standardized state. libstd ignores SIGPIPE, and signal-handling
             // libraries often set a mask. Child processes inherit ignored
@@ -216,27 +213,25 @@ impl Command {
             // UNIX programs do not reset these things on their own, so we
             // need to clean things up now to avoid confusing the program
             // we're about to run.
-            let mut set: libc::sigset_t = mem::uninitialized();
+            let mut set = MaybeUninit::<libc::sigset_t>::uninit();
             if cfg!(target_os = "android") {
                 // Implementing sigemptyset allow us to support older Android
                 // versions. See the comment about Android and sig* functions in
                 // process_common.rs
-                libc::memset(&mut set as *mut _ as *mut _,
-                             0,
-                             mem::size_of::<libc::sigset_t>());
+                set.as_mut_ptr().write_bytes(0u8, 1);
             } else {
-                t!(cvt(libc::sigemptyset(&mut set)));
+                cvt(libc::sigemptyset(set.as_mut_ptr()))?;
             }
-            t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
-                                         ptr::null_mut())));
+            cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(),
+                                         ptr::null_mut()))?;
             let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
             if ret == libc::SIG_ERR {
-                return io::Error::last_os_error()
+                return Err(io::Error::last_os_error())
             }
         }
 
         for callback in self.get_closures().iter_mut() {
-            t!(callback());
+            callback()?;
         }
 
         // Although we're performing an exec here we may also return with an
@@ -261,7 +256,7 @@ impl Command {
         }
 
         libc::execvp(self.get_argv()[0], self.get_argv().as_ptr());
-        io::Error::last_os_error()
+        Err(io::Error::last_os_error())
     }
 
     #[cfg(not(any(target_os = "macos", target_os = "freebsd",
@@ -279,13 +274,13 @@ impl Command {
     fn posix_spawn(&mut self, stdio: &ChildPipes, envp: Option<&CStringArray>)
         -> io::Result<Option<Process>>
     {
-        use crate::mem;
+        use crate::mem::MaybeUninit;
         use crate::sys;
 
         if self.get_gid().is_some() ||
             self.get_uid().is_some() ||
             self.env_saw_path() ||
-            self.get_closures().len() != 0 {
+            !self.get_closures().is_empty() {
             return Ok(None)
         }
 
@@ -321,63 +316,63 @@ impl Command {
 
         let mut p = Process { pid: 0, status: None };
 
-        struct PosixSpawnFileActions(libc::posix_spawn_file_actions_t);
+        struct PosixSpawnFileActions(MaybeUninit<libc::posix_spawn_file_actions_t>);
 
         impl Drop for PosixSpawnFileActions {
             fn drop(&mut self) {
                 unsafe {
-                    libc::posix_spawn_file_actions_destroy(&mut self.0);
+                    libc::posix_spawn_file_actions_destroy(self.0.as_mut_ptr());
                 }
             }
         }
 
-        struct PosixSpawnattr(libc::posix_spawnattr_t);
+        struct PosixSpawnattr(MaybeUninit<libc::posix_spawnattr_t>);
 
         impl Drop for PosixSpawnattr {
             fn drop(&mut self) {
                 unsafe {
-                    libc::posix_spawnattr_destroy(&mut self.0);
+                    libc::posix_spawnattr_destroy(self.0.as_mut_ptr());
                 }
             }
         }
 
         unsafe {
-            let mut file_actions = PosixSpawnFileActions(mem::uninitialized());
-            let mut attrs = PosixSpawnattr(mem::uninitialized());
+            let mut file_actions = PosixSpawnFileActions(MaybeUninit::uninit());
+            let mut attrs = PosixSpawnattr(MaybeUninit::uninit());
 
-            libc::posix_spawnattr_init(&mut attrs.0);
-            libc::posix_spawn_file_actions_init(&mut file_actions.0);
+            libc::posix_spawnattr_init(attrs.0.as_mut_ptr());
+            libc::posix_spawn_file_actions_init(file_actions.0.as_mut_ptr());
 
             if let Some(fd) = stdio.stdin.fd() {
-                cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
+                cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
                                                            fd,
                                                            libc::STDIN_FILENO))?;
             }
             if let Some(fd) = stdio.stdout.fd() {
-                cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
+                cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
                                                            fd,
                                                            libc::STDOUT_FILENO))?;
             }
             if let Some(fd) = stdio.stderr.fd() {
-                cvt(libc::posix_spawn_file_actions_adddup2(&mut file_actions.0,
+                cvt(libc::posix_spawn_file_actions_adddup2(file_actions.0.as_mut_ptr(),
                                                            fd,
                                                            libc::STDERR_FILENO))?;
             }
             if let Some((f, cwd)) = addchdir {
-                cvt(f(&mut file_actions.0, cwd.as_ptr()))?;
+                cvt(f(file_actions.0.as_mut_ptr(), cwd.as_ptr()))?;
             }
 
-            let mut set: libc::sigset_t = mem::uninitialized();
-            cvt(libc::sigemptyset(&mut set))?;
-            cvt(libc::posix_spawnattr_setsigmask(&mut attrs.0,
-                                                 &set))?;
-            cvt(libc::sigaddset(&mut set, libc::SIGPIPE))?;
-            cvt(libc::posix_spawnattr_setsigdefault(&mut attrs.0,
-                                                    &set))?;
+            let mut set = MaybeUninit::<libc::sigset_t>::uninit();
+            cvt(libc::sigemptyset(set.as_mut_ptr()))?;
+            cvt(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(),
+                                                 set.as_ptr()))?;
+            cvt(libc::sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?;
+            cvt(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(),
+                                                    set.as_ptr()))?;
 
             let flags = libc::POSIX_SPAWN_SETSIGDEF |
                 libc::POSIX_SPAWN_SETSIGMASK;
-            cvt(libc::posix_spawnattr_setflags(&mut attrs.0, flags as _))?;
+            cvt(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?;
 
             // Make sure we synchronize access to the global `environ` resource
             let _env_lock = sys::os::env_lock();
@@ -386,8 +381,8 @@ impl Command {
             let ret = libc::posix_spawnp(
                 &mut p.pid,
                 self.get_argv()[0],
-                &file_actions.0,
-                &attrs.0,
+                file_actions.0.as_ptr(),
+                attrs.0.as_ptr(),
                 self.get_argv().as_ptr() as *const _,
                 envp as *const _,
             );
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs
index 77f1439e17b..c5be1763302 100644
--- a/src/libstd/sys/unix/rand.rs
+++ b/src/libstd/sys/unix/rand.rs
@@ -15,7 +15,8 @@ pub fn hashmap_random_keys() -> (u64, u64) {
           not(target_os = "ios"),
           not(target_os = "openbsd"),
           not(target_os = "freebsd"),
-          not(target_os = "fuchsia")))]
+          not(target_os = "fuchsia"),
+          not(target_os = "redox")))]
 mod imp {
     use crate::fs::File;
     use crate::io::Read;
@@ -47,7 +48,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 {
@@ -169,3 +175,15 @@ mod imp {
         unsafe { zx_cprng_draw(v.as_mut_ptr(), v.len()) }
     }
 }
+
+#[cfg(target_os = "redox")]
+mod imp {
+    use crate::fs::File;
+    use crate::io::Read;
+
+    pub fn fill_bytes(v: &mut [u8]) {
+        // Open rand:, read from it, and close it again.
+        let mut file = File::open("rand:").expect("failed to open rand:");
+        file.read_exact(v).expect("failed to read rand:")
+    }
+}
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index f4a1783ce89..988881e3596 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -122,12 +122,26 @@ impl Thread {
                                      name.as_ptr() as *mut libc::c_void);
         }
     }
+
+    #[cfg(target_os = "solaris")]
+    pub fn set_name(name: &CStr) {
+        weak! {
+            fn pthread_setname_np(
+                libc::pthread_t, *const libc::c_char
+            ) -> libc::c_int
+        }
+
+        if let Some(f) = pthread_setname_np.get() {
+            unsafe { f(libc::pthread_self(), name.as_ptr()); }
+        }
+    }
+
     #[cfg(any(target_env = "newlib",
-              target_os = "solaris",
               target_os = "haiku",
               target_os = "l4re",
               target_os = "emscripten",
-              target_os = "hermit"))]
+              target_os = "hermit",
+              target_os = "redox"))]
     pub fn set_name(_name: &CStr) {
         // Newlib, Illumos, Haiku, and Emscripten have no way to set a thread name.
     }
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index e21c32cd91b..02f377d55c9 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -137,9 +137,21 @@ mod inner {
         t: Timespec::zero(),
     };
 
+    #[repr(C)]
+    #[derive(Copy, Clone)]
+    struct mach_timebase_info {
+        numer: u32,
+        denom: u32,
+    }
+    type mach_timebase_info_t = *mut mach_timebase_info;
+    type kern_return_t = libc::c_int;
+
     impl Instant {
         pub fn now() -> Instant {
-            Instant { t: unsafe { libc::mach_absolute_time() } }
+            extern "C" {
+                fn mach_absolute_time() -> u64;
+            }
+            Instant { t: unsafe { mach_absolute_time() } }
         }
 
         pub const fn zero() -> Instant {
@@ -230,8 +242,8 @@ mod inner {
         Some(mul_div_u64(nanos, info.denom as u64, info.numer as u64))
     }
 
-    fn info() -> libc::mach_timebase_info {
-        static mut INFO: libc::mach_timebase_info = libc::mach_timebase_info {
+    fn info() -> mach_timebase_info {
+        static mut INFO: mach_timebase_info = mach_timebase_info {
             numer: 0,
             denom: 0,
         };
@@ -245,7 +257,12 @@ mod inner {
 
             // ... otherwise learn for ourselves ...
             let mut info = mem::zeroed();
-            libc::mach_timebase_info(&mut info);
+            extern "C" {
+                fn mach_timebase_info(info: mach_timebase_info_t)
+                                      -> kern_return_t;
+            }
+
+            mach_timebase_info(&mut info);
 
             // ... and attempt to be the one thread that stores it globally for
             // all other threads
diff --git a/src/libstd/sys/vxworks/alloc.rs b/src/libstd/sys/vxworks/alloc.rs
new file mode 100644
index 00000000000..e0c560b9214
--- /dev/null
+++ b/src/libstd/sys/vxworks/alloc.rs
@@ -0,0 +1,53 @@
+use crate::ptr;
+use crate::sys_common::alloc::{MIN_ALIGN, realloc_fallback};
+use crate::alloc::{GlobalAlloc, Layout, System};
+
+#[stable(feature = "alloc_system_type", since = "1.28.0")]
+unsafe impl GlobalAlloc for System {
+    #[inline]
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
+            libc::malloc(layout.size()) as *mut u8
+        } else {
+            aligned_malloc(&layout)
+        }
+    }
+
+    #[inline]
+    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+        if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
+            libc::calloc(layout.size(), 1) as *mut u8
+        } else {
+            let ptr = self.alloc(layout.clone());
+            if !ptr.is_null() {
+                ptr::write_bytes(ptr, 0, layout.size());
+            }
+            ptr
+        }
+    }
+
+    #[inline]
+    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
+        libc::free(ptr as *mut libc::c_void)
+    }
+
+    #[inline]
+    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
+        if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
+            libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
+        } else {
+            realloc_fallback(self, ptr, layout, new_size)
+        }
+    }
+}
+
+#[inline]
+unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
+    let mut out = ptr::null_mut();
+    let ret = libc::posix_memalign(&mut out, layout.align(), layout.size());
+    if ret != 0 {
+        ptr::null_mut()
+    } else {
+        out as *mut u8
+    }
+}
diff --git a/src/libstd/sys/redox/args.rs b/src/libstd/sys/vxworks/args.rs
index f9e2f5ba311..11c3cb78819 100644
--- a/src/libstd/sys/redox/args.rs
+++ b/src/libstd/sys/vxworks/args.rs
@@ -1,10 +1,4 @@
-//! Global initialization and retrieval of command line arguments.
-//!
-//! On some platforms these are stored during runtime startup,
-//! and on some they are retrieved from the system on demand.
-
 #![allow(dead_code)] // runtime init functions not used during testing
-
 use crate::ffi::OsString;
 use crate::marker::PhantomData;
 use crate::vec;
@@ -46,51 +40,46 @@ impl DoubleEndedIterator for Args {
 }
 
 mod imp {
-    use crate::os::unix::prelude::*;
-    use crate::mem;
+    use crate::ptr;
     use crate::ffi::{CStr, OsString};
     use crate::marker::PhantomData;
+    use libc;
     use super::Args;
 
     use crate::sys_common::mutex::Mutex;
 
-    static mut GLOBAL_ARGS_PTR: usize = 0;
+    static mut ARGC: isize = 0;
+    static mut ARGV: *const *const u8 = ptr::null();
     static LOCK: Mutex = Mutex::new();
 
     pub unsafe fn init(argc: isize, argv: *const *const u8) {
-        let args = (0..argc).map(|i| {
-            CStr::from_ptr(*argv.offset(i) as *const libc::c_char).to_bytes().to_vec()
-        }).collect();
-
         let _guard = LOCK.lock();
-        let ptr = get_global_ptr();
-        assert!((*ptr).is_none());
-        (*ptr) = Some(box args);
+        ARGC = argc;
+        ARGV = argv;
     }
 
     pub unsafe fn cleanup() {
         let _guard = LOCK.lock();
-        *get_global_ptr() = None;
+        ARGC = 0;
+        ARGV = ptr::null();
     }
 
     pub fn args() -> Args {
-        let bytes = clone().unwrap_or_default();
-        let v: Vec<OsString> = bytes.into_iter().map(|v| {
-            OsStringExt::from_vec(v)
-        }).collect();
-        Args { iter: v.into_iter(), _dont_send_or_sync_me: PhantomData }
+        Args {
+            iter: clone().into_iter(),
+            _dont_send_or_sync_me: PhantomData
+        }
     }
 
-    fn clone() -> Option<Vec<Vec<u8>>> {
+    fn clone() -> Vec<OsString> {
         unsafe {
             let _guard = LOCK.lock();
-            let ptr = get_global_ptr();
-            (*ptr).as_ref().map(|s| (**s).clone())
+            let ret = (0..ARGC).map(|i| {
+                let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
+                use crate::sys::vxworks::ext::ffi::OsStringExt;
+                OsStringExt::from_vec(cstr.to_bytes().to_vec())
+            }).collect();
+            return ret
         }
     }
-
-    unsafe fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
-        mem::transmute(&GLOBAL_ARGS_PTR)
-    }
-
 }
diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/vxworks/backtrace/mod.rs
index 0887e5a4df9..0887e5a4df9 100644
--- a/src/libstd/sys/unix/backtrace/mod.rs
+++ b/src/libstd/sys/vxworks/backtrace/mod.rs
diff --git a/src/libstd/sys/unix/backtrace/printing/dladdr.rs b/src/libstd/sys/vxworks/backtrace/printing/dladdr.rs
index cf3bda640e9..202164dd3c4 100644
--- a/src/libstd/sys/unix/backtrace/printing/dladdr.rs
+++ b/src/libstd/sys/vxworks/backtrace/printing/dladdr.rs
@@ -30,5 +30,6 @@ struct Dl_info {
 }
 
 extern {
+    #[ link_name = "_rtld_dladdr" ]
     fn dladdr(addr: *const libc::c_void, info: *mut Dl_info) -> libc::c_int;
 }
diff --git a/src/libstd/sys/unix/backtrace/printing/mod.rs b/src/libstd/sys/vxworks/backtrace/printing/mod.rs
index d090caede43..d090caede43 100644
--- a/src/libstd/sys/unix/backtrace/printing/mod.rs
+++ b/src/libstd/sys/vxworks/backtrace/printing/mod.rs
diff --git a/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs b/src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs
index a628d107ad6..a628d107ad6 100644
--- a/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
+++ b/src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs
diff --git a/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs b/src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs
index e6379132baf..e6379132baf 100644
--- a/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
+++ b/src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs
diff --git a/src/libstd/sys/unix/backtrace/tracing/mod.rs b/src/libstd/sys/vxworks/backtrace/tracing/mod.rs
index 11863e64545..11863e64545 100644
--- a/src/libstd/sys/unix/backtrace/tracing/mod.rs
+++ b/src/libstd/sys/vxworks/backtrace/tracing/mod.rs
diff --git a/src/libstd/sys/redox/cmath.rs b/src/libstd/sys/vxworks/cmath.rs
index f6bb58934fc..f6bb58934fc 100644
--- a/src/libstd/sys/redox/cmath.rs
+++ b/src/libstd/sys/vxworks/cmath.rs
diff --git a/src/libstd/sys/vxworks/condvar.rs b/src/libstd/sys/vxworks/condvar.rs
new file mode 100644
index 00000000000..783c3eb7c76
--- /dev/null
+++ b/src/libstd/sys/vxworks/condvar.rs
@@ -0,0 +1,96 @@
+use crate::cell::UnsafeCell;
+use crate::sys::mutex::{self, Mutex};
+use crate::time::Duration;
+
+pub struct Condvar { inner: UnsafeCell<libc::pthread_cond_t> }
+
+unsafe impl Send for Condvar {}
+unsafe impl Sync for Condvar {}
+
+const TIMESPEC_MAX: libc::timespec = libc::timespec {
+    tv_sec: <libc::time_t>::max_value(),
+    tv_nsec: 1_000_000_000 - 1,
+};
+
+fn saturating_cast_to_time_t(value: u64) -> libc::time_t {
+    if value > <libc::time_t>::max_value() as u64 {
+        <libc::time_t>::max_value()
+    } else {
+        value as libc::time_t
+    }
+}
+
+impl Condvar {
+    pub const fn new() -> Condvar {
+        // Might be moved and address is changing it is better to avoid
+        // initialization of potentially opaque OS data before it landed
+        Condvar { inner: UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER) }
+    }
+
+    pub unsafe fn init(&mut self) {
+        use crate::mem::MaybeUninit;
+        let mut attr = MaybeUninit::<libc::pthread_condattr_t>::uninit();
+        let r = libc::pthread_condattr_init(attr.as_mut_ptr());
+        assert_eq!(r, 0);
+        let r = libc::pthread_condattr_setclock(attr.as_mut_ptr(), libc::CLOCK_MONOTONIC);
+        assert_eq!(r, 0);
+        let r = libc::pthread_cond_init(self.inner.get(), attr.as_ptr());
+        assert_eq!(r, 0);
+        let r = libc::pthread_condattr_destroy(attr.as_mut_ptr());
+        assert_eq!(r, 0);
+    }
+
+    #[inline]
+    pub unsafe fn notify_one(&self) {
+        let r = libc::pthread_cond_signal(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+
+    #[inline]
+    pub unsafe fn notify_all(&self) {
+        let r = libc::pthread_cond_broadcast(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+
+    #[inline]
+    pub unsafe fn wait(&self, mutex: &Mutex) {
+        let r = libc::pthread_cond_wait(self.inner.get(), mutex::raw(mutex));
+        debug_assert_eq!(r, 0);
+    }
+
+    // This implementation is used on systems that support pthread_condattr_setclock
+    // where we configure condition variable to use monotonic clock (instead of
+    // default system clock). This approach avoids all problems that result
+    // from changes made to the system time.
+    pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
+        use crate::mem;
+
+        let mut now: libc::timespec = mem::zeroed();
+        let r = libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut now);
+        assert_eq!(r, 0);
+
+        // Nanosecond calculations can't overflow because both values are below 1e9.
+        let nsec = dur.subsec_nanos() + now.tv_nsec as u32;
+
+        let sec = saturating_cast_to_time_t(dur.as_secs())
+            .checked_add((nsec / 1_000_000_000) as libc::time_t)
+            .and_then(|s| s.checked_add(now.tv_sec));
+        let nsec = nsec % 1_000_000_000;
+
+        let timeout = sec.map(|s| {
+            libc::timespec { tv_sec: s, tv_nsec: nsec as _}
+        }).unwrap_or(TIMESPEC_MAX);
+
+        let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
+                                            &timeout);
+        assert!(r == libc::ETIMEDOUT || r == 0);
+        r == 0
+    }
+
+
+    #[inline]
+    pub unsafe fn destroy(&self) {
+        let r = libc::pthread_cond_destroy(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+}
diff --git a/src/libstd/sys/redox/env.rs b/src/libstd/sys/vxworks/env.rs
index bcc0e126b9d..fe1aedd5859 100644
--- a/src/libstd/sys/redox/env.rs
+++ b/src/libstd/sys/vxworks/env.rs
@@ -1,6 +1,6 @@
 pub mod os {
-    pub const FAMILY: &str = "redox";
-    pub const OS: &str = "redox";
+    pub const FAMILY: &str = "vxworks";
+    pub const OS: &str = "vxworks";
     pub const DLL_PREFIX: &str = "lib";
     pub const DLL_SUFFIX: &str = ".so";
     pub const DLL_EXTENSION: &str = "so";
diff --git a/src/libstd/sys/redox/ext/ffi.rs b/src/libstd/sys/vxworks/ext/ffi.rs
index 974d7b82c12..76b34a6b5d8 100644
--- a/src/libstd/sys/redox/ext/ffi.rs
+++ b/src/libstd/sys/vxworks/ext/ffi.rs
@@ -1,10 +1,10 @@
-//! Redox-specific extension to the primitives in the `std::ffi` module.
+//! Unix-specific extension to the primitives in the `std::ffi` module
 //!
 //! # Examples
 //!
 //! ```
 //! use std::ffi::OsString;
-//! use std::os::redox::ffi::OsStringExt;
+//! use std::os::unix::ffi::OsStringExt;
 //!
 //! let bytes = b"foo".to_vec();
 //!
@@ -19,7 +19,7 @@
 //!
 //! ```
 //! use std::ffi::OsStr;
-//! use std::os::redox::ffi::OsStrExt;
+//! use std::os::unix::ffi::OsStrExt;
 //!
 //! let bytes = b"foo";
 //!
diff --git a/src/libstd/sys/vxworks/ext/fs.rs b/src/libstd/sys/vxworks/ext/fs.rs
new file mode 100644
index 00000000000..7ab7f2a1a26
--- /dev/null
+++ b/src/libstd/sys/vxworks/ext/fs.rs
@@ -0,0 +1,801 @@
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use crate::fs::{self, Permissions};
+use crate::io;
+use libc;
+use crate::path::Path;
+use crate::sys;
+use crate::sys_common::{FromInner, AsInner, AsInnerMut};
+use crate::sys::platform::fs::MetadataExt as UnixMetadataExt;
+
+/// Unix-specific extensions to [`File`].
+///
+/// [`File`]: ../../../../std/fs/struct.File.html
+#[stable(feature = "file_offset", since = "1.15.0")]
+pub trait FileExt {
+    /// Reads a number of bytes starting from a given offset.
+    ///
+    /// Returns the number of bytes read.
+    ///
+    /// The offset is relative to the start of the file and thus independent
+    /// from the current cursor.
+    ///
+    /// The current file cursor is not affected by this function.
+    ///
+    /// Note that similar to [`File::read`], it is not an error to return with a
+    /// short read.
+    ///
+    /// [`File::read`]: ../../../../std/fs/struct.File.html#method.read
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::fs::File;
+    /// use std::os::unix::prelude::FileExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let mut buf = [0u8; 8];
+    ///     let file = File::open("foo.txt")?;
+    ///
+    ///     // We now read 8 bytes from the offset 10.
+    ///     let num_bytes_read = file.read_at(&mut buf, 10)?;
+    ///     println!("read {} bytes: {:?}", num_bytes_read, buf);
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "file_offset", since = "1.15.0")]
+    fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
+
+    /// Reads the exact number of byte required to fill `buf` from the given offset.
+    ///
+    /// The offset is relative to the start of the file and thus independent
+    /// from the current cursor.
+    ///
+    /// The current file cursor is not affected by this function.
+    ///
+    /// Similar to [`Read::read_exact`] but uses [`read_at`] instead of `read`.
+    ///
+    /// [`Read::read_exact`]: ../../../../std/io/trait.Read.html#method.read_exact
+    /// [`read_at`]: #tymethod.read_at
+    ///
+    /// # Errors
+    ///
+    /// If this function encounters an error of the kind
+    /// [`ErrorKind::Interrupted`] then the error is ignored and the operation
+    /// will continue.
+    ///
+    /// If this function encounters an "end of file" before completely filling
+    /// the buffer, it returns an error of the kind [`ErrorKind::UnexpectedEof`].
+    /// The contents of `buf` are unspecified in this case.
+    ///
+    /// If any other read error is encountered then this function immediately
+    /// returns. The contents of `buf` are unspecified in this case.
+    ///
+    /// If this function returns an error, it is unspecified how many bytes it
+    /// has read, but it will never read more than would be necessary to
+    /// completely fill the buffer.
+    ///
+    /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted
+    /// [`ErrorKind::UnexpectedEof`]: ../../../../std/io/enum.ErrorKind.html#variant.UnexpectedEof
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(rw_exact_all_at)]
+    /// use std::io;
+    /// use std::fs::File;
+    /// use std::os::unix::prelude::FileExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let mut buf = [0u8; 8];
+    ///     let file = File::open("foo.txt")?;
+    ///
+    ///     // We now read exactly 8 bytes from the offset 10.
+    ///     file.read_exact_at(&mut buf, 10)?;
+    ///     println!("read {} bytes: {:?}", buf.len(), buf);
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "rw_exact_all_at", since = "1.33.0")]
+    fn read_exact_at(&self, mut buf: &mut [u8], mut offset: u64) -> io::Result<()> {
+        while !buf.is_empty() {
+            match self.read_at(buf, offset) {
+                Ok(0) => break,
+                Ok(n) => {
+                    let tmp = buf;
+                    buf = &mut tmp[n..];
+                    offset += n as u64;
+                }
+                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
+                Err(e) => return Err(e),
+            }
+        }
+        if !buf.is_empty() {
+            Err(io::Error::new(io::ErrorKind::UnexpectedEof,
+                               "failed to fill whole buffer"))
+        } else {
+            Ok(())
+        }
+    }
+
+    /// Writes a number of bytes starting from a given offset.
+    ///
+    /// Returns the number of bytes written.
+    ///
+    /// The offset is relative to the start of the file and thus independent
+    /// from the current cursor.
+    ///
+    /// The current file cursor is not affected by this function.
+    ///
+    /// When writing beyond the end of the file, the file is appropriately
+    /// extended and the intermediate bytes are initialized with the value 0.
+    ///
+    /// Note that similar to [`File::write`], it is not an error to return a
+    /// short write.
+    ///
+    /// [`File::write`]: ../../../../std/fs/struct.File.html#write.v
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    /// use std::io;
+    /// use std::os::unix::prelude::FileExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let file = File::open("foo.txt")?;
+    ///
+    ///     // We now write at the offset 10.
+    ///     file.write_at(b"sushi", 10)?;
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "file_offset", since = "1.15.0")]
+    fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
+
+    /// Attempts to write an entire buffer starting from a given offset.
+    ///
+    /// The offset is relative to the start of the file and thus independent
+    /// from the current cursor.
+    ///
+    /// The current file cursor is not affected by this function.
+    ///
+    /// This method will continuously call [`write_at`] until there is no more data
+    /// to be written or an error of non-[`ErrorKind::Interrupted`] kind is
+    /// returned. This method will not return until the entire buffer has been
+    /// successfully written or such an error occurs. The first error that is
+    /// not of [`ErrorKind::Interrupted`] kind generated from this method will be
+    /// returned.
+    ///
+    /// # Errors
+    ///
+    /// This function will return the first error of
+    /// non-[`ErrorKind::Interrupted`] kind that [`write_at`] returns.
+    ///
+    /// [`ErrorKind::Interrupted`]: ../../../../std/io/enum.ErrorKind.html#variant.Interrupted
+    /// [`write_at`]: #tymethod.write_at
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(rw_exact_all_at)]
+    /// use std::fs::File;
+    /// use std::io;
+    /// use std::os::unix::prelude::FileExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let file = File::open("foo.txt")?;
+    ///
+    ///     // We now write at the offset 10.
+    ///     file.write_all_at(b"sushi", 10)?;
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "rw_exact_all_at", since = "1.33.0")]
+    fn write_all_at(&self, mut buf: &[u8], mut offset: u64) -> io::Result<()> {
+        while !buf.is_empty() {
+            match self.write_at(buf, offset) {
+                Ok(0) => return Err(io::Error::new(io::ErrorKind::WriteZero,
+                                                   "failed to write whole buffer")),
+                Ok(n) => {
+                    buf = &buf[n..];
+                    offset += n as u64
+                }
+                Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
+                Err(e) => return Err(e),
+            }
+        }
+        Ok(())
+    }
+}
+
+#[stable(feature = "file_offset", since = "1.15.0")]
+impl FileExt for fs::File {
+    fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
+        self.as_inner().read_at(buf, offset)
+    }
+    fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
+        self.as_inner().write_at(buf, offset)
+    }
+}
+
+/// Unix-specific extensions to [`fs::Permissions`].
+///
+/// [`fs::Permissions`]: ../../../../std/fs/struct.Permissions.html
+#[stable(feature = "fs_ext", since = "1.1.0")]
+pub trait PermissionsExt {
+    /// Returns the underlying raw `st_mode` bits that contain the standard
+    /// Unix permissions for this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    /// use std::os::unix::fs::PermissionsExt;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let f = File::create("foo.txt")?;
+    ///     let metadata = f.metadata()?;
+    ///     let permissions = metadata.permissions();
+    ///
+    ///     println!("permissions: {}", permissions.mode());
+    ///     Ok(()) }
+    /// ```
+    #[stable(feature = "fs_ext", since = "1.1.0")]
+    fn mode(&self) -> u32;
+
+    /// Sets the underlying raw bits for this set of permissions.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    /// use std::os::unix::fs::PermissionsExt;
+    ///
+    /// fn main() -> std::io::Result<()> {
+    ///     let f = File::create("foo.txt")?;
+    ///     let metadata = f.metadata()?;
+    ///     let mut permissions = metadata.permissions();
+    ///
+    ///     permissions.set_mode(0o644); // Read/write for owner and read for others.
+    ///     assert_eq!(permissions.mode(), 0o644);
+    ///     Ok(()) }
+    /// ```
+    #[stable(feature = "fs_ext", since = "1.1.0")]
+    fn set_mode(&mut self, mode: u32);
+
+    /// Creates a new instance of `Permissions` from the given set of Unix
+    /// permission bits.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs::Permissions;
+    /// use std::os::unix::fs::PermissionsExt;
+    ///
+    /// // Read/write for owner and read for others.
+    /// let permissions = Permissions::from_mode(0o644);
+    /// assert_eq!(permissions.mode(), 0o644);
+    /// ```
+    #[stable(feature = "fs_ext", since = "1.1.0")]
+    fn from_mode(mode: u32) -> Self;
+}
+
+#[stable(feature = "fs_ext", since = "1.1.0")]
+impl PermissionsExt for Permissions {
+    fn mode(&self) -> u32 {
+        self.as_inner().mode()
+    }
+
+    fn set_mode(&mut self, mode: u32) {
+        *self = Permissions::from_inner(FromInner::from_inner(mode));
+    }
+
+    fn from_mode(mode: u32) -> Permissions {
+        Permissions::from_inner(FromInner::from_inner(mode))
+    }
+}
+
+/// Unix-specific extensions to [`fs::OpenOptions`].
+///
+/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html
+#[stable(feature = "fs_ext", since = "1.1.0")]
+pub trait OpenOptionsExt {
+    /// Sets the mode bits that a new file will be created with.
+    ///
+    /// If a new file is created as part of a `File::open_opts` call then this
+    /// specified `mode` will be used as the permission bits for the new file.
+    /// If no `mode` is set, the default of `0o666` will be used.
+    /// The operating system masks out bits with the systems `umask`, to produce
+    /// the final permissions.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::OpenOptions;
+    /// use std::os::unix::fs::OpenOptionsExt;
+    ///
+    /// # fn main() {
+    /// let mut options = OpenOptions::new();
+    /// options.mode(0o644); // Give read/write for owner and read for others.
+    /// let file = options.open("foo.txt");
+    /// # }
+    /// ```
+    #[stable(feature = "fs_ext", since = "1.1.0")]
+    fn mode(&mut self, mode: u32) -> &mut Self;
+
+    /// Pass custom flags to the `flags` argument of `open`.
+    ///
+    /// The bits that define the access mode are masked out with `O_ACCMODE`, to
+    /// ensure they do not interfere with the access mode set by Rusts options.
+    ///
+    /// Custom flags can only set flags, not remove flags set by Rusts options.
+    /// This options overwrites any previously set custom flags.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// # #![feature(libc)]
+    /// extern crate libc;
+    /// use std::fs::OpenOptions;
+    /// use std::os::unix::fs::OpenOptionsExt;
+    ///
+    /// # fn main() {
+    /// let mut options = OpenOptions::new();
+    /// options.write(true);
+    /// if cfg!(unix) {
+    ///     options.custom_flags(libc::O_NOFOLLOW);
+    /// }
+    /// let file = options.open("foo.txt");
+    /// # }
+    /// ```
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
+    fn custom_flags(&mut self, flags: i32) -> &mut Self;
+}
+
+/*#[stable(feature = "fs_ext", since = "1.1.0")]
+impl OpenOptionsExt for OpenOptions {
+    fn mode(&mut self, mode: u32) -> &mut OpenOptions {
+        self.as_inner_mut().mode(mode); self
+    }
+
+    fn custom_flags(&mut self, flags: i32) -> &mut OpenOptions {
+        self.as_inner_mut().custom_flags(flags); self
+    }
+}
+*/
+
+/// Unix-specific extensions to [`fs::Metadata`].
+///
+/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+pub trait MetadataExt {
+    /// Returns the ID of the device containing the file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let dev_id = meta.dev();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn dev(&self) -> u64;
+    /// Returns the inode number.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let inode = meta.ino();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn ino(&self) -> u64;
+    /// Returns the rights applied to this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let mode = meta.mode();
+    ///     let user_has_write_access      = mode & 0o200;
+    ///     let user_has_read_write_access = mode & 0o600;
+    ///     let group_has_read_access      = mode & 0o040;
+    ///     let others_have_exec_access    = mode & 0o001;
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn mode(&self) -> u32;
+    /// Returns the number of hard links pointing to this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///  use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let nb_hard_links = meta.nlink();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn nlink(&self) -> u64;
+    /// Returns the user ID of the owner of this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let user_id = meta.uid();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn uid(&self) -> u32;
+    /// Returns the group ID of the owner of this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let group_id = meta.gid();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn gid(&self) -> u32;
+    /// Returns the device ID of this file (if it is a special one).
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let device_id = meta.rdev();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn rdev(&self) -> u64;
+    /// Returns the total size of this file in bytes.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let file_size = meta.size();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn size(&self) -> u64;
+    /// Returns the time of the last access to the file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let last_access_time = meta.atime();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn atime(&self) -> i64;
+    /// Returns the time of the last access to the file in nanoseconds.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let nano_last_access_time = meta.atime_nsec();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn mtime(&self) -> i64;
+    /// Returns the time of the last modification of the file in nanoseconds.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let nano_last_modification_time = meta.mtime_nsec();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn ctime(&self) -> i64;
+    /// Returns the time of the last status change of the file in nanoseconds.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let nano_last_status_change_time = meta.ctime_nsec();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn blksize(&self) -> u64;
+    /// Returns the number of blocks allocated to the file, in 512-byte units.
+    ///
+    /// Please note that this may be smaller than `st_size / 512` when the file has holes.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("some_file")?;
+    ///     let blocks = meta.blocks();
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn blocks(&self) -> u64;
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    fn attrib(&self) -> u8;
+}
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+impl MetadataExt for fs::Metadata {
+    fn dev(&self) -> u64 { self.st_dev() }
+    fn ino(&self) -> u64 { self.st_ino() }
+    fn mode(&self) -> u32 { self.st_mode() }
+    fn nlink(&self) -> u64 { self.st_nlink() }
+    fn uid(&self) -> u32 { self.st_uid() }
+    fn gid(&self) -> u32 { self.st_gid() }
+    fn rdev(&self) -> u64 { self.st_rdev() }
+    fn size(&self) -> u64 { self.st_size() }
+    fn atime(&self) -> i64 { self.st_atime() }
+    fn mtime(&self) -> i64 { self.st_mtime() }
+    fn ctime(&self) -> i64 { self.st_ctime() }
+    fn blksize(&self) -> u64 { self.st_blksize() }
+    fn blocks(&self) -> u64 { self.st_blocks() }
+    fn attrib(&self) -> u8 {self.st_attrib() }
+}
+
+/// Unix-specific extensions for [`FileType`].
+///
+/// Adds support for special Unix file types such as block/character devices,
+/// pipes, and sockets.
+///
+/// [`FileType`]: ../../../../std/fs/struct.FileType.html
+#[stable(feature = "file_type_ext", since = "1.5.0")]
+pub trait FileTypeExt {
+    /// Returns whether this file type is a block device.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::FileTypeExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("block_device_file")?;
+    ///     let file_type = meta.file_type();
+    ///     assert!(file_type.is_block_device());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "file_type_ext", since = "1.5.0")]
+    fn is_block_device(&self) -> bool;
+    /// Returns whether this file type is a char device.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::FileTypeExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("char_device_file")?;
+    ///     let file_type = meta.file_type();
+    ///     assert!(file_type.is_char_device());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "file_type_ext", since = "1.5.0")]
+    fn is_char_device(&self) -> bool;
+    /// Returns whether this file type is a fifo.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::FileTypeExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("fifo_file")?;
+    ///     let file_type = meta.file_type();
+    ///     assert!(file_type.is_fifo());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "file_type_ext", since = "1.5.0")]
+    fn is_fifo(&self) -> bool;
+    /// Returns whether this file type is a socket.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::FileTypeExt;
+    /// use std::io;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let meta = fs::metadata("unix.socket")?;
+    ///     let file_type = meta.file_type();
+    ///     assert!(file_type.is_socket());
+    ///     Ok(())
+    /// }
+    /// ```
+    #[stable(feature = "file_type_ext", since = "1.5.0")]
+    fn is_socket(&self) -> bool;
+}
+
+#[stable(feature = "file_type_ext", since = "1.5.0")]
+impl FileTypeExt for fs::FileType {
+    fn is_block_device(&self) -> bool { self.as_inner().is(libc::S_IFBLK) }
+    fn is_char_device(&self) -> bool { self.as_inner().is(libc::S_IFCHR) }
+    fn is_fifo(&self) -> bool { self.as_inner().is(libc::S_IFIFO) }
+    fn is_socket(&self) -> bool { self.as_inner().is(libc::S_IFSOCK) }
+}
+
+/// Unix-specific extension methods for [`fs::DirEntry`].
+///
+/// [`fs::DirEntry`]: ../../../../std/fs/struct.DirEntry.html
+#[stable(feature = "dir_entry_ext", since = "1.1.0")]
+pub trait DirEntryExt {
+    /// Returns the underlying `d_ino` field in the contained `dirent`
+    /// structure.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs;
+    /// use std::os::unix::fs::DirEntryExt;
+    ///
+    /// if let Ok(entries) = fs::read_dir(".") {
+    ///     for entry in entries {
+    ///         if let Ok(entry) = entry {
+    ///             // Here, `entry` is a `DirEntry`.
+    ///             println!("{:?}: {}", entry.file_name(), entry.ino());
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    #[stable(feature = "dir_entry_ext", since = "1.1.0")]
+    fn ino(&self) -> u64;
+}
+
+#[stable(feature = "dir_entry_ext", since = "1.1.0")]
+impl DirEntryExt for fs::DirEntry {
+    fn ino(&self) -> u64 { self.as_inner().ino() }
+}
+
+/// Creates a new symbolic link on the filesystem.
+///
+/// The `dst` path will be a symbolic link pointing to the `src` path.
+///
+/// # Note
+///
+/// On Windows, you must specify whether a symbolic link points to a file
+/// or directory.  Use `os::windows::fs::symlink_file` to create a
+/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
+/// symbolic link to a directory.  Additionally, the process must have
+/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
+/// symbolic link.
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::os::unix::fs;
+///
+/// fn main() -> std::io::Result<()> {
+///     fs::symlink("a.txt", "b.txt")?;
+///     Ok(())
+/// }
+/// ```
+#[stable(feature = "symlink", since = "1.1.0")]
+pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
+{
+    sys::fs::symlink(src.as_ref(), dst.as_ref())
+}
+
+/// Unix-specific extensions to [`fs::DirBuilder`].
+///
+/// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html
+#[stable(feature = "dir_builder", since = "1.6.0")]
+pub trait DirBuilderExt {
+    /// Sets the mode to create new directories with. This option defaults to
+    /// 0o777.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::DirBuilder;
+    /// use std::os::unix::fs::DirBuilderExt;
+    ///
+    /// let mut builder = DirBuilder::new();
+    /// builder.mode(0o755);
+    /// ```
+    #[stable(feature = "dir_builder", since = "1.6.0")]
+    fn mode(&mut self, mode: u32) -> &mut Self;
+}
+
+#[stable(feature = "dir_builder", since = "1.6.0")]
+impl DirBuilderExt for fs::DirBuilder {
+    fn mode(&mut self, mode: u32) -> &mut fs::DirBuilder {
+        self.as_inner_mut().set_mode(mode);
+        self
+    }
+}
diff --git a/src/libstd/sys/redox/ext/io.rs b/src/libstd/sys/vxworks/ext/io.rs
index c21d216478f..6bcc59495e3 100644
--- a/src/libstd/sys/redox/ext/io.rs
+++ b/src/libstd/sys/vxworks/ext/io.rs
@@ -3,14 +3,14 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::fs;
-use crate::net;
+use crate::os::raw;
 use crate::sys;
 use crate::io;
-use crate::sys_common::{self, AsInner, FromInner, IntoInner};
+use crate::sys_common::{AsInner, FromInner, IntoInner};
 
 /// Raw file descriptors.
 #[stable(feature = "rust1", since = "1.0.0")]
-pub type RawFd = usize;
+pub type RawFd = raw::c_int;
 
 /// A trait to extract the raw unix file descriptor from an underlying
 /// object.
@@ -33,7 +33,7 @@ pub trait AsRawFd {
 /// descriptor.
 #[stable(feature = "from_raw_os", since = "1.1.0")]
 pub trait FromRawFd {
-    /// Constructs a new instances of `Self` from the given raw file
+    /// Constructs a new instance of `Self` from the given raw file
     /// descriptor.
     ///
     /// This function **consumes ownership** of the specified file
@@ -81,92 +81,32 @@ impl IntoRawFd for fs::File {
     }
 }
 
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawFd for net::TcpStream {
-    fn as_raw_fd(&self) -> RawFd {
-        self.as_inner().as_inner().fd().raw()
-    }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawFd for net::TcpListener {
-    fn as_raw_fd(&self) -> RawFd {
-        self.as_inner().as_inner().fd().raw()
-    }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawFd for net::UdpSocket {
-    fn as_raw_fd(&self) -> RawFd {
-        self.as_inner().as_inner().fd().raw()
-    }
-}
-
 #[stable(feature = "asraw_stdio", since = "1.21.0")]
 impl AsRawFd for io::Stdin {
-    fn as_raw_fd(&self) -> RawFd { 0 }
+    fn as_raw_fd(&self) -> RawFd { libc::STDIN_FILENO }
 }
 
 #[stable(feature = "asraw_stdio", since = "1.21.0")]
 impl AsRawFd for io::Stdout {
-    fn as_raw_fd(&self) -> RawFd { 1 }
+    fn as_raw_fd(&self) -> RawFd { libc::STDOUT_FILENO }
 }
 
 #[stable(feature = "asraw_stdio", since = "1.21.0")]
 impl AsRawFd for io::Stderr {
-    fn as_raw_fd(&self) -> RawFd { 2 }
+    fn as_raw_fd(&self) -> RawFd { libc::STDERR_FILENO }
 }
 
 #[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
 impl<'a> AsRawFd for io::StdinLock<'a> {
-    fn as_raw_fd(&self) -> RawFd { 0 }
+    fn as_raw_fd(&self) -> RawFd { libc::STDIN_FILENO }
 }
 
 #[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
 impl<'a> AsRawFd for io::StdoutLock<'a> {
-    fn as_raw_fd(&self) -> RawFd { 1 }
+    fn as_raw_fd(&self) -> RawFd { libc::STDOUT_FILENO }
 }
 
 #[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
 impl<'a> AsRawFd for io::StderrLock<'a> {
-    fn as_raw_fd(&self) -> RawFd { 2 }
-}
-
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-impl FromRawFd for net::TcpStream {
-    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
-        let file = sys::fs::File::from_inner(fd);
-        net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(file))
-    }
-}
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-impl FromRawFd for net::TcpListener {
-    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
-        let file = sys::fs::File::from_inner(fd);
-        net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(file))
-    }
-}
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-impl FromRawFd for net::UdpSocket {
-    unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
-        let file = sys::fs::File::from_inner(fd);
-        net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(file))
-    }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawFd for net::TcpStream {
-    fn into_raw_fd(self) -> RawFd {
-        self.into_inner().into_inner().into_fd().into_raw()
-    }
-}
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawFd for net::TcpListener {
-    fn into_raw_fd(self) -> RawFd {
-        self.into_inner().into_inner().into_fd().into_raw()
-    }
-}
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawFd for net::UdpSocket {
-    fn into_raw_fd(self) -> RawFd {
-        self.into_inner().into_inner().into_fd().into_raw()
-    }
+    fn as_raw_fd(&self) -> RawFd { libc::STDERR_FILENO }
 }
diff --git a/src/libstd/sys/vxworks/ext/mod.rs b/src/libstd/sys/vxworks/ext/mod.rs
new file mode 100644
index 00000000000..c2ebc38c300
--- /dev/null
+++ b/src/libstd/sys/vxworks/ext/mod.rs
@@ -0,0 +1,20 @@
+// Uhhh
+#![stable(feature = "rust1", since = "1.0.0")]
+#![allow(missing_docs)]
+
+pub mod io;
+pub mod ffi;
+pub mod fs;
+pub mod raw;
+pub mod process;
+pub mod net;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod prelude {
+    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+    pub use super::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
+    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+    pub use super::ffi::{OsStrExt, OsStringExt};
+    #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
+    pub use super::fs::{PermissionsExt, OpenOptionsExt, MetadataExt, FileTypeExt};
+}
diff --git a/src/libstd/sys/vxworks/ext/net.rs b/src/libstd/sys/vxworks/ext/net.rs
new file mode 100644
index 00000000000..3f0a7e9e843
--- /dev/null
+++ b/src/libstd/sys/vxworks/ext/net.rs
@@ -0,0 +1,1825 @@
+#![stable(feature = "unix_socket", since = "1.10.0")]
+
+//! Unix-specific networking functionality
+
+#[cfg(unix)]
+use libc;
+
+use crate::ascii;
+use crate::ffi::OsStr;
+use crate::fmt;
+use crate::io::{self, Initializer, IoSlice, IoSliceMut};
+use crate::mem;
+use crate::net::{self, Shutdown};
+use crate::os::unix::ffi::OsStrExt;
+use crate::os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
+use crate::path::Path;
+use crate::time::Duration;
+use crate::sys::{self, cvt};
+use crate::sys::net::Socket;
+use crate::sys_common::{self, AsInner, FromInner, IntoInner};
+
+const MSG_NOSIGNAL: libc::c_int = 0x0;
+
+fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
+    // Work with an actual instance of the type since using a null pointer is UB
+    let base = addr as *const _ as usize;
+    let path = &addr.sun_path as *const _ as usize;
+    path - base
+}
+
+unsafe fn sockaddr_un(path: &Path) -> io::Result<(libc::sockaddr_un, libc::socklen_t)> {
+    let mut addr: libc::sockaddr_un = mem::zeroed();
+    addr.sun_family = libc::AF_UNIX as libc::sa_family_t;
+
+    let bytes = path.as_os_str().as_bytes();
+
+    if bytes.contains(&0) {
+        return Err(io::Error::new(io::ErrorKind::InvalidInput,
+                                  "paths may not contain interior null bytes"));
+    }
+
+    if bytes.len() >= addr.sun_path.len() {
+        return Err(io::Error::new(io::ErrorKind::InvalidInput,
+                                  "path must be shorter than SUN_LEN"));
+    }
+    for (dst, src) in addr.sun_path.iter_mut().zip(bytes.iter()) {
+        *dst = *src as libc::c_char;
+    }
+    // null byte for pathname addresses is already there because we zeroed the
+    // struct
+
+    let mut len = sun_path_offset(&addr) + bytes.len();
+    match bytes.get(0) {
+        Some(&0) | None => {}
+        Some(_) => len += 1,
+    }
+    Ok((addr, len as libc::socklen_t))
+}
+
+enum AddressKind<'a> {
+    Unnamed,
+    Pathname(&'a Path),
+    Abstract(&'a [u8]),
+}
+
+/// An address associated with a Unix socket.
+///
+/// # Examples
+///
+/// ```
+/// use std::os::unix::net::UnixListener;
+///
+/// let socket = match UnixListener::bind("/tmp/sock") {
+///     Ok(sock) => sock,
+///     Err(e) => {
+///         println!("Couldn't bind: {:?}", e);
+///         return
+///     }
+/// };
+/// let addr = socket.local_addr().expect("Couldn't get local address");
+/// ```
+#[derive(Clone)]
+#[stable(feature = "unix_socket", since = "1.10.0")]
+pub struct SocketAddr {
+    addr: libc::sockaddr_un,
+    len: libc::socklen_t,
+}
+
+impl SocketAddr {
+    fn new<F>(f: F) -> io::Result<SocketAddr>
+        where F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> libc::c_int
+    {
+        unsafe {
+            let mut addr: libc::sockaddr_un = mem::zeroed();
+            let mut len = mem::size_of::<libc::sockaddr_un>() as libc::socklen_t;
+            cvt(f(&mut addr as *mut _ as *mut _, &mut len))?;
+            SocketAddr::from_parts(addr, len)
+        }
+    }
+
+    fn from_parts(addr: libc::sockaddr_un, mut len: libc::socklen_t) -> io::Result<SocketAddr> {
+        if len == 0 {
+            // When there is a datagram from unnamed unix socket
+            // linux returns zero bytes of address
+            len = sun_path_offset(&addr) as libc::socklen_t;  // i.e., zero-length address
+        } else if addr.sun_family != libc::AF_UNIX as libc::sa_family_t {
+            return Err(io::Error::new(io::ErrorKind::InvalidInput,
+                                      "file descriptor did not correspond to a Unix socket"));
+        }
+
+        Ok(SocketAddr {
+            addr,
+            len,
+        })
+    }
+
+    /// Returns `true` if the address is unnamed.
+    ///
+    /// # Examples
+    ///
+    /// A named address:
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let socket = UnixListener::bind("/tmp/sock").unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.is_unnamed(), false);
+    /// ```
+    ///
+    /// An unnamed address:
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let socket = UnixDatagram::unbound().unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.is_unnamed(), true);
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn is_unnamed(&self) -> bool {
+        if let AddressKind::Unnamed = self.address() {
+            true
+        } else {
+            false
+        }
+    }
+
+    /// Returns the contents of this address if it is a `pathname` address.
+    ///
+    /// # Examples
+    ///
+    /// With a pathname:
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    /// use std::path::Path;
+    ///
+    /// let socket = UnixListener::bind("/tmp/sock").unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
+    /// ```
+    ///
+    /// Without a pathname:
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let socket = UnixDatagram::unbound().unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// assert_eq!(addr.as_pathname(), None);
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn as_pathname(&self) -> Option<&Path> {
+        if let AddressKind::Pathname(path) = self.address() {
+            Some(path)
+        } else {
+            None
+        }
+    }
+
+    fn address<'a>(&'a self) -> AddressKind<'a> {
+        let len = self.len as usize - sun_path_offset(&self.addr);
+        let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
+
+        if self.addr.sun_path[0] == 0 {
+            AddressKind::Abstract(&path[1..len])
+        } else {
+            AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref())
+        }
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl fmt::Debug for SocketAddr {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self.address() {
+            AddressKind::Unnamed => write!(fmt, "(unnamed)"),
+            AddressKind::Abstract(name) => write!(fmt, "{} (abstract)", AsciiEscaped(name)),
+            AddressKind::Pathname(path) => write!(fmt, "{:?} (pathname)", path),
+        }
+    }
+}
+
+struct AsciiEscaped<'a>(&'a [u8]);
+
+impl<'a> fmt::Display for AsciiEscaped<'a> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(fmt, "\"")?;
+        for byte in self.0.iter().cloned().flat_map(ascii::escape_default) {
+            write!(fmt, "{}", byte as char)?;
+        }
+        write!(fmt, "\"")
+    }
+}
+
+/// A Unix stream socket.
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::os::unix::net::UnixStream;
+/// use std::io::prelude::*;
+///
+/// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap();
+/// stream.write_all(b"hello world").unwrap();
+/// let mut response = String::new();
+/// stream.read_to_string(&mut response).unwrap();
+/// println!("{}", response);
+/// ```
+#[stable(feature = "unix_socket", since = "1.10.0")]
+pub struct UnixStream(Socket);
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl fmt::Debug for UnixStream {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let mut builder = fmt.debug_struct("UnixStream");
+        builder.field("fd", self.0.as_inner());
+        if let Ok(addr) = self.local_addr() {
+            builder.field("local", &addr);
+        }
+        if let Ok(addr) = self.peer_addr() {
+            builder.field("peer", &addr);
+        }
+        builder.finish()
+    }
+}
+
+impl UnixStream {
+    /// Connects to the socket named by `path`.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = match UnixStream::connect("/tmp/sock") {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't connect: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
+        fn inner(path: &Path) -> io::Result<UnixStream> {
+            unsafe {
+                let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
+                let (addr, len) = sockaddr_un(path)?;
+
+                cvt(libc::connect(*inner.as_inner(), &addr as *const _ as *const _, len))?;
+                Ok(UnixStream(inner))
+            }
+        }
+        inner(path.as_ref())
+    }
+
+    /// Creates an unnamed pair of connected sockets.
+    ///
+    /// Returns two `UnixStream`s which are connected to each other.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let (sock1, sock2) = match UnixStream::pair() {
+    ///     Ok((sock1, sock2)) => (sock1, sock2),
+    ///     Err(e) => {
+    ///         println!("Couldn't create a pair of sockets: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
+        let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
+        Ok((UnixStream(i1), UnixStream(i2)))
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `UnixStream` is a reference to the same stream that this
+    /// object references. Both handles will read and write the same stream of
+    /// data, and options set on one stream will be propagated to the other
+    /// stream.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn try_clone(&self) -> io::Result<UnixStream> {
+        self.0.duplicate().map(UnixStream)
+    }
+
+    /// Returns the socket address of the local half of this connection.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// let addr = socket.local_addr().expect("Couldn't get local address");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
+    }
+
+    /// Returns the socket address of the remote half of this connection.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// let addr = socket.peer_addr().expect("Couldn't get peer address");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
+    }
+
+    /// Sets the read timeout for the socket.
+    ///
+    /// If the provided value is [`None`], then [`read`] calls will block
+    /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
+    /// method.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
+    /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
+    /// [`Duration`]: ../../../../std/time/struct.Duration.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
+    /// ```
+    ///
+    /// An [`Err`] is returned if the zero [`Duration`] is passed to this
+    /// method:
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
+    /// let err = result.unwrap_err();
+    /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
+        self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
+    }
+
+    /// Sets the write timeout for the socket.
+    ///
+    /// If the provided value is [`None`], then [`write`] calls will block
+    /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
+    /// passed to this method.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
+    /// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write
+    /// [`Duration`]: ../../../../std/time/struct.Duration.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
+    /// ```
+    ///
+    /// An [`Err`] is returned if the zero [`Duration`] is passed to this
+    /// method:
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::net::UdpSocket;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
+    /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
+    /// let err = result.unwrap_err();
+    /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
+        self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
+    }
+
+    /// Returns the read timeout of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
+    /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
+        self.0.timeout(libc::SO_RCVTIMEO)
+    }
+
+    /// Returns the write timeout of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
+    /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
+        self.0.timeout(libc::SO_SNDTIMEO)
+    }
+
+    /// Moves the socket into or out of nonblocking mode.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        self.0.set_nonblocking(nonblocking)
+    }
+
+    /// Returns the value of the `SO_ERROR` option.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// if let Ok(Some(err)) = socket.take_error() {
+    ///     println!("Got error: {:?}", err);
+    /// }
+    /// ```
+    ///
+    /// # Platform specific
+    /// On Redox this always returns `None`.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.0.take_error()
+    }
+
+    /// Shuts down the read, write, or both halves of this connection.
+    ///
+    /// This function will cause all pending and future I/O calls on the
+    /// specified portions to immediately return with an appropriate value
+    /// (see the documentation of [`Shutdown`]).
+    ///
+    /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixStream;
+    /// use std::net::Shutdown;
+    ///
+    /// let socket = UnixStream::connect("/tmp/sock").unwrap();
+    /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        self.0.shutdown(how)
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl io::Read for UnixStream {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        io::Read::read(&mut &*self, buf)
+    }
+
+    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        io::Read::read_vectored(&mut &*self, bufs)
+    }
+
+    #[inline]
+    unsafe fn initializer(&self) -> Initializer {
+        Initializer::nop()
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl<'a> io::Read for &'a UnixStream {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        self.0.read(buf)
+    }
+
+    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        self.0.read_vectored(bufs)
+    }
+
+    #[inline]
+    unsafe fn initializer(&self) -> Initializer {
+        Initializer::nop()
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl io::Write for UnixStream {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        io::Write::write(&mut &*self, buf)
+    }
+
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        io::Write::write_vectored(&mut &*self, bufs)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        io::Write::flush(&mut &*self)
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl<'a> io::Write for &'a UnixStream {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.0.write(buf)
+    }
+
+    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        self.0.write_vectored(bufs)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl AsRawFd for UnixStream {
+    fn as_raw_fd(&self) -> RawFd {
+        *self.0.as_inner()
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl FromRawFd for UnixStream {
+    unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
+        UnixStream(Socket::from_inner(fd))
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl IntoRawFd for UnixStream {
+    fn into_raw_fd(self) -> RawFd {
+        self.0.into_inner()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRawFd for net::TcpStream {
+    fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRawFd for net::TcpListener {
+    fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl AsRawFd for net::UdpSocket {
+    fn as_raw_fd(&self) -> RawFd { *self.as_inner().socket().as_inner() }
+}
+
+#[stable(feature = "from_raw_os", since = "1.1.0")]
+impl FromRawFd for net::TcpStream {
+    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpStream {
+        let socket = sys::net::Socket::from_inner(fd);
+        net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(socket))
+    }
+}
+
+#[stable(feature = "from_raw_os", since = "1.1.0")]
+impl FromRawFd for net::TcpListener {
+    unsafe fn from_raw_fd(fd: RawFd) -> net::TcpListener {
+        let socket = sys::net::Socket::from_inner(fd);
+        net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(socket))
+    }
+}
+
+#[stable(feature = "from_raw_os", since = "1.1.0")]
+impl FromRawFd for net::UdpSocket {
+    unsafe fn from_raw_fd(fd: RawFd) -> net::UdpSocket {
+        let socket = sys::net::Socket::from_inner(fd);
+        net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(socket))
+    }
+}
+
+#[stable(feature = "into_raw_os", since = "1.4.0")]
+impl IntoRawFd for net::TcpStream {
+    fn into_raw_fd(self) -> RawFd {
+        self.into_inner().into_socket().into_inner()
+    }
+}
+#[stable(feature = "into_raw_os", since = "1.4.0")]
+impl IntoRawFd for net::TcpListener {
+    fn into_raw_fd(self) -> RawFd {
+        self.into_inner().into_socket().into_inner()
+    }
+}
+#[stable(feature = "into_raw_os", since = "1.4.0")]
+impl IntoRawFd for net::UdpSocket {
+    fn into_raw_fd(self) -> RawFd {
+        self.into_inner().into_socket().into_inner()
+    }
+}
+
+/// A structure representing a Unix domain socket server.
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::thread;
+/// use std::os::unix::net::{UnixStream, UnixListener};
+///
+/// fn handle_client(stream: UnixStream) {
+///     // ...
+/// }
+///
+/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+///
+/// // accept connections and process them, spawning a new thread for each one
+/// for stream in listener.incoming() {
+///     match stream {
+///         Ok(stream) => {
+///             /* connection succeeded */
+///             thread::spawn(|| handle_client(stream));
+///         }
+///         Err(err) => {
+///             /* connection failed */
+///             break;
+///         }
+///     }
+/// }
+/// ```
+#[stable(feature = "unix_socket", since = "1.10.0")]
+pub struct UnixListener(Socket);
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl fmt::Debug for UnixListener {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let mut builder = fmt.debug_struct("UnixListener");
+        builder.field("fd", self.0.as_inner());
+        if let Ok(addr) = self.local_addr() {
+            builder.field("local", &addr);
+        }
+        builder.finish()
+    }
+}
+
+impl UnixListener {
+    /// Creates a new `UnixListener` bound to the specified socket.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = match UnixListener::bind("/path/to/the/socket") {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't connect: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
+        fn inner(path: &Path) -> io::Result<UnixListener> {
+            unsafe {
+                let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
+                let (addr, len) = sockaddr_un(path)?;
+
+                cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len as _))?;
+                cvt(libc::listen(*inner.as_inner(), 128))?;
+
+                Ok(UnixListener(inner))
+            }
+        }
+        inner(path.as_ref())
+    }
+
+    /// Accepts a new incoming connection to this listener.
+    ///
+    /// This function will block the calling thread until a new Unix connection
+    /// is established. When established, the corresponding [`UnixStream`] and
+    /// the remote peer's address will be returned.
+    ///
+    /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// match listener.accept() {
+    ///     Ok((socket, addr)) => println!("Got a client: {:?}", addr),
+    ///     Err(e) => println!("accept function failed: {:?}", e),
+    /// }
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
+        let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
+        let mut len = mem::size_of_val(&storage) as libc::socklen_t;
+        let sock = self.0.accept(&mut storage as *mut _ as *mut _, &mut len)?;
+        let addr = SocketAddr::from_parts(storage, len)?;
+        Ok((UnixStream(sock), addr))
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `UnixListener` is a reference to the same socket that this
+    /// object references. Both handles can be used to accept incoming
+    /// connections and options set on one listener will affect the other.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// let listener_copy = listener.try_clone().expect("try_clone failed");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn try_clone(&self) -> io::Result<UnixListener> {
+        self.0.duplicate().map(UnixListener)
+    }
+
+    /// Returns the local socket address of this listener.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// let addr = listener.local_addr().expect("Couldn't get local address");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
+    }
+
+    /// Moves the socket into or out of nonblocking mode.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        self.0.set_nonblocking(nonblocking)
+    }
+
+    /// Returns the value of the `SO_ERROR` option.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixListener;
+    ///
+    /// let listener = UnixListener::bind("/tmp/sock").unwrap();
+    ///
+    /// if let Ok(Some(err)) = listener.take_error() {
+    ///     println!("Got error: {:?}", err);
+    /// }
+    /// ```
+    ///
+    /// # Platform specific
+    /// On Redox this always returns `None`.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.0.take_error()
+    }
+
+    /// Returns an iterator over incoming connections.
+    ///
+    /// The iterator will never return [`None`] and will also not yield the
+    /// peer's [`SocketAddr`] structure.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`SocketAddr`]: struct.SocketAddr.html
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::thread;
+    /// use std::os::unix::net::{UnixStream, UnixListener};
+    ///
+    /// fn handle_client(stream: UnixStream) {
+    ///     // ...
+    /// }
+    ///
+    /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    ///
+    /// for stream in listener.incoming() {
+    ///     match stream {
+    ///         Ok(stream) => {
+    ///             thread::spawn(|| handle_client(stream));
+    ///         }
+    ///         Err(err) => {
+    ///             break;
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn incoming<'a>(&'a self) -> Incoming<'a> {
+        Incoming { listener: self }
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl AsRawFd for UnixListener {
+    fn as_raw_fd(&self) -> RawFd {
+        *self.0.as_inner()
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl FromRawFd for UnixListener {
+    unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
+        UnixListener(Socket::from_inner(fd))
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl IntoRawFd for UnixListener {
+    fn into_raw_fd(self) -> RawFd {
+        self.0.into_inner()
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl<'a> IntoIterator for &'a UnixListener {
+    type Item = io::Result<UnixStream>;
+    type IntoIter = Incoming<'a>;
+
+    fn into_iter(self) -> Incoming<'a> {
+        self.incoming()
+    }
+}
+
+/// An iterator over incoming connections to a [`UnixListener`].
+///
+/// It will never return [`None`].
+///
+/// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+/// [`UnixListener`]: struct.UnixListener.html
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::thread;
+/// use std::os::unix::net::{UnixStream, UnixListener};
+///
+/// fn handle_client(stream: UnixStream) {
+///     // ...
+/// }
+///
+/// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+///
+/// for stream in listener.incoming() {
+///     match stream {
+///         Ok(stream) => {
+///             thread::spawn(|| handle_client(stream));
+///         }
+///         Err(err) => {
+///             break;
+///         }
+///     }
+/// }
+/// ```
+#[derive(Debug)]
+#[stable(feature = "unix_socket", since = "1.10.0")]
+pub struct Incoming<'a> {
+    listener: &'a UnixListener,
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl<'a> Iterator for Incoming<'a> {
+    type Item = io::Result<UnixStream>;
+
+    fn next(&mut self) -> Option<io::Result<UnixStream>> {
+        Some(self.listener.accept().map(|s| s.0))
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (usize::max_value(), None)
+    }
+}
+
+/// A Unix datagram socket.
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::os::unix::net::UnixDatagram;
+///
+/// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
+/// socket.send_to(b"hello world", "/path/to/other/socket").unwrap();
+/// let mut buf = [0; 100];
+/// let (count, address) = socket.recv_from(&mut buf).unwrap();
+/// println!("socket {:?} sent {:?}", address, &buf[..count]);
+/// ```
+#[stable(feature = "unix_socket", since = "1.10.0")]
+pub struct UnixDatagram(Socket);
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl fmt::Debug for UnixDatagram {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let mut builder = fmt.debug_struct("UnixDatagram");
+        builder.field("fd", self.0.as_inner());
+        if let Ok(addr) = self.local_addr() {
+            builder.field("local", &addr);
+        }
+        if let Ok(addr) = self.peer_addr() {
+            builder.field("peer", &addr);
+        }
+        builder.finish()
+    }
+}
+
+impl UnixDatagram {
+    /// Creates a Unix datagram socket bound to the given path.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = match UnixDatagram::bind("/path/to/the/socket") {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't bind: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
+        fn inner(path: &Path) -> io::Result<UnixDatagram> {
+            unsafe {
+                let socket = UnixDatagram::unbound()?;
+                let (addr, len) = sockaddr_un(path)?;
+
+                cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?;
+
+                Ok(socket)
+            }
+        }
+        inner(path.as_ref())
+    }
+
+    /// Creates a Unix Datagram socket which is not bound to any address.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = match UnixDatagram::unbound() {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't unbound: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn unbound() -> io::Result<UnixDatagram> {
+        let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
+        Ok(UnixDatagram(inner))
+    }
+
+    /// Creates an unnamed pair of connected sockets.
+    ///
+    /// Returns two `UnixDatagrams`s which are connected to each other.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let (sock1, sock2) = match UnixDatagram::pair() {
+    ///     Ok((sock1, sock2)) => (sock1, sock2),
+    ///     Err(e) => {
+    ///         println!("Couldn't unbound: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
+        let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
+        Ok((UnixDatagram(i1), UnixDatagram(i2)))
+    }
+
+    /// Connects the socket to the specified address.
+    ///
+    /// The [`send`] method may be used to send data to the specified address.
+    /// [`recv`] and [`recv_from`] will only receive data from that address.
+    ///
+    /// [`send`]: #method.send
+    /// [`recv`]: #method.recv
+    /// [`recv_from`]: #method.recv_from
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// match sock.connect("/path/to/the/socket") {
+    ///     Ok(sock) => sock,
+    ///     Err(e) => {
+    ///         println!("Couldn't connect: {:?}", e);
+    ///         return
+    ///     }
+    /// };
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
+        fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
+            unsafe {
+                let (addr, len) = sockaddr_un(path)?;
+
+                cvt(libc::connect(*d.0.as_inner(), &addr as *const _ as *const _, len))?;
+
+                Ok(())
+            }
+        }
+        inner(self, path.as_ref())
+    }
+
+    /// Creates a new independently owned handle to the underlying socket.
+    ///
+    /// The returned `UnixDatagram` is a reference to the same socket that this
+    /// object references. Both handles can be used to accept incoming
+    /// connections and options set on one side will affect the other.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
+    ///
+    /// let sock_copy = sock.try_clone().expect("try_clone failed");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn try_clone(&self) -> io::Result<UnixDatagram> {
+        self.0.duplicate().map(UnixDatagram)
+    }
+
+    /// Returns the address of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
+    ///
+    /// let addr = sock.local_addr().expect("Couldn't get local address");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn local_addr(&self) -> io::Result<SocketAddr> {
+        SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
+    }
+
+    /// Returns the address of this socket's peer.
+    ///
+    /// The [`connect`] method will connect the socket to a peer.
+    ///
+    /// [`connect`]: #method.connect
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.connect("/path/to/the/socket").unwrap();
+    ///
+    /// let addr = sock.peer_addr().expect("Couldn't get peer address");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+        SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
+    }
+
+    /// Receives data from the socket.
+    ///
+    /// On success, returns the number of bytes read and the address from
+    /// whence the data came.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// let mut buf = vec![0; 10];
+    /// match sock.recv_from(buf.as_mut_slice()) {
+    ///     Ok((size, sender)) => println!("received {} bytes from {:?}", size, sender),
+    ///     Err(e) => println!("recv_from function failed: {:?}", e),
+    /// }
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        let mut count = 0;
+        let addr = SocketAddr::new(|addr, len| {
+            unsafe {
+                count = libc::recvfrom(*self.0.as_inner(),
+                                       buf.as_mut_ptr() as *mut _,
+                                       buf.len(),
+                                       0,
+                                       addr,
+                                       len);
+                if count > 0 {
+                    1
+                } else if count == 0 {
+                    0
+                } else {
+                    -1
+                }
+            }
+        })?;
+
+        Ok((count as usize, addr))
+    }
+
+    /// Receives data from the socket.
+    ///
+    /// On success, returns the number of bytes read.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::bind("/path/to/the/socket").unwrap();
+    /// let mut buf = vec![0; 10];
+    /// sock.recv(buf.as_mut_slice()).expect("recv function failed");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.0.read(buf)
+    }
+
+    /// Sends data on the socket to the specified address.
+    ///
+    /// On success, returns the number of bytes written.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.send_to(b"omelette au fromage", "/some/sock").expect("send_to function failed");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
+        fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
+            unsafe {
+                let (addr, len) = sockaddr_un(path)?;
+
+                let count = cvt(libc::sendto(*d.0.as_inner(),
+                                             buf.as_ptr() as *const _,
+                                             buf.len(),
+                                             MSG_NOSIGNAL,
+                                             &addr as *const _ as *const _,
+                                             len))?;
+                Ok(count as usize)
+            }
+        }
+        inner(self, buf, path.as_ref())
+    }
+
+    /// Sends data on the socket to the socket's peer.
+    ///
+    /// The peer address may be set by the `connect` method, and this method
+    /// will return an error if the socket has not already been connected.
+    ///
+    /// On success, returns the number of bytes written.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.connect("/some/sock").expect("Couldn't connect");
+    /// sock.send(b"omelette au fromage").expect("send_to function failed");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
+        self.0.write(buf)
+    }
+
+    /// Sets the read timeout for the socket.
+    ///
+    /// If the provided value is [`None`], then [`recv`] and [`recv_from`] calls will
+    /// block indefinitely. An [`Err`] is returned if the zero [`Duration`]
+    /// is passed to this method.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
+    /// [`recv`]: #method.recv
+    /// [`recv_from`]: #method.recv_from
+    /// [`Duration`]: ../../../../std/time/struct.Duration.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::time::Duration;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
+    /// ```
+    ///
+    /// An [`Err`] is returned if the zero [`Duration`] is passed to this
+    /// method:
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixDatagram::unbound().unwrap();
+    /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
+    /// let err = result.unwrap_err();
+    /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
+        self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
+    }
+
+    /// Sets the write timeout for the socket.
+    ///
+    /// If the provided value is [`None`], then [`send`] and [`send_to`] calls will
+    /// block indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
+    /// method.
+    ///
+    /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
+    /// [`send`]: #method.send
+    /// [`send_to`]: #method.send_to
+    /// [`Duration`]: ../../../../std/time/struct.Duration.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::time::Duration;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.set_write_timeout(Some(Duration::new(1, 0)))
+    ///     .expect("set_write_timeout function failed");
+    /// ```
+    ///
+    /// An [`Err`] is returned if the zero [`Duration`] is passed to this
+    /// method:
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::time::Duration;
+    ///
+    /// let socket = UnixDatagram::unbound().unwrap();
+    /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
+    /// let err = result.unwrap_err();
+    /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
+        self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
+    }
+
+    /// Returns the read timeout of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::time::Duration;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.set_read_timeout(Some(Duration::new(1, 0))).expect("set_read_timeout function failed");
+    /// assert_eq!(sock.read_timeout().unwrap(), Some(Duration::new(1, 0)));
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
+        self.0.timeout(libc::SO_RCVTIMEO)
+    }
+
+    /// Returns the write timeout of this socket.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::time::Duration;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.set_write_timeout(Some(Duration::new(1, 0)))
+    ///     .expect("set_write_timeout function failed");
+    /// assert_eq!(sock.write_timeout().unwrap(), Some(Duration::new(1, 0)));
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
+        self.0.timeout(libc::SO_SNDTIMEO)
+    }
+
+    /// Moves the socket into or out of nonblocking mode.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.set_nonblocking(true).expect("set_nonblocking function failed");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        self.0.set_nonblocking(nonblocking)
+    }
+
+    /// Returns the value of the `SO_ERROR` option.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// if let Ok(Some(err)) = sock.take_error() {
+    ///     println!("Got error: {:?}", err);
+    /// }
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        self.0.take_error()
+    }
+
+    /// Shut down the read, write, or both halves of this connection.
+    ///
+    /// This function will cause all pending and future I/O calls on the
+    /// specified portions to immediately return with an appropriate value
+    /// (see the documentation of [`Shutdown`]).
+    ///
+    /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
+    ///
+    /// ```no_run
+    /// use std::os::unix::net::UnixDatagram;
+    /// use std::net::Shutdown;
+    ///
+    /// let sock = UnixDatagram::unbound().unwrap();
+    /// sock.shutdown(Shutdown::Both).expect("shutdown function failed");
+    /// ```
+    #[stable(feature = "unix_socket", since = "1.10.0")]
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        self.0.shutdown(how)
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl AsRawFd for UnixDatagram {
+    fn as_raw_fd(&self) -> RawFd {
+        *self.0.as_inner()
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl FromRawFd for UnixDatagram {
+    unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
+        UnixDatagram(Socket::from_inner(fd))
+    }
+}
+
+#[stable(feature = "unix_socket", since = "1.10.0")]
+impl IntoRawFd for UnixDatagram {
+    fn into_raw_fd(self) -> RawFd {
+        self.0.into_inner()
+    }
+}
+
+#[cfg(all(test, not(target_os = "emscripten")))]
+mod test {
+    use crate::thread;
+    use crate::io::{self, ErrorKind};
+    use crate::io::prelude::*;
+    use crate::time::Duration;
+    use crate::sys_common::io::test::tmpdir;
+
+    use super::*;
+
+    macro_rules! or_panic {
+        ($e:expr) => {
+            match $e {
+                Ok(e) => e,
+                Err(e) => panic!("{}", e),
+            }
+        }
+    }
+
+    #[test]
+    fn basic() {
+        let dir = tmpdir();
+        let socket_path = dir.path().join("sock");
+        let msg1 = b"hello";
+        let msg2 = b"world!";
+
+        let listener = or_panic!(UnixListener::bind(&socket_path));
+        let thread = thread::spawn(move || {
+            let mut stream = or_panic!(listener.accept()).0;
+            let mut buf = [0; 5];
+            or_panic!(stream.read(&mut buf));
+            assert_eq!(&msg1[..], &buf[..]);
+            or_panic!(stream.write_all(msg2));
+        });
+
+        let mut stream = or_panic!(UnixStream::connect(&socket_path));
+        assert_eq!(Some(&*socket_path),
+                   stream.peer_addr().unwrap().as_pathname());
+        or_panic!(stream.write_all(msg1));
+        let mut buf = vec![];
+        or_panic!(stream.read_to_end(&mut buf));
+        assert_eq!(&msg2[..], &buf[..]);
+        drop(stream);
+
+        thread.join().unwrap();
+    }
+
+    #[test]
+    fn vectored() {
+        let (mut s1, mut s2) = or_panic!(UnixStream::pair());
+
+        let len = or_panic!(s1.write_vectored(
+            &[IoSlice::new(b"hello"), IoSlice::new(b" "), IoSlice::new(b"world!")],
+        ));
+        assert_eq!(len, 12);
+
+        let mut buf1 = [0; 6];
+        let mut buf2 = [0; 7];
+        let len = or_panic!(s2.read_vectored(
+            &mut [IoSliceMut::new(&mut buf1), IoSliceMut::new(&mut buf2)],
+        ));
+        assert_eq!(len, 12);
+        assert_eq!(&buf1, b"hello ");
+        assert_eq!(&buf2, b"world!\0");
+    }
+
+    #[test]
+    fn pair() {
+        let msg1 = b"hello";
+        let msg2 = b"world!";
+
+        let (mut s1, mut s2) = or_panic!(UnixStream::pair());
+        let thread = thread::spawn(move || {
+            // s1 must be moved in or the test will hang!
+            let mut buf = [0; 5];
+            or_panic!(s1.read(&mut buf));
+            assert_eq!(&msg1[..], &buf[..]);
+            or_panic!(s1.write_all(msg2));
+        });
+
+        or_panic!(s2.write_all(msg1));
+        let mut buf = vec![];
+        or_panic!(s2.read_to_end(&mut buf));
+        assert_eq!(&msg2[..], &buf[..]);
+        drop(s2);
+
+        thread.join().unwrap();
+    }
+
+    #[test]
+    fn try_clone() {
+        let dir = tmpdir();
+        let socket_path = dir.path().join("sock");
+        let msg1 = b"hello";
+        let msg2 = b"world";
+
+        let listener = or_panic!(UnixListener::bind(&socket_path));
+        let thread = thread::spawn(move || {
+            let mut stream = or_panic!(listener.accept()).0;
+            or_panic!(stream.write_all(msg1));
+            or_panic!(stream.write_all(msg2));
+        });
+
+        let mut stream = or_panic!(UnixStream::connect(&socket_path));
+        let mut stream2 = or_panic!(stream.try_clone());
+
+        let mut buf = [0; 5];
+        or_panic!(stream.read(&mut buf));
+        assert_eq!(&msg1[..], &buf[..]);
+        or_panic!(stream2.read(&mut buf));
+        assert_eq!(&msg2[..], &buf[..]);
+
+        thread.join().unwrap();
+    }
+
+    #[test]
+    fn iter() {
+        let dir = tmpdir();
+        let socket_path = dir.path().join("sock");
+
+        let listener = or_panic!(UnixListener::bind(&socket_path));
+        let thread = thread::spawn(move || {
+            for stream in listener.incoming().take(2) {
+                let mut stream = or_panic!(stream);
+                let mut buf = [0];
+                or_panic!(stream.read(&mut buf));
+            }
+        });
+
+        for _ in 0..2 {
+            let mut stream = or_panic!(UnixStream::connect(&socket_path));
+            or_panic!(stream.write_all(&[0]));
+        }
+
+        thread.join().unwrap();
+    }
+
+    #[test]
+    fn long_path() {
+        let dir = tmpdir();
+        let socket_path = dir.path()
+                             .join("asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa\
+                                    sasdfasdfasdasdfasdfasdfadfasdfasdfasdfasdfasdf");
+        match UnixStream::connect(&socket_path) {
+            Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
+            Err(e) => panic!("unexpected error {}", e),
+            Ok(_) => panic!("unexpected success"),
+        }
+
+        match UnixListener::bind(&socket_path) {
+            Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
+            Err(e) => panic!("unexpected error {}", e),
+            Ok(_) => panic!("unexpected success"),
+        }
+
+        match UnixDatagram::bind(&socket_path) {
+            Err(ref e) if e.kind() == io::ErrorKind::InvalidInput => {}
+            Err(e) => panic!("unexpected error {}", e),
+            Ok(_) => panic!("unexpected success"),
+        }
+    }
+
+    #[test]
+    fn timeouts() {
+        let dir = tmpdir();
+        let socket_path = dir.path().join("sock");
+
+        let _listener = or_panic!(UnixListener::bind(&socket_path));
+
+        let stream = or_panic!(UnixStream::connect(&socket_path));
+        let dur = Duration::new(15410, 0);
+
+        assert_eq!(None, or_panic!(stream.read_timeout()));
+
+        or_panic!(stream.set_read_timeout(Some(dur)));
+        assert_eq!(Some(dur), or_panic!(stream.read_timeout()));
+
+        assert_eq!(None, or_panic!(stream.write_timeout()));
+
+        or_panic!(stream.set_write_timeout(Some(dur)));
+        assert_eq!(Some(dur), or_panic!(stream.write_timeout()));
+
+        or_panic!(stream.set_read_timeout(None));
+        assert_eq!(None, or_panic!(stream.read_timeout()));
+
+        or_panic!(stream.set_write_timeout(None));
+        assert_eq!(None, or_panic!(stream.write_timeout()));
+    }
+
+    #[test]
+    fn test_read_timeout() {
+        let dir = tmpdir();
+        let socket_path = dir.path().join("sock");
+
+        let _listener = or_panic!(UnixListener::bind(&socket_path));
+
+        let mut stream = or_panic!(UnixStream::connect(&socket_path));
+        or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
+
+        let mut buf = [0; 10];
+        let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+                "unexpected_error: {:?}", kind);
+    }
+
+    #[test]
+    fn test_read_with_timeout() {
+        let dir = tmpdir();
+        let socket_path = dir.path().join("sock");
+
+        let listener = or_panic!(UnixListener::bind(&socket_path));
+
+        let mut stream = or_panic!(UnixStream::connect(&socket_path));
+        or_panic!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
+
+        let mut other_end = or_panic!(listener.accept()).0;
+        or_panic!(other_end.write_all(b"hello world"));
+
+        let mut buf = [0; 11];
+        or_panic!(stream.read(&mut buf));
+        assert_eq!(b"hello world", &buf[..]);
+
+        let kind = stream.read_exact(&mut buf).err().expect("expected error").kind();
+        assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
+                "unexpected_error: {:?}", kind);
+    }
+
+    // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
+    // when passed zero Durations
+    #[test]
+    fn test_unix_stream_timeout_zero_duration() {
+        let dir = tmpdir();
+        let socket_path = dir.path().join("sock");
+
+        let listener = or_panic!(UnixListener::bind(&socket_path));
+        let stream = or_panic!(UnixStream::connect(&socket_path));
+
+        let result = stream.set_write_timeout(Some(Duration::new(0, 0)));
+        let err = result.unwrap_err();
+        assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+        let result = stream.set_read_timeout(Some(Duration::new(0, 0)));
+        let err = result.unwrap_err();
+        assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+        drop(listener);
+    }
+
+    #[test]
+    fn test_unix_datagram() {
+        let dir = tmpdir();
+        let path1 = dir.path().join("sock1");
+        let path2 = dir.path().join("sock2");
+
+        let sock1 = or_panic!(UnixDatagram::bind(&path1));
+        let sock2 = or_panic!(UnixDatagram::bind(&path2));
+
+        let msg = b"hello world";
+        or_panic!(sock1.send_to(msg, &path2));
+        let mut buf = [0; 11];
+        or_panic!(sock2.recv_from(&mut buf));
+        assert_eq!(msg, &buf[..]);
+    }
+
+    #[test]
+    fn test_unnamed_unix_datagram() {
+        let dir = tmpdir();
+        let path1 = dir.path().join("sock1");
+
+        let sock1 = or_panic!(UnixDatagram::bind(&path1));
+        let sock2 = or_panic!(UnixDatagram::unbound());
+
+        let msg = b"hello world";
+        or_panic!(sock2.send_to(msg, &path1));
+        let mut buf = [0; 11];
+        let (usize, addr) = or_panic!(sock1.recv_from(&mut buf));
+        assert_eq!(usize, 11);
+        assert!(addr.is_unnamed());
+        assert_eq!(msg, &buf[..]);
+    }
+
+    #[test]
+    fn test_connect_unix_datagram() {
+        let dir = tmpdir();
+        let path1 = dir.path().join("sock1");
+        let path2 = dir.path().join("sock2");
+
+        let bsock1 = or_panic!(UnixDatagram::bind(&path1));
+        let bsock2 = or_panic!(UnixDatagram::bind(&path2));
+        let sock = or_panic!(UnixDatagram::unbound());
+        or_panic!(sock.connect(&path1));
+
+        // Check send()
+        let msg = b"hello there";
+        or_panic!(sock.send(msg));
+        let mut buf = [0; 11];
+        let (usize, addr) = or_panic!(bsock1.recv_from(&mut buf));
+        assert_eq!(usize, 11);
+        assert!(addr.is_unnamed());
+        assert_eq!(msg, &buf[..]);
+
+        // Changing default socket works too
+        or_panic!(sock.connect(&path2));
+        or_panic!(sock.send(msg));
+        or_panic!(bsock2.recv_from(&mut buf));
+    }
+
+    #[test]
+    fn test_unix_datagram_recv() {
+        let dir = tmpdir();
+        let path1 = dir.path().join("sock1");
+
+        let sock1 = or_panic!(UnixDatagram::bind(&path1));
+        let sock2 = or_panic!(UnixDatagram::unbound());
+        or_panic!(sock2.connect(&path1));
+
+        let msg = b"hello world";
+        or_panic!(sock2.send(msg));
+        let mut buf = [0; 11];
+        let size = or_panic!(sock1.recv(&mut buf));
+        assert_eq!(size, 11);
+        assert_eq!(msg, &buf[..]);
+    }
+
+    #[test]
+    fn datagram_pair() {
+        let msg1 = b"hello";
+        let msg2 = b"world!";
+
+        let (s1, s2) = or_panic!(UnixDatagram::pair());
+        let thread = thread::spawn(move || {
+            // s1 must be moved in or the test will hang!
+            let mut buf = [0; 5];
+            or_panic!(s1.recv(&mut buf));
+            assert_eq!(&msg1[..], &buf[..]);
+            or_panic!(s1.send(msg2));
+        });
+
+        or_panic!(s2.send(msg1));
+        let mut buf = [0; 6];
+        or_panic!(s2.recv(&mut buf));
+        assert_eq!(&msg2[..], &buf[..]);
+        drop(s2);
+
+        thread.join().unwrap();
+    }
+
+    // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
+    // when passed zero Durations
+    #[test]
+    fn test_unix_datagram_timeout_zero_duration() {
+        let dir = tmpdir();
+        let path = dir.path().join("sock");
+
+        let datagram = or_panic!(UnixDatagram::bind(&path));
+
+        let result = datagram.set_write_timeout(Some(Duration::new(0, 0)));
+        let err = result.unwrap_err();
+        assert_eq!(err.kind(), ErrorKind::InvalidInput);
+
+        let result = datagram.set_read_timeout(Some(Duration::new(0, 0)));
+        let err = result.unwrap_err();
+        assert_eq!(err.kind(), ErrorKind::InvalidInput);
+    }
+
+    #[test]
+    fn abstract_namespace_not_allowed() {
+        assert!(UnixStream::connect("\0asdf").is_err());
+    }
+}
diff --git a/src/libstd/sys/redox/ext/process.rs b/src/libstd/sys/vxworks/ext/process.rs
index e981cb93d44..4de72fa1816 100644
--- a/src/libstd/sys/redox/ext/process.rs
+++ b/src/libstd/sys/vxworks/ext/process.rs
@@ -1,14 +1,14 @@
-//! Redox-specific extensions to primitives in the `std::process` module.
+//! Unix-specific extensions to primitives in the `std::process` module.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::io;
-use crate::os::unix::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd};
+use crate::sys::vxworks::ext::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd};
 use crate::process;
 use crate::sys;
 use crate::sys_common::{AsInnerMut, AsInner, FromInner, IntoInner};
 
-/// Redox-specific extensions to the [`process::Command`] builder,
+/// Unix-specific extensions to the [`process::Command`] builder.
 ///
 /// [`process::Command`]: ../../../../std/process/struct.Command.html
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -17,12 +17,12 @@ pub trait CommandExt {
     /// `setuid` call in the child process. Failure in the `setuid`
     /// call will cause the spawn to fail.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn uid(&mut self, id: u32) -> &mut process::Command;
+    fn uid(&mut self, id: u16) -> &mut process::Command;
 
     /// Similar to `uid`, but sets the group ID of the child process. This has
     /// the same semantics as the `uid` field.
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn gid(&mut self, id: u32) -> &mut process::Command;
+    fn gid(&mut self, id: u16) -> &mut process::Command;
 
     /// Schedules a closure to be run just before the `exec` function is
     /// invoked.
@@ -79,10 +79,20 @@ pub trait CommandExt {
     /// an error indicating why the exec (or another part of the setup of the
     /// `Command`) failed.
     ///
+    /// `exec` not returning has the same implications as calling
+    /// [`process::exit`] – no destructors on the current stack or any other
+    /// thread’s stack will be run. Therefore, it is recommended to only call
+    /// `exec` at a point where it is fine to not run any destructors. Note,
+    /// that the `execvp` syscall independently guarantees that all memory is
+    /// freed and all file descriptors with the `CLOEXEC` option (set by default
+    /// on all file descriptors opened by the standard library) are closed.
+    ///
     /// This function, unlike `spawn`, will **not** `fork` the process to create
     /// a new child. Like spawn, however, the default behavior for the stdio
     /// descriptors will be to inherited from the current process.
     ///
+    /// [`process::exit`]: ../../../process/fn.exit.html
+    ///
     /// # Notes
     ///
     /// The process may be in a "broken state" if this function returns in
@@ -97,12 +107,12 @@ pub trait CommandExt {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl CommandExt for process::Command {
-    fn uid(&mut self, id: u32) -> &mut process::Command {
+    fn uid(&mut self, id: u16) -> &mut process::Command {
         self.as_inner_mut().uid(id);
         self
     }
 
-    fn gid(&mut self, id: u32) -> &mut process::Command {
+    fn gid(&mut self, id: u16) -> &mut process::Command {
         self.as_inner_mut().gid(id);
         self
     }
@@ -119,7 +129,7 @@ impl CommandExt for process::Command {
     }
 }
 
-/// Redox-specific extensions to [`process::ExitStatus`].
+/// Unix-specific extensions to [`process::ExitStatus`].
 ///
 /// [`process::ExitStatus`]: ../../../../std/process/struct.ExitStatus.html
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -195,3 +205,9 @@ impl IntoRawFd for process::ChildStderr {
         self.into_inner().into_fd().into_raw()
     }
 }
+
+/// Returns the OS-assigned process identifier associated with this process's parent.
+#[stable(feature = "unix_ppid", since = "1.27.0")]
+pub fn parent_id() -> u32 {
+    crate::sys::os::getppid()
+}
diff --git a/src/libstd/sys/vxworks/ext/raw.rs b/src/libstd/sys/vxworks/ext/raw.rs
new file mode 100644
index 00000000000..1f134f4e2d1
--- /dev/null
+++ b/src/libstd/sys/vxworks/ext/raw.rs
@@ -0,0 +1,5 @@
+#![stable(feature = "raw_ext", since = "1.1.0")]
+
+#[doc(inline)]
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub use crate::sys::platform::raw::pthread_t;
diff --git a/src/libstd/sys/vxworks/fast_thread_local.rs b/src/libstd/sys/vxworks/fast_thread_local.rs
new file mode 100644
index 00000000000..f5a2e263d25
--- /dev/null
+++ b/src/libstd/sys/vxworks/fast_thread_local.rs
@@ -0,0 +1,36 @@
+#![cfg(target_thread_local)]
+#![unstable(feature = "thread_local_internals", issue = "0")]
+
+// Since what appears to be glibc 2.18 this symbol has been shipped which
+// GCC and clang both use to invoke destructors in thread_local globals, so
+// let's do the same!
+//
+// Note, however, that we run on lots older linuxes, as well as cross
+// compiling from a newer linux to an older linux, so we also have a
+// fallback implementation to use as well.
+//
+// Due to rust-lang/rust#18804, make sure this is not generic!
+pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
+    use crate::mem;
+    use crate::sys_common::thread_local::register_dtor_fallback;
+
+    extern {
+        #[linkage = "extern_weak"]
+        static __dso_handle: *mut u8;
+        #[linkage = "extern_weak"]
+        static __cxa_thread_atexit_impl: *const libc::c_void;
+    }
+    if !__cxa_thread_atexit_impl.is_null() {
+        type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8),
+                                  arg: *mut u8,
+                                  dso_handle: *mut u8) -> libc::c_int;
+        mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)
+            (dtor, t, &__dso_handle as *const _ as *mut _);
+        return
+    }
+    register_dtor_fallback(t, dtor);
+}
+
+pub fn requires_move_before_drop() -> bool {
+    false
+}
diff --git a/src/libstd/sys/vxworks/fd.rs b/src/libstd/sys/vxworks/fd.rs
new file mode 100644
index 00000000000..db2865d2529
--- /dev/null
+++ b/src/libstd/sys/vxworks/fd.rs
@@ -0,0 +1,188 @@
+#![unstable(reason = "not public", issue = "0", feature = "fd")]
+
+use crate::cmp;
+use crate::io::{self, Read, Initializer, IoSlice, IoSliceMut};
+use crate::mem;
+use crate::sys::cvt;
+use crate::sys_common::AsInner;
+
+use libc::{self, c_int, c_void, ssize_t};
+
+#[derive(Debug)]
+pub struct FileDesc {
+    fd: c_int,
+}
+
+fn max_len() -> usize {
+    // The maximum read limit on most posix-like systems is `SSIZE_MAX`,
+    // with the man page quoting that if the count of bytes to read is
+    // greater than `SSIZE_MAX` the result is "unspecified".
+    <ssize_t>::max_value() as usize
+}
+
+impl FileDesc {
+    pub fn new(fd: c_int) -> FileDesc {
+        FileDesc { fd: fd }
+    }
+
+    pub fn raw(&self) -> c_int { self.fd }
+
+    /// Extracts the actual filedescriptor without closing it.
+    pub fn into_raw(self) -> c_int {
+        let fd = self.fd;
+        mem::forget(self);
+        fd
+    }
+
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        let ret = cvt(unsafe {
+            libc::read(self.fd,
+                       buf.as_mut_ptr() as *mut c_void,
+                       cmp::min(buf.len(), max_len()))
+        })?;
+        Ok(ret as usize)
+    }
+
+    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        let ret = cvt(unsafe {
+            libc::readv(self.fd,
+                        bufs.as_ptr() as *const libc::iovec,
+                        cmp::min(bufs.len(), c_int::max_value() as usize) as c_int)
+        })?;
+        Ok(ret as usize)
+    }
+
+    pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        let mut me = self;
+        (&mut me).read_to_end(buf)
+    }
+
+    pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
+        unsafe fn cvt_pread(fd: c_int, buf: *mut c_void, count: usize, offset: i64)
+            -> io::Result<isize>
+        {
+            use libc::pread;
+            cvt(pread(fd, buf, count, offset))
+        }
+
+        unsafe {
+            cvt_pread(self.fd,
+                buf.as_mut_ptr() as *mut c_void,
+                cmp::min(buf.len(), max_len()),
+                offset as i64)
+            .map(|n| n as usize)
+        }
+    }
+
+    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        let ret = cvt(unsafe {
+            libc::write(self.fd,
+            buf.as_ptr() as *const c_void,
+            cmp::min(buf.len(), max_len()))
+        })?;
+        Ok(ret as usize)
+    }
+
+    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        let ret = cvt(unsafe {
+            libc::writev(self.fd,
+                         bufs.as_ptr() as *const libc::iovec,
+                         cmp::min(bufs.len(), c_int::max_value() as usize) as c_int)
+        })?;
+        Ok(ret as usize)
+    }
+
+    pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
+        unsafe fn cvt_pwrite(fd: c_int, buf: *const c_void, count: usize, offset: i64)
+            -> io::Result<isize>
+        {
+            use libc::pwrite;
+            cvt(pwrite(fd, buf, count, offset))
+        }
+
+        unsafe {
+            cvt_pwrite(self.fd,
+                buf.as_ptr() as *const c_void,
+                cmp::min(buf.len(), max_len()),
+                offset as i64)
+                .map(|n| n as usize)
+        }
+    }
+
+    pub fn get_cloexec(&self) -> io::Result<bool> {
+        unsafe {
+            Ok((cvt(libc::fcntl(self.fd, libc::F_GETFD))? & libc::FD_CLOEXEC) != 0)
+        }
+    }
+
+    pub fn set_cloexec(&self) -> io::Result<()> {
+        unsafe {
+            let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?;
+            let new = previous | libc::FD_CLOEXEC;
+            if new != previous {
+                cvt(libc::fcntl(self.fd, libc::F_SETFD, new))?;
+            }
+            Ok(())
+        }
+    }
+
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        unsafe {
+            let v = nonblocking as c_int;
+            cvt(libc::ioctl(self.fd, libc::FIONBIO, &v))?;
+            Ok(())
+        }
+    }
+
+    // refer to pxPipeDrv library documentation.
+    // VxWorks uses fcntl to set O_NONBLOCK to the pipes
+    pub fn set_nonblocking_pipe(&self, nonblocking: bool) -> io::Result<()> {
+        unsafe {
+            let mut flags = cvt(libc::fcntl(self.fd, libc::F_GETFL, 0))?;
+            flags = if nonblocking {
+                flags | libc::O_NONBLOCK
+            } else {
+                flags & !libc::O_NONBLOCK
+            };
+            cvt(libc::fcntl(self.fd, libc::F_SETFL, flags))?;
+            Ok(())
+        }
+    }
+
+
+    pub fn duplicate(&self) -> io::Result<FileDesc> {
+        let fd = self.raw();
+        match cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD_CLOEXEC, 0) }) {
+            Ok(newfd) => {
+                Ok(FileDesc::new(newfd))
+            }
+            Err(e) => return Err(e),
+        }
+    }
+}
+
+impl<'a> Read for &'a FileDesc {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        (**self).read(buf)
+    }
+
+    #[inline]
+    unsafe fn initializer(&self) -> Initializer {
+        Initializer::nop()
+    }
+}
+
+impl AsInner<c_int> for FileDesc {
+    fn as_inner(&self) -> &c_int { &self.fd }
+}
+
+impl Drop for FileDesc {
+    fn drop(&mut self) {
+        // Note that errors are ignored when closing a file descriptor. The
+        // reason for this is that if an error occurs we don't actually know if
+        // the file descriptor was closed or not, and if we retried (for
+        // something like EINTR), we might close another valid file descriptor
+        // (opened after we closed ours.
+        let _ = unsafe { libc::close(self.fd) };
+    }
+}
diff --git a/src/libstd/sys/vxworks/fs.rs b/src/libstd/sys/vxworks/fs.rs
new file mode 100644
index 00000000000..d537d2258fd
--- /dev/null
+++ b/src/libstd/sys/vxworks/fs.rs
@@ -0,0 +1,575 @@
+// copies from linuxx
+use crate::ffi::{CString, CStr, OsString, OsStr};
+use crate::sys::vxworks::ext::ffi::OsStrExt;
+use crate::fmt;
+use crate::io::{self, Error, ErrorKind, SeekFrom, IoSlice, IoSliceMut};
+use crate::mem;
+use crate::path::{Path, PathBuf};
+use crate::ptr;
+use crate::sync::Arc;
+use crate::sys::fd::FileDesc;
+use crate::sys::time::SystemTime;
+use crate::sys::{cvt, cvt_r};
+use crate::sys_common::{AsInner, FromInner};
+use libc::{self, c_int, mode_t, stat64, off_t};
+use libc::{ftruncate, lseek, dirent, readdir_r as readdir64_r, open};
+use crate::sys::vxworks::ext::ffi::OsStringExt;
+pub struct File(FileDesc);
+
+#[derive(Clone)]
+pub struct FileAttr {
+    stat: stat64,
+}
+
+// all DirEntry's will have a reference to this struct
+struct InnerReadDir {
+    dirp: Dir,
+    root: PathBuf,
+}
+
+#[derive(Clone)]
+pub struct ReadDir {
+    inner: Arc<InnerReadDir>,
+    end_of_stream: bool,
+}
+
+struct Dir(*mut libc::DIR);
+
+unsafe impl Send for Dir {}
+unsafe impl Sync for Dir {}
+
+pub struct DirEntry {
+    entry: dirent,
+    dir: ReadDir,
+}
+
+#[derive(Clone, Debug)]
+pub struct OpenOptions {
+    // generic
+    read: bool,
+    write: bool,
+    append: bool,
+    truncate: bool,
+    create: bool,
+    create_new: bool,
+    // system-specific
+    custom_flags: i32,
+    mode: mode_t,
+}
+
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct FilePermissions { mode: mode_t }
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+pub struct FileType { mode: mode_t }
+
+#[derive(Debug)]
+pub struct DirBuilder { mode: mode_t }
+
+impl FileAttr {
+    pub fn size(&self) -> u64 { self.stat.st_size as u64 }
+    pub fn perm(&self) -> FilePermissions {
+        FilePermissions { mode: (self.stat.st_mode as mode_t) }
+    }
+
+    pub fn file_type(&self) -> FileType {
+        FileType { mode: self.stat.st_mode as mode_t }
+    }
+
+    pub fn modified(&self) -> io::Result<SystemTime> {
+        Ok(SystemTime::from(libc::timespec {
+            tv_sec: self.stat.st_mtime as libc::time_t,
+            tv_nsec: 0, // hack 2.0;
+        }))
+    }
+
+    pub fn accessed(&self) -> io::Result<SystemTime> {
+        Ok(SystemTime::from(libc::timespec {
+        tv_sec: self.stat.st_atime as libc::time_t,
+        tv_nsec: 0, // hack - a proper fix would be better
+        }))
+    }
+
+    pub fn created(&self) -> io::Result<SystemTime> {
+        Err(io::Error::new(io::ErrorKind::Other,
+                           "creation time is not available on this platform currently"))
+    }
+
+}
+
+impl AsInner<stat64> for FileAttr {
+    fn as_inner(&self) -> &stat64 { &self.stat }
+}
+
+impl FilePermissions {
+    pub fn readonly(&self) -> bool {
+        // check if any class (owner, group, others) has write permission
+        self.mode & 0o222 == 0
+    }
+
+    pub fn set_readonly(&mut self, readonly: bool) {
+        if readonly {
+            // remove write permission for all classes; equivalent to `chmod a-w <file>`
+            self.mode &= !0o222;
+        } else {
+            // add write permission for all classes; equivalent to `chmod a+w <file>`
+            self.mode |= 0o222;
+        }
+    }
+    pub fn mode(&self) -> u32 { self.mode as u32 }
+}
+
+impl FileType {
+    pub fn is_dir(&self) -> bool { self.is(libc::S_IFDIR) }
+    pub fn is_file(&self) -> bool { self.is(libc::S_IFREG) }
+    pub fn is_symlink(&self) -> bool { self.is(libc::S_IFLNK) }
+
+    pub fn is(&self, mode: mode_t) -> bool { self.mode & libc::S_IFMT == mode }
+}
+
+impl FromInner<u32> for FilePermissions {
+    fn from_inner(mode: u32) -> FilePermissions {
+        FilePermissions { mode: mode as mode_t }
+    }
+}
+
+impl fmt::Debug for ReadDir {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame.
+        // Thus the result will be e g 'ReadDir("/home")'
+        fmt::Debug::fmt(&*self.inner.root, f)
+    }
+}
+
+impl Iterator for ReadDir {
+    type Item = io::Result<DirEntry>;
+    fn next(&mut self) -> Option<io::Result<DirEntry>> {
+        if self.end_of_stream {
+            return None;
+        }
+
+        unsafe {
+            let mut ret = DirEntry {
+                entry: mem::zeroed(),
+                dir: self.clone(),
+            };
+            let mut entry_ptr = ptr::null_mut();
+            loop {
+                if readdir64_r(self.inner.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
+                    if entry_ptr.is_null() {
+                        // We encountered an error (which will be returned in this iteration), but
+                        // we also reached the end of the directory stream. The `end_of_stream`
+                        // flag is enabled to make sure that we return `None` in the next iteration
+                        // (instead of looping forever)
+                        self.end_of_stream = true;
+                    }
+                    return Some(Err(Error::last_os_error()))
+                }
+                if entry_ptr.is_null() {
+                    return None
+                }
+                if ret.name_bytes() != b"." && ret.name_bytes() != b".." {
+                    return Some(Ok(ret))
+                }
+            }
+        }
+    }
+}
+
+impl Drop for Dir {
+    fn drop(&mut self) {
+        let r = unsafe { libc::closedir(self.0) };
+        debug_assert_eq!(r, 0);
+    }
+}
+
+impl DirEntry {
+    pub fn path(&self) -> PathBuf {
+            use crate::sys::vxworks::ext::ffi::OsStrExt;
+            self.dir.inner.root.join(OsStr::from_bytes(self.name_bytes()))
+    }
+
+    pub fn file_name(&self) -> OsString {
+        OsStr::from_bytes(self.name_bytes()).to_os_string()
+    }
+
+
+    pub fn metadata(&self) -> io::Result<FileAttr> {
+        lstat(&self.path())
+    }
+
+    pub fn file_type(&self) -> io::Result<FileType> {
+        lstat(&self.path()).map(|m| m.file_type())
+
+    }
+
+    pub fn ino(&self) -> u64 {
+        self.entry.d_ino as u64
+    }
+
+    fn name_bytes(&self) -> &[u8] {
+        unsafe {
+            //&*self.name
+            CStr::from_ptr(self.entry.d_name.as_ptr()).to_bytes()
+        }
+    }
+}
+
+impl OpenOptions {
+    pub fn new() -> OpenOptions {
+        OpenOptions {
+            // generic
+            read: false,
+            write: false,
+            append: false,
+            truncate: false,
+            create: false,
+            create_new: false,
+            // system-specific
+            custom_flags: 0,
+            mode: 0o666,
+        }
+    }
+
+    pub fn read(&mut self, read: bool) { self.read = read; }
+    pub fn write(&mut self, write: bool) { self.write = write; }
+    pub fn append(&mut self, append: bool) { self.append = append; }
+    pub fn truncate(&mut self, truncate: bool) { self.truncate = truncate; }
+    pub fn create(&mut self, create: bool) { self.create = create; }
+    pub fn create_new(&mut self, create_new: bool) { self.create_new = create_new; }
+    pub fn mode(&mut self, mode: u32) { self.mode = mode as mode_t; }
+
+    fn get_access_mode(&self) -> io::Result<c_int> {
+        match (self.read, self.write, self.append) {
+            (true,  false, false) => Ok(libc::O_RDONLY),
+            (false, true,  false) => Ok(libc::O_WRONLY),
+            (true,  true,  false) => Ok(libc::O_RDWR),
+            (false, _,     true)  => Ok(libc::O_WRONLY | libc::O_APPEND),
+            (true,  _,     true)  => Ok(libc::O_RDWR | libc::O_APPEND),
+            (false, false, false) => Err(Error::from_raw_os_error(libc::EINVAL)),
+        }
+    }
+
+    fn get_creation_mode(&self) -> io::Result<c_int> {
+        match (self.write, self.append) {
+            (true, false) => {}
+            (false, false) =>
+                if self.truncate || self.create || self.create_new {
+                    return Err(Error::from_raw_os_error(libc::EINVAL));
+                },
+            (_, true) =>
+                if self.truncate && !self.create_new {
+                    return Err(Error::from_raw_os_error(libc::EINVAL));
+                },
+        }
+
+        Ok(match (self.create, self.truncate, self.create_new) {
+                (false, false, false) => 0,
+                (true,  false, false) => libc::O_CREAT,
+                (false, true,  false) => libc::O_TRUNC,
+                (true,  true,  false) => libc::O_CREAT | libc::O_TRUNC,
+                (_,      _,    true)  => libc::O_CREAT | libc::O_EXCL,
+           })
+    }
+}
+
+impl File {
+    pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
+        let path = cstr(path)?;
+        File::open_c(&path, opts)
+    }
+
+    pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> {
+        let flags = libc::O_CLOEXEC |
+                opts.get_access_mode()? |
+                opts.get_creation_mode()? |
+                (opts.custom_flags as c_int & !libc::O_ACCMODE);
+        let fd = cvt_r(|| unsafe {
+            open(path.as_ptr(), flags, opts.mode as c_int)
+        })?;
+        Ok(File(FileDesc::new(fd)))
+    }
+
+    pub fn file_attr(&self) -> io::Result<FileAttr> {
+        let mut stat: stat64 = unsafe { mem::zeroed() };
+        cvt(unsafe {
+            ::libc::fstat(self.0.raw(), &mut stat)
+        })?;
+        Ok(FileAttr { stat: stat })
+    }
+
+    pub fn fsync(&self) -> io::Result<()> {
+        cvt_r(|| unsafe { libc::fsync(self.0.raw()) })?;
+        Ok(())
+    }
+
+    pub fn datasync(&self) -> io::Result<()> {
+        cvt_r(|| unsafe { os_datasync(self.0.raw()) })?;
+        return Ok(());
+        unsafe fn os_datasync(fd: c_int) -> c_int { libc::fsync(fd) } //not supported
+    }
+
+    pub fn truncate(&self, size: u64) -> io::Result<()> {
+        return cvt_r(|| unsafe {
+            ftruncate(self.0.raw(), size as off_t)
+        }).map(|_| ());
+    }
+
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.0.read(buf)
+    }
+
+    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        self.0.read_vectored(bufs)
+    }
+
+    pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
+        self.0.read_at(buf, offset)
+    }
+
+    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        self.0.write(buf)
+    }
+
+    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        self.0.write_vectored(bufs)
+    }
+
+    pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
+        self.0.write_at(buf, offset)
+    }
+
+    pub fn flush(&self) -> io::Result<()> { Ok(()) }
+
+    pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
+        let (whence, pos) = match pos {
+            // Casting to `i64` is fine, too large values will end up as
+            // negative which will cause an error in `"lseek64"`.
+            SeekFrom::Start(off) => (libc::SEEK_SET, off as i64),
+            SeekFrom::End(off) => (libc::SEEK_END, off),
+            SeekFrom::Current(off) => (libc::SEEK_CUR, off),
+        };
+        let n = cvt(unsafe { lseek(self.0.raw(), pos, whence) })?;
+        Ok(n as u64)
+    }
+
+    pub fn duplicate(&self) -> io::Result<File> {
+        self.0.duplicate().map(File)
+    }
+
+    pub fn fd(&self) -> &FileDesc { &self.0 }
+
+    pub fn into_fd(self) -> FileDesc { self.0 }
+
+    pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> {
+        cvt_r(|| unsafe { libc::fchmod(self.0.raw(), perm.mode) })?;
+        Ok(())
+    }
+
+    pub fn diverge(&self) -> ! {
+        panic!()
+    }
+}
+
+impl DirBuilder {
+    pub fn new() -> DirBuilder {
+        DirBuilder { mode: 0o777 }
+    }
+
+    pub fn mkdir(&self, p: &Path) -> io::Result<()> {
+        let p = cstr(p)?;
+        cvt(unsafe { libc::mkdir(p.as_ptr(), self.mode) })?;
+        Ok(())
+    }
+
+    pub fn set_mode(&mut self, mode: u32) {
+        self.mode = mode as mode_t;
+    }
+}
+
+fn cstr(path: &Path) -> io::Result<CString> {
+    use crate::sys::vxworks::ext::ffi::OsStrExt;
+    Ok(CString::new(path.as_os_str().as_bytes())?)
+}
+
+impl FromInner<c_int> for File {
+    fn from_inner(fd: c_int) -> File {
+        File(FileDesc::new(fd))
+    }
+}
+
+impl fmt::Debug for File {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fn get_path(_fd: c_int) -> Option<PathBuf> {
+            // FIXME(#:(): implement this for VxWorks
+            None
+        }
+        fn get_mode(_fd: c_int) -> Option<(bool, bool)> {
+            // FIXME(#:(): implement this for VxWorks
+            None
+        }
+
+        let fd = self.0.raw();
+        let mut b = f.debug_struct("File");
+        b.field("fd", &fd);
+        if let Some(path) = get_path(fd) {
+            b.field("path", &path);
+        }
+        if let Some((read, write)) = get_mode(fd) {
+            b.field("read", &read).field("write", &write);
+        }
+        b.finish()
+    }
+}
+
+pub fn readdir(p: &Path) -> io::Result<ReadDir> {
+    let root = p.to_path_buf();
+    let p = cstr(p)?;
+    unsafe {
+        let ptr = libc::opendir(p.as_ptr());
+        if ptr.is_null() {
+            Err(Error::last_os_error())
+        } else {
+            let inner = InnerReadDir { dirp: Dir(ptr), root };
+            Ok(ReadDir{
+                inner: Arc::new(inner),
+                end_of_stream: false,
+            })
+        }
+    }
+}
+
+pub fn unlink(p: &Path) -> io::Result<()> {
+    let p = cstr(p)?;
+    cvt(unsafe { libc::unlink(p.as_ptr()) })?;
+    Ok(())
+}
+
+pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
+    let old = cstr(old)?;
+    let new = cstr(new)?;
+    cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) })?;
+    Ok(())
+}
+
+pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
+    let p = cstr(p)?;
+    cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) })?;
+    Ok(())
+}
+
+pub fn rmdir(p: &Path) -> io::Result<()> {
+    let p = cstr(p)?;
+    cvt(unsafe { libc::rmdir(p.as_ptr()) })?;
+    Ok(())
+}
+
+pub fn remove_dir_all(path: &Path) -> io::Result<()> {
+    let filetype = lstat(path)?.file_type();
+    if filetype.is_symlink() {
+        unlink(path)
+    } else {
+        remove_dir_all_recursive(path)
+    }
+}
+
+fn remove_dir_all_recursive(path: &Path) -> io::Result<()> {
+    for child in readdir(path)? {
+        let child = child?;
+        if child.file_type()?.is_dir() {
+            remove_dir_all_recursive(&child.path())?;
+        } else {
+            unlink(&child.path())?;
+        }
+    }
+    rmdir(path)
+}
+
+pub fn readlink(p: &Path) -> io::Result<PathBuf> {
+    let c_path = cstr(p)?;
+    let p = c_path.as_ptr();
+
+    let mut buf = Vec::with_capacity(256);
+
+    loop {
+        let buf_read = cvt(unsafe {
+            libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity())
+        })? as usize;
+
+        unsafe { buf.set_len(buf_read); }
+
+        if buf_read != buf.capacity() {
+            buf.shrink_to_fit();
+
+            return Ok(PathBuf::from(OsString::from_vec(buf)));
+        }
+
+        // Trigger the internal buffer resizing logic of `Vec` by requiring
+        // more space than the current capacity. The length is guaranteed to be
+        // the same as the capacity due to the if statement above.
+        buf.reserve(1);
+    }
+}
+
+pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
+    let src = cstr(src)?;
+    let dst = cstr(dst)?;
+    cvt(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })?;
+    Ok(())
+}
+
+pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
+    let src = cstr(src)?;
+    let dst = cstr(dst)?;
+    cvt(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })?;
+    Ok(())
+}
+
+pub fn stat(p: &Path) -> io::Result<FileAttr> {
+    let p = cstr(p)?;
+    let mut stat: stat64 = unsafe { mem::zeroed() };
+    cvt(unsafe {
+        libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _)
+    })?;
+    Ok(FileAttr { stat })
+}
+
+pub fn lstat(p: &Path) -> io::Result<FileAttr> {
+    let p = cstr(p)?;
+    let mut stat: stat64 = unsafe { mem::zeroed() };
+    cvt(unsafe {
+        ::libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _)
+    })?;
+    Ok(FileAttr { stat })
+}
+
+pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
+    use crate::sys::vxworks::ext::ffi::OsStrExt;
+    let path = CString::new(p.as_os_str().as_bytes())?;
+    let buf;
+    unsafe {
+        let r = libc::realpath(path.as_ptr(), ptr::null_mut());
+        if r.is_null() {
+            return Err(io::Error::last_os_error())
+        }
+        buf = CStr::from_ptr(r).to_bytes().to_vec();
+        libc::free(r as *mut _);
+    }
+    Ok(PathBuf::from(OsString::from_vec(buf)))
+}
+
+pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
+    use crate::fs::File;
+    if !from.is_file() {
+        return Err(Error::new(ErrorKind::InvalidInput,
+                              "the source path is not an existing regular file"))
+    }
+
+    let mut reader = File::open(from)?;
+    let mut writer = File::create(to)?;
+    let perm = reader.metadata()?.permissions();
+
+    let ret = io::copy(&mut reader, &mut writer)?;
+    writer.set_permissions(perm)?;
+    Ok(ret)
+}
diff --git a/src/libstd/sys/vxworks/io.rs b/src/libstd/sys/vxworks/io.rs
new file mode 100644
index 00000000000..8cd11cbf5df
--- /dev/null
+++ b/src/libstd/sys/vxworks/io.rs
@@ -0,0 +1,86 @@
+use crate::marker::PhantomData;
+use crate::slice;
+
+use libc::{iovec, c_void};
+
+#[repr(transparent)]
+pub struct IoSlice<'a> {
+    vec: iovec,
+    _p: PhantomData<&'a [u8]>,
+}
+
+impl<'a> IoSlice<'a> {
+    #[inline]
+    pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
+        IoSlice {
+            vec: iovec {
+                iov_base: buf.as_ptr() as *mut u8 as *mut c_void,
+                iov_len: buf.len()
+            },
+            _p: PhantomData,
+        }
+    }
+
+    #[inline]
+    pub fn advance(&mut self, n: usize) {
+        if self.vec.iov_len < n {
+            panic!("advancing IoSlice beyond its length");
+        }
+
+        unsafe {
+            self.vec.iov_len -= n;
+            self.vec.iov_base = self.vec.iov_base.add(n);
+        }
+    }
+
+    #[inline]
+    pub fn as_slice(&self) -> &[u8] {
+        unsafe {
+            slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
+        }
+    }
+}
+
+pub struct IoSliceMut<'a> {
+    vec: iovec,
+    _p: PhantomData<&'a mut [u8]>,
+}
+
+impl<'a> IoSliceMut<'a> {
+    #[inline]
+    pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
+        IoSliceMut {
+            vec: iovec {
+                iov_base: buf.as_mut_ptr() as *mut c_void,
+                iov_len: buf.len()
+            },
+            _p: PhantomData,
+        }
+    }
+
+    #[inline]
+    pub fn advance(&mut self, n: usize) {
+        if self.vec.iov_len < n {
+            panic!("advancing IoSliceMut beyond its length");
+        }
+
+        unsafe {
+            self.vec.iov_len -= n;
+            self.vec.iov_base = self.vec.iov_base.add(n);
+        }
+    }
+
+    #[inline]
+    pub fn as_slice(&self) -> &[u8] {
+        unsafe {
+            slice::from_raw_parts(self.vec.iov_base as *mut u8, self.vec.iov_len)
+        }
+    }
+
+    #[inline]
+    pub fn as_mut_slice(&mut self) -> &mut [u8] {
+        unsafe {
+            slice::from_raw_parts_mut(self.vec.iov_base as *mut u8, self.vec.iov_len)
+        }
+    }
+}
diff --git a/src/libstd/sys/vxworks/memchr.rs b/src/libstd/sys/vxworks/memchr.rs
new file mode 100644
index 00000000000..b5b4e6d9c13
--- /dev/null
+++ b/src/libstd/sys/vxworks/memchr.rs
@@ -0,0 +1,24 @@
+// Original implementation taken from rust-memchr.
+// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
+
+pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
+    let p = unsafe {
+        libc::memchr(
+            haystack.as_ptr() as *const libc::c_void,
+            needle as libc::c_int,
+            haystack.len())
+    };
+    if p.is_null() {
+        None
+    } else {
+        Some(p as usize - (haystack.as_ptr() as usize))
+    }
+}
+
+pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
+    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
+        core::slice::memchr::memrchr(needle, haystack)
+    }
+
+    memrchr_specific(needle, haystack)
+}
diff --git a/src/libstd/sys/vxworks/mod.rs b/src/libstd/sys/vxworks/mod.rs
new file mode 100644
index 00000000000..1eff4fbcd83
--- /dev/null
+++ b/src/libstd/sys/vxworks/mod.rs
@@ -0,0 +1,125 @@
+#![allow(dead_code)]
+#![allow(missing_docs, nonstandard_style)]
+
+use crate::io::ErrorKind;
+
+pub use crate::os::vxworks as platform;
+pub use self::rand::hashmap_random_keys;
+pub use libc::strlen;
+
+pub mod alloc;
+pub mod args;
+pub mod cmath;
+pub mod condvar;
+pub mod env;
+pub mod ext;
+pub mod fast_thread_local;
+pub mod fd;
+pub mod fs;
+pub mod memchr;
+pub mod io;
+pub mod mutex;
+pub mod net;
+pub mod os;
+pub mod path;
+pub mod pipe;
+pub mod process;
+pub mod rand;
+pub mod rwlock;
+pub mod stack_overflow;
+pub mod thread;
+pub mod thread_local;
+pub mod time;
+pub mod stdio;
+
+pub use crate::sys_common::os_str_bytes as os_str;
+
+#[cfg(not(test))]
+pub fn init() {
+    // By default, some platforms will send a *signal* when an EPIPE error
+    // would otherwise be delivered. This runtime doesn't install a SIGPIPE
+    // handler, causing it to kill the program, which isn't exactly what we
+    // want!
+    //
+    // Hence, we set SIGPIPE to ignore when the program starts up in order
+    // to prevent this problem.
+    unsafe {
+        reset_sigpipe();
+    }
+
+    unsafe fn reset_sigpipe() { }
+}
+
+pub use libc::signal;
+
+pub fn decode_error_kind(errno: i32) -> ErrorKind {
+    match errno as libc::c_int {
+        libc::ECONNREFUSED => ErrorKind::ConnectionRefused,
+        libc::ECONNRESET => ErrorKind::ConnectionReset,
+        libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied,
+        libc::EPIPE => ErrorKind::BrokenPipe,
+        libc::ENOTCONN => ErrorKind::NotConnected,
+        libc::ECONNABORTED => ErrorKind::ConnectionAborted,
+        libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
+        libc::EADDRINUSE => ErrorKind::AddrInUse,
+        libc::ENOENT => ErrorKind::NotFound,
+        libc::EINTR => ErrorKind::Interrupted,
+        libc::EINVAL => ErrorKind::InvalidInput,
+        libc::ETIMEDOUT => ErrorKind::TimedOut,
+        libc::EEXIST => ErrorKind::AlreadyExists,
+
+        // These two constants can have the same value on some systems,
+        // but different values on others, so we can't use a match
+        // clause
+        x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
+            ErrorKind::WouldBlock,
+
+        _ => ErrorKind::Other,
+    }
+}
+
+#[doc(hidden)]
+pub trait IsMinusOne {
+    fn is_minus_one(&self) -> bool;
+}
+
+macro_rules! impl_is_minus_one {
+    ($($t:ident)*) => ($(impl IsMinusOne for $t {
+        fn is_minus_one(&self) -> bool {
+            *self == -1
+        }
+    })*)
+}
+
+impl_is_minus_one! { i8 i16 i32 i64 isize }
+
+pub fn cvt<T: IsMinusOne>(t: T) -> crate::io::Result<T> {
+    if t.is_minus_one() {
+        Err(crate::io::Error::last_os_error())
+    } else {
+        Ok(t)
+    }
+}
+
+pub fn cvt_r<T, F>(mut f: F) -> crate::io::Result<T>
+    where T: IsMinusOne,
+          F: FnMut() -> T
+{
+    loop {
+        match cvt(f()) {
+            Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
+            other => return other,
+        }
+    }
+}
+
+// On Unix-like platforms, libc::abort will unregister signal handlers
+// including the SIGABRT handler, preventing the abort from being blocked, and
+// fclose streams, with the side effect of flushing them so libc bufferred
+// output will be printed.  Additionally the shell will generally print a more
+// understandable error message like "Abort trap" rather than "Illegal
+// instruction" that intrinsics::abort would cause, as intrinsics::abort is
+// implemented as an illegal instruction.
+pub unsafe fn abort_internal() -> ! {
+    libc::abort()
+}
diff --git a/src/libstd/sys/vxworks/mutex.rs b/src/libstd/sys/vxworks/mutex.rs
new file mode 100644
index 00000000000..b43af8fdcaa
--- /dev/null
+++ b/src/libstd/sys/vxworks/mutex.rs
@@ -0,0 +1,127 @@
+use crate::cell::UnsafeCell;
+use crate::mem::MaybeUninit;
+
+pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t> }
+
+#[inline]
+pub unsafe fn raw(m: &Mutex) -> *mut libc::pthread_mutex_t {
+    m.inner.get()
+}
+
+unsafe impl Send for Mutex {}
+unsafe impl Sync for Mutex {}
+
+#[allow(dead_code)] // sys isn't exported yet
+impl Mutex {
+    pub const fn new() -> Mutex {
+        // Might be moved to a different address, so it is better to avoid
+        // initialization of potentially opaque OS data before it landed.
+        // Be very careful using this newly constructed `Mutex`, reentrant
+        // locking is undefined behavior until `init` is called!
+        Mutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
+    }
+    #[inline]
+    pub unsafe fn init(&mut self) {
+        // Issue #33770
+        //
+        // A pthread mutex initialized with PTHREAD_MUTEX_INITIALIZER will have
+        // a type of PTHREAD_MUTEX_DEFAULT, which has undefined behavior if you
+        // try to re-lock it from the same thread when you already hold a lock.
+        //
+        // In practice, glibc takes advantage of this undefined behavior to
+        // implement hardware lock elision, which uses hardware transactional
+        // memory to avoid acquiring the lock. While a transaction is in
+        // progress, the lock appears to be unlocked. This isn't a problem for
+        // other threads since the transactional memory will abort if a conflict
+        // is detected, however no abort is generated if re-locking from the
+        // same thread.
+        //
+        // Since locking the same mutex twice will result in two aliasing &mut
+        // references, we instead create the mutex with type
+        // PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to
+        // re-lock it from the same thread, thus avoiding undefined behavior.
+        let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
+        let r = libc::pthread_mutexattr_init(attr.as_mut_ptr());
+        debug_assert_eq!(r, 0);
+        let r = libc::pthread_mutexattr_settype(attr.as_mut_ptr(), libc::PTHREAD_MUTEX_NORMAL);
+        debug_assert_eq!(r, 0);
+        let r = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
+        debug_assert_eq!(r, 0);
+        let r = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
+        debug_assert_eq!(r, 0);
+    }
+    #[inline]
+    pub unsafe fn lock(&self) {
+        let r = libc::pthread_mutex_lock(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+    #[inline]
+    pub unsafe fn unlock(&self) {
+        let r = libc::pthread_mutex_unlock(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+    #[inline]
+    pub unsafe fn try_lock(&self) -> bool {
+        libc::pthread_mutex_trylock(self.inner.get()) == 0
+    }
+    #[inline]
+    #[cfg(not(target_os = "dragonfly"))]
+    pub unsafe fn destroy(&self) {
+        let r = libc::pthread_mutex_destroy(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+    #[inline]
+    #[cfg(target_os = "dragonfly")]
+    pub unsafe fn destroy(&self) {
+        let r = libc::pthread_mutex_destroy(self.inner.get());
+        // On DragonFly pthread_mutex_destroy() returns EINVAL if called on a
+        // mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER.
+        // Once it is used (locked/unlocked) or pthread_mutex_init() is called,
+        // this behaviour no longer occurs.
+        debug_assert!(r == 0 || r == libc::EINVAL);
+    }
+}
+
+pub struct ReentrantMutex { inner: UnsafeCell<libc::pthread_mutex_t> }
+
+unsafe impl Send for ReentrantMutex {}
+unsafe impl Sync for ReentrantMutex {}
+
+impl ReentrantMutex {
+    pub unsafe fn uninitialized() -> ReentrantMutex {
+        ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
+    }
+
+    pub unsafe fn init(&mut self) {
+        let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
+        let result = libc::pthread_mutexattr_init(attr.as_mut_ptr());
+        debug_assert_eq!(result, 0);
+        let result = libc::pthread_mutexattr_settype(attr.as_mut_ptr(),
+                                                    libc::PTHREAD_MUTEX_RECURSIVE);
+        debug_assert_eq!(result, 0);
+        let result = libc::pthread_mutex_init(self.inner.get(), attr.as_ptr());
+        debug_assert_eq!(result, 0);
+        let result = libc::pthread_mutexattr_destroy(attr.as_mut_ptr());
+        debug_assert_eq!(result, 0);
+    }
+
+    pub unsafe fn lock(&self) {
+        let result = libc::pthread_mutex_lock(self.inner.get());
+        debug_assert_eq!(result, 0);
+    }
+
+    #[inline]
+    pub unsafe fn try_lock(&self) -> bool {
+        libc::pthread_mutex_trylock(self.inner.get()) == 0
+    }
+
+    pub unsafe fn unlock(&self) {
+        let result = libc::pthread_mutex_unlock(self.inner.get());
+        debug_assert_eq!(result, 0);
+    }
+
+    pub unsafe fn destroy(&self) {
+        let result = libc::pthread_mutex_destroy(self.inner.get());
+        debug_assert_eq!(result, 0);
+    }
+}
diff --git a/src/libstd/sys/vxworks/net.rs b/src/libstd/sys/vxworks/net.rs
new file mode 100644
index 00000000000..56962e11dcf
--- /dev/null
+++ b/src/libstd/sys/vxworks/net.rs
@@ -0,0 +1,357 @@
+use crate::ffi::CStr;
+use crate::io;
+use crate::io::{IoSlice, IoSliceMut};
+use libc::{self, c_int, c_void, size_t, sockaddr, socklen_t, EAI_SYSTEM, MSG_PEEK};
+use crate::mem;
+use crate::net::{SocketAddr, Shutdown};
+use crate::str;
+use crate::sys::fd::FileDesc;
+use crate::sys_common::{AsInner, FromInner, IntoInner};
+use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr};
+use crate::time::{Duration, Instant};
+use crate::cmp;
+
+pub use crate::sys::{cvt, cvt_r};
+
+#[allow(unused_extern_crates)]
+pub extern crate libc as netc;
+
+pub type wrlen_t = size_t;
+
+
+const SOCK_CLOEXEC: c_int = 0;
+const SO_NOSIGPIPE: c_int = 0;
+
+pub struct Socket(FileDesc);
+
+pub fn init() {}
+
+pub fn cvt_gai(err: c_int) -> io::Result<()> {
+    if err == 0 {
+        return Ok(())
+    }
+
+    // We may need to trigger a glibc workaround. See on_resolver_failure() for details.
+    on_resolver_failure();
+
+    if err == EAI_SYSTEM {
+        return Err(io::Error::last_os_error())
+    }
+
+    let detail = unsafe {
+        str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap()
+            .to_owned()
+    };
+    Err(io::Error::new(io::ErrorKind::Other,
+                       &format!("failed to lookup address information: {}",
+                                detail)[..]))
+}
+
+impl Socket {
+    pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
+        let fam = match *addr {
+            SocketAddr::V4(..) => libc::AF_INET,
+            SocketAddr::V6(..) => libc::AF_INET6,
+        };
+        Socket::new_raw(fam, ty)
+    }
+
+    pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
+        unsafe {
+            let fd = cvt(libc::socket(fam, ty, 0))?;
+            let fd = FileDesc::new(fd);
+            fd.set_cloexec()?;
+            let socket = Socket(fd);
+            Ok(socket)
+        }
+    }
+
+    pub fn new_pair(_fam: c_int, _ty: c_int) -> io::Result<(Socket, Socket)> {
+            unimplemented!();
+    }
+
+    pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
+        self.set_nonblocking(true)?;
+        let r = unsafe {
+            let (addrp, len) = addr.into_inner();
+            cvt(libc::connect(self.0.raw(), addrp, len))
+        };
+        self.set_nonblocking(false)?;
+
+        match r {
+            Ok(_) => return Ok(()),
+            // there's no ErrorKind for EINPROGRESS :(
+            Err(ref e) if e.raw_os_error() == Some(libc::EINPROGRESS) => {}
+            Err(e) => return Err(e),
+        }
+
+        let mut pollfd = libc::pollfd {
+            fd: self.0.raw(),
+            events: libc::POLLOUT,
+            revents: 0,
+        };
+
+        if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
+            return Err(io::Error::new(io::ErrorKind::InvalidInput,
+                                      "cannot set a 0 duration timeout"));
+        }
+
+        let start = Instant::now();
+
+        loop {
+            let elapsed = start.elapsed();
+            if elapsed >= timeout {
+                return Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out"));
+            }
+
+            let timeout = timeout - elapsed;
+            let mut timeout = timeout.as_secs()
+                .saturating_mul(1_000)
+                .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000);
+            if timeout == 0 {
+                timeout = 1;
+            }
+
+            let timeout = cmp::min(timeout, c_int::max_value() as u64) as c_int;
+
+            match unsafe { libc::poll(&mut pollfd, 1, timeout) } {
+                -1 => {
+                    let err = io::Error::last_os_error();
+                    if err.kind() != io::ErrorKind::Interrupted {
+                        return Err(err);
+                    }
+                }
+                0 => {}
+                _ => {
+                    // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
+                    // for POLLHUP rather than read readiness
+                    if pollfd.revents & libc::POLLHUP != 0 {
+                        let e = self.take_error()?
+                            .unwrap_or_else(|| {
+                                io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
+                            });
+                        return Err(e);
+                    }
+
+                    return Ok(());
+                }
+            }
+        }
+    }
+
+    pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t)
+                  -> io::Result<Socket> {
+        let fd = cvt_r(|| unsafe {
+            libc::accept(self.0.raw(), storage, len)
+        })?;
+        let fd = FileDesc::new(fd);
+        fd.set_cloexec()?;
+        Ok(Socket(fd))
+    }
+
+    pub fn duplicate(&self) -> io::Result<Socket> {
+        self.0.duplicate().map(Socket)
+    }
+
+    fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
+        let ret = cvt(unsafe {
+            libc::recv(self.0.raw(),
+                       buf.as_mut_ptr() as *mut c_void,
+                       buf.len(),
+                       flags)
+        })?;
+        Ok(ret as usize)
+    }
+
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.recv_with_flags(buf, 0)
+    }
+
+    pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.recv_with_flags(buf, MSG_PEEK)
+    }
+
+    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+        self.0.read_vectored(bufs)
+    }
+
+    fn recv_from_with_flags(&self, buf: &mut [u8], flags: c_int)
+                            -> io::Result<(usize, SocketAddr)> {
+        let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
+        let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t;
+
+        let n = cvt(unsafe {
+            libc::recvfrom(self.0.raw(),
+                        buf.as_mut_ptr() as *mut c_void,
+                        buf.len(),
+                        flags,
+                        &mut storage as *mut _ as *mut _,
+                        &mut addrlen)
+        })?;
+        Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
+    }
+
+    pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        self.recv_from_with_flags(buf, 0)
+    }
+
+    pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
+        self.recv_from_with_flags(buf, MSG_PEEK)
+    }
+
+    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        self.0.write(buf)
+    }
+
+    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+        self.0.write_vectored(bufs)
+    }
+
+    pub fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> {
+        let timeout = match dur {
+            Some(dur) => {
+                if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
+                    return Err(io::Error::new(io::ErrorKind::InvalidInput,
+                                              "cannot set a 0 duration timeout"));
+                }
+
+                let secs = if dur.as_secs() > libc::time_t::max_value() as u64 {
+                    libc::time_t::max_value()
+                } else {
+                    dur.as_secs() as libc::time_t
+                };
+                let mut timeout = libc::timeval {
+                    tv_sec: secs,
+                    tv_usec: (dur.subsec_nanos() / 1000) as libc::suseconds_t,
+                };
+                if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
+                    timeout.tv_usec = 1;
+                }
+                timeout
+            }
+            None => {
+                libc::timeval {
+                    tv_sec: 0,
+                    tv_usec: 0,
+                }
+            }
+        };
+        setsockopt(self, libc::SOL_SOCKET, kind, timeout)
+    }
+
+    pub fn timeout(&self, kind: libc::c_int) -> io::Result<Option<Duration>> {
+        let raw: libc::timeval = getsockopt(self, libc::SOL_SOCKET, kind)?;
+        if raw.tv_sec == 0 && raw.tv_usec == 0 {
+            Ok(None)
+        } else {
+            let sec = raw.tv_sec as u64;
+            let nsec = (raw.tv_usec as u32) * 1000;
+            Ok(Some(Duration::new(sec, nsec)))
+        }
+    }
+
+    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
+        let how = match how {
+            Shutdown::Write => libc::SHUT_WR,
+            Shutdown::Read => libc::SHUT_RD,
+            Shutdown::Both => libc::SHUT_RDWR,
+        };
+        cvt(unsafe { libc::shutdown(self.0.raw(), how) })?;
+        Ok(())
+    }
+
+    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
+        setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int)
+    }
+
+    pub fn nodelay(&self) -> io::Result<bool> {
+        let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY)?;
+        Ok(raw != 0)
+    }
+
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+        let mut nonblocking = nonblocking as libc::c_int;
+        cvt(unsafe { libc::ioctl(*self.as_inner(), libc::FIONBIO, &mut nonblocking) }).map(|_| ())
+    }
+
+    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+        let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
+        if raw == 0 {
+            Ok(None)
+        } else {
+            Ok(Some(io::Error::from_raw_os_error(raw as i32)))
+        }
+    }
+}
+
+impl AsInner<c_int> for Socket {
+    fn as_inner(&self) -> &c_int { self.0.as_inner() }
+}
+
+impl FromInner<c_int> for Socket {
+    fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) }
+}
+
+impl IntoInner<c_int> for Socket {
+    fn into_inner(self) -> c_int { self.0.into_raw() }
+}
+
+// In versions of glibc prior to 2.26, there's a bug where the DNS resolver
+// will cache the contents of /etc/resolv.conf, so changes to that file on disk
+// can be ignored by a long-running program. That can break DNS lookups on e.g.
+// laptops where the network comes and goes. See
+// https://sourceware.org/bugzilla/show_bug.cgi?id=984. Note however that some
+// distros including Debian have patched glibc to fix this for a long time.
+//
+// A workaround for this bug is to call the res_init libc function, to clear
+// the cached configs. Unfortunately, while we believe glibc's implementation
+// of res_init is thread-safe, we know that other implementations are not
+// (https://github.com/rust-lang/rust/issues/43592). Code here in libstd could
+// try to synchronize its res_init calls with a Mutex, but that wouldn't
+// protect programs that call into libc in other ways. So instead of calling
+// res_init unconditionally, we call it only when we detect we're linking
+// against glibc version < 2.26. (That is, when we both know its needed and
+// believe it's thread-safe).
+#[cfg(target_env = "gnu")]
+fn on_resolver_failure() {
+/*
+    use crate::sys;
+
+    // If the version fails to parse, we treat it the same as "not glibc".
+    if let Some(version) = sys::os::glibc_version() {
+        if version < (2, 26) {
+            unsafe { libc::res_init() };
+        }
+    }
+    */
+}
+
+#[cfg(not(target_env = "gnu"))]
+fn on_resolver_failure() {}
+
+#[cfg(all(test, taget_env = "gnu"))]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_res_init() {
+        // This mostly just tests that the weak linkage doesn't panic wildly...
+        res_init_if_glibc_before_2_26().unwrap();
+    }
+
+    #[test]
+    fn test_parse_glibc_version() {
+        let cases = [
+            ("0.0", Some((0, 0))),
+            ("01.+2", Some((1, 2))),
+            ("3.4.5.six", Some((3, 4))),
+            ("1", None),
+            ("1.-2", None),
+            ("1.foo", None),
+            ("foo.1", None),
+        ];
+        for &(version_str, parsed) in cases.iter() {
+            assert_eq!(parsed, parse_glibc_version(version_str));
+        }
+    }
+}
diff --git a/src/libstd/sys/redox/os.rs b/src/libstd/sys/vxworks/os.rs
index 3ae201f698c..5dc35a6176b 100644
--- a/src/libstd/sys/redox/os.rs
+++ b/src/libstd/sys/vxworks/os.rs
@@ -1,72 +1,136 @@
-//! Implementation of `std::os` functionality for unix systems
-
-#![allow(unused_imports)] // lots of cfg code here
-
-use libc::c_char;
-
-use crate::os::unix::prelude::*;
-
 use crate::error::Error as StdError;
-use crate::ffi::{CStr, CString, OsStr, OsString};
+use crate::ffi::{CString, CStr, OsString, OsStr};
 use crate::fmt;
-use crate::io::{self, Read, Write};
+use crate::io;
 use crate::iter;
+use libc::{self, c_int, c_char /*,c_void */};
 use crate::marker::PhantomData;
 use crate::mem;
 use crate::memchr;
-use crate::path::{self, PathBuf};
+use crate::path::{self, PathBuf, Path};
 use crate::ptr;
 use crate::slice;
 use crate::str;
 use crate::sys_common::mutex::Mutex;
-use crate::sys::{cvt, cvt_libc, fd, syscall};
+use crate::sys::cvt;
+/*use sys::fd; this one is probably important */
 use crate::vec;
 
-extern {
-    #[link_name = "__errno_location"]
-    fn errno_location() -> *mut i32;
+const TMPBUF_SZ: usize = 128;
+static ENV_LOCK: Mutex = Mutex::new();
+
+
+// This is a terrible fix
+use crate::sys::os_str::Buf;
+use crate::sys_common::{FromInner, IntoInner, AsInner};
+
+pub trait OsStringExt {
+    fn from_vec(vec: Vec<u8>) -> Self;
+    fn into_vec(self) -> Vec<u8>;
 }
 
-/// Returns the platform-specific value of errno
-pub fn errno() -> i32 {
-    unsafe {
-        (*errno_location())
+impl OsStringExt for OsString {
+    fn from_vec(vec: Vec<u8>) -> OsString {
+        FromInner::from_inner(Buf { inner: vec })
     }
+    fn into_vec(self) -> Vec<u8> {
+        self.into_inner().inner
+    }
+}
+
+pub trait OsStrExt {
+    fn from_bytes(slice: &[u8]) -> &Self;
+    fn as_bytes(&self) -> &[u8];
+}
+
+impl OsStrExt for OsStr {
+    fn from_bytes(slice: &[u8]) -> &OsStr {
+        unsafe { mem::transmute(slice) }
+    }
+    fn as_bytes(&self) -> &[u8] {
+        &self.as_inner().inner
+    }
+}
+
+pub fn errno() -> i32 {
+    unsafe { libc::errnoGet() }
+}
+
+pub fn set_errno(e: i32) {
+    unsafe { libc::errnoSet(e as c_int); }
 }
 
 /// Gets a detailed string description for the given error number.
 pub fn error_string(errno: i32) -> String {
-    if let Some(string) = syscall::STR_ERROR.get(errno as usize) {
-        string.to_string()
-    } else {
-        "unknown error".to_string()
+    let mut buf = [0 as c_char; TMPBUF_SZ];
+    extern {
+        fn strerror_r(
+            errnum: c_int,
+            buf: *mut c_char,
+            buflen: libc::size_t
+        ) -> c_int;
+    }
+
+    let p = buf.as_mut_ptr();
+    unsafe {
+        if strerror_r(errno as c_int, p, buf.len()) < 0 {
+            panic!("strerror_r failure");
+        }
+        let p = p as *const _;
+        str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
     }
 }
 
 pub fn getcwd() -> io::Result<PathBuf> {
-    let mut buf = [0; 4096];
-    let count = cvt(syscall::getcwd(&mut buf))?;
-    Ok(PathBuf::from(OsString::from_vec(buf[.. count].to_vec())))
+    let mut buf = Vec::with_capacity(512);
+    loop {
+        unsafe {
+            let ptr = buf.as_mut_ptr() as *mut libc::c_char;
+            if !libc::getcwd(ptr, buf.capacity() as libc::size_t).is_null() {
+                let len = CStr::from_ptr(buf.as_ptr() as *const libc::c_char).to_bytes().len();
+                buf.set_len(len);
+                buf.shrink_to_fit();
+                return Ok(PathBuf::from(OsString::from_vec(buf)));
+            } else {
+                let error = io::Error::last_os_error();
+                if error.raw_os_error() != Some(libc::ERANGE) {
+                    return Err(error);
+                }
+            }
+            // Trigger the internal buffer resizing logic of `Vec` by requiring
+            // more space than the current capacity.
+            let cap = buf.capacity();
+            buf.set_len(cap);
+            buf.reserve(1);
+        }
+    }
 }
 
 pub fn chdir(p: &path::Path) -> io::Result<()> {
-    cvt(syscall::chdir(p.to_str().unwrap())).and(Ok(()))
+    let p: &OsStr = p.as_ref();
+    let p = CString::new(p.as_bytes())?;
+    unsafe {
+        match libc::chdir(p.as_ptr()) == (0 as c_int) {
+            true => Ok(()),
+            false => Err(io::Error::last_os_error()),
+        }
+    }
 }
 
 pub struct SplitPaths<'a> {
     iter: iter::Map<slice::Split<'a, u8, fn(&u8) -> bool>,
-                    fn(&'a [u8]) -> PathBuf>,
+            fn(&'a [u8]) -> PathBuf>,
 }
 
 pub fn split_paths(unparsed: &OsStr) -> SplitPaths<'_> {
     fn bytes_to_path(b: &[u8]) -> PathBuf {
         PathBuf::from(<OsStr as OsStrExt>::from_bytes(b))
     }
-    fn is_semicolon(b: &u8) -> bool { *b == b';' }
+    fn is_colon(b: &u8) -> bool { *b == b':' }
     let unparsed = unparsed.as_bytes();
     SplitPaths {
-        iter: unparsed.split(is_semicolon as fn(&u8) -> bool)
-                      .map(bytes_to_path as fn(&[u8]) -> PathBuf)
+        iter: unparsed.split(is_colon as fn(&u8) -> bool)
+                        .map(bytes_to_path as fn(&[u8]) -> PathBuf)
     }
 }
 
@@ -83,11 +147,13 @@ pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
     where I: Iterator<Item=T>, T: AsRef<OsStr>
 {
     let mut joined = Vec::new();
-    let sep = b';';
+    let sep = b':';
 
     for (i, path) in paths.enumerate() {
         let path = path.as_ref().as_bytes();
-        if i > 0 { joined.push(sep) }
+        if i > 0 {
+            joined.push(sep)
+        }
         if path.contains(&sep) {
             return Err(JoinPathsError)
         }
@@ -107,22 +173,17 @@ impl StdError for JoinPathsError {
 }
 
 pub fn current_exe() -> io::Result<PathBuf> {
-    use crate::fs::File;
-
-    let mut file = File::open("sys:exe")?;
+    #[cfg(test)]
+    use realstd::env;
 
-    let mut path = String::new();
-    file.read_to_string(&mut path)?;
+    #[cfg(not(test))]
+    use crate::env;
 
-    if path.ends_with('\n') {
-        path.pop();
-    }
-
-    Ok(PathBuf::from(path))
+    let exe_path = env::args().next().unwrap();
+    let path = Path::new(&exe_path);
+    path.canonicalize()
 }
 
-pub static ENV_LOCK: Mutex = Mutex::new();
-
 pub struct Env {
     iter: vec::IntoIter<(OsString, OsString)>,
     _dont_send_or_sync_me: PhantomData<*mut ()>,
@@ -147,7 +208,7 @@ pub fn env() -> Env {
         let mut environ = *environ();
         if environ == ptr::null() {
             panic!("os::env() failure getting env string from OS: {}",
-                   io::Error::last_os_error());
+                io::Error::last_os_error());
         }
         let mut result = Vec::new();
         while *environ != ptr::null() {
@@ -200,7 +261,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
 
     unsafe {
         let _guard = ENV_LOCK.lock();
-        cvt_libc(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ())
+        cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ())
     }
 }
 
@@ -209,12 +270,14 @@ pub fn unsetenv(n: &OsStr) -> io::Result<()> {
 
     unsafe {
         let _guard = ENV_LOCK.lock();
-        cvt_libc(libc::unsetenv(nbuf.as_ptr())).map(|_| ())
+        cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ())
     }
 }
 
 pub fn page_size() -> usize {
-    4096
+    unsafe {
+        libc::sysconf(libc::_SC_PAGESIZE) as usize
+    }
 }
 
 pub fn temp_dir() -> PathBuf {
@@ -224,18 +287,38 @@ pub fn temp_dir() -> PathBuf {
 }
 
 pub fn home_dir() -> Option<PathBuf> {
-    return crate::env::var_os("HOME").map(PathBuf::from);
+    return crate::env::var_os("HOME").or_else(|| unsafe {
+        fallback()
+    }).map(PathBuf::from);
+
+    unsafe fn fallback() -> Option<OsString> {
+        let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) {
+            n if n < 0 => 512 as usize,
+            n => n as usize,
+        };
+        let mut buf = Vec::with_capacity(amt);
+        let mut passwd: libc::passwd = mem::zeroed();
+        let mut result = ptr::null_mut();
+        match libc::getpwuid_r(libc::getuid(), &mut passwd, buf.as_mut_ptr(),
+                                buf.capacity(), &mut result) {
+            0 if !result.is_null() => {
+                let ptr = passwd.pw_dir as *const _;
+                let bytes = CStr::from_ptr(ptr).to_bytes().to_vec();
+                Some(OsStringExt::from_vec(bytes))
+            },
+            _ => None,
+        }
+    }
 }
 
 pub fn exit(code: i32) -> ! {
-    let _ = syscall::exit(code as usize);
-    unreachable!();
+    unsafe { libc::exit(code as c_int) }
 }
 
 pub fn getpid() -> u32 {
-    syscall::getpid().unwrap() as u32
+    unsafe { libc::getpid() as u32 }
 }
 
 pub fn getppid() -> u32 {
-    syscall::getppid().unwrap() as u32
+    unsafe { libc::getppid() as u32 }
 }
diff --git a/src/libstd/sys/vxworks/path.rs b/src/libstd/sys/vxworks/path.rs
new file mode 100644
index 00000000000..7a183956107
--- /dev/null
+++ b/src/libstd/sys/vxworks/path.rs
@@ -0,0 +1,19 @@
+use crate::path::Prefix;
+use crate::ffi::OsStr;
+
+#[inline]
+pub fn is_sep_byte(b: u8) -> bool {
+    b == b'/'
+}
+
+#[inline]
+pub fn is_verbatim_sep(b: u8) -> bool {
+    b == b'/'
+}
+
+pub fn parse_prefix(_: &OsStr) -> Option<Prefix<'_>> {
+    None
+}
+
+pub const MAIN_SEP_STR: &str = "/";
+pub const MAIN_SEP: char = '/';
diff --git a/src/libstd/sys/vxworks/pipe.rs b/src/libstd/sys/vxworks/pipe.rs
new file mode 100644
index 00000000000..e09dbe6e99b
--- /dev/null
+++ b/src/libstd/sys/vxworks/pipe.rs
@@ -0,0 +1,95 @@
+use crate::io::{self, IoSlice, IoSliceMut};
+use libc::{self /*, c_int apparently not used? */};
+use crate::mem;
+use crate::sync::atomic::{AtomicBool};
+use crate::sys::fd::FileDesc;
+use crate::sys::{cvt, cvt_r};
+
+pub struct AnonPipe(FileDesc);
+
+pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
+    static INVALID: AtomicBool = AtomicBool::new(false);
+
+    let mut fds = [0; 2];
+    cvt(unsafe { libc::pipe(fds.as_mut_ptr()) })?;
+
+    let fd0 = FileDesc::new(fds[0]);
+    let fd1 = FileDesc::new(fds[1]);
+    fd0.set_cloexec()?;
+    fd1.set_cloexec()?;
+    Ok((AnonPipe(fd0), AnonPipe(fd1)))
+}
+
+impl AnonPipe {
+    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+        self.0.read(buf)
+    }
+    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
+                self.0.read_vectored(bufs)
+        }
+
+    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
+        self.0.write(buf)
+    }
+
+        pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
+                self.0.write_vectored(bufs)
+        }
+
+    pub fn fd(&self) -> &FileDesc { &self.0 }
+    pub fn into_fd(self) -> FileDesc { self.0 }
+    pub fn diverge(&self) -> ! {
+        panic!()
+     }
+}
+
+pub fn read2(p1: AnonPipe,
+             v1: &mut Vec<u8>,
+             p2: AnonPipe,
+             v2: &mut Vec<u8>) -> io::Result<()> {
+
+    // Set both pipes into nonblocking mode as we're gonna be reading from both
+    // in the `select` loop below, and we wouldn't want one to block the other!
+    let p1 = p1.into_fd();
+    let p2 = p2.into_fd();
+    p1.set_nonblocking_pipe(true)?;
+    p2.set_nonblocking_pipe(true)?;
+
+    let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
+    fds[0].fd = p1.raw();
+    fds[0].events = libc::POLLIN;
+    fds[1].fd = p2.raw();
+    fds[1].events = libc::POLLIN;
+    loop {
+        // wait for either pipe to become readable using `poll`
+        cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?;
+
+        if fds[0].revents != 0 && read(&p1, v1)? {
+            p2.set_nonblocking_pipe(false)?;
+            return p2.read_to_end(v2).map(|_| ());
+        }
+        if fds[1].revents != 0 && read(&p2, v2)? {
+            p1.set_nonblocking_pipe(false)?;
+            return p1.read_to_end(v1).map(|_| ());
+        }
+    }
+
+    // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
+    // EAGAIN. If we hit EOF, then this will happen because the underlying
+    // reader will return Ok(0), in which case we'll see `Ok` ourselves. In
+    // this case we flip the other fd back into blocking mode and read
+    // whatever's leftover on that file descriptor.
+    fn read(fd: &FileDesc, dst: &mut Vec<u8>) -> Result<bool, io::Error> {
+        match fd.read_to_end(dst) {
+            Ok(_) => Ok(true),
+            Err(e) => {
+                if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
+                   e.raw_os_error() == Some(libc::EAGAIN) {
+                    Ok(false)
+                } else {
+                    Err(e)
+                }
+            }
+        }
+    }
+}
diff --git a/src/libstd/sys/vxworks/process/mod.rs b/src/libstd/sys/vxworks/process/mod.rs
new file mode 100644
index 00000000000..4dc706006f4
--- /dev/null
+++ b/src/libstd/sys/vxworks/process/mod.rs
@@ -0,0 +1,7 @@
+pub use self::process_common::{Command, ExitStatus, ExitCode, Stdio, StdioPipes};
+pub use self::process_inner::Process;
+
+mod process_common;
+#[path = "process_vxworks.rs"]
+mod process_inner;
+mod rtp;
diff --git a/src/libstd/sys/vxworks/process/process_common.rs b/src/libstd/sys/vxworks/process/process_common.rs
new file mode 100644
index 00000000000..397200c39c2
--- /dev/null
+++ b/src/libstd/sys/vxworks/process/process_common.rs
@@ -0,0 +1,405 @@
+use crate::os::unix::prelude::*;
+
+use crate::ffi::{OsString, OsStr, CString, CStr};
+use crate::fmt;
+use crate::io;
+use crate::ptr;
+use crate::sys::fd::FileDesc;
+use crate::sys::fs::{File, OpenOptions};
+use crate::sys::pipe::{self, AnonPipe};
+use crate::sys_common::process::{CommandEnv, DefaultEnvKey};
+use crate::collections::BTreeMap;
+
+use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
+
+////////////////////////////////////////////////////////////////////////////////
+// Command
+////////////////////////////////////////////////////////////////////////////////
+
+pub struct Command {
+    // Currently we try hard to ensure that the call to `.exec()` doesn't
+    // actually allocate any memory. While many platforms try to ensure that
+    // memory allocation works after a fork in a multithreaded process, it's
+    // been observed to be buggy and somewhat unreliable, so we do our best to
+    // just not do it at all!
+    //
+    // Along those lines, the `argv` and `envp` raw pointers here are exactly
+    // what's gonna get passed to `execvp`. The `argv` array starts with the
+    // `program` and ends with a NULL, and the `envp` pointer, if present, is
+    // also null-terminated.
+    //
+    // Right now we don't support removing arguments, so there's no much fancy
+    // support there, but we support adding and removing environment variables,
+    // so a side table is used to track where in the `envp` array each key is
+    // located. Whenever we add a key we update it in place if it's already
+    // present, and whenever we remove a key we update the locations of all
+    // other keys.
+    program: CString,
+    args: Vec<CString>,
+    argv: Argv,
+    env: CommandEnv<DefaultEnvKey>,
+
+    cwd: Option<CString>,
+    uid: Option<uid_t>,
+    gid: Option<gid_t>,
+    saw_nul: bool,
+    closures: Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>>,
+    stdin: Option<Stdio>,
+    stdout: Option<Stdio>,
+    stderr: Option<Stdio>,
+}
+
+// Create a new type for argv, so that we can make it `Send`
+struct Argv(Vec<*const c_char>);
+
+// It is safe to make Argv Send, because it contains pointers to memory owned by `Command.args`
+unsafe impl Send for Argv {}
+
+// passed back to std::process with the pipes connected to the child, if any
+// were requested
+pub struct StdioPipes {
+    pub stdin: Option<AnonPipe>,
+    pub stdout: Option<AnonPipe>,
+    pub stderr: Option<AnonPipe>,
+}
+
+// passed to do_exec() with configuration of what the child stdio should look
+// like
+pub struct ChildPipes {
+    pub stdin: ChildStdio,
+    pub stdout: ChildStdio,
+    pub stderr: ChildStdio,
+}
+
+pub enum ChildStdio {
+    Inherit,
+    Explicit(c_int),
+    Owned(FileDesc),
+}
+
+pub enum Stdio {
+    Inherit,
+    Null,
+    MakePipe,
+    Fd(FileDesc),
+}
+
+impl Command {
+    pub fn new(program: &OsStr) -> Command {
+        let mut saw_nul = false;
+        let program = os2c(program, &mut saw_nul);
+        Command {
+            argv: Argv(vec![program.as_ptr(), ptr::null()]),
+            program,
+            args: Vec::new(),
+            env: Default::default(),
+            cwd: None,
+            uid: None,
+            gid: None,
+            saw_nul,
+            closures: Vec::new(),
+            stdin: None,
+            stdout: None,
+            stderr: None,
+        }
+    }
+
+    pub fn arg(&mut self, arg: &OsStr) {
+        // Overwrite the trailing NULL pointer in `argv` and then add a new null
+        // pointer.
+        let arg = os2c(arg, &mut self.saw_nul);
+        self.argv.0[self.args.len() + 1] = arg.as_ptr();
+        self.argv.0.push(ptr::null());
+
+        // Also make sure we keep track of the owned value to schedule a
+        // destructor for this memory.
+        self.args.push(arg);
+    }
+
+    pub fn cwd(&mut self, dir: &OsStr) {
+        self.cwd = Some(os2c(dir, &mut self.saw_nul));
+    }
+    pub fn uid(&mut self, id: uid_t) {
+        self.uid = Some(id);
+    }
+    pub fn gid(&mut self, id: gid_t) {
+        self.gid = Some(id);
+    }
+
+    pub fn saw_nul(&self) -> bool {
+        self.saw_nul
+    }
+    pub fn get_argv(&self) -> &Vec<*const c_char> {
+        &self.argv.0
+    }
+
+    #[allow(dead_code)]
+    pub fn get_cwd(&self) -> &Option<CString> {
+        &self.cwd
+    }
+    #[allow(dead_code)]
+    pub fn get_uid(&self) -> Option<uid_t> {
+        self.uid
+    }
+    #[allow(dead_code)]
+    pub fn get_gid(&self) -> Option<gid_t> {
+        self.gid
+    }
+
+    pub fn get_closures(&mut self) -> &mut Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>> {
+        &mut self.closures
+    }
+
+    pub unsafe fn pre_exec(
+        &mut self,
+        _f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>,
+    ) {
+        // Fork() is not supported in vxWorks so no way to run the closure in the new procecss.
+        unimplemented!();;
+    }
+
+    pub fn stdin(&mut self, stdin: Stdio) {
+        self.stdin = Some(stdin);
+    }
+
+    pub fn stdout(&mut self, stdout: Stdio) {
+        self.stdout = Some(stdout);
+    }
+
+    pub fn stderr(&mut self, stderr: Stdio) {
+        self.stderr = Some(stderr);
+    }
+
+    pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
+        &mut self.env
+    }
+
+    pub fn capture_env(&mut self) -> Option<CStringArray> {
+        let maybe_env = self.env.capture_if_changed();
+        maybe_env.map(|env| construct_envp(env, &mut self.saw_nul))
+    }
+    #[allow(dead_code)]
+    pub fn env_saw_path(&self) -> bool {
+        self.env.have_changed_path()
+    }
+
+    pub fn setup_io(&self, default: Stdio, needs_stdin: bool)
+                -> io::Result<(StdioPipes, ChildPipes)> {
+        let null = Stdio::Null;
+        let default_stdin = if needs_stdin {&default} else {&null};
+        let stdin = self.stdin.as_ref().unwrap_or(default_stdin);
+        let stdout = self.stdout.as_ref().unwrap_or(&default);
+        let stderr = self.stderr.as_ref().unwrap_or(&default);
+        let (their_stdin, our_stdin) = stdin.to_child_stdio(true)?;
+        let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?;
+        let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?;
+        let ours = StdioPipes {
+            stdin: our_stdin,
+            stdout: our_stdout,
+            stderr: our_stderr,
+        };
+        let theirs = ChildPipes {
+            stdin: their_stdin,
+            stdout: their_stdout,
+            stderr: their_stderr,
+        };
+        Ok((ours, theirs))
+    }
+}
+
+fn os2c(s: &OsStr, saw_nul: &mut bool) -> CString {
+    CString::new(s.as_bytes()).unwrap_or_else(|_e| {
+        *saw_nul = true;
+        CString::new("<string-with-nul>").unwrap()
+    })
+}
+
+// Helper type to manage ownership of the strings within a C-style array.
+pub struct CStringArray {
+    items: Vec<CString>,
+    ptrs: Vec<*const c_char>
+}
+
+impl CStringArray {
+    pub fn with_capacity(capacity: usize) -> Self {
+        let mut result = CStringArray {
+            items: Vec::with_capacity(capacity),
+            ptrs: Vec::with_capacity(capacity+1)
+        };
+        result.ptrs.push(ptr::null());
+        result
+    }
+    pub fn push(&mut self, item: CString) {
+        let l = self.ptrs.len();
+        self.ptrs[l-1] = item.as_ptr();
+        self.ptrs.push(ptr::null());
+        self.items.push(item);
+    }
+    pub fn as_ptr(&self) -> *const *const c_char {
+        self.ptrs.as_ptr()
+    }
+}
+
+fn construct_envp(env: BTreeMap<DefaultEnvKey, OsString>, saw_nul: &mut bool) -> CStringArray {
+    let mut result = CStringArray::with_capacity(env.len());
+    for (k, v) in env {
+        let mut k: OsString = k.into();
+
+        // Reserve additional space for '=' and null terminator
+        k.reserve_exact(v.len() + 2);
+        k.push("=");
+        k.push(&v);
+
+        // Add the new entry into the array
+        if let Ok(item) = CString::new(k.into_vec()) {
+            result.push(item);
+        } else {
+            *saw_nul = true;
+        }
+    }
+
+    result
+}
+
+impl Stdio {
+    pub fn to_child_stdio(&self, readable: bool)
+                      -> io::Result<(ChildStdio, Option<AnonPipe>)> {
+        match *self {
+            Stdio::Inherit => {
+                Ok((ChildStdio::Inherit, None))
+            },
+
+            // Make sure that the source descriptors are not an stdio
+            // descriptor, otherwise the order which we set the child's
+            // descriptors may blow away a descriptor which we are hoping to
+            // save. For example, suppose we want the child's stderr to be the
+            // parent's stdout, and the child's stdout to be the parent's
+            // stderr. No matter which we dup first, the second will get
+            // overwritten prematurely.
+            Stdio::Fd(ref fd) => {
+                if fd.raw() >= 0 && fd.raw() <= libc::STDERR_FILENO {
+                    Ok((ChildStdio::Owned(fd.duplicate()?), None))
+                } else {
+                    Ok((ChildStdio::Explicit(fd.raw()), None))
+                }
+            }
+
+            Stdio::MakePipe => {
+                let (reader, writer) = pipe::anon_pipe()?;
+                let (ours, theirs) = if readable {
+                    (writer, reader)
+                } else {
+                    (reader, writer)
+                };
+                Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours)))
+            }
+
+            Stdio::Null => {
+                let mut opts = OpenOptions::new();
+                opts.read(readable);
+                opts.write(!readable);
+                let path = unsafe {
+                    CStr::from_ptr("/null\0".as_ptr() as *const _)
+                };
+                let fd = File::open_c(&path, &opts)?;
+                Ok((ChildStdio::Owned(fd.into_fd()), None))
+            }
+        }
+    }
+}
+
+impl From<AnonPipe> for Stdio {
+    fn from(pipe: AnonPipe) -> Stdio {
+        Stdio::Fd(pipe.into_fd())
+    }
+}
+
+impl From<File> for Stdio {
+    fn from(file: File) -> Stdio {
+        Stdio::Fd(file.into_fd())
+    }
+}
+
+impl ChildStdio {
+    pub fn fd(&self) -> Option<c_int> {
+        match *self {
+            ChildStdio::Inherit => None,
+            ChildStdio::Explicit(fd) => Some(fd),
+            ChildStdio::Owned(ref fd) => Some(fd.raw()),
+        }
+    }
+}
+
+impl fmt::Debug for Command {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{:?}", self.program)?;
+        for arg in &self.args {
+            write!(f, " {:?}", arg)?;
+        }
+        Ok(())
+    }
+}
+
+/// Unix exit statuses
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct ExitStatus(c_int);
+
+impl ExitStatus {
+    pub fn new(status: c_int) -> ExitStatus {
+        ExitStatus(status)
+    }
+
+    fn exited(&self) -> bool {
+        /*unsafe*/ { libc::WIFEXITED(self.0) }
+    }
+
+    pub fn success(&self) -> bool {
+        self.code() == Some(0)
+    }
+
+    pub fn code(&self) -> Option<i32> {
+        if self.exited() {
+            Some(/*unsafe*/ { libc::WEXITSTATUS(self.0) })
+        } else {
+            None
+        }
+    }
+
+    pub fn signal(&self) -> Option<i32> {
+        if !self.exited() {
+            Some(/*unsafe*/ { libc::WTERMSIG(self.0) })
+        } else {
+            None
+        }
+    }
+}
+
+impl From<c_int> for ExitStatus {
+    fn from(a: c_int) -> ExitStatus {
+        ExitStatus(a)
+    }
+}
+
+impl fmt::Display for ExitStatus {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if let Some(code) = self.code() {
+            write!(f, "exit code: {}", code)
+        } else {
+            let signal = self.signal().unwrap();
+            write!(f, "signal: {}", signal)
+        }
+    }
+}
+
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+pub struct ExitCode(u8);
+
+impl ExitCode {
+    pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
+    pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);
+
+    #[inline]
+    pub fn as_i32(&self) -> i32 {
+        self.0 as i32
+    }
+}
diff --git a/src/libstd/sys/vxworks/process/process_vxworks.rs b/src/libstd/sys/vxworks/process/process_vxworks.rs
new file mode 100644
index 00000000000..b07966fa206
--- /dev/null
+++ b/src/libstd/sys/vxworks/process/process_vxworks.rs
@@ -0,0 +1,156 @@
+use crate::io::{self, Error, ErrorKind};
+use libc::{self, c_int, c_char};
+use libc::{RTP_ID};
+use crate::sys;
+use crate::sys::cvt;
+use crate::sys::process::rtp;
+use crate::sys::process::process_common::*;
+
+////////////////////////////////////////////////////////////////////////////////
+// Command
+////////////////////////////////////////////////////////////////////////////////
+
+impl Command {
+    pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
+                 -> io::Result<(Process, StdioPipes)> {
+        use crate::sys::{cvt_r};
+        const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX";
+
+        if self.saw_nul() {
+            return Err(io::Error::new(ErrorKind::InvalidInput,
+                                      "nul byte found in provided data"));
+        }
+        let (ours, theirs) = self.setup_io(default, needs_stdin)?;
+        let mut p = Process { pid: 0, status: None };
+
+        unsafe {
+            macro_rules! t {
+                ($e:expr) => (match $e {
+                    Ok(e) => e,
+                    Err(e) => return Err(e.into()),
+                })
+            }
+
+            let mut orig_stdin = libc::STDIN_FILENO;
+            let mut orig_stdout = libc::STDOUT_FILENO;
+            let mut orig_stderr = libc::STDERR_FILENO;
+
+            if let Some(fd) = theirs.stdin.fd() {
+                orig_stdin = t!(cvt_r(|| libc::dup(libc::STDIN_FILENO)));
+                t!(cvt_r(|| libc::dup2(fd, libc::STDIN_FILENO)));
+            }
+            if let Some(fd) = theirs.stdout.fd() {
+                orig_stdout = t!(cvt_r(|| libc::dup(libc::STDOUT_FILENO)));
+                t!(cvt_r(|| libc::dup2(fd, libc::STDOUT_FILENO)));
+            }
+            if let Some(fd) = theirs.stderr.fd() {
+                orig_stderr = t!(cvt_r(|| libc::dup(libc::STDERR_FILENO)));
+                t!(cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO)));
+            }
+
+            if let Some(ref cwd) = *self.get_cwd() {
+                t!(cvt(libc::chdir(cwd.as_ptr())));
+            }
+
+            let ret = rtp::rtpSpawn(
+                self.get_argv()[0],                   // executing program
+                self.get_argv().as_ptr() as *const _, // argv
+                *sys::os::environ() as *const *const c_char,
+                100 as c_int,                         // initial priority
+                0x16000,                                    // initial stack size. 0 defaults
+                                                      // to 0x4000 in 32 bit and 0x8000 in 64 bit
+                0,                                    // options
+                0                                     // task options
+            );
+
+            // Because FileDesc was not used, each duplicated file descriptor
+            // needs to be closed manually
+            if orig_stdin != libc::STDIN_FILENO {
+                t!(cvt_r(|| libc::dup2(orig_stdin, libc::STDIN_FILENO)));
+                libc::close(orig_stdin);
+            }
+            if orig_stdout != libc::STDOUT_FILENO {
+                t!(cvt_r(|| libc::dup2(orig_stdout, libc::STDOUT_FILENO)));
+                libc::close(orig_stdout);
+            }
+            if orig_stderr != libc::STDERR_FILENO {
+                t!(cvt_r(|| libc::dup2(orig_stderr, libc::STDERR_FILENO)));
+                libc::close(orig_stderr);
+            }
+
+            if ret != rtp::RTP_ID_ERROR {
+                p.pid = ret;
+                Ok((p, ours))
+            } else {
+                Err(io::Error::last_os_error())
+            }
+        }
+    }
+
+    pub fn exec(&mut self, default: Stdio) -> io::Error {
+        let ret = Command::spawn(self, default, false);
+        match ret {
+            Ok(t) => unsafe {
+                let mut status = 0 as c_int;
+                libc::waitpid(t.0.pid, &mut status, 0);
+                libc::exit(0);
+            },
+            Err(e) => e,
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Processes
+////////////////////////////////////////////////////////////////////////////////
+
+/// The unique id of the process (this should never be negative).
+pub struct Process {
+    pid: RTP_ID,
+    status: Option<ExitStatus>,
+}
+
+impl Process {
+    pub fn id(&self) -> u32 {
+        self.pid as u32
+    }
+
+    pub fn kill(&mut self) -> io::Result<()> {
+        // If we've already waited on this process then the pid can be recycled
+        // and used for another process, and we probably shouldn't be killing
+        // random processes, so just return an error.
+        if self.status.is_some() {
+            Err(Error::new(ErrorKind::InvalidInput,
+                           "invalid argument: can't kill an exited process"))
+        } else {
+            cvt(unsafe { libc::kill(self.pid, libc::SIGKILL) }).map(|_| ())
+        }
+    }
+
+    pub fn wait(&mut self) -> io::Result<ExitStatus> {
+        use crate::sys::cvt_r;
+        if let Some(status) = self.status {
+            return Ok(status)
+        }
+        let mut status = 0 as c_int;
+        cvt_r(|| unsafe { libc::waitpid(self.pid, &mut status, 0) })?;
+        self.status = Some(ExitStatus::new(status));
+        Ok(ExitStatus::new(status))
+    }
+
+    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
+        if let Some(status) = self.status {
+            return Ok(Some(status))
+        }
+        let mut status = 0 as c_int;
+        let pid = cvt(unsafe {
+            libc::waitpid(self.pid, &mut status, libc::WNOHANG)
+        })?;
+        if pid == 0 {
+            Ok(None)
+        } else {
+            self.status = Some(ExitStatus::new(status));
+            Ok(Some(ExitStatus::new(status)))
+        }
+    }
+}
diff --git a/src/libstd/sys/vxworks/process/rtp.rs b/src/libstd/sys/vxworks/process/rtp.rs
new file mode 100644
index 00000000000..3e6e0017abc
--- /dev/null
+++ b/src/libstd/sys/vxworks/process/rtp.rs
@@ -0,0 +1,298 @@
+#![allow(non_camel_case_types, unused)]
+
+use libc::{self, c_int, size_t, c_char, BOOL, RTP_DESC, RTP_ID, TASK_ID};
+
+
+// Copied directly from rtpLibCommon.h, rtpLib.h, signal.h and taskLibCommon.h (for task options)
+
+// ****     definitions for rtpLibCommon.h    ****
+
+pub const RTP_GLOBAL_SYMBOLS     : c_int = 0x01; // register global symbols for RTP
+pub const RTP_LOCAL_SYMBOLS      : c_int = 0x02; // idem for local symbols
+pub const RTP_ALL_SYMBOLS        : c_int = (RTP_GLOBAL_SYMBOLS | RTP_LOCAL_SYMBOLS);
+pub const RTP_DEBUG              : c_int = 0x10; // set RTP in debug mode when created
+pub const RTP_BUFFER_VAL_OFF     : c_int = 0x20; // disable buffer validation for all
+                                                 // system calls issued from the RTP
+pub const RTP_LOADED_WAIT        : c_int = 0x40; // Wait until the RTP is loaded
+pub const RTP_CPU_AFFINITY_NONE  : c_int = 0x80; // Remove any CPU affinity (SMP)
+
+// Error Status codes
+
+pub const M_rtpLib : c_int = 178 << 16;
+
+pub const S_rtpLib_INVALID_FILE                   : c_int = (M_rtpLib | 1);
+pub const S_rtpLib_INVALID_OPTION                 : c_int = (M_rtpLib | 2);
+pub const S_rtpLib_ACCESS_DENIED                  : c_int = (M_rtpLib | 3);
+pub const S_rtpLib_INVALID_RTP_ID                 : c_int = (M_rtpLib | 4);
+pub const S_rtpLib_NO_SYMBOL_TABLE                : c_int = (M_rtpLib | 5);
+pub const S_rtpLib_INVALID_SEGMENT_START_ADDRESS  : c_int = (M_rtpLib | 6);
+pub const S_rtpLib_INVALID_SYMBOL_REGISTR_POLICY  : c_int = (M_rtpLib | 7);
+pub const S_rtpLib_INSTANTIATE_FAILED             : c_int = (M_rtpLib | 8);
+pub const S_rtpLib_INVALID_TASK_OPTION            : c_int = (M_rtpLib | 9);
+pub const S_rtpLib_RTP_NAME_LENGTH_EXCEEDED       : c_int = (M_rtpLib | 10);    // rtpInfoGet
+
+pub const VX_RTP_NAME_LENGTH                      : c_int  = 255;    // max name length for diplay
+
+
+// The 'status' field (32 bit integer) of a RTP holds the RTP state and status.
+//
+// NOTE: RTP_STATE_GET()    : read the RTP state(s)
+//       RTP_STATE_PUT()    : write the RTP state(s)
+//       RTP_STATE_SET()    : set a RTP state
+//       RTP_STATE_UNSET()  : unset a RTP state
+//
+//       RTP_STATUS_GET()   : read the RTP status
+//       RTP_STATUS_PUT()   : write the RTP status
+//       RTP_STATUS_SET()   : set a RTP status
+//       RTP_STATUS_UNSET() : unset a RTP status
+//
+// The PUT/SET/UNSET macros are available only in the kernel headers.
+
+
+// RTP states
+
+pub const RTP_STATE_CREATE           : c_int  = 0x0001; // RrtpStructTP is under construction
+pub const RTP_STATE_NORMAL           : c_int  = 0x0002; // RrtpStructTP is ready
+pub const RTP_STATE_DELETE           : c_int  = 0x0004; // RrtpStructTP is being deleted
+
+pub const RTP_STATUS_STOP            : c_int  = 0x0100; // RTP hrtpStructas recieved stopped signal
+pub const RTP_STATUS_ELECTED_DELETER : c_int  = 0x0200; // RTP drtpStructelete has started
+
+pub const RTP_STATE_MASK             : c_int  = (RTP_STATE_CREATE | RTP_STATE_NORMAL |
+                                                 RTP_STATE_DELETE);
+pub const RTP_STATUS_MASK            : c_int  = (RTP_STATUS_STOP | RTP_STATUS_ELECTED_DELETER);
+
+pub fn RTP_STATE_GET  (value : c_int) -> c_int {
+    value & RTP_STATE_MASK
+}
+pub fn RTP_STATUS_GET (value : c_int) -> c_int {
+    value & RTP_STATUS_MASK
+}
+
+// Indicates that the RTP_ID returned is not valid.
+
+// RTP_ID_ERROR is supposed to be set to -1, but you can't set
+// an unsigned value to a negative without casting, and you
+// can't cast unless the size of the integer types are the same,
+// but the size of RTP_ID may differ between kernel and user space.
+// Bitwise or-ing min and max should get the same result.
+pub const RTP_ID_ERROR : RTP_ID = RTP_ID::min_value() | RTP_ID::max_value();
+
+// IS_RTP_ C macros
+
+pub fn IS_RTP_STATE_NORMAL           (value : c_int) -> bool {
+    (RTP_STATE_GET(value)  & RTP_STATE_NORMAL) == RTP_STATE_NORMAL
+}
+pub fn IS_RTP_STATE_CREATE           (value : c_int) -> bool {
+    (RTP_STATE_GET(value)  & RTP_STATE_CREATE) == RTP_STATE_CREATE
+}
+pub fn IS_RTP_STATE_DELETE           (value : c_int) -> bool {
+    (RTP_STATE_GET(value)  & RTP_STATE_DELETE) == RTP_STATE_DELETE
+}
+pub fn IS_RTP_STATUS_STOP            (value : c_int) -> bool {
+    (RTP_STATUS_GET(value) & RTP_STATUS_STOP ) == RTP_STATUS_STOP
+}
+pub fn IS_RTP_STATUS_ELECTED_DELETER (value : c_int) -> bool {
+    (RTP_STATUS_GET(value) &  RTP_STATUS_ELECTED_DELETER) == RTP_STATUS_ELECTED_DELETER
+}
+
+// **** end of definitions for rtpLibCommon.h ****
+
+
+
+
+// ****    definitions for rtpLib.h     ****
+
+pub fn rtpExit(exitCode : c_int) -> ! {
+    unsafe{ libc::exit (exitCode) }
+}
+
+/* rtpLib.h in the kernel
+pub const RTP_DEL_VIA_TASK_DELETE : c_int  = 0x1;          // rtpDelete() via taskDestroy()
+pub const RTP_DEL_FORCE           : c_int  = 0x2;          // Forceful  rtpDelete()
+pub const RTP_ID_ANY              : RTP_ID = 0;            // used for when a kernel task
+                                                           // wants to wait for the next
+                                                           // RTP to finish
+
+
+// Function pointers
+
+pub type RTP_PRE_CREATE_HOOK    = size_t;
+pub type RTP_POST_CREATE_HOOK   = size_t;
+pub type RTP_INIT_COMPLETE_HOOK = size_t;
+pub type RTP_DELETE_HOOK        = size_t;
+*/
+
+// **** end of definitions for rtpLib.h ****
+
+
+
+
+
+// ****     definitions for signal.h    ****
+pub fn rtpKill(rtpId : RTP_ID, signo : c_int) -> c_int {
+    unsafe{ libc::kill(rtpId as c_int, signo) }
+}
+
+pub fn rtpSigqueue(rtpId : RTP_ID, signo : c_int, value : size_t) -> c_int {
+    unsafe{ libc::sigqueue(rtpId as c_int, signo, value) }
+}
+
+pub fn _rtpSigqueue(rtpId : RTP_ID, signo : c_int, value : *mut size_t, code : c_int) -> c_int {
+    unsafe{ libc::_sigqueue(rtpId, signo, value, code) }
+}
+
+pub fn taskRaise(signo : c_int) -> c_int {
+    unsafe{ libc::taskKill(libc::taskIdSelf(), signo) }
+}
+pub fn rtpRaise(signo : c_int) -> c_int {
+    unsafe{ libc::raise(signo) }
+}
+
+// **** end of definitions for signal.h ****
+
+
+
+// ****     definitions for taskLibCommon.h    ****
+pub const VX_PRIVATE_ENV      : c_int = 0x0080;  // 1 = private environment variables
+pub const VX_NO_STACK_FILL    : c_int = 0x0100;  // 1 = avoid stack fill of 0xee
+pub const VX_PRIVATE_UMASK    : c_int = 0x0400;  // 1 = private file creation mode mask
+pub const VX_TASK_NOACTIVATE  : c_int = 0x2000;  // taskOpen() does not taskActivate()
+pub const VX_NO_STACK_PROTECT : c_int = 0x4000;  // no over/underflow stack protection,
+                                                 // stack space remains executable
+
+// define for all valid user task options
+
+pub const VX_USR_TASK_OPTIONS_BASE: c_int = (VX_PRIVATE_ENV      |
+                                             VX_NO_STACK_FILL    |
+                                             VX_TASK_NOACTIVATE  |
+                                             VX_NO_STACK_PROTECT |
+                                             VX_PRIVATE_UMASK);
+
+// **** end of definitions for taskLibCommon.h ****
+
+
+
+extern "C" {
+// functions in rtpLibCommon.h
+
+// forward declarations
+    pub fn rtpSpawn (
+        pubrtpFileName : *const c_char,
+        argv           : *const *const c_char,
+        envp           : *const *const c_char,
+        priority       : c_int,
+        uStackSize     : size_t,
+        options        : c_int,
+        taskOptions    : c_int,
+    ) -> RTP_ID;
+
+    pub fn rtpInfoGet (
+        rtpId     : RTP_ID,
+        rtpStruct : *mut RTP_DESC,
+    ) -> c_int;
+
+/* functions in rtpLib.h for kernel
+
+
+    // function declarations
+
+    pub fn rtpDelete (
+        id      : RTP_ID,
+        options : c_int,
+        status  : c_int,
+    ) -> c_int;
+
+    pub fn rtpDeleteForce (
+        rtpId : RTP_ID
+    ) -> c_int;
+
+    pub fn rtpShow (
+        rtpNameOrId : *mut c_char,
+        level       : c_int,
+    ) -> BOOL;
+
+    // RTP signals are always present when RTPs are included.  The public RTP
+    // signal APIs are declared here.
+
+
+    pub fn rtpKill (
+        rtpId : RTP_ID,
+        signo : c_int,
+    ) -> c_int;
+
+    pub fn rtpSigqueue (
+        rtpId : RTP_ID,
+        signo : c_int,
+        value : size_t, // Actual type is const union sigval value,
+                        // which is a union of int and void *
+    ) -> c_int;
+
+    pub fn rtpTaskKill (
+        tid   : TASK_ID,
+        signo : c_int,
+    ) -> c_int;
+
+    pub fn rtpTaskSigqueue (
+        tid   : TASK_ID,
+        signo : c_int,
+        value : const size_t, // Actual type is const union sigval,
+                        // which is a union of int and void *
+    ) -> c_int;
+
+    pub fn rtpWait (
+        rtpWaitId : RTP_ID,
+        timeout   : libc::alloc_jemalloc_Vx_ticks_t,
+        pRtpId    : *mut RTP_ID,
+        pStatus   : *mut c_int,
+    ) -> c_int;
+
+                             // Other public functions
+
+
+    pub fn rtpPreCreateHookAdd     (
+        hook      : RTP_PRE_CREATE_HOOK,
+        addToHead : BOOL,
+    ) -> c_int;
+
+    pub fn rtpPreCreateHookDelete  (
+        hook      : RTP_POST_CREATE_HOOK,
+    ) -> c_int;
+
+    pub fn rtpPostCreateHookAdd    (
+        hook      : RTP_POST_CREATE_HOOK,
+        addToHead : BOOL,
+    ) -> c_int;
+
+    pub fn rtpPostCreateHookDelete (
+        hook      : RTP_POST_CREATE_HOOK,
+    ) -> c_int;
+
+    pub fn rtpInitCompleteHookAdd  (
+        hook      : RTP_INIT_COMPLETE_HOOK,
+        addToHead : BOOL,
+    ) -> c_int;
+
+    pub fn rtpInitCompleteHookDelete (
+        hook      : RTP_INIT_COMPLETE_HOOK,
+    ) -> c_int;
+
+    pub fn rtpDeleteHookAdd        (
+        hook      : RTP_DELETE_HOOK,
+        addToHead : BOOL,
+    ) -> c_int;
+
+    pub fn rtpDeleteHookDelete     (
+        hook      : RTP_DELETE_HOOK,
+    ) -> c_int;
+
+    pub fn rtpMemShow              (
+        rtpNameOrId : *mut c_char,
+        level       : c_int,
+    ) -> c_int;
+
+    pub fn rtpHookShow             (
+
+    );
+*/
+}
diff --git a/src/libstd/sys/vxworks/rand.rs b/src/libstd/sys/vxworks/rand.rs
new file mode 100644
index 00000000000..1ec0cbe4dcf
--- /dev/null
+++ b/src/libstd/sys/vxworks/rand.rs
@@ -0,0 +1,31 @@
+use crate::mem;
+use crate::slice;
+
+pub fn hashmap_random_keys() -> (u64, u64) {
+    let mut v = (0, 0);
+    unsafe {
+        let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8,
+                                             mem::size_of_val(&v));
+        imp::fill_bytes(view);
+    }
+    return v
+}
+
+mod imp {
+    use libc;
+    use crate::io;
+
+    extern "C" {
+        fn randBytes (randBuf: *mut libc::c_uchar,
+                      numOfBytes: libc::c_int) -> libc::c_int;
+    }
+
+    pub fn fill_bytes(v: &mut [u8]) {
+        let ret = unsafe {
+            randBytes(v.as_mut_ptr() as *mut libc::c_uchar, v.len() as libc::c_int)
+        };
+        if ret == -1 {
+            panic!("couldn't generate random bytes: {}", io::Error::last_os_error());
+        }
+    }
+}
diff --git a/src/libstd/sys/vxworks/rwlock.rs b/src/libstd/sys/vxworks/rwlock.rs
new file mode 100644
index 00000000000..718f422ed11
--- /dev/null
+++ b/src/libstd/sys/vxworks/rwlock.rs
@@ -0,0 +1,113 @@
+use libc;
+use crate::cell::UnsafeCell;
+use crate::sync::atomic::{AtomicUsize, Ordering};
+
+pub struct RWLock {
+    inner: UnsafeCell<libc::pthread_rwlock_t>,
+    write_locked: UnsafeCell<bool>,
+    num_readers: AtomicUsize,
+}
+
+unsafe impl Send for RWLock {}
+unsafe impl Sync for RWLock {}
+
+impl RWLock {
+    pub const fn new() -> RWLock {
+        RWLock {
+            inner: UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER),
+            write_locked: UnsafeCell::new(false),
+            num_readers: AtomicUsize::new(0),
+        }
+    }
+
+    #[inline]
+    pub unsafe fn read(&self) {
+        let r = libc::pthread_rwlock_rdlock(self.inner.get());
+        if r == libc::EAGAIN {
+            panic!("rwlock maximum reader count exceeded");
+        } else if r == libc::EDEADLK || *self.write_locked.get() {
+            if r == 0 {
+                self.raw_unlock();
+            }
+        panic!("rwlock read lock would result in deadlock");
+        } else {
+            debug_assert_eq!(r, 0);
+            self.num_readers.fetch_add(1, Ordering::Relaxed);
+        }
+    }
+
+    #[inline]
+    pub unsafe fn try_read(&self) -> bool {
+        let r = libc::pthread_rwlock_tryrdlock(self.inner.get());
+        if r == 0 {
+            if *self.write_locked.get() {
+                self.raw_unlock();
+                false
+            } else {
+                self.num_readers.fetch_add(1, Ordering::Relaxed);
+                true
+            }
+        } else {
+            false
+        }
+    }
+
+    #[inline]
+    pub unsafe fn write(&self) {
+        let r = libc::pthread_rwlock_wrlock(self.inner.get());
+        // See comments above for why we check for EDEADLK and write_locked. We
+        // also need to check that num_readers is 0.
+        if r == libc::EDEADLK || *self.write_locked.get() ||
+            self.num_readers.load(Ordering::Relaxed) != 0 {
+            if r == 0 {
+                self.raw_unlock();
+            }
+        panic!("rwlock write lock would result in deadlock");
+        } else {
+            debug_assert_eq!(r, 0);
+        }
+        *self.write_locked.get() = true;
+    }
+
+    #[inline]
+    pub unsafe fn try_write(&self) -> bool {
+        let r = libc::pthread_rwlock_trywrlock(self.inner.get());
+        if r == 0 {
+            if *self.write_locked.get() || self.num_readers.load(Ordering::Relaxed) != 0 {
+                self.raw_unlock();
+                false
+            } else {
+                *self.write_locked.get() = true;
+                true
+            }
+            } else {
+                false
+        }
+    }
+
+    #[inline]
+    unsafe fn raw_unlock(&self) {
+        let r = libc::pthread_rwlock_unlock(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+
+    #[inline]
+    pub unsafe fn read_unlock(&self) {
+        debug_assert!(!*self.write_locked.get());
+        self.num_readers.fetch_sub(1, Ordering::Relaxed);
+        self.raw_unlock();
+    }
+
+     #[inline]
+    pub unsafe fn write_unlock(&self) {
+        debug_assert_eq!(self.num_readers.load(Ordering::Relaxed), 0);
+        debug_assert!(*self.write_locked.get());
+        *self.write_locked.get() = false;
+        self.raw_unlock();
+    }
+    #[inline]
+    pub unsafe fn destroy(&self) {
+        let r = libc::pthread_rwlock_destroy(self.inner.get());
+        debug_assert_eq!(r, 0);
+    }
+}
diff --git a/src/libstd/sys/vxworks/stack_overflow.rs b/src/libstd/sys/vxworks/stack_overflow.rs
new file mode 100644
index 00000000000..08e7b310ca1
--- /dev/null
+++ b/src/libstd/sys/vxworks/stack_overflow.rs
@@ -0,0 +1,41 @@
+#![cfg_attr(test, allow(dead_code))]
+
+use self::imp::{make_handler, drop_handler};
+
+pub use self::imp::cleanup;
+pub use self::imp::init;
+
+pub struct Handler {
+    _data: *mut libc::c_void
+}
+
+impl Handler {
+    pub unsafe fn new() -> Handler {
+        make_handler()
+    }
+}
+
+impl Drop for Handler {
+    fn drop(&mut self) {
+        unsafe {
+            drop_handler(self);
+        }
+    }
+}
+
+mod imp {
+    use crate::ptr;
+
+    pub unsafe fn init() {
+    }
+
+    pub unsafe fn cleanup() {
+    }
+
+    pub unsafe fn make_handler() -> super::Handler {
+        super::Handler { _data: ptr::null_mut() }
+    }
+
+    pub unsafe fn drop_handler(_handler: &mut super::Handler) {
+    }
+}
diff --git a/src/libstd/sys/redox/stdio.rs b/src/libstd/sys/vxworks/stdio.rs
index 33f5bdbb5d3..35f163bbdb1 100644
--- a/src/libstd/sys/redox/stdio.rs
+++ b/src/libstd/sys/vxworks/stdio.rs
@@ -1,5 +1,4 @@
 use crate::io;
-use crate::sys::{cvt, syscall};
 use crate::sys::fd::FileDesc;
 
 pub struct Stdin(());
@@ -12,9 +11,9 @@ impl Stdin {
 
 impl io::Read for Stdin {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        let fd = FileDesc::new(0);
+        let fd = FileDesc::new(libc::STDIN_FILENO);
         let ret = fd.read(buf);
-        fd.into_raw();
+        fd.into_raw(); // do not close this FD
         ret
     }
 }
@@ -25,14 +24,14 @@ impl Stdout {
 
 impl io::Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        let fd = FileDesc::new(1);
+        let fd = FileDesc::new(libc::STDOUT_FILENO);
         let ret = fd.write(buf);
-        fd.into_raw();
+        fd.into_raw(); // do not close this FD
         ret
     }
 
     fn flush(&mut self) -> io::Result<()> {
-        cvt(syscall::fsync(1)).and(Ok(()))
+        Ok(())
     }
 }
 
@@ -42,19 +41,19 @@ impl Stderr {
 
 impl io::Write for Stderr {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        let fd = FileDesc::new(2);
+        let fd = FileDesc::new(libc::STDERR_FILENO);
         let ret = fd.write(buf);
-        fd.into_raw();
+        fd.into_raw(); // do not close this FD
         ret
     }
 
     fn flush(&mut self) -> io::Result<()> {
-        cvt(syscall::fsync(2)).and(Ok(()))
+        Ok(())
     }
 }
 
 pub fn is_ebadf(err: &io::Error) -> bool {
-    err.raw_os_error() == Some(crate::sys::syscall::EBADF as i32)
+    err.raw_os_error() == Some(libc::EBADF as i32)
 }
 
 pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs
new file mode 100644
index 00000000000..58af8cbe48e
--- /dev/null
+++ b/src/libstd/sys/vxworks/thread.rs
@@ -0,0 +1,143 @@
+use crate::cmp;
+use crate::ffi::CStr;
+use crate::io;
+use crate::mem;
+use crate::ptr;
+use crate::sys::os;
+use crate::time::Duration;
+
+use crate::sys_common::thread::*;
+
+pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
+
+pub struct Thread {
+    id: libc::pthread_t,
+}
+
+// Some platforms may have pthread_t as a pointer in which case we still want
+// a thread to be Send/Sync
+unsafe impl Send for Thread {}
+unsafe impl Sync for Thread {}
+
+// The pthread_attr_setstacksize symbol doesn't exist in the emscripten libc,
+// so we have to not link to it to satisfy emcc's ERROR_ON_UNDEFINED_SYMBOLS.
+unsafe fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
+                                    stack_size: libc::size_t) -> libc::c_int {
+    libc::pthread_attr_setstacksize(attr, stack_size)
+}
+
+impl Thread {
+    // unsafe: see thread::Builder::spawn_unchecked for safety requirements
+    pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
+                          -> io::Result<Thread> {
+        let p = box p;
+        let mut native: libc::pthread_t = mem::zeroed();
+        let mut attr: libc::pthread_attr_t = mem::zeroed();
+        assert_eq!(libc::pthread_attr_init(&mut attr), 0);
+
+        let stack_size = cmp::max(stack, min_stack_size(&attr));
+
+        match pthread_attr_setstacksize(&mut attr,
+                                        stack_size) {
+            0 => {}
+            n => {
+                assert_eq!(n, libc::EINVAL);
+                // EINVAL means |stack_size| is either too small or not a
+                // multiple of the system page size.  Because it's definitely
+                // >= PTHREAD_STACK_MIN, it must be an alignment issue.
+                // Round up to the nearest page and try again.
+                let page_size = os::page_size();
+                let stack_size = (stack_size + page_size - 1) &
+                                 (-(page_size as isize - 1) as usize - 1);
+                assert_eq!(libc::pthread_attr_setstacksize(&mut attr,
+                                                           stack_size), 0);
+            }
+        };
+
+        let ret = libc::pthread_create(&mut native, &attr, thread_start,
+                                       &*p as *const _ as *mut _);
+        assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
+
+        return if ret != 0 {
+            Err(io::Error::from_raw_os_error(ret))
+        } else {
+            mem::forget(p); // ownership passed to pthread_create
+            Ok(Thread { id: native })
+        };
+
+        extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
+            unsafe { start_thread(main as *mut u8); }
+            ptr::null_mut()
+        }
+    }
+
+    pub fn yield_now() {
+        let ret = unsafe { libc::sched_yield() };
+        debug_assert_eq!(ret, 0);
+    }
+
+    pub fn set_name(_name: &CStr) {
+        assert!(false, "FIXME: set_name");
+    }
+
+    pub fn sleep(dur: Duration) {
+        let mut secs = dur.as_secs();
+        let mut nsecs = dur.subsec_nanos() as _;
+
+        // If we're awoken with a signal then the return value will be -1 and
+        // nanosleep will fill in `ts` with the remaining time.
+        unsafe {
+            while secs > 0 || nsecs > 0 {
+                let mut ts = libc::timespec {
+                    tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t,
+                    tv_nsec: nsecs,
+                };
+                secs -= ts.tv_sec as u64;
+                if libc::nanosleep(&ts, &mut ts) == -1 {
+                    assert_eq!(os::errno(), libc::EINTR);
+                    secs += ts.tv_sec as u64;
+                    nsecs = ts.tv_nsec;
+                } else {
+                    nsecs = 0;
+                }
+            }
+        }
+    }
+
+    pub fn join(self) {
+        unsafe {
+            let ret = libc::pthread_join(self.id, ptr::null_mut());
+            mem::forget(self);
+            assert!(ret == 0,
+                    "failed to join thread: {}", io::Error::from_raw_os_error(ret));
+        }
+    }
+
+    pub fn id(&self) -> libc::pthread_t { self.id }
+
+    pub fn into_id(self) -> libc::pthread_t {
+        let id = self.id;
+        mem::forget(self);
+        id
+    }
+}
+
+impl Drop for Thread {
+    fn drop(&mut self) {
+        let ret = unsafe { libc::pthread_detach(self.id) };
+        debug_assert_eq!(ret, 0);
+    }
+}
+
+#[cfg_attr(test, allow(dead_code))]
+pub mod guard {
+    use crate::ops::Range;
+    pub type Guard = Range<usize>;
+    pub unsafe fn current() -> Option<Guard> { None }
+    pub unsafe fn init() -> Option<Guard> { None }
+    pub unsafe fn deinit() {}
+}
+
+fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
+    libc::PTHREAD_STACK_MIN
+}
diff --git a/src/libstd/sys/vxworks/thread_local.rs b/src/libstd/sys/vxworks/thread_local.rs
new file mode 100644
index 00000000000..ac615b76b36
--- /dev/null
+++ b/src/libstd/sys/vxworks/thread_local.rs
@@ -0,0 +1,34 @@
+#![allow(dead_code)] // not used on all platforms
+
+use crate::mem;
+
+pub type Key = libc::pthread_key_t;
+
+#[inline]
+pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
+    let mut key = 0;
+    assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0);
+    key
+}
+
+#[inline]
+pub unsafe fn set(key: Key, value: *mut u8) {
+    let r = libc::pthread_setspecific(key, value as *mut _);
+    debug_assert_eq!(r, 0);
+}
+
+#[inline]
+pub unsafe fn get(key: Key) -> *mut u8 {
+    libc::pthread_getspecific(key) as *mut u8
+}
+
+#[inline]
+pub unsafe fn destroy(key: Key) {
+    let r = libc::pthread_key_delete(key);
+    debug_assert_eq!(r, 0);
+}
+
+#[inline]
+pub fn requires_synchronized_create() -> bool {
+    false
+}
diff --git a/src/libstd/sys/vxworks/time.rs b/src/libstd/sys/vxworks/time.rs
new file mode 100644
index 00000000000..cb3a4241ea6
--- /dev/null
+++ b/src/libstd/sys/vxworks/time.rs
@@ -0,0 +1,224 @@
+use crate::cmp::Ordering;
+use libc;
+use crate::time::Duration;
+use ::core::hash::{Hash, Hasher};
+
+pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
+use crate::convert::TryInto;
+
+const NSEC_PER_SEC: u64 = 1_000_000_000;
+
+#[derive(Copy, Clone)]
+struct Timespec {
+    t: libc::timespec,
+}
+
+impl Timespec {
+    const fn zero() -> Timespec {
+        Timespec {
+            t: libc::timespec { tv_sec: 0, tv_nsec: 0 },
+        }
+    }
+    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
+        if self >= other {
+            Ok(if self.t.tv_nsec >= other.t.tv_nsec {
+                Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
+                                (self.t.tv_nsec - other.t.tv_nsec) as u32)
+                } else {
+                    Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
+                        self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
+                        other.t.tv_nsec as u32)
+                })
+        } else {
+            match other.sub_timespec(self) {
+                Ok(d) => Err(d),
+                Err(d) => Ok(d),
+            }
+        }
+    }
+
+    fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
+        let mut secs = other
+            .as_secs()
+            .try_into() // <- target type would be `libc::time_t`
+            .ok()
+            .and_then(|secs| self.t.tv_sec.checked_add(secs))?;
+
+        // Nano calculations can't overflow because nanos are <1B which fit
+        // in a u32.
+        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
+        if nsec >= NSEC_PER_SEC as u32 {
+            nsec -= NSEC_PER_SEC as u32;
+            secs = secs.checked_add(1)?;
+        }
+        Some(Timespec {
+            t: libc::timespec {
+                tv_sec: secs,
+                tv_nsec: nsec as _,
+            },
+        })
+    }
+
+    fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
+        let mut secs = other
+            .as_secs()
+            .try_into() // <- target type would be `libc::time_t`
+            .ok()
+            .and_then(|secs| self.t.tv_sec.checked_sub(secs))?;
+
+        // Similar to above, nanos can't overflow.
+        let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
+        if nsec < 0 {
+            nsec += NSEC_PER_SEC as i32;
+            secs = secs.checked_sub(1)?;
+        }
+        Some(Timespec {
+            t: libc::timespec {
+                tv_sec: secs,
+                tv_nsec: nsec as _,
+            },
+        })
+    }
+}
+
+impl PartialEq for Timespec {
+    fn eq(&self, other: &Timespec) -> bool {
+        self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
+    }
+}
+
+impl Eq for Timespec {}
+
+impl PartialOrd for Timespec {
+    fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Timespec {
+    fn cmp(&self, other: &Timespec) -> Ordering {
+        let me = (self.t.tv_sec, self.t.tv_nsec);
+        let other = (other.t.tv_sec, other.t.tv_nsec);
+        me.cmp(&other)
+    }
+}
+
+impl Hash for Timespec {
+    fn hash<H : Hasher>(&self, state: &mut H) {
+        self.t.tv_sec.hash(state);
+        self.t.tv_nsec.hash(state);
+    }
+}
+mod inner {
+    use crate::fmt;
+    use libc;
+    use crate::sys::cvt;
+    use crate::time::Duration;
+
+    use super::Timespec;
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+    pub struct Instant {
+        t: Timespec,
+    }
+
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
+    pub struct SystemTime {
+        t: Timespec,
+    }
+
+    pub const UNIX_EPOCH: SystemTime = SystemTime {
+        t: Timespec {
+            t: libc::timespec {
+                tv_sec: 0,
+                tv_nsec: 0,
+            },
+        },
+    };
+
+    impl Instant {
+        pub fn now() -> Instant {
+            Instant { t: now(libc::CLOCK_MONOTONIC) }
+        }
+
+        pub const fn zero() -> Instant {
+            Instant {
+                t: Timespec::zero(),
+            }
+        }
+
+        pub fn actually_monotonic() -> bool {
+            true
+        }
+
+        pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
+            self.t.sub_timespec(&other.t).ok()
+        }
+
+        pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
+            Some(Instant { t: self.t.checked_add_duration(other)? })
+        }
+
+        pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
+            Some(Instant { t: self.t.checked_sub_duration(other)? })
+        }
+    }
+
+    impl fmt::Debug for Instant {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            f.debug_struct("Instant")
+             .field("tv_sec", &self.t.t.tv_sec)
+             .field("tv_nsec", &self.t.t.tv_nsec)
+             .finish()
+        }
+    }
+
+    impl SystemTime {
+        pub fn now() -> SystemTime {
+            SystemTime { t: now(libc::CLOCK_REALTIME) }
+        }
+
+        pub fn sub_time(&self, other: &SystemTime)
+                        -> Result<Duration, Duration> {
+            self.t.sub_timespec(&other.t)
+        }
+
+        pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+            Some(SystemTime { t: self.t.checked_add_duration(other)? })
+        }
+
+        pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+            Some(SystemTime { t: self.t.checked_sub_duration(other)? })
+        }
+    }
+
+    impl From<libc::timespec> for SystemTime {
+        fn from(t: libc::timespec) -> SystemTime {
+            SystemTime { t: Timespec { t: t } }
+        }
+    }
+
+    impl fmt::Debug for SystemTime {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            f.debug_struct("SystemTime")
+             .field("tv_sec", &self.t.t.tv_sec)
+             .field("tv_nsec", &self.t.t.tv_nsec)
+             .finish()
+        }
+    }
+
+    pub type clock_t = libc::c_int;
+
+    fn now(clock: clock_t) -> Timespec {
+        let mut t = Timespec {
+            t: libc::timespec {
+                tv_sec: 0,
+                tv_nsec: 0,
+            }
+        };
+        cvt(unsafe {
+            libc::clock_gettime(clock, &mut t.t)
+        }).unwrap();
+        t
+    }
+}
diff --git a/src/libstd/sys/vxworks/weak.rs b/src/libstd/sys/vxworks/weak.rs
new file mode 100644
index 00000000000..284f2116423
--- /dev/null
+++ b/src/libstd/sys/vxworks/weak.rs
@@ -0,0 +1,60 @@
+//! Support for "weak linkage" to symbols on Unix
+//!
+//! Some I/O operations we do in libstd require newer versions of OSes but we
+//! need to maintain binary compatibility with older releases for now. In order
+//! to use the new functionality when available we use this module for
+//! detection.
+//!
+//! One option to use here is weak linkage, but that is unfortunately only
+//! really workable on Linux. Hence, use dlsym to get the symbol value at
+//! runtime. This is also done for compatibility with older versions of glibc,
+//! and to avoid creating dependencies on GLIBC_PRIVATE symbols. It assumes that
+//! we've been dynamically linked to the library the symbol comes from, but that
+//! is currently always the case for things like libpthread/libc.
+//!
+//! A long time ago this used weak linkage for the __pthread_get_minstack
+//! symbol, but that caused Debian to detect an unnecessarily strict versioned
+//! dependency on libc6 (#23628).
+
+use crate::ffi::CStr;
+use crate::marker;
+use crate::mem;
+use crate::sync::atomic::{AtomicUsize, Ordering};
+
+pub struct Weak<F> {
+    name: &'static str,
+    addr: AtomicUsize,
+    _marker: marker::PhantomData<F>,
+}
+
+impl<F> Weak<F> {
+    pub const fn new(name: &'static str) -> Weak<F> {
+        Weak {
+            name,
+            addr: AtomicUsize::new(1),
+            _marker: marker::PhantomData,
+        }
+    }
+
+    pub fn get(&self) -> Option<F> {
+        assert_eq!(mem::size_of::<F>(), mem::size_of::<usize>());
+        unsafe {
+            if self.addr.load(Ordering::SeqCst) == 1 {
+                self.addr.store(fetch(self.name), Ordering::SeqCst);
+            }
+            match self.addr.load(Ordering::SeqCst) {
+                0 => None,
+                addr => Some(mem::transmute_copy::<usize, F>(&addr)),
+            }
+        }
+    }
+}
+
+unsafe fn fetch(name: &str) -> usize {
+    let name = match CStr::from_bytes_with_nul(name.as_bytes()) {
+        Ok(cstr) => cstr,
+        Err(..) => return 0,
+    };
+    assert!(false, "FIXME: fetch");
+   libc::dlsym(libc::RTLD_DEFAULT, name.as_ptr()) as usize
+}
diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs
index 9c8e59e4fb5..8b4b354d9fc 100644
--- a/src/libstd/sys/wasi/args.rs
+++ b/src/libstd/sys/wasi/args.rs
@@ -32,7 +32,7 @@ fn maybe_args() -> io::Result<Args> {
         let (mut argc, mut argv_buf_size) = (0, 0);
         cvt_wasi(libc::__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?;
 
-        let mut argc = vec![0 as *mut libc::c_char; argc];
+        let mut argc = vec![core::ptr::null_mut::<libc::c_char>(); argc];
         let mut argv_buf = vec![0; argv_buf_size];
         cvt_wasi(libc::__wasi_args_get(argc.as_mut_ptr(), argv_buf.as_mut_ptr()))?;
 
diff --git a/src/libstd/sys/wasi/backtrace.rs b/src/libstd/sys/wasi/backtrace.rs
deleted file mode 100644
index 7d56b298997..00000000000
--- a/src/libstd/sys/wasi/backtrace.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use crate::io;
-use crate::sys::unsupported;
-use crate::sys_common::backtrace::Frame;
-
-pub struct BacktraceContext;
-
-pub fn unwind_backtrace(_frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    unsupported()
-}
-
-pub fn resolve_symname<F>(_frame: Frame,
-                          _callback: F,
-                          _: &BacktraceContext) -> io::Result<()>
-    where F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    unsupported()
-}
-
-pub fn foreach_symbol_fileline<F>(_: Frame,
-                                  _: F,
-                                  _: &BacktraceContext) -> io::Result<bool>
-    where F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    unsupported()
-}
diff --git a/src/libstd/sys/wasi/io.rs b/src/libstd/sys/wasi/io.rs
index cc8f1e16fa0..ffecca5d1b6 100644
--- a/src/libstd/sys/wasi/io.rs
+++ b/src/libstd/sys/wasi/io.rs
@@ -22,6 +22,18 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        if self.vec.buf_len < n {
+            panic!("advancing IoSlice beyond its length");
+        }
+
+        unsafe {
+            self.vec.buf_len -= n;
+            self.vec.buf = self.vec.buf.add(n);
+        }
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         unsafe {
             slice::from_raw_parts(self.vec.buf as *const u8, self.vec.buf_len)
@@ -29,6 +41,7 @@ impl<'a> IoSlice<'a> {
     }
 }
 
+#[repr(transparent)]
 pub struct IoSliceMut<'a> {
     vec: __wasi_iovec_t,
     _p: PhantomData<&'a mut [u8]>,
@@ -47,6 +60,18 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        if self.vec.buf_len < n {
+            panic!("advancing IoSlice beyond its length");
+        }
+
+        unsafe {
+            self.vec.buf_len -= n;
+            self.vec.buf = self.vec.buf.add(n);
+        }
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         unsafe {
             slice::from_raw_parts(self.vec.buf as *const u8, self.vec.buf_len)
diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs
index a9bb0151d05..f842869e08e 100644
--- a/src/libstd/sys/wasi/mod.rs
+++ b/src/libstd/sys/wasi/mod.rs
@@ -21,8 +21,6 @@ use crate::os::raw::c_char;
 
 pub mod alloc;
 pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 #[path = "../wasm/cmath.rs"]
 pub mod cmath;
 #[path = "../wasm/condvar.rs"]
@@ -49,6 +47,8 @@ pub mod stdio;
 pub mod thread;
 #[path = "../wasm/thread_local.rs"]
 pub mod thread_local;
+#[path = "../wasm/fast_thread_local.rs"]
+pub mod fast_thread_local;
 pub mod time;
 pub mod ext;
 
diff --git a/src/libstd/sys/wasm/args.rs b/src/libstd/sys/wasm/args.rs
index 6766099c1ec..b3c77b86995 100644
--- a/src/libstd/sys/wasm/args.rs
+++ b/src/libstd/sys/wasm/args.rs
@@ -37,10 +37,6 @@ 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/wasm/backtrace.rs b/src/libstd/sys/wasm/backtrace.rs
deleted file mode 100644
index 7d56b298997..00000000000
--- a/src/libstd/sys/wasm/backtrace.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-use crate::io;
-use crate::sys::unsupported;
-use crate::sys_common::backtrace::Frame;
-
-pub struct BacktraceContext;
-
-pub fn unwind_backtrace(_frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    unsupported()
-}
-
-pub fn resolve_symname<F>(_frame: Frame,
-                          _callback: F,
-                          _: &BacktraceContext) -> io::Result<()>
-    where F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    unsupported()
-}
-
-pub fn foreach_symbol_fileline<F>(_: Frame,
-                                  _: F,
-                                  _: &BacktraceContext) -> io::Result<bool>
-    where F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    unsupported()
-}
diff --git a/src/libstd/sys/wasm/fast_thread_local.rs b/src/libstd/sys/wasm/fast_thread_local.rs
new file mode 100644
index 00000000000..ff2198175f0
--- /dev/null
+++ b/src/libstd/sys/wasm/fast_thread_local.rs
@@ -0,0 +1,9 @@
+#![unstable(feature = "thread_local_internals", issue = "0")]
+
+pub unsafe fn register_dtor(_t: *mut u8, _dtor: unsafe extern fn(*mut u8)) {
+    // FIXME: right now there is no concept of "thread exit", but this is likely
+    // going to show up at some point in the form of an exported symbol that the
+    // wasm runtime is oging to be expected to call. For now we basically just
+    // ignore the arguments, but if such a function starts to exist it will
+    // likely look like the OSX implementation in `unix/fast_thread_local.rs`
+}
diff --git a/src/libstd/sys/wasm/io.rs b/src/libstd/sys/wasm/io.rs
index 4b423a5cbc1..976e122463d 100644
--- a/src/libstd/sys/wasm/io.rs
+++ b/src/libstd/sys/wasm/io.rs
@@ -1,3 +1,5 @@
+use crate::mem;
+
 pub struct IoSlice<'a>(&'a [u8]);
 
 impl<'a> IoSlice<'a> {
@@ -7,6 +9,11 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        self.0 = &self.0[n..]
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         self.0
     }
@@ -21,6 +28,13 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        let slice = mem::replace(&mut self.0, &mut []);
+        let (_, remaining) = slice.split_at_mut(n);
+        self.0 = remaining;
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         self.0
     }
diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs
index 670d07de1d1..56cbafcfdb8 100644
--- a/src/libstd/sys/wasm/mod.rs
+++ b/src/libstd/sys/wasm/mod.rs
@@ -23,8 +23,6 @@ use crate::time::Duration;
 
 pub mod alloc;
 pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 pub mod cmath;
 pub mod env;
 pub mod fs;
@@ -39,10 +37,12 @@ pub mod stack_overflow;
 pub mod thread;
 pub mod time;
 pub mod stdio;
+pub mod thread_local;
+pub mod fast_thread_local;
 
 pub use crate::sys_common::os_str_bytes as os_str;
 
-cfg_if! {
+cfg_if::cfg_if! {
     if #[cfg(target_feature = "atomics")] {
         #[path = "condvar_atomics.rs"]
         pub mod condvar;
@@ -50,13 +50,10 @@ cfg_if! {
         pub mod mutex;
         #[path = "rwlock_atomics.rs"]
         pub mod rwlock;
-        #[path = "thread_local_atomics.rs"]
-        pub mod thread_local;
     } else {
         pub mod condvar;
         pub mod mutex;
         pub mod rwlock;
-        pub mod thread_local;
     }
 }
 
diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs
index 1dc786cd5d7..d06965f3278 100644
--- a/src/libstd/sys/wasm/thread.rs
+++ b/src/libstd/sys/wasm/thread.rs
@@ -59,48 +59,40 @@ pub mod guard {
     pub unsafe fn init() -> Option<Guard> { None }
 }
 
-cfg_if! {
-    if #[cfg(all(target_feature = "atomics", feature = "wasm-bindgen-threads"))] {
-        #[link(wasm_import_module = "__wbindgen_thread_xform__")]
-        extern {
-            fn __wbindgen_current_id() -> u32;
-            fn __wbindgen_tcb_get() -> u32;
-            fn __wbindgen_tcb_set(ptr: u32);
+// This is only used by atomics primitives when the `atomics` feature is
+// enabled. In that mode we currently just use our own thread-local to store our
+// current thread's ID, and then we lazily initialize it to something allocated
+// from a global counter.
+#[cfg(target_feature = "atomics")]
+pub fn my_id() -> u32 {
+    use crate::sync::atomic::{AtomicU32, Ordering::SeqCst};
+
+    static NEXT_ID: AtomicU32 = AtomicU32::new(0);
+
+    #[thread_local]
+    static mut MY_ID: u32 = 0;
+
+    unsafe {
+        // If our thread ID isn't set yet then we need to allocate one. Do so
+        // with with a simple "atomically add to a global counter" strategy.
+        // This strategy doesn't handled what happens when the counter
+        // overflows, however, so just abort everything once the counter
+        // overflows and eventually we could have some sort of recycling scheme
+        // (or maybe this is all totally irrelevant by that point!). In any case
+        // though we're using a CAS loop instead of a `fetch_add` to ensure that
+        // the global counter never overflows.
+        if MY_ID == 0 {
+            let mut cur = NEXT_ID.load(SeqCst);
+            MY_ID = loop {
+                let next = cur.checked_add(1).unwrap_or_else(|| {
+                    crate::arch::wasm32::unreachable()
+                });
+                match NEXT_ID.compare_exchange(cur, next, SeqCst, SeqCst) {
+                    Ok(_) => break next,
+                    Err(i) => cur = i,
+                }
+            };
         }
-        pub fn my_id() -> u32 {
-            unsafe { __wbindgen_current_id() }
-        }
-
-        // These are currently only ever used in `thread_local_atomics.rs`, if
-        // you'd like to use them be sure to update that and make sure everyone
-        // agrees what's what.
-        pub fn tcb_get() -> *mut u8 {
-            use crate::mem;
-            assert_eq!(mem::size_of::<*mut u8>(), mem::size_of::<u32>());
-            unsafe { __wbindgen_tcb_get() as *mut u8 }
-        }
-
-        pub fn tcb_set(ptr: *mut u8) {
-            unsafe { __wbindgen_tcb_set(ptr as u32); }
-        }
-
-        // FIXME: still need something for hooking exiting a thread to free
-        // data...
-
-    } else if #[cfg(target_feature = "atomics")] {
-        pub fn my_id() -> u32 {
-            panic!("thread ids not implemented on wasm with atomics yet")
-        }
-
-        pub fn tcb_get() -> *mut u8 {
-            panic!("thread local data not implemented on wasm with atomics yet")
-        }
-
-        pub fn tcb_set(_ptr: *mut u8) {
-            panic!("thread local data not implemented on wasm with atomics yet")
-        }
-    } else {
-        // stubbed out because no functions actually access these intrinsics
-        // unless atomics are enabled
+        MY_ID
     }
 }
diff --git a/src/libstd/sys/wasm/thread_local.rs b/src/libstd/sys/wasm/thread_local.rs
index 29e9854bcfc..8a0ca6f3d25 100644
--- a/src/libstd/sys/wasm/thread_local.rs
+++ b/src/libstd/sys/wasm/thread_local.rs
@@ -1,40 +1,26 @@
-use crate::boxed::Box;
-use crate::ptr;
-
 pub type Key = usize;
 
-struct Allocated {
-    value: *mut u8,
-    dtor: Option<unsafe extern fn(*mut u8)>,
-}
-
 #[inline]
-pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
-    Box::into_raw(Box::new(Allocated {
-        value: ptr::null_mut(),
-        dtor,
-    })) as usize
+pub unsafe fn create(_dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
-pub unsafe fn set(key: Key, value: *mut u8) {
-    (*(key as *mut Allocated)).value = value;
+pub unsafe fn set(_key: Key, _value: *mut u8) {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
-pub unsafe fn get(key: Key) -> *mut u8 {
-    (*(key as *mut Allocated)).value
+pub unsafe fn get(_key: Key) -> *mut u8 {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
-pub unsafe fn destroy(key: Key) {
-    let key = Box::from_raw(key as *mut Allocated);
-    if let Some(f) = key.dtor {
-        f(key.value);
-    }
+pub unsafe fn destroy(_key: Key) {
+    panic!("should not be used on the wasm target");
 }
 
 #[inline]
 pub fn requires_synchronized_create() -> bool {
-    false
+    panic!("should not be used on the wasm target");
 }
diff --git a/src/libstd/sys/wasm/thread_local_atomics.rs b/src/libstd/sys/wasm/thread_local_atomics.rs
deleted file mode 100644
index b408ad0d5c1..00000000000
--- a/src/libstd/sys/wasm/thread_local_atomics.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-use crate::sys::thread;
-use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
-
-const MAX_KEYS: usize = 128;
-static NEXT_KEY: AtomicUsize = AtomicUsize::new(0);
-
-struct ThreadControlBlock {
-    keys: [*mut u8; MAX_KEYS],
-}
-
-impl ThreadControlBlock {
-    fn new() -> ThreadControlBlock {
-        ThreadControlBlock {
-            keys: [0 as *mut u8; MAX_KEYS],
-        }
-    }
-
-    fn get() -> *mut ThreadControlBlock {
-        let ptr = thread::tcb_get();
-        if !ptr.is_null() {
-            return ptr as *mut ThreadControlBlock
-        }
-        let tcb = Box::into_raw(Box::new(ThreadControlBlock::new()));
-        thread::tcb_set(tcb as *mut u8);
-        tcb
-    }
-}
-
-pub type Key = usize;
-
-pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
-    drop(dtor); // FIXME: need to figure out how to hook thread exit to run this
-    let key = NEXT_KEY.fetch_add(1, SeqCst);
-    if key >= MAX_KEYS {
-        NEXT_KEY.store(MAX_KEYS, SeqCst);
-        panic!("cannot allocate space for more TLS keys");
-    }
-    // offset by 1 so we never hand out 0. This is currently required by
-    // `sys_common/thread_local.rs` where it can't cope with keys of value 0
-    // because it messes up the atomic management.
-    return key + 1
-}
-
-pub unsafe fn set(key: Key, value: *mut u8) {
-    (*ThreadControlBlock::get()).keys[key - 1] = value;
-}
-
-pub unsafe fn get(key: Key) -> *mut u8 {
-    (*ThreadControlBlock::get()).keys[key - 1]
-}
-
-pub unsafe fn destroy(_key: Key) {
-    // FIXME: should implement this somehow, this isn't typically called but it
-    // can be called if two threads race to initialize a TLS slot and one ends
-    // up not being needed.
-}
-
-#[inline]
-pub fn requires_synchronized_create() -> bool {
-    false
-}
diff --git a/src/libstd/sys/windows/args.rs b/src/libstd/sys/windows/args.rs
index 744d7ec59d3..b04bb484eed 100644
--- a/src/libstd/sys/windows/args.rs
+++ b/src/libstd/sys/windows/args.rs
@@ -181,8 +181,6 @@ 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/windows/backtrace/backtrace_gnu.rs b/src/libstd/sys/windows/backtrace/backtrace_gnu.rs
deleted file mode 100644
index 7ac1f8122f7..00000000000
--- a/src/libstd/sys/windows/backtrace/backtrace_gnu.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-use crate::io;
-use crate::sys::c;
-use crate::path::PathBuf;
-use crate::fs::{OpenOptions, File};
-use crate::sys::ext::fs::OpenOptionsExt;
-use crate::sys::handle::Handle;
-
-use libc::c_char;
-use super::super::{fill_utf16_buf, os2path, to_u16s, wide_char_to_multi_byte};
-
-fn query_full_process_image_name() -> io::Result<PathBuf> {
-    unsafe {
-        let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION,
-                                                        c::FALSE,
-                                                        c::GetCurrentProcessId()));
-        fill_utf16_buf(|buf, mut sz| {
-            if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 {
-                0
-            } else {
-                sz
-            }
-        }, os2path)
-    }
-}
-
-fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> {
-    // We query the current image name, open the file without FILE_SHARE_DELETE so it
-    // can't be moved and then get the current image name again. If the names are the
-    // same than we have successfully locked the file
-    let image_name1 = query_full_process_image_name()?;
-    let file = OpenOptions::new()
-                .read(true)
-                .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE)
-                .open(&image_name1)?;
-    let image_name2 = query_full_process_image_name()?;
-
-    if image_name1 != image_name2 {
-        return Err(io::Error::new(io::ErrorKind::Other,
-                                  "executable moved while trying to lock it"));
-    }
-
-    Ok((image_name1, file))
-}
-
-// Get the executable filename for libbacktrace
-// This returns the path in the ANSI code page and a File which should remain open
-// for as long as the path should remain valid
-pub fn get_executable_filename() -> io::Result<(Vec<c_char>, File)> {
-    let (executable, file) = lock_and_get_executable_filename()?;
-    let u16_executable = to_u16s(executable.into_os_string())?;
-    Ok((wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS,
-                                &u16_executable, true)?, file))
-}
diff --git a/src/libstd/sys/windows/backtrace/mod.rs b/src/libstd/sys/windows/backtrace/mod.rs
deleted file mode 100644
index c5b0cc87210..00000000000
--- a/src/libstd/sys/windows/backtrace/mod.rs
+++ /dev/null
@@ -1,355 +0,0 @@
-//! As always, windows has something very different than unix, we mainly want
-//! to avoid having to depend too much on libunwind for windows.
-//!
-//! If you google around, you'll find a fair bit of references to built-in
-//! functions to get backtraces on windows. It turns out that most of these are
-//! in an external library called dbghelp. I was unable to find this library
-//! via `-ldbghelp`, but it is apparently normal to do the `dlopen` equivalent
-//! of it.
-//!
-//! You'll also find that there's a function called CaptureStackBackTrace
-//! mentioned frequently (which is also easy to use), but sadly I didn't have a
-//! copy of that function in my mingw install (maybe it was broken?). Instead,
-//! this takes the route of using StackWalk64 in order to walk the stack.
-
-#![allow(deprecated)] // dynamic_lib
-
-use crate::io;
-use crate::mem;
-use crate::ptr;
-use crate::sys::c;
-use crate::sys::dynamic_lib::DynamicLibrary;
-use crate::sys_common::backtrace::Frame;
-
-use libc::c_void;
-
-macro_rules! sym {
-    ($lib:expr, $e:expr, $t:ident) => (
-        $lib.symbol($e).map(|f| unsafe {
-            $crate::mem::transmute::<usize, $t>(f)
-        })
-    )
-}
-
-mod printing;
-
-#[cfg(target_env = "gnu")]
-#[path = "backtrace_gnu.rs"]
-pub mod gnu;
-
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-use self::printing::{load_printing_fns_64, load_printing_fns_ex};
-
-pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> {
-    let dbghelp = DynamicLibrary::open("dbghelp.dll")?;
-
-    // Fetch the symbols necessary from dbghelp.dll
-    let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn)?;
-    let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn)?;
-
-    // StackWalkEx might not be present and we'll fall back to StackWalk64
-    let sw_var = match sym!(dbghelp, "StackWalkEx", StackWalkExFn) {
-        Ok(StackWalkEx) => {
-            StackWalkVariant::StackWalkEx(StackWalkEx, load_printing_fns_ex(&dbghelp)?)
-        }
-        Err(e) => match sym!(dbghelp, "StackWalk64", StackWalk64Fn) {
-            Ok(StackWalk64) => {
-                StackWalkVariant::StackWalk64(StackWalk64, load_printing_fns_64(&dbghelp)?)
-            }
-            Err(..) => return Err(e),
-        },
-    };
-
-    // Allocate necessary structures for doing the stack walk
-    let process = unsafe { c::GetCurrentProcess() };
-
-    let backtrace_context = BacktraceContext {
-        handle: process,
-        SymCleanup,
-        StackWalkVariant: sw_var,
-        dbghelp,
-    };
-
-    // Initialize this process's symbols
-    let ret = unsafe { SymInitialize(process, ptr::null_mut(), c::TRUE) };
-    if ret != c::TRUE {
-        return Ok((0, backtrace_context));
-    }
-
-    // And now that we're done with all the setup, do the stack walking!
-    match backtrace_context.StackWalkVariant {
-        StackWalkVariant::StackWalkEx(StackWalkEx, _) => {
-            set_frames(StackWalkEx, frames).map(|i| (i, backtrace_context))
-        }
-
-        StackWalkVariant::StackWalk64(StackWalk64, _) => {
-            set_frames(StackWalk64, frames).map(|i| (i, backtrace_context))
-        }
-    }
-}
-
-fn set_frames<W: StackWalker>(StackWalk: W, frames: &mut [Frame]) -> io::Result<usize> {
-    let process = unsafe { c::GetCurrentProcess() };
-    let thread = unsafe { c::GetCurrentProcess() };
-    let mut context: c::CONTEXT = unsafe { mem::zeroed() };
-    unsafe { c::RtlCaptureContext(&mut context) };
-    let mut frame = W::Item::new();
-    let image = frame.init(&context);
-
-    let mut i = 0;
-    while i < frames.len()
-        && StackWalk.walk(image, process, thread, &mut frame, &mut context) == c::TRUE
-    {
-        let addr = frame.get_addr();
-        frames[i] = Frame {
-            symbol_addr: addr,
-            exact_position: addr,
-            inline_context: frame.get_inline_context(),
-        };
-
-        i += 1
-    }
-    Ok(i)
-}
-
-type SymInitializeFn = unsafe extern "system" fn(c::HANDLE, *mut c_void, c::BOOL) -> c::BOOL;
-type SymCleanupFn = unsafe extern "system" fn(c::HANDLE) -> c::BOOL;
-
-type StackWalkExFn = unsafe extern "system" fn(
-    c::DWORD,
-    c::HANDLE,
-    c::HANDLE,
-    *mut c::STACKFRAME_EX,
-    *mut c::CONTEXT,
-    *mut c_void,
-    *mut c_void,
-    *mut c_void,
-    *mut c_void,
-    c::DWORD,
-) -> c::BOOL;
-
-type StackWalk64Fn = unsafe extern "system" fn(
-    c::DWORD,
-    c::HANDLE,
-    c::HANDLE,
-    *mut c::STACKFRAME64,
-    *mut c::CONTEXT,
-    *mut c_void,
-    *mut c_void,
-    *mut c_void,
-    *mut c_void,
-) -> c::BOOL;
-
-trait StackWalker {
-    type Item: StackFrame;
-
-    fn walk(
-        &self,
-        _: c::DWORD,
-        _: c::HANDLE,
-        _: c::HANDLE,
-        _: &mut Self::Item,
-        _: &mut c::CONTEXT
-    ) -> c::BOOL;
-}
-
-impl StackWalker for StackWalkExFn {
-    type Item = c::STACKFRAME_EX;
-    fn walk(
-        &self,
-        image: c::DWORD,
-        process: c::HANDLE,
-        thread: c::HANDLE,
-        frame: &mut Self::Item,
-        context: &mut c::CONTEXT,
-    ) -> c::BOOL {
-        unsafe {
-            self(
-                image,
-                process,
-                thread,
-                frame,
-                context,
-                ptr::null_mut(),
-                ptr::null_mut(),
-                ptr::null_mut(),
-                ptr::null_mut(),
-                0,
-            )
-        }
-    }
-}
-
-impl StackWalker for StackWalk64Fn {
-    type Item = c::STACKFRAME64;
-    fn walk(
-        &self,
-        image: c::DWORD,
-        process: c::HANDLE,
-        thread: c::HANDLE,
-        frame: &mut Self::Item,
-        context: &mut c::CONTEXT,
-    ) -> c::BOOL {
-        unsafe {
-            self(
-                image,
-                process,
-                thread,
-                frame,
-                context,
-                ptr::null_mut(),
-                ptr::null_mut(),
-                ptr::null_mut(),
-                ptr::null_mut(),
-            )
-        }
-    }
-}
-
-trait StackFrame {
-    fn new() -> Self;
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD;
-    fn get_addr(&self) -> *const u8;
-    fn get_inline_context(&self) -> u32;
-}
-
-impl StackFrame for c::STACKFRAME_EX {
-    fn new() -> c::STACKFRAME_EX {
-        unsafe { mem::zeroed() }
-    }
-
-    #[cfg(target_arch = "x86")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Eip as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Esp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Ebp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_I386
-    }
-
-    #[cfg(target_arch = "x86_64")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Rip as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Rsp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Rbp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_AMD64
-    }
-
-    #[cfg(target_arch = "arm")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Pc as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Sp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.R11 as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_ARMNT
-    }
-
-    #[cfg(target_arch = "aarch64")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Pc as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Sp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Fp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_ARM64
-    }
-
-    fn get_addr(&self) -> *const u8 {
-        (self.AddrPC.Offset - 1) as *const u8
-    }
-
-    fn get_inline_context(&self) -> u32 {
-        self.InlineFrameContext
-    }
-}
-
-impl StackFrame for c::STACKFRAME64 {
-    fn new() -> c::STACKFRAME64 {
-        unsafe { mem::zeroed() }
-    }
-
-    #[cfg(target_arch = "x86")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Eip as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Esp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Ebp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_I386
-    }
-
-    #[cfg(target_arch = "x86_64")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Rip as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Rsp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Rbp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_AMD64
-    }
-
-    #[cfg(target_arch = "arm")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Pc as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Sp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.R11 as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_ARMNT
-    }
-
-    #[cfg(target_arch = "aarch64")]
-    fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
-        self.AddrPC.Offset = ctx.Pc as u64;
-        self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrStack.Offset = ctx.Sp as u64;
-        self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        self.AddrFrame.Offset = ctx.Fp as u64;
-        self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
-        c::IMAGE_FILE_MACHINE_ARM64
-    }
-
-    fn get_addr(&self) -> *const u8 {
-        (self.AddrPC.Offset - 1) as *const u8
-    }
-
-    fn get_inline_context(&self) -> u32 {
-        0
-    }
-}
-
-enum StackWalkVariant {
-    StackWalkEx(StackWalkExFn, printing::PrintingFnsEx),
-    StackWalk64(StackWalk64Fn, printing::PrintingFns64),
-}
-
-pub struct BacktraceContext {
-    handle: c::HANDLE,
-    SymCleanup: SymCleanupFn,
-    // Only used in printing for msvc and not gnu
-    // The gnu version is effectively a ZST dummy.
-    #[allow(dead_code)]
-    StackWalkVariant: StackWalkVariant,
-    // keeping DynamycLibrary loaded until its functions no longer needed
-    #[allow(dead_code)]
-    dbghelp: DynamicLibrary,
-}
-
-impl Drop for BacktraceContext {
-    fn drop(&mut self) {
-        unsafe {
-            (self.SymCleanup)(self.handle);
-        }
-    }
-}
diff --git a/src/libstd/sys/windows/backtrace/printing/mod.rs b/src/libstd/sys/windows/backtrace/printing/mod.rs
deleted file mode 100644
index 9497d51ac17..00000000000
--- a/src/libstd/sys/windows/backtrace/printing/mod.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-#[cfg(target_env = "msvc")]
-#[path = "msvc.rs"]
-mod printing;
-
-#[cfg(target_env = "gnu")]
-mod printing {
-    pub use crate::sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
-
-    // dummy functions to mirror those present in msvc version.
-    use crate::sys::dynamic_lib::DynamicLibrary;
-    use crate::io;
-    pub struct PrintingFnsEx {}
-    pub struct PrintingFns64 {}
-    pub fn load_printing_fns_ex(_: &DynamicLibrary) -> io::Result<PrintingFnsEx> {
-        Ok(PrintingFnsEx{})
-    }
-    pub fn load_printing_fns_64(_: &DynamicLibrary) -> io::Result<PrintingFns64> {
-        Ok(PrintingFns64{})
-    }
-}
-
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-pub use self::printing::{load_printing_fns_ex, load_printing_fns_64,
-                         PrintingFnsEx, PrintingFns64};
diff --git a/src/libstd/sys/windows/backtrace/printing/msvc.rs b/src/libstd/sys/windows/backtrace/printing/msvc.rs
deleted file mode 100644
index 13a1512d0eb..00000000000
--- a/src/libstd/sys/windows/backtrace/printing/msvc.rs
+++ /dev/null
@@ -1,208 +0,0 @@
-use crate::ffi::CStr;
-use crate::io;
-use crate::mem;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys::backtrace::StackWalkVariant;
-use crate::sys::c;
-use crate::sys::dynamic_lib::DynamicLibrary;
-use crate::sys_common::backtrace::Frame;
-
-use libc::{c_char, c_ulong};
-
-// Structs holding printing functions and loaders for them
-// Two versions depending on whether dbghelp.dll has StackWalkEx or not
-// (the former being in newer Windows versions, the older being in Win7 and before)
-pub struct PrintingFnsEx {
-    resolve_symname: SymFromInlineContextFn,
-    sym_get_line: SymGetLineFromInlineContextFn,
-}
-pub struct PrintingFns64 {
-    resolve_symname: SymFromAddrFn,
-    sym_get_line: SymGetLineFromAddr64Fn,
-}
-
-pub fn load_printing_fns_ex(dbghelp: &DynamicLibrary) -> io::Result<PrintingFnsEx> {
-    Ok(PrintingFnsEx {
-        resolve_symname: sym!(dbghelp, "SymFromInlineContext", SymFromInlineContextFn)?,
-        sym_get_line: sym!(
-            dbghelp,
-            "SymGetLineFromInlineContext",
-            SymGetLineFromInlineContextFn
-        )?,
-    })
-}
-pub fn load_printing_fns_64(dbghelp: &DynamicLibrary) -> io::Result<PrintingFns64> {
-    Ok(PrintingFns64 {
-        resolve_symname: sym!(dbghelp, "SymFromAddr", SymFromAddrFn)?,
-        sym_get_line: sym!(dbghelp, "SymGetLineFromAddr64", SymGetLineFromAddr64Fn)?,
-    })
-}
-
-type SymFromAddrFn =
-    unsafe extern "system" fn(c::HANDLE, u64, *mut u64, *mut c::SYMBOL_INFO) -> c::BOOL;
-type SymFromInlineContextFn =
-    unsafe extern "system" fn(c::HANDLE, u64, c::ULONG, *mut u64, *mut c::SYMBOL_INFO) -> c::BOOL;
-
-type SymGetLineFromAddr64Fn =
-    unsafe extern "system" fn(c::HANDLE, u64, *mut u32, *mut c::IMAGEHLP_LINE64) -> c::BOOL;
-type SymGetLineFromInlineContextFn = unsafe extern "system" fn(
-    c::HANDLE,
-    u64,
-    c::ULONG,
-    u64,
-    *mut c::DWORD,
-    *mut c::IMAGEHLP_LINE64,
-) -> c::BOOL;
-
-/// Converts a pointer to symbol to its string value.
-pub fn resolve_symname<F>(frame: Frame, callback: F, context: &BacktraceContext) -> io::Result<()>
-where
-    F: FnOnce(Option<&str>) -> io::Result<()>,
-{
-    match context.StackWalkVariant {
-        StackWalkVariant::StackWalkEx(_, ref fns) => resolve_symname_internal(
-            |process: c::HANDLE,
-             symbol_address: u64,
-             inline_context: c::ULONG,
-             info: *mut c::SYMBOL_INFO| unsafe {
-                let mut displacement = 0u64;
-                (fns.resolve_symname)(
-                    process,
-                    symbol_address,
-                    inline_context,
-                    &mut displacement,
-                    info,
-                )
-            },
-            frame,
-            callback,
-            context,
-        ),
-        StackWalkVariant::StackWalk64(_, ref fns) => resolve_symname_internal(
-            |process: c::HANDLE,
-             symbol_address: u64,
-             _inline_context: c::ULONG,
-             info: *mut c::SYMBOL_INFO| unsafe {
-                let mut displacement = 0u64;
-                (fns.resolve_symname)(process, symbol_address, &mut displacement, info)
-            },
-            frame,
-            callback,
-            context,
-        ),
-    }
-}
-
-fn resolve_symname_internal<F, R>(
-    mut symbol_resolver: R,
-    frame: Frame,
-    callback: F,
-    context: &BacktraceContext,
-) -> io::Result<()>
-where
-    F: FnOnce(Option<&str>) -> io::Result<()>,
-    R: FnMut(c::HANDLE, u64, c::ULONG, *mut c::SYMBOL_INFO) -> c::BOOL,
-{
-    unsafe {
-        let mut info: c::SYMBOL_INFO = mem::zeroed();
-        info.MaxNameLen = c::MAX_SYM_NAME as c_ulong;
-        // the struct size in C.  the value is different to
-        // `size_of::<SYMBOL_INFO>() - MAX_SYM_NAME + 1` (== 81)
-        // due to struct alignment.
-        info.SizeOfStruct = 88;
-
-        let ret = symbol_resolver(
-            context.handle,
-            frame.symbol_addr as u64,
-            frame.inline_context,
-            &mut info,
-        );
-        let valid_range = if ret == c::TRUE && frame.symbol_addr as usize >= info.Address as usize {
-            if info.Size != 0 {
-                (frame.symbol_addr as usize) < info.Address as usize + info.Size as usize
-            } else {
-                true
-            }
-        } else {
-            false
-        };
-        let symname = if valid_range {
-            let ptr = info.Name.as_ptr() as *const c_char;
-            CStr::from_ptr(ptr).to_str().ok()
-        } else {
-            None
-        };
-        callback(symname)
-    }
-}
-
-pub fn foreach_symbol_fileline<F>(
-    frame: Frame,
-    callback: F,
-    context: &BacktraceContext,
-) -> io::Result<bool>
-where
-    F: FnMut(&[u8], u32) -> io::Result<()>,
-{
-    match context.StackWalkVariant {
-        StackWalkVariant::StackWalkEx(_, ref fns) => foreach_symbol_fileline_iternal(
-            |process: c::HANDLE,
-             frame_address: u64,
-             inline_context: c::ULONG,
-             line: *mut c::IMAGEHLP_LINE64| unsafe {
-                let mut displacement = 0u32;
-                (fns.sym_get_line)(
-                    process,
-                    frame_address,
-                    inline_context,
-                    0,
-                    &mut displacement,
-                    line,
-                )
-            },
-            frame,
-            callback,
-            context,
-        ),
-        StackWalkVariant::StackWalk64(_, ref fns) => foreach_symbol_fileline_iternal(
-            |process: c::HANDLE,
-             frame_address: u64,
-             _inline_context: c::ULONG,
-             line: *mut c::IMAGEHLP_LINE64| unsafe {
-                let mut displacement = 0u32;
-                (fns.sym_get_line)(process, frame_address, &mut displacement, line)
-            },
-            frame,
-            callback,
-            context,
-        ),
-    }
-}
-
-fn foreach_symbol_fileline_iternal<F, G>(
-    mut line_getter: G,
-    frame: Frame,
-    mut callback: F,
-    context: &BacktraceContext,
-) -> io::Result<bool>
-where
-    F: FnMut(&[u8], u32) -> io::Result<()>,
-    G: FnMut(c::HANDLE, u64, c::ULONG, *mut c::IMAGEHLP_LINE64) -> c::BOOL,
-{
-    unsafe {
-        let mut line: c::IMAGEHLP_LINE64 = mem::zeroed();
-        line.SizeOfStruct = mem::size_of::<c::IMAGEHLP_LINE64>() as u32;
-
-        let ret = line_getter(
-            context.handle,
-            frame.exact_position as u64,
-            frame.inline_context,
-            &mut line,
-        );
-        if ret == c::TRUE {
-            let name = CStr::from_ptr(line.Filename).to_bytes();
-            callback(name, line.LineNumber as u32)?;
-        }
-        Ok(false)
-    }
-}
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index 518eccf754c..b1f9d9766f7 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -5,8 +5,6 @@
 #![unstable(issue = "0", feature = "windows_c")]
 
 use crate::os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort, c_char};
-#[cfg(target_arch = "x86_64")]
-use crate::os::raw::c_ulonglong;
 use crate::ptr;
 
 use libc::{wchar_t, size_t, c_void};
@@ -33,16 +31,10 @@ pub type WORD = u16;
 pub type CHAR = c_char;
 pub type ULONG_PTR = usize;
 pub type ULONG = c_ulong;
-#[cfg(target_arch = "x86_64")]
-pub type ULONGLONG = u64;
-#[cfg(target_arch = "x86_64")]
-pub type DWORDLONG = ULONGLONG;
 
 pub type LPBOOL = *mut BOOL;
 pub type LPBYTE = *mut BYTE;
-pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
 pub type LPCSTR = *const CHAR;
-pub type LPCVOID = *const c_void;
 pub type LPCWSTR = *const WCHAR;
 pub type LPDWORD = *mut DWORD;
 pub type LPHANDLE = *mut HANDLE;
@@ -108,11 +100,6 @@ pub const SECURITY_SQOS_PRESENT: DWORD = 0x00100000;
 
 pub const FIONBIO: c_ulong = 0x8004667e;
 
-#[cfg(target_arch = "arm")]
-const ARM_MAX_BREAKPOINTS: usize = 8;
-#[cfg(target_arch = "arm")]
-const ARM_MAX_WATCHPOINTS: usize = 1;
-
 #[repr(C)]
 #[derive(Copy)]
 pub struct WIN32_FIND_DATAW {
@@ -132,6 +119,7 @@ impl Clone for WIN32_FIND_DATAW {
 }
 
 pub const WSA_FLAG_OVERLAPPED: DWORD = 0x01;
+pub const WSA_FLAG_NO_HANDLE_INHERIT: DWORD = 0x80;
 
 pub const WSADESCRIPTION_LEN: usize = 256;
 pub const WSASYS_STATUS_LEN: usize = 128;
@@ -141,6 +129,7 @@ pub const INVALID_SOCKET: SOCKET = !0;
 pub const WSAEACCES: c_int = 10013;
 pub const WSAEINVAL: c_int = 10022;
 pub const WSAEWOULDBLOCK: c_int = 10035;
+pub const WSAEPROTOTYPE: c_int = 10041;
 pub const WSAEADDRINUSE: c_int = 10048;
 pub const WSAEADDRNOTAVAIL: c_int = 10049;
 pub const WSAECONNABORTED: c_int = 10053;
@@ -152,7 +141,6 @@ pub const WSAECONNREFUSED: c_int = 10061;
 
 pub const MAX_PROTOCOL_CHAIN: DWORD = 7;
 
-pub const TOKEN_READ: DWORD = 0x20008;
 pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
 pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
 pub const IO_REPARSE_TAG_SYMLINK: DWORD = 0xa000000c;
@@ -168,8 +156,6 @@ pub const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD;
 pub const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
 pub const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
 
-pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
-
 pub const PROGRESS_CONTINUE: DWORD = 0;
 
 pub const ERROR_FILE_NOT_FOUND: DWORD = 2;
@@ -270,26 +256,6 @@ pub const WAIT_OBJECT_0: DWORD = 0x00000000;
 pub const WAIT_TIMEOUT: DWORD = 258;
 pub const WAIT_FAILED: DWORD = 0xFFFFFFFF;
 
-#[cfg(target_env = "msvc")]
-#[cfg(feature = "backtrace")]
-pub const MAX_SYM_NAME: usize = 2000;
-#[cfg(target_arch = "x86")]
-#[cfg(feature = "backtrace")]
-pub const IMAGE_FILE_MACHINE_I386: DWORD = 0x014c;
-#[cfg(target_arch = "x86_64")]
-#[cfg(feature = "backtrace")]
-pub const IMAGE_FILE_MACHINE_AMD64: DWORD = 0x8664;
-#[cfg(target_arch = "aarch64")]
-#[cfg(feature = "backtrace")]
-pub const IMAGE_FILE_MACHINE_ARM64: DWORD = 0xAA64;
-#[cfg(target_arch = "arm")]
-#[cfg(feature = "backtrace")]
-pub const IMAGE_FILE_MACHINE_ARMNT: DWORD = 0x01c4;
-
-pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
-pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
-pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
-
 pub const PIPE_ACCESS_INBOUND: DWORD = 0x00000001;
 pub const PIPE_ACCESS_OUTBOUND: DWORD = 0x00000002;
 pub const FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD = 0x00080000;
@@ -370,20 +336,6 @@ pub struct WIN32_FILE_ATTRIBUTE_DATA {
 }
 
 #[repr(C)]
-pub struct BY_HANDLE_FILE_INFORMATION {
-    pub dwFileAttributes: DWORD,
-    pub ftCreationTime: FILETIME,
-    pub ftLastAccessTime: FILETIME,
-    pub ftLastWriteTime: FILETIME,
-    pub dwVolumeSerialNumber: DWORD,
-    pub nFileSizeHigh: DWORD,
-    pub nFileSizeLow: DWORD,
-    pub nNumberOfLinks: DWORD,
-    pub nFileIndexHigh: DWORD,
-    pub nFileIndexLow: DWORD,
-}
-
-#[repr(C)]
 #[allow(dead_code)] // we only use some variants
 pub enum FILE_INFO_BY_HANDLE_CLASS {
     FileBasicInfo                   = 0,
@@ -489,25 +441,6 @@ pub struct REPARSE_MOUNTPOINT_DATA_BUFFER {
 }
 
 #[repr(C)]
-pub struct EXCEPTION_RECORD {
-    pub ExceptionCode: DWORD,
-    pub ExceptionFlags: DWORD,
-    pub ExceptionRecord: *mut EXCEPTION_RECORD,
-    pub ExceptionAddress: LPVOID,
-    pub NumberParameters: DWORD,
-    pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS]
-}
-
-#[repr(C)]
-pub struct EXCEPTION_POINTERS {
-    pub ExceptionRecord: *mut EXCEPTION_RECORD,
-    pub ContextRecord: *mut CONTEXT,
-}
-
-pub type PVECTORED_EXCEPTION_HANDLER = extern "system"
-        fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG;
-
-#[repr(C)]
 pub struct GUID {
     pub Data1: DWORD,
     pub Data2: WORD,
@@ -581,41 +514,6 @@ pub struct OVERLAPPED {
 }
 
 #[repr(C)]
-#[cfg(target_env = "msvc")]
-#[cfg(feature = "backtrace")]
-pub struct SYMBOL_INFO {
-    pub SizeOfStruct: c_ulong,
-    pub TypeIndex: c_ulong,
-    pub Reserved: [u64; 2],
-    pub Index: c_ulong,
-    pub Size: c_ulong,
-    pub ModBase: u64,
-    pub Flags: c_ulong,
-    pub Value: u64,
-    pub Address: u64,
-    pub Register: c_ulong,
-    pub Scope: c_ulong,
-    pub Tag: c_ulong,
-    pub NameLen: c_ulong,
-    pub MaxNameLen: c_ulong,
-    // note that windows has this as 1, but it basically just means that
-    // the name is inline at the end of the struct. For us, we just bump
-    // the struct size up to MAX_SYM_NAME.
-    pub Name: [c_char; MAX_SYM_NAME],
-}
-
-#[repr(C)]
-#[cfg(target_env = "msvc")]
-#[cfg(feature = "backtrace")]
-pub struct IMAGEHLP_LINE64 {
-    pub SizeOfStruct: u32,
-    pub Key: *const c_void,
-    pub LineNumber: u32,
-    pub Filename: *const c_char,
-    pub Address: u64,
-}
-
-#[repr(C)]
 #[allow(dead_code)] // we only use some variants
 pub enum ADDRESS_MODE {
     AddrMode1616,
@@ -625,280 +523,6 @@ pub enum ADDRESS_MODE {
 }
 
 #[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct ADDRESS64 {
-    pub Offset: u64,
-    pub Segment: u16,
-    pub Mode: ADDRESS_MODE,
-}
-
-#[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct STACKFRAME_EX {
-    pub AddrPC: ADDRESS64,
-    pub AddrReturn: ADDRESS64,
-    pub AddrFrame: ADDRESS64,
-    pub AddrStack: ADDRESS64,
-    pub AddrBStore: ADDRESS64,
-    pub FuncTableEntry: *mut c_void,
-    pub Params: [u64; 4],
-    pub Far: BOOL,
-    pub Virtual: BOOL,
-    pub Reserved: [u64; 3],
-    pub KdHelp: KDHELP64,
-    pub StackFrameSize: DWORD,
-    pub InlineFrameContext: DWORD,
-}
-
-#[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct STACKFRAME64 {
-    pub AddrPC: ADDRESS64,
-    pub AddrReturn: ADDRESS64,
-    pub AddrFrame: ADDRESS64,
-    pub AddrStack: ADDRESS64,
-    pub AddrBStore: ADDRESS64,
-    pub FuncTableEntry: *mut c_void,
-    pub Params: [u64; 4],
-    pub Far: BOOL,
-    pub Virtual: BOOL,
-    pub Reserved: [u64; 3],
-    pub KdHelp: KDHELP64,
-}
-
-#[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct KDHELP64 {
-    pub Thread: u64,
-    pub ThCallbackStack: DWORD,
-    pub ThCallbackBStore: DWORD,
-    pub NextCallback: DWORD,
-    pub FramePointer: DWORD,
-    pub KiCallUserMode: u64,
-    pub KeUserCallbackDispatcher: u64,
-    pub SystemRangeStart: u64,
-    pub KiUserExceptionDispatcher: u64,
-    pub StackBase: u64,
-    pub StackLimit: u64,
-    pub Reserved: [u64; 5],
-}
-
-#[cfg(target_arch = "x86")]
-#[repr(C)]
-pub struct CONTEXT {
-    pub ContextFlags: DWORD,
-    pub Dr0: DWORD,
-    pub Dr1: DWORD,
-    pub Dr2: DWORD,
-    pub Dr3: DWORD,
-    pub Dr6: DWORD,
-    pub Dr7: DWORD,
-    pub FloatSave: FLOATING_SAVE_AREA,
-    pub SegGs: DWORD,
-    pub SegFs: DWORD,
-    pub SegEs: DWORD,
-    pub SegDs: DWORD,
-    pub Edi: DWORD,
-    pub Esi: DWORD,
-    pub Ebx: DWORD,
-    pub Edx: DWORD,
-    pub Ecx: DWORD,
-    pub Eax: DWORD,
-    pub Ebp: DWORD,
-    pub Eip: DWORD,
-    pub SegCs: DWORD,
-    pub EFlags: DWORD,
-    pub Esp: DWORD,
-    pub SegSs: DWORD,
-    pub ExtendedRegisters: [u8; 512],
-}
-
-#[cfg(target_arch = "x86")]
-#[repr(C)]
-pub struct FLOATING_SAVE_AREA {
-    pub ControlWord: DWORD,
-    pub StatusWord: DWORD,
-    pub TagWord: DWORD,
-    pub ErrorOffset: DWORD,
-    pub ErrorSelector: DWORD,
-    pub DataOffset: DWORD,
-    pub DataSelector: DWORD,
-    pub RegisterArea: [u8; 80],
-    pub Cr0NpxState: DWORD,
-}
-
-#[cfg(target_arch = "x86_64")]
-#[repr(C, align(16))]
-pub struct CONTEXT {
-    pub P1Home: DWORDLONG,
-    pub P2Home: DWORDLONG,
-    pub P3Home: DWORDLONG,
-    pub P4Home: DWORDLONG,
-    pub P5Home: DWORDLONG,
-    pub P6Home: DWORDLONG,
-
-    pub ContextFlags: DWORD,
-    pub MxCsr: DWORD,
-
-    pub SegCs: WORD,
-    pub SegDs: WORD,
-    pub SegEs: WORD,
-    pub SegFs: WORD,
-    pub SegGs: WORD,
-    pub SegSs: WORD,
-    pub EFlags: DWORD,
-
-    pub Dr0: DWORDLONG,
-    pub Dr1: DWORDLONG,
-    pub Dr2: DWORDLONG,
-    pub Dr3: DWORDLONG,
-    pub Dr6: DWORDLONG,
-    pub Dr7: DWORDLONG,
-
-    pub Rax: DWORDLONG,
-    pub Rcx: DWORDLONG,
-    pub Rdx: DWORDLONG,
-    pub Rbx: DWORDLONG,
-    pub Rsp: DWORDLONG,
-    pub Rbp: DWORDLONG,
-    pub Rsi: DWORDLONG,
-    pub Rdi: DWORDLONG,
-    pub R8:  DWORDLONG,
-    pub R9:  DWORDLONG,
-    pub R10: DWORDLONG,
-    pub R11: DWORDLONG,
-    pub R12: DWORDLONG,
-    pub R13: DWORDLONG,
-    pub R14: DWORDLONG,
-    pub R15: DWORDLONG,
-
-    pub Rip: DWORDLONG,
-
-    pub FltSave: FLOATING_SAVE_AREA,
-
-    pub VectorRegister: [M128A; 26],
-    pub VectorControl: DWORDLONG,
-
-    pub DebugControl: DWORDLONG,
-    pub LastBranchToRip: DWORDLONG,
-    pub LastBranchFromRip: DWORDLONG,
-    pub LastExceptionToRip: DWORDLONG,
-    pub LastExceptionFromRip: DWORDLONG,
-}
-
-#[cfg(target_arch = "x86_64")]
-#[repr(C, align(16))]
-pub struct M128A {
-    pub Low:  c_ulonglong,
-    pub High: c_longlong
-}
-
-#[cfg(target_arch = "x86_64")]
-#[repr(C, align(16))]
-pub struct FLOATING_SAVE_AREA {
-    _Dummy: [u8; 512] // FIXME: Fill this out
-}
-
-#[cfg(target_arch = "arm")]
-#[repr(C)]
-pub struct CONTEXT {
-    pub ContextFlags: ULONG,
-    pub R0: ULONG,
-    pub R1: ULONG,
-    pub R2: ULONG,
-    pub R3: ULONG,
-    pub R4: ULONG,
-    pub R5: ULONG,
-    pub R6: ULONG,
-    pub R7: ULONG,
-    pub R8: ULONG,
-    pub R9: ULONG,
-    pub R10: ULONG,
-    pub R11: ULONG,
-    pub R12: ULONG,
-    pub Sp: ULONG,
-    pub Lr: ULONG,
-    pub Pc: ULONG,
-    pub Cpsr: ULONG,
-    pub Fpscr: ULONG,
-    pub Padding: ULONG,
-    pub D: [u64; 32],
-    pub Bvr: [ULONG; ARM_MAX_BREAKPOINTS],
-    pub Bcr: [ULONG; ARM_MAX_BREAKPOINTS],
-    pub Wvr: [ULONG; ARM_MAX_WATCHPOINTS],
-    pub Wcr: [ULONG; ARM_MAX_WATCHPOINTS],
-    pub Padding2: [ULONG; 2]
-}
-
-// FIXME(#43348): This structure is used for backtrace only, and a fake
-// definition is provided here only to allow rustdoc to pass type-check. This
-// will not appear in the final documentation. This should be also defined for
-// other architectures supported by Windows such as ARM, and for historical
-// interest, maybe MIPS and PowerPC as well.
-#[cfg(all(rustdoc, not(any(target_arch = "x86_64", target_arch = "x86",
-      target_arch = "aarch64", target_arch = "arm"))))]
-pub enum CONTEXT {}
-
-#[cfg(target_arch = "aarch64")]
-pub const ARM64_MAX_BREAKPOINTS: usize = 8;
-
-#[cfg(target_arch = "aarch64")]
-pub const ARM64_MAX_WATCHPOINTS: usize = 2;
-
-#[cfg(target_arch = "aarch64")]
-#[repr(C)]
-pub struct ARM64_NT_NEON128 {
-    pub D: [f64; 2],
-}
-
-#[cfg(target_arch = "aarch64")]
-#[repr(C, align(16))]
-pub struct CONTEXT {
-    pub ContextFlags: DWORD,
-    pub Cpsr: DWORD,
-    pub X0: u64,
-    pub X1: u64,
-    pub X2: u64,
-    pub X3: u64,
-    pub X4: u64,
-    pub X5: u64,
-    pub X6: u64,
-    pub X7: u64,
-    pub X8: u64,
-    pub X9: u64,
-    pub X10: u64,
-    pub X11: u64,
-    pub X12: u64,
-    pub X13: u64,
-    pub X14: u64,
-    pub X15: u64,
-    pub X16: u64,
-    pub X17: u64,
-    pub X18: u64,
-    pub X19: u64,
-    pub X20: u64,
-    pub X21: u64,
-    pub X22: u64,
-    pub X23: u64,
-    pub X24: u64,
-    pub X25: u64,
-    pub X26: u64,
-    pub X27: u64,
-    pub X28: u64,
-    pub Fp: u64,
-    pub Lr: u64,
-    pub Sp: u64,
-    pub Pc: u64,
-    pub V: [ARM64_NT_NEON128; 32],
-    pub Fpcr: DWORD,
-    pub Fpsr: DWORD,
-    pub Bcr: [DWORD; ARM64_MAX_BREAKPOINTS],
-    pub Bvr: [DWORD; ARM64_MAX_BREAKPOINTS],
-    pub Wcr: [DWORD; ARM64_MAX_WATCHPOINTS],
-    pub Wvr: [DWORD; ARM64_MAX_WATCHPOINTS],
-}
-
-#[repr(C)]
 pub struct SOCKADDR_STORAGE_LH {
     pub ss_family: ADDRESS_FAMILY,
     pub __ss_pad1: [CHAR; 6],
@@ -960,16 +584,6 @@ pub enum EXCEPTION_DISPOSITION {
 }
 
 #[repr(C)]
-#[derive(Copy, Clone)]
-pub struct CONSOLE_READCONSOLE_CONTROL {
-    pub nLength: ULONG,
-    pub nInitialChars: ULONG,
-    pub dwCtrlWakeupMask: ULONG,
-    pub dwControlKeyState: ULONG,
-}
-pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
-
-#[repr(C)]
 #[derive(Copy)]
 pub struct fd_set {
     pub fd_count: c_uint,
@@ -989,6 +603,134 @@ pub struct timeval {
     pub tv_usec: c_long,
 }
 
+// Functions forbidden when targeting UWP
+cfg_if::cfg_if! {
+if #[cfg(not(target_vendor = "uwp"))] {
+    pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
+    pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
+    pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
+
+    #[repr(C)]
+    pub struct EXCEPTION_RECORD {
+        pub ExceptionCode: DWORD,
+        pub ExceptionFlags: DWORD,
+        pub ExceptionRecord: *mut EXCEPTION_RECORD,
+        pub ExceptionAddress: LPVOID,
+        pub NumberParameters: DWORD,
+        pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS]
+    }
+
+    pub enum CONTEXT {}
+
+    #[repr(C)]
+    pub struct EXCEPTION_POINTERS {
+        pub ExceptionRecord: *mut EXCEPTION_RECORD,
+        pub ContextRecord: *mut CONTEXT,
+    }
+
+    pub type PVECTORED_EXCEPTION_HANDLER = extern "system"
+            fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG;
+
+    #[repr(C)]
+    #[derive(Copy, Clone)]
+    pub struct CONSOLE_READCONSOLE_CONTROL {
+        pub nLength: ULONG,
+        pub nInitialChars: ULONG,
+        pub dwCtrlWakeupMask: ULONG,
+        pub dwControlKeyState: ULONG,
+    }
+
+    pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
+
+    #[repr(C)]
+    pub struct BY_HANDLE_FILE_INFORMATION {
+        pub dwFileAttributes: DWORD,
+        pub ftCreationTime: FILETIME,
+        pub ftLastAccessTime: FILETIME,
+        pub ftLastWriteTime: FILETIME,
+        pub dwVolumeSerialNumber: DWORD,
+        pub nFileSizeHigh: DWORD,
+        pub nFileSizeLow: DWORD,
+        pub nNumberOfLinks: DWORD,
+        pub nFileIndexHigh: DWORD,
+        pub nFileIndexLow: DWORD,
+    }
+
+    pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
+    pub type LPCVOID = *const c_void;
+
+    pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
+
+    pub const TOKEN_READ: DWORD = 0x20008;
+
+    extern "system" {
+        #[link_name = "SystemFunction036"]
+        pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN;
+
+        pub fn ReadConsoleW(hConsoleInput: HANDLE,
+                            lpBuffer: LPVOID,
+                            nNumberOfCharsToRead: DWORD,
+                            lpNumberOfCharsRead: LPDWORD,
+                            pInputControl: PCONSOLE_READCONSOLE_CONTROL) -> BOOL;
+
+        pub fn WriteConsoleW(hConsoleOutput: HANDLE,
+                             lpBuffer: LPCVOID,
+                             nNumberOfCharsToWrite: DWORD,
+                             lpNumberOfCharsWritten: LPDWORD,
+                             lpReserved: LPVOID) -> BOOL;
+
+        pub fn GetConsoleMode(hConsoleHandle: HANDLE,
+                              lpMode: LPDWORD) -> BOOL;
+        // Allowed but unused by UWP
+        pub fn OpenProcessToken(ProcessHandle: HANDLE,
+                                DesiredAccess: DWORD,
+                                TokenHandle: *mut HANDLE) -> BOOL;
+        pub fn GetUserProfileDirectoryW(hToken: HANDLE,
+                                        lpProfileDir: LPWSTR,
+                                        lpcchSize: *mut DWORD) -> BOOL;
+        pub fn GetFileInformationByHandle(hFile: HANDLE,
+                            lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
+                            -> BOOL;
+        pub fn SetHandleInformation(hObject: HANDLE,
+                                    dwMask: DWORD,
+                                    dwFlags: DWORD) -> BOOL;
+        pub fn AddVectoredExceptionHandler(FirstHandler: ULONG,
+                                           VectoredHandler: PVECTORED_EXCEPTION_HANDLER)
+                                           -> LPVOID;
+        pub fn CreateHardLinkW(lpSymlinkFileName: LPCWSTR,
+                               lpTargetFileName: LPCWSTR,
+                               lpSecurityAttributes: LPSECURITY_ATTRIBUTES)
+                               -> BOOL;
+    }
+}
+}
+
+// UWP specific functions & types
+cfg_if::cfg_if! {
+if #[cfg(target_vendor = "uwp")] {
+    pub const BCRYPT_USE_SYSTEM_PREFERRED_RNG: DWORD = 0x00000002;
+
+    #[repr(C)]
+    pub struct FILE_STANDARD_INFO {
+        pub AllocationSize: LARGE_INTEGER,
+        pub EndOfFile: LARGE_INTEGER,
+        pub NumberOfLinks: DWORD,
+        pub DeletePending: BOOLEAN,
+        pub Directory: BOOLEAN,
+    }
+
+    extern "system" {
+        pub fn GetFileInformationByHandleEx(hFile: HANDLE,
+                                            fileInfoClass: FILE_INFO_BY_HANDLE_CLASS,
+                                            lpFileInformation: LPVOID,
+                                            dwBufferSize: DWORD) -> BOOL;
+        pub fn BCryptGenRandom(hAlgorithm: LPVOID, pBuffer: *mut u8,
+                               cbBuffer: ULONG, dwFlags: ULONG) -> LONG;
+    }
+}
+}
+
+// Shared between Desktop & UWP
 extern "system" {
     pub fn WSAStartup(wVersionRequested: WORD,
                       lpWSAData: LPWSADATA) -> c_int;
@@ -1028,34 +770,13 @@ extern "system" {
     pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
     pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
 
-    pub fn ReadConsoleW(hConsoleInput: HANDLE,
-                        lpBuffer: LPVOID,
-                        nNumberOfCharsToRead: DWORD,
-                        lpNumberOfCharsRead: LPDWORD,
-                        pInputControl: PCONSOLE_READCONSOLE_CONTROL) -> BOOL;
-
-    pub fn WriteConsoleW(hConsoleOutput: HANDLE,
-                         lpBuffer: LPCVOID,
-                         nNumberOfCharsToWrite: DWORD,
-                         lpNumberOfCharsWritten: LPDWORD,
-                         lpReserved: LPVOID) -> BOOL;
-
-    pub fn GetConsoleMode(hConsoleHandle: HANDLE,
-                          lpMode: LPDWORD) -> BOOL;
     pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
     pub fn SetFileAttributesW(lpFileName: LPCWSTR,
                               dwFileAttributes: DWORD) -> BOOL;
-    pub fn GetFileInformationByHandle(hFile: HANDLE,
-                            lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
-                            -> BOOL;
-
     pub fn SetLastError(dwErrCode: DWORD);
     pub fn GetCommandLineW() -> *mut LPCWSTR;
     pub fn GetTempPathW(nBufferLength: DWORD,
                         lpBuffer: LPCWSTR) -> DWORD;
-    pub fn OpenProcessToken(ProcessHandle: HANDLE,
-                            DesiredAccess: DWORD,
-                            TokenHandle: *mut HANDLE) -> BOOL;
     pub fn GetCurrentProcess() -> HANDLE;
     pub fn GetCurrentThread() -> HANDLE;
     pub fn GetStdHandle(which: DWORD) -> HANDLE;
@@ -1080,21 +801,12 @@ extern "system" {
     pub fn SwitchToThread() -> BOOL;
     pub fn Sleep(dwMilliseconds: DWORD);
     pub fn GetProcessId(handle: HANDLE) -> DWORD;
-    pub fn GetUserProfileDirectoryW(hToken: HANDLE,
-                                    lpProfileDir: LPWSTR,
-                                    lpcchSize: *mut DWORD) -> BOOL;
-    pub fn SetHandleInformation(hObject: HANDLE,
-                                dwMask: DWORD,
-                                dwFlags: DWORD) -> BOOL;
     pub fn CopyFileExW(lpExistingFileName: LPCWSTR,
                        lpNewFileName: LPCWSTR,
                        lpProgressRoutine: LPPROGRESS_ROUTINE,
                        lpData: LPVOID,
                        pbCancel: LPBOOL,
                        dwCopyFlags: DWORD) -> BOOL;
-    pub fn AddVectoredExceptionHandler(FirstHandler: ULONG,
-                                       VectoredHandler: PVECTORED_EXCEPTION_HANDLER)
-                                       -> LPVOID;
     pub fn FormatMessageW(flags: DWORD,
                           lpSrc: LPVOID,
                           msgId: DWORD,
@@ -1191,10 +903,6 @@ extern "system" {
                      lpOverlapped: LPOVERLAPPED)
                      -> BOOL;
     pub fn CloseHandle(hObject: HANDLE) -> BOOL;
-    pub fn CreateHardLinkW(lpSymlinkFileName: LPCWSTR,
-                           lpTargetFileName: LPCWSTR,
-                           lpSecurityAttributes: LPSECURITY_ATTRIBUTES)
-                           -> BOOL;
     pub fn MoveFileExW(lpExistingFileName: LPCWSTR,
                        lpNewFileName: LPCWSTR,
                        dwFlags: DWORD)
@@ -1220,8 +928,6 @@ extern "system" {
     pub fn FindNextFileW(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW)
                          -> BOOL;
     pub fn FindClose(findFile: HANDLE) -> BOOL;
-    #[cfg(feature = "backtrace")]
-    pub fn RtlCaptureContext(ctx: *mut CONTEXT);
     pub fn getsockopt(s: SOCKET,
                       level: c_int,
                       optname: c_int,
@@ -1252,10 +958,6 @@ extern "system" {
                        res: *mut *mut ADDRINFOA) -> c_int;
     pub fn freeaddrinfo(res: *mut ADDRINFOA);
 
-    #[cfg(feature = "backtrace")]
-    pub fn LoadLibraryW(name: LPCWSTR) -> HMODULE;
-    #[cfg(feature = "backtrace")]
-    pub fn FreeLibrary(handle: HMODULE) -> BOOL;
     pub fn GetProcAddress(handle: HMODULE,
                           name: LPCSTR) -> *mut c_void;
     pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
@@ -1290,8 +992,6 @@ extern "system" {
                   exceptfds: *mut fd_set,
                   timeout: *const timeval) -> c_int;
 
-    #[link_name = "SystemFunction036"]
-    pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN;
 
     pub fn GetProcessHeap() -> HANDLE;
     pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
@@ -1315,6 +1015,7 @@ compat_fn! {
                                      _dwFlags: DWORD) -> DWORD {
         SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
     }
+    #[cfg(not(target_vendor = "uwp"))]
     pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL {
         SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
     }
@@ -1361,34 +1062,3 @@ compat_fn! {
         panic!("rwlocks not available")
     }
 }
-
-#[cfg(all(target_env = "gnu", feature = "backtrace"))]
-mod gnu {
-    use super::*;
-
-    pub const PROCESS_QUERY_INFORMATION: DWORD = 0x0400;
-
-    pub const CP_ACP: UINT = 0;
-
-    pub const WC_NO_BEST_FIT_CHARS: DWORD = 0x00000400;
-
-    extern "system" {
-        pub fn OpenProcess(dwDesiredAccess: DWORD,
-                           bInheritHandle: BOOL,
-                           dwProcessId: DWORD) -> HANDLE;
-    }
-
-    compat_fn! {
-        kernel32:
-
-        pub fn QueryFullProcessImageNameW(_hProcess: HANDLE,
-                                          _dwFlags: DWORD,
-                                          _lpExeName: LPWSTR,
-                                          _lpdwSize: LPDWORD) -> BOOL {
-            SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
-        }
-    }
-}
-
-#[cfg(all(target_env = "gnu", feature = "backtrace"))]
-pub use self::gnu::*;
diff --git a/src/libstd/sys/windows/compat.rs b/src/libstd/sys/windows/compat.rs
index 748c1616d1d..544b2087f92 100644
--- a/src/libstd/sys/windows/compat.rs
+++ b/src/libstd/sys/windows/compat.rs
@@ -37,12 +37,14 @@ pub fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str,
 
 macro_rules! compat_fn {
     ($module:ident: $(
+        $(#[$meta:meta])*
         pub fn $symbol:ident($($argname:ident: $argtype:ty),*)
                                   -> $rettype:ty {
             $($body:expr);*
         }
     )*) => ($(
         #[allow(unused_variables)]
+        $(#[$meta])*
         pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype {
             use crate::sync::atomic::{AtomicUsize, Ordering};
             use crate::mem;
diff --git a/src/libstd/sys/windows/dynamic_lib.rs b/src/libstd/sys/windows/dynamic_lib.rs
deleted file mode 100644
index b9d5105cb73..00000000000
--- a/src/libstd/sys/windows/dynamic_lib.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-use crate::os::windows::prelude::*;
-
-use crate::ffi::{CString, OsStr};
-use crate::io;
-use crate::sys::c;
-
-pub struct DynamicLibrary {
-    handle: c::HMODULE,
-}
-
-impl DynamicLibrary {
-    pub fn open(filename: &str) -> io::Result<DynamicLibrary> {
-        let filename = OsStr::new(filename)
-                             .encode_wide()
-                             .chain(Some(0))
-                             .collect::<Vec<_>>();
-        let result = unsafe {
-            c::LoadLibraryW(filename.as_ptr())
-        };
-        if result.is_null() {
-            Err(io::Error::last_os_error())
-        } else {
-            Ok(DynamicLibrary { handle: result })
-        }
-    }
-
-    pub fn symbol(&self, symbol: &str) -> io::Result<usize> {
-        let symbol = CString::new(symbol)?;
-        unsafe {
-            match c::GetProcAddress(self.handle, symbol.as_ptr()) as usize {
-                0 => Err(io::Error::last_os_error()),
-                n => Ok(n),
-            }
-        }
-    }
-}
-
-impl Drop for DynamicLibrary {
-    fn drop(&mut self) {
-        unsafe {
-            c::FreeLibrary(self.handle);
-        }
-    }
-}
diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs
index 268a14ff0aa..23964dc5bd5 100644
--- a/src/libstd/sys/windows/ext/fs.rs
+++ b/src/libstd/sys/windows/ext/fs.rs
@@ -437,6 +437,33 @@ pub trait MetadataExt {
     /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn file_size(&self) -> u64;
+
+    /// Returns the value of the `dwVolumeSerialNumber` field of this
+    /// metadata.
+    ///
+    /// This will return `None` if the `Metadata` instance was created from a
+    /// call to `DirEntry::metadata`. If this `Metadata` was created by using
+    /// `fs::metadata` or `File::metadata`, then this will return `Some`.
+    #[unstable(feature = "windows_by_handle", issue = "63010")]
+    fn volume_serial_number(&self) -> Option<u32>;
+
+    /// Returns the value of the `nNumberOfLinks` field of this
+    /// metadata.
+    ///
+    /// This will return `None` if the `Metadata` instance was created from a
+    /// call to `DirEntry::metadata`. If this `Metadata` was created by using
+    /// `fs::metadata` or `File::metadata`, then this will return `Some`.
+    #[unstable(feature = "windows_by_handle", issue = "63010")]
+    fn number_of_links(&self) -> Option<u32>;
+
+    /// Returns the value of the `nFileIndex{Low,High}` fields of this
+    /// metadata.
+    ///
+    /// This will return `None` if the `Metadata` instance was created from a
+    /// call to `DirEntry::metadata`. If this `Metadata` was created by using
+    /// `fs::metadata` or `File::metadata`, then this will return `Some`.
+    #[unstable(feature = "windows_by_handle", issue = "63010")]
+    fn file_index(&self) -> Option<u64>;
 }
 
 #[stable(feature = "metadata_ext", since = "1.1.0")]
@@ -446,6 +473,9 @@ impl MetadataExt for Metadata {
     fn last_access_time(&self) -> u64 { self.as_inner().accessed_u64() }
     fn last_write_time(&self) -> u64 { self.as_inner().modified_u64() }
     fn file_size(&self) -> u64 { self.as_inner().size() }
+    fn volume_serial_number(&self) -> Option<u32> { self.as_inner().volume_serial_number() }
+    fn number_of_links(&self) -> Option<u32> { self.as_inner().number_of_links() }
+    fn file_index(&self) -> Option<u64> { self.as_inner().file_index() }
 }
 
 /// Windows-specific extensions to [`FileType`].
diff --git a/src/libstd/sys/windows/fast_thread_local.rs b/src/libstd/sys/windows/fast_thread_local.rs
index 0ccc67e3fd5..31d0bd1e72e 100644
--- a/src/libstd/sys/windows/fast_thread_local.rs
+++ b/src/libstd/sys/windows/fast_thread_local.rs
@@ -2,7 +2,3 @@
 #![cfg(target_thread_local)]
 
 pub use crate::sys_common::thread_local::register_dtor_fallback as register_dtor;
-
-pub fn requires_move_before_drop() -> bool {
-    false
-}
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index d5cb205c85f..204f6af5fc1 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -25,6 +25,9 @@ pub struct FileAttr {
     last_write_time: c::FILETIME,
     file_size: u64,
     reparse_tag: c::DWORD,
+    volume_serial_number: Option<u32>,
+    number_of_links: Option<u32>,
+    file_index: Option<u64>,
 }
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -156,6 +159,9 @@ impl DirEntry {
                 } else {
                     0
                 },
+            volume_serial_number: None,
+            number_of_links: None,
+            file_index: None,
         })
     }
 }
@@ -287,20 +293,71 @@ impl File {
         Ok(())
     }
 
+    #[cfg(not(target_vendor = "uwp"))]
     pub fn file_attr(&self) -> io::Result<FileAttr> {
         unsafe {
             let mut info: c::BY_HANDLE_FILE_INFORMATION = mem::zeroed();
-            cvt(c::GetFileInformationByHandle(self.handle.raw(),
-                                              &mut info))?;
-            let mut attr = FileAttr {
+            cvt(c::GetFileInformationByHandle(self.handle.raw(), &mut info))?;
+            let mut reparse_tag = 0;
+            if info.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
+                let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+                if let Ok((_, buf)) = self.reparse_point(&mut b) {
+                    reparse_tag = buf.ReparseTag;
+                }
+            }
+            Ok(FileAttr {
                 attributes: info.dwFileAttributes,
                 creation_time: info.ftCreationTime,
                 last_access_time: info.ftLastAccessTime,
                 last_write_time: info.ftLastWriteTime,
-                file_size: ((info.nFileSizeHigh as u64) << 32) | (info.nFileSizeLow as u64),
+                file_size: (info.nFileSizeLow as u64) | ((info.nFileSizeHigh as u64) << 32),
+                reparse_tag,
+                volume_serial_number: Some(info.dwVolumeSerialNumber),
+                number_of_links: Some(info.nNumberOfLinks),
+                file_index: Some((info.nFileIndexLow as u64) |
+                                 ((info.nFileIndexHigh as u64) << 32)),
+            })
+        }
+    }
+
+    #[cfg(target_vendor = "uwp")]
+    pub fn file_attr(&self) -> io::Result<FileAttr> {
+        unsafe {
+            let mut info: c::FILE_BASIC_INFO = mem::zeroed();
+            let size = mem::size_of_val(&info);
+            cvt(c::GetFileInformationByHandleEx(self.handle.raw(),
+                                              c::FileBasicInfo,
+                                              &mut info as *mut _ as *mut libc::c_void,
+                                              size as c::DWORD))?;
+            let mut attr = FileAttr {
+                attributes: info.FileAttributes,
+                creation_time: c::FILETIME {
+                    dwLowDateTime: info.CreationTime as c::DWORD,
+                    dwHighDateTime: (info.CreationTime >> 32) as c::DWORD,
+                },
+                last_access_time: c::FILETIME {
+                    dwLowDateTime: info.LastAccessTime as c::DWORD,
+                    dwHighDateTime: (info.LastAccessTime >> 32) as c::DWORD,
+                },
+                last_write_time: c::FILETIME {
+                    dwLowDateTime: info.LastWriteTime as c::DWORD,
+                    dwHighDateTime: (info.LastWriteTime >> 32) as c::DWORD,
+                },
+                file_size: 0,
                 reparse_tag: 0,
+                volume_serial_number: None,
+                number_of_links: None,
+                file_index: None,
             };
-            if attr.is_reparse_point() {
+            let mut info: c::FILE_STANDARD_INFO = mem::zeroed();
+            let size = mem::size_of_val(&info);
+            cvt(c::GetFileInformationByHandleEx(self.handle.raw(),
+                                                c::FileStandardInfo,
+                                                &mut info as *mut _ as *mut libc::c_void,
+                                                size as c::DWORD))?;
+            attr.file_size = info.AllocationSize as u64;
+            attr.number_of_links = Some(info.NumberOfLinks);
+            if attr.file_type().is_reparse_point() {
                 let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
                 if let Ok((_, buf)) = self.reparse_point(&mut b) {
                     attr.reparse_tag = buf.ReparseTag;
@@ -463,7 +520,9 @@ impl FileAttr {
         FilePermissions { attrs: self.attributes }
     }
 
-    pub fn attrs(&self) -> u32 { self.attributes as u32 }
+    pub fn attrs(&self) -> u32 {
+        self.attributes
+    }
 
     pub fn file_type(&self) -> FileType {
         FileType::new(self.attributes, self.reparse_tag)
@@ -493,8 +552,16 @@ impl FileAttr {
         to_u64(&self.creation_time)
     }
 
-    fn is_reparse_point(&self) -> bool {
-        self.attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0
+    pub fn volume_serial_number(&self) -> Option<u32> {
+        self.volume_serial_number
+    }
+
+    pub fn number_of_links(&self) -> Option<u32> {
+        self.number_of_links
+    }
+
+    pub fn file_index(&self) -> Option<u64> {
+        self.file_index
     }
 }
 
@@ -670,6 +737,7 @@ pub fn symlink_inner(src: &Path, dst: &Path, dir: bool) -> io::Result<()> {
     Ok(())
 }
 
+#[cfg(not(target_vendor = "uwp"))]
 pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
     let src = to_u16s(src)?;
     let dst = to_u16s(dst)?;
@@ -679,6 +747,12 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
     Ok(())
 }
 
+#[cfg(target_vendor = "uwp")]
+pub fn link(_src: &Path, _dst: &Path) -> io::Result<()> {
+    return Err(io::Error::new(io::ErrorKind::Other,
+                            "hard link are not supported on UWP"));
+}
+
 pub fn stat(path: &Path) -> io::Result<FileAttr> {
     let mut opts = OpenOptions::new();
     // No read or write permissions are necessary
diff --git a/src/libstd/sys/windows/io.rs b/src/libstd/sys/windows/io.rs
index c045a63e911..e44dcbe164d 100644
--- a/src/libstd/sys/windows/io.rs
+++ b/src/libstd/sys/windows/io.rs
@@ -22,6 +22,18 @@ impl<'a> IoSlice<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        if (self.vec.len as usize) < n {
+            panic!("advancing IoSlice beyond its length");
+        }
+
+        unsafe {
+            self.vec.len -= n as c::ULONG;
+            self.vec.buf = self.vec.buf.add(n);
+        }
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         unsafe {
             slice::from_raw_parts(self.vec.buf as *mut u8, self.vec.len as usize)
@@ -29,6 +41,7 @@ impl<'a> IoSlice<'a> {
     }
 }
 
+#[repr(transparent)]
 pub struct IoSliceMut<'a> {
     vec: c::WSABUF,
     _p: PhantomData<&'a mut [u8]>,
@@ -48,6 +61,18 @@ impl<'a> IoSliceMut<'a> {
     }
 
     #[inline]
+    pub fn advance(&mut self, n: usize) {
+        if (self.vec.len as usize) < n {
+            panic!("advancing IoSliceMut beyond its length");
+        }
+
+        unsafe {
+            self.vec.len -= n as c::ULONG;
+            self.vec.buf = self.vec.buf.add(n);
+        }
+    }
+
+    #[inline]
     pub fn as_slice(&self) -> &[u8] {
         unsafe {
             slice::from_raw_parts(self.vec.buf as *mut u8, self.vec.len as usize)
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 1425254a2e1..d59ac5959a6 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -14,13 +14,9 @@ pub use self::rand::hashmap_random_keys;
 
 pub mod alloc;
 pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
 pub mod c;
 pub mod cmath;
 pub mod condvar;
-#[cfg(feature = "backtrace")]
-pub mod dynamic_lib;
 pub mod env;
 pub mod ext;
 pub mod fast_thread_local;
@@ -37,11 +33,20 @@ pub mod pipe;
 pub mod process;
 pub mod rand;
 pub mod rwlock;
-pub mod stack_overflow;
 pub mod thread;
 pub mod thread_local;
 pub mod time;
-pub mod stdio;
+cfg_if::cfg_if! {
+    if #[cfg(not(target_vendor = "uwp"))] {
+        pub mod stdio;
+        pub mod stack_overflow;
+    } else {
+        pub mod stdio_uwp;
+        pub mod stack_overflow_uwp;
+        pub use self::stdio_uwp as stdio;
+        pub use self::stack_overflow_uwp as stack_overflow;
+    }
+}
 
 #[cfg(not(test))]
 pub fn init() {
@@ -199,7 +204,7 @@ fn wide_char_to_multi_byte(code_page: u32,
     }
 }
 
-pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
+pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] {
     match v.iter().position(|c| *c == 0) {
         // don't include the 0
         Some(i) => &v[..i],
diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs
index 7dd1af5441b..32f4011fb32 100644
--- a/src/libstd/sys/windows/net.rs
+++ b/src/libstd/sys/windows/net.rs
@@ -97,12 +97,26 @@ impl Socket {
         };
         let socket = unsafe {
             match c::WSASocketW(fam, ty, 0, ptr::null_mut(), 0,
-                                c::WSA_FLAG_OVERLAPPED) {
-                c::INVALID_SOCKET => Err(last_error()),
+                                c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT) {
+                c::INVALID_SOCKET => {
+                    match c::WSAGetLastError() {
+                        c::WSAEPROTOTYPE => {
+                            match c::WSASocketW(fam, ty, 0, ptr::null_mut(), 0,
+                                                c::WSA_FLAG_OVERLAPPED) {
+                                c::INVALID_SOCKET => Err(last_error()),
+                                n => {
+                                    let s = Socket(n);
+                                    s.set_no_inherit()?;
+                                    Ok(s)
+                                },
+                            }
+                        },
+                        n => Err(io::Error::from_raw_os_error(n)),
+                    }
+                },
                 n => Ok(Socket(n)),
             }
         }?;
-        socket.set_no_inherit()?;
         Ok(socket)
     }
 
@@ -168,7 +182,6 @@ impl Socket {
                 n => Ok(Socket(n)),
             }
         }?;
-        socket.set_no_inherit()?;
         Ok(socket)
     }
 
@@ -178,16 +191,34 @@ impl Socket {
             cvt(c::WSADuplicateSocketW(self.0,
                                             c::GetCurrentProcessId(),
                                             &mut info))?;
+
             match c::WSASocketW(info.iAddressFamily,
                                 info.iSocketType,
                                 info.iProtocol,
                                 &mut info, 0,
-                                c::WSA_FLAG_OVERLAPPED) {
-                c::INVALID_SOCKET => Err(last_error()),
+                                c::WSA_FLAG_OVERLAPPED | c::WSA_FLAG_NO_HANDLE_INHERIT) {
+                c::INVALID_SOCKET => {
+                    match c::WSAGetLastError() {
+                        c::WSAEPROTOTYPE => {
+                            match c::WSASocketW(info.iAddressFamily,
+                                                info.iSocketType,
+                                                info.iProtocol,
+                                                &mut info, 0,
+                                                c::WSA_FLAG_OVERLAPPED) {
+                                c::INVALID_SOCKET => Err(last_error()),
+                                n => {
+                                    let s = Socket(n);
+                                    s.set_no_inherit()?;
+                                    Ok(s)
+                                },
+                            }
+                        },
+                        n => Err(io::Error::from_raw_os_error(n)),
+                    }
+                },
                 n => Ok(Socket(n)),
             }
         }?;
-        socket.set_no_inherit()?;
         Ok(socket)
     }
 
@@ -312,6 +343,7 @@ impl Socket {
         }
     }
 
+    #[cfg(not(target_vendor = "uwp"))]
     fn set_no_inherit(&self) -> io::Result<()> {
         sys::cvt(unsafe {
             c::SetHandleInformation(self.0 as c::HANDLE,
@@ -319,6 +351,11 @@ impl Socket {
         }).map(|_| ())
     }
 
+    #[cfg(target_vendor = "uwp")]
+    fn set_no_inherit(&self) -> io::Result<()> {
+        Err(io::Error::new(io::ErrorKind::Other, "Unavailable on UWP"))
+    }
+
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         let how = match how {
             Shutdown::Write => c::SD_SEND,
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index 4e50b5521eb..7c400dce686 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -13,7 +13,6 @@ use crate::path::{self, PathBuf};
 use crate::ptr;
 use crate::slice;
 use crate::sys::{c, cvt};
-use crate::sys::handle::Handle;
 
 use super::to_u16s;
 
@@ -284,10 +283,11 @@ pub fn temp_dir() -> PathBuf {
     }, super::os2path).unwrap()
 }
 
-pub fn home_dir() -> Option<PathBuf> {
-    crate::env::var_os("HOME").or_else(|| {
-        crate::env::var_os("USERPROFILE")
-    }).map(PathBuf::from).or_else(|| unsafe {
+#[cfg(not(target_vendor = "uwp"))]
+fn home_dir_crt() -> Option<PathBuf> {
+    unsafe {
+        use crate::sys::handle::Handle;
+
         let me = c::GetCurrentProcess();
         let mut token = ptr::null_mut();
         if c::OpenProcessToken(me, c::TOKEN_READ, &mut token) == 0 {
@@ -301,7 +301,18 @@ pub fn home_dir() -> Option<PathBuf> {
                 _ => sz - 1, // sz includes the null terminator
             }
         }, super::os2path).ok()
-    })
+    }
+}
+
+#[cfg(target_vendor = "uwp")]
+fn home_dir_crt() -> Option<PathBuf> {
+    None
+}
+
+pub fn home_dir() -> Option<PathBuf> {
+    crate::env::var_os("HOME").or_else(|| {
+        crate::env::var_os("USERPROFILE")
+    }).map(PathBuf::from).or_else(|| home_dir_crt())
 }
 
 pub fn exit(code: i32) -> ! {
diff --git a/src/libstd/sys/windows/path.rs b/src/libstd/sys/windows/path.rs
index f3178a5e9e6..7eae28cb14f 100644
--- a/src/libstd/sys/windows/path.rs
+++ b/src/libstd/sys/windows/path.rs
@@ -19,7 +19,7 @@ pub fn is_verbatim_sep(b: u8) -> bool {
     b == b'\\'
 }
 
-pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix<'a>> {
+pub fn parse_prefix(path: &OsStr) -> Option<Prefix<'_>> {
     use crate::path::Prefix::*;
     unsafe {
         // The unsafety here stems from converting between &OsStr and &[u8]
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index 493ee8a9a2d..041d5385eb6 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -45,7 +45,7 @@ pub struct Pipes {
 /// mode. This means that technically speaking it should only ever be used
 /// with `OVERLAPPED` instances, but also works out ok if it's only ever used
 /// once at a time (which we do indeed guarantee).
-pub fn anon_pipe(ours_readable: bool) -> io::Result<Pipes> {
+pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Result<Pipes> {
     // Note that we specifically do *not* use `CreatePipe` here because
     // unfortunately the anonymous pipes returned do not support overlapped
     // operations. Instead, we create a "hopefully unique" name and create a
@@ -137,6 +137,13 @@ pub fn anon_pipe(ours_readable: bool) -> io::Result<Pipes> {
         opts.write(ours_readable);
         opts.read(!ours_readable);
         opts.share_mode(0);
+        let size = mem::size_of::<c::SECURITY_ATTRIBUTES>();
+        let mut sa = c::SECURITY_ATTRIBUTES {
+            nLength: size as c::DWORD,
+            lpSecurityDescriptor: ptr::null_mut(),
+            bInheritHandle: their_handle_inheritable as i32,
+        };
+        opts.security_attributes(&mut sa);
         let theirs = File::open(Path::new(&name), &opts)?;
         let theirs = AnonPipe { inner: theirs.into_handle() };
 
@@ -342,7 +349,7 @@ impl<'a> Drop for AsyncPipe<'a> {
         // If anything here fails, there's not really much we can do, so we leak
         // the buffer/OVERLAPPED pointers to ensure we're at least memory safe.
         if self.pipe.cancel_io().is_err() || self.result().is_err() {
-            let buf = mem::replace(self.dst, Vec::new());
+            let buf = mem::take(self.dst);
             let overlapped = Box::new(unsafe { mem::zeroed() });
             let overlapped = mem::replace(&mut self.overlapped, overlapped);
             mem::forget((buf, overlapped));
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index e39b7ae8890..05e0ca67064 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -267,13 +267,8 @@ impl Stdio {
 
             Stdio::MakePipe => {
                 let ours_readable = stdio_id != c::STD_INPUT_HANDLE;
-                let pipes = pipe::anon_pipe(ours_readable)?;
+                let pipes = pipe::anon_pipe(ours_readable, true)?;
                 *pipe = Some(pipes.ours);
-                cvt(unsafe {
-                    c::SetHandleInformation(pipes.theirs.handle().raw(),
-                                            c::HANDLE_FLAG_INHERIT,
-                                            c::HANDLE_FLAG_INHERIT)
-                })?;
                 Ok(pipes.theirs.into_handle())
             }
 
diff --git a/src/libstd/sys/windows/rand.rs b/src/libstd/sys/windows/rand.rs
index 0193f4defa1..c9bcb5d7415 100644
--- a/src/libstd/sys/windows/rand.rs
+++ b/src/libstd/sys/windows/rand.rs
@@ -2,6 +2,7 @@ use crate::io;
 use crate::mem;
 use crate::sys::c;
 
+#[cfg(not(target_vendor = "uwp"))]
 pub fn hashmap_random_keys() -> (u64, u64) {
     let mut v = (0, 0);
     let ret = unsafe {
@@ -14,3 +15,20 @@ pub fn hashmap_random_keys() -> (u64, u64) {
     }
     return v
 }
+
+#[cfg(target_vendor = "uwp")]
+pub fn hashmap_random_keys() -> (u64, u64) {
+    use crate::ptr;
+
+    let mut v = (0, 0);
+    let ret = unsafe {
+        c::BCryptGenRandom(ptr::null_mut(), &mut v as *mut _ as *mut u8,
+                           mem::size_of_val(&v) as c::ULONG,
+                           c::BCRYPT_USE_SYSTEM_PREFERRED_RNG)
+    };
+    if ret != 0 {
+        panic!("couldn't generate random bytes: {}",
+               io::Error::last_os_error());
+    }
+    return v
+}
diff --git a/src/libstd/sys/redox/stack_overflow.rs b/src/libstd/sys/windows/stack_overflow_uwp.rs
index cf01d323d45..e7236cf359c 100644
--- a/src/libstd/sys/redox/stack_overflow.rs
+++ b/src/libstd/sys/windows/stack_overflow_uwp.rs
@@ -3,15 +3,11 @@
 pub struct Handler;
 
 impl Handler {
-    pub unsafe fn new() -> Handler {
+    pub fn new() -> Handler {
         Handler
     }
 }
 
-pub unsafe fn init() {
+pub unsafe fn init() {}
 
-}
-
-pub unsafe fn cleanup() {
-
-}
+pub unsafe fn cleanup() {}
diff --git a/src/libstd/sys/windows/stdio_uwp.rs b/src/libstd/sys/windows/stdio_uwp.rs
new file mode 100644
index 00000000000..489d3df2860
--- /dev/null
+++ b/src/libstd/sys/windows/stdio_uwp.rs
@@ -0,0 +1,85 @@
+#![unstable(issue = "0", feature = "windows_stdio")]
+
+use crate::io;
+use crate::sys::c;
+use crate::sys::handle::Handle;
+use crate::mem::ManuallyDrop;
+
+pub struct Stdin {
+}
+pub struct Stdout;
+pub struct Stderr;
+
+const MAX_BUFFER_SIZE: usize = 8192;
+pub const STDIN_BUF_SIZE: usize = MAX_BUFFER_SIZE / 2 * 3;
+
+pub fn get_handle(handle_id: c::DWORD) -> io::Result<c::HANDLE> {
+    let handle = unsafe { c::GetStdHandle(handle_id) };
+    if handle == c::INVALID_HANDLE_VALUE {
+        Err(io::Error::last_os_error())
+    } else if handle.is_null() {
+        Err(io::Error::from_raw_os_error(c::ERROR_INVALID_HANDLE as i32))
+    } else {
+        Ok(handle)
+    }
+}
+
+fn write(handle_id: c::DWORD, data: &[u8]) -> io::Result<usize> {
+    let handle = get_handle(handle_id)?;
+    let handle = Handle::new(handle);
+    ManuallyDrop::new(handle).write(data)
+}
+
+impl Stdin {
+    pub fn new() -> io::Result<Stdin> {
+        Ok(Stdin { })
+    }
+}
+
+impl io::Read for Stdin {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        let handle = get_handle(c::STD_INPUT_HANDLE)?;
+        let handle = Handle::new(handle);
+        ManuallyDrop::new(handle).read(buf)
+    }
+}
+
+impl Stdout {
+    pub fn new() -> io::Result<Stdout> {
+        Ok(Stdout)
+    }
+}
+
+impl io::Write for Stdout {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        write(c::STD_OUTPUT_HANDLE, buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+impl Stderr {
+    pub fn new() -> io::Result<Stderr> {
+        Ok(Stderr)
+    }
+}
+
+impl io::Write for Stderr {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        write(c::STD_ERROR_HANDLE, buf)
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+pub fn is_ebadf(err: &io::Error) -> bool {
+    err.raw_os_error() == Some(c::ERROR_INVALID_HANDLE as i32)
+}
+
+pub fn panic_output() -> Option<impl io::Write> {
+    Stderr::new().ok()
+}
diff --git a/src/libstd/sys_common/alloc.rs b/src/libstd/sys_common/alloc.rs
index 978a70bee09..1cfc7ed17f2 100644
--- a/src/libstd/sys_common/alloc.rs
+++ b/src/libstd/sys_common/alloc.rs
@@ -12,7 +12,8 @@ use crate::ptr;
               target_arch = "powerpc",
               target_arch = "powerpc64",
               target_arch = "asmjs",
-              target_arch = "wasm32")))]
+              target_arch = "wasm32",
+              target_arch = "hexagon")))]
 pub const MIN_ALIGN: usize = 8;
 #[cfg(all(any(target_arch = "x86_64",
               target_arch = "aarch64",
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 8d8d8169b43..bf37ff7ddbd 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -2,40 +2,17 @@
 /// supported platforms.
 
 use crate::env;
-use crate::io::prelude::*;
 use crate::io;
+use crate::io::prelude::*;
+use crate::mem;
 use crate::path::{self, Path};
 use crate::ptr;
-use crate::str;
 use crate::sync::atomic::{self, Ordering};
 use crate::sys::mutex::Mutex;
 
-use rustc_demangle::demangle;
-
-pub use crate::sys::backtrace::{
-    unwind_backtrace,
-    resolve_symname,
-    foreach_symbol_fileline,
-    BacktraceContext
-};
-
-#[cfg(target_pointer_width = "64")]
-pub const HEX_WIDTH: usize = 18;
-
-#[cfg(target_pointer_width = "32")]
-pub const HEX_WIDTH: usize = 10;
-
-/// Represents an item in the backtrace list. See `unwind_backtrace` for how
-/// it is created.
-#[derive(Debug, Copy, Clone)]
-pub struct Frame {
-    /// Exact address of the call that failed.
-    pub exact_position: *const u8,
-    /// Address of the enclosing function.
-    pub symbol_addr: *const u8,
-    /// Which inlined function is this frame referring to
-    pub inline_context: u32,
-}
+use backtrace::{BytesOrWideString, Frame, Symbol};
+
+pub const HEX_WIDTH: usize = 2 + 2 * mem::size_of::<usize>();
 
 /// Max number of frames to print.
 const MAX_NB_FRAMES: usize = 100;
@@ -49,7 +26,7 @@ pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
     // test mode immediately return here to optimize away any references to the
     // libbacktrace symbols
     if cfg!(test) {
-        return Ok(())
+        return Ok(());
     }
 
     // Use a lock to prevent mixed output in multithreading context.
@@ -63,75 +40,39 @@ pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
 }
 
 fn _print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
-    let mut frames = [Frame {
-        exact_position: ptr::null(),
-        symbol_addr: ptr::null(),
-        inline_context: 0,
-    }; MAX_NB_FRAMES];
-    let (nb_frames, context) = unwind_backtrace(&mut frames)?;
-    let (skipped_before, skipped_after) =
-        filter_frames(&frames[..nb_frames], format, &context);
-    if skipped_before + skipped_after > 0 {
-        writeln!(w, "note: Some details are omitted, \
-                     run with `RUST_BACKTRACE=full` for a verbose backtrace.")?;
-    }
     writeln!(w, "stack backtrace:")?;
 
-    let filtered_frames = &frames[..nb_frames - skipped_after];
-    for (index, frame) in filtered_frames.iter().skip(skipped_before).enumerate() {
-        resolve_symname(*frame, |symname| {
-            output(w, index, *frame, symname, format)
-        }, &context)?;
-        let has_more_filenames = foreach_symbol_fileline(*frame, |file, line| {
-            output_fileline(w, file, line, format)
-        }, &context)?;
-        if has_more_filenames {
-            w.write_all(b" <... and possibly more>")?;
-        }
-    }
-
-    Ok(())
-}
-
-/// Returns a number of frames to remove at the beginning and at the end of the
-/// backtrace, according to the backtrace format.
-fn filter_frames(frames: &[Frame],
-                 format: PrintFormat,
-                 context: &BacktraceContext) -> (usize, usize)
-{
-    if format == PrintFormat::Full {
-        return (0, 0);
-    }
-
-    let skipped_before = 0;
-
-    let skipped_after = frames.len() - frames.iter().position(|frame| {
-        let mut is_marker = false;
-        let _ = resolve_symname(*frame, |symname| {
-            if let Some(mangled_symbol_name) = symname {
-                // Use grep to find the concerned functions
-                if mangled_symbol_name.contains("__rust_begin_short_backtrace") {
-                    is_marker = true;
-                }
+    let mut printer = Printer::new(format, w);
+    unsafe {
+        backtrace::trace_unsynchronized(|frame| {
+            let mut hit = false;
+            backtrace::resolve_frame_unsynchronized(frame, |symbol| {
+                hit = true;
+                printer.output(frame, Some(symbol));
+            });
+            if !hit {
+                printer.output(frame, None);
             }
-            Ok(())
-        }, context);
-        is_marker
-    }).unwrap_or(frames.len());
-
-    if skipped_before + skipped_after >= frames.len() {
-        // Avoid showing completely empty backtraces
-        return (0, 0);
+            !printer.done
+        });
     }
-
-    (skipped_before, skipped_after)
+    if printer.skipped {
+        writeln!(
+            w,
+            "note: Some details are omitted, \
+             run with `RUST_BACKTRACE=full` for a verbose backtrace."
+        )?;
+    }
+    Ok(())
 }
 
-
 /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
 #[inline(never)]
 pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
-    where F: FnOnce() -> T, F: Send, T: Send
+where
+    F: FnOnce() -> T,
+    F: Send,
+    T: Send,
 {
     f()
 }
@@ -156,7 +97,7 @@ pub fn log_enabled() -> Option<PrintFormat> {
         _ => return Some(PrintFormat::Full),
     }
 
-    let val = env::var_os("RUST_BACKTRACE").and_then(|x|
+    let val = env::var_os("RUST_BACKTRACE").and_then(|x| {
         if &x == "0" {
             None
         } else if &x == "full" {
@@ -164,80 +105,141 @@ pub fn log_enabled() -> Option<PrintFormat> {
         } else {
             Some(PrintFormat::Short)
         }
+    });
+    ENABLED.store(
+        match val {
+            Some(v) => v as isize,
+            None => 1,
+        },
+        Ordering::SeqCst,
     );
-    ENABLED.store(match val {
-        Some(v) => v as isize,
-        None => 1,
-    }, Ordering::SeqCst);
     val
 }
 
-/// Prints the symbol of the backtrace frame.
-///
-/// These output functions should now be used everywhere to ensure consistency.
-/// You may want to also use `output_fileline`.
-fn output(w: &mut dyn Write, idx: usize, frame: Frame,
-              s: Option<&str>, format: PrintFormat) -> io::Result<()> {
-    // Remove the `17: 0x0 - <unknown>` line.
-    if format == PrintFormat::Short && frame.exact_position == ptr::null() {
-        return Ok(());
+struct Printer<'a, 'b> {
+    format: PrintFormat,
+    done: bool,
+    skipped: bool,
+    idx: usize,
+    out: &'a mut (dyn Write + 'b),
+}
+
+impl<'a, 'b> Printer<'a, 'b> {
+    fn new(format: PrintFormat, out: &'a mut (dyn Write + 'b)) -> Printer<'a, 'b> {
+        Printer { format, done: false, skipped: false, idx: 0, out }
     }
-    match format {
-        PrintFormat::Full => write!(w,
-                                    "  {:2}: {:2$?} - ",
-                                    idx,
-                                    frame.exact_position,
-                                    HEX_WIDTH)?,
-        PrintFormat::Short => write!(w, "  {:2}: ", idx)?,
+
+    /// Prints the symbol of the backtrace frame.
+    ///
+    /// These output functions should now be used everywhere to ensure consistency.
+    /// You may want to also use `output_fileline`.
+    fn output(&mut self, frame: &Frame, symbol: Option<&Symbol>) {
+        if self.idx > MAX_NB_FRAMES {
+            self.done = true;
+            self.skipped = true;
+            return;
+        }
+        if self._output(frame, symbol).is_err() {
+            self.done = true;
+        }
+        self.idx += 1;
     }
-    match s {
-        Some(string) => {
-            let symbol = demangle(string);
-            match format {
-                PrintFormat::Full => write!(w, "{}", symbol)?,
-                // strip the trailing hash if short mode
-                PrintFormat::Short => write!(w, "{:#}", symbol)?,
+
+    fn _output(&mut self, frame: &Frame, symbol: Option<&Symbol>) -> io::Result<()> {
+        if self.format == PrintFormat::Short {
+            if let Some(sym) = symbol.and_then(|s| s.name()).and_then(|s| s.as_str()) {
+                if sym.contains("__rust_begin_short_backtrace") {
+                    self.skipped = true;
+                    self.done = true;
+                    return Ok(());
+                }
+            }
+
+            // Remove the `17: 0x0 - <unknown>` line.
+            if self.format == PrintFormat::Short && frame.ip() == ptr::null_mut() {
+                self.skipped = true;
+                return Ok(());
             }
         }
-        None => w.write_all(b"<unknown>")?,
-    }
-    w.write_all(b"\n")
-}
 
-/// Prints the filename and line number of the backtrace frame.
-///
-/// See also `output`.
-#[allow(dead_code)]
-fn output_fileline(w: &mut dyn Write,
-                   file: &[u8],
-                   line: u32,
-                   format: PrintFormat) -> io::Result<()> {
-    // prior line: "  ##: {:2$} - func"
-    w.write_all(b"")?;
-    match format {
-        PrintFormat::Full => write!(w,
-                                    "           {:1$}",
-                                    "",
-                                    HEX_WIDTH)?,
-        PrintFormat::Short => write!(w, "           ")?,
-    }
+        match self.format {
+            PrintFormat::Full => {
+                write!(self.out, "  {:2}: {:2$?} - ", self.idx, frame.ip(), HEX_WIDTH)?
+            }
+            PrintFormat::Short => write!(self.out, "  {:2}: ", self.idx)?,
+        }
 
-    let file = str::from_utf8(file).unwrap_or("<unknown>");
-    let file_path = Path::new(file);
-    let mut already_printed = false;
-    if format == PrintFormat::Short && file_path.is_absolute() {
-        if let Ok(cwd) = env::current_dir() {
-            if let Ok(stripped) = file_path.strip_prefix(&cwd) {
-                if let Some(s) = stripped.to_str() {
-                    write!(w, "  at .{}{}:{}", path::MAIN_SEPARATOR, s, line)?;
-                    already_printed = true;
+        match symbol.and_then(|s| s.name()) {
+            Some(symbol) => {
+                match self.format {
+                    PrintFormat::Full => write!(self.out, "{}", symbol)?,
+                    // Strip the trailing hash if short mode.
+                    PrintFormat::Short => write!(self.out, "{:#}", symbol)?,
                 }
             }
+            None => self.out.write_all(b"<unknown>")?,
         }
-    }
-    if !already_printed {
-        write!(w, "  at {}:{}", file, line)?;
+        self.out.write_all(b"\n")?;
+        if let Some(sym) = symbol {
+            self.output_fileline(sym)?;
+        }
+        Ok(())
     }
 
-    w.write_all(b"\n")
+    /// Prints the filename and line number of the backtrace frame.
+    ///
+    /// See also `output`.
+    fn output_fileline(&mut self, symbol: &Symbol) -> io::Result<()> {
+        #[cfg(windows)]
+        let path_buf;
+        let file = match symbol.filename_raw() {
+            #[cfg(unix)]
+            Some(BytesOrWideString::Bytes(bytes)) => {
+                use crate::os::unix::prelude::*;
+                Path::new(crate::ffi::OsStr::from_bytes(bytes))
+            }
+            #[cfg(not(unix))]
+            Some(BytesOrWideString::Bytes(bytes)) => {
+                Path::new(crate::str::from_utf8(bytes).unwrap_or("<unknown>"))
+            }
+            #[cfg(windows)]
+            Some(BytesOrWideString::Wide(wide)) => {
+                use crate::os::windows::prelude::*;
+                path_buf = crate::ffi::OsString::from_wide(wide);
+                Path::new(&path_buf)
+            }
+            #[cfg(not(windows))]
+            Some(BytesOrWideString::Wide(_wide)) => {
+                Path::new("<unknown>")
+            }
+            None => return Ok(()),
+        };
+        let line = match symbol.lineno() {
+            Some(line) => line,
+            None => return Ok(()),
+        };
+        // prior line: "  ##: {:2$} - func"
+        self.out.write_all(b"")?;
+        match self.format {
+            PrintFormat::Full => write!(self.out, "           {:1$}", "", HEX_WIDTH)?,
+            PrintFormat::Short => write!(self.out, "           ")?,
+        }
+
+        let mut already_printed = false;
+        if self.format == PrintFormat::Short && file.is_absolute() {
+            if let Ok(cwd) = env::current_dir() {
+                if let Ok(stripped) = file.strip_prefix(&cwd) {
+                    if let Some(s) = stripped.to_str() {
+                        write!(self.out, "  at .{}{}:{}", path::MAIN_SEPARATOR, s, line)?;
+                        already_printed = true;
+                    }
+                }
+            }
+        }
+        if !already_printed {
+            write!(self.out, "  at {}:{}", file.display(), line)?;
+        }
+
+        self.out.write_all(b"\n")
+    }
 }
diff --git a/src/libstd/sys_common/gnu/libbacktrace.rs b/src/libstd/sys_common/gnu/libbacktrace.rs
deleted file mode 100644
index 6cd050242dd..00000000000
--- a/src/libstd/sys_common/gnu/libbacktrace.rs
+++ /dev/null
@@ -1,175 +0,0 @@
-use backtrace_sys::backtrace_state;
-
-use crate::ffi::CStr;
-use crate::io;
-use crate::mem;
-use crate::ptr;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-pub fn foreach_symbol_fileline<F>(frame: Frame,
-                                  mut f: F,
-                                  _: &BacktraceContext) -> io::Result<bool>
-where F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    // pcinfo may return an arbitrary number of file:line pairs,
-    // in the order of stack trace (i.e., inlined calls first).
-    // in order to avoid allocation, we stack-allocate a fixed size of entries.
-    const FILELINE_SIZE: usize = 32;
-    let mut fileline_buf = [(ptr::null(), !0); FILELINE_SIZE];
-    let ret;
-    let fileline_count = {
-        let state = unsafe { init_state() };
-        if state.is_null() {
-            return Err(io::Error::new(
-                io::ErrorKind::Other,
-                "failed to allocate libbacktrace state")
-            )
-        }
-        let mut fileline_win: &mut [FileLine] = &mut fileline_buf;
-        let fileline_addr = &mut fileline_win as *mut &mut [FileLine];
-        ret = unsafe {
-            backtrace_sys::backtrace_pcinfo(
-                state,
-                frame.exact_position as libc::uintptr_t,
-                pcinfo_cb,
-                error_cb,
-                fileline_addr as *mut libc::c_void,
-            )
-        };
-        FILELINE_SIZE - fileline_win.len()
-    };
-    if ret == 0 {
-        for &(file, line) in &fileline_buf[..fileline_count] {
-            if file.is_null() { continue; } // just to be sure
-            let file = unsafe { CStr::from_ptr(file).to_bytes() };
-            f(file, line)?;
-        }
-        Ok(fileline_count == FILELINE_SIZE)
-    } else {
-        Ok(false)
-    }
-}
-
-/// Converts a pointer to symbol to its string value.
-pub fn resolve_symname<F>(frame: Frame,
-                          callback: F,
-                          _: &BacktraceContext) -> io::Result<()>
-    where F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    let symname = {
-        let state = unsafe { init_state() };
-        if state.is_null() {
-            return Err(io::Error::new(
-                io::ErrorKind::Other,
-                "failed to allocate libbacktrace state")
-            )
-        }
-        let mut data: *const libc::c_char = ptr::null();
-        let data_addr = &mut data as *mut *const libc::c_char;
-        let ret = unsafe {
-            backtrace_sys::backtrace_syminfo(
-                state,
-                frame.symbol_addr as libc::uintptr_t,
-                syminfo_cb,
-                error_cb,
-                data_addr as *mut libc::c_void,
-            )
-        };
-        if ret == 0 || data.is_null() {
-            None
-        } else {
-            unsafe {
-                CStr::from_ptr(data).to_str().ok()
-            }
-        }
-    };
-    callback(symname)
-}
-
-////////////////////////////////////////////////////////////////////////
-// helper callbacks
-////////////////////////////////////////////////////////////////////////
-
-type FileLine = (*const libc::c_char, u32);
-
-extern fn error_cb(_data: *mut libc::c_void, _msg: *const libc::c_char,
-                   _errnum: libc::c_int) {
-    // do nothing for now
-}
-extern fn syminfo_cb(data: *mut libc::c_void,
-                     _pc: libc::uintptr_t,
-                     symname: *const libc::c_char,
-                     _symval: libc::uintptr_t,
-                     _symsize: libc::uintptr_t) {
-    let slot = data as *mut *const libc::c_char;
-    unsafe { *slot = symname; }
-}
-extern fn pcinfo_cb(data: *mut libc::c_void,
-                    _pc: libc::uintptr_t,
-                    filename: *const libc::c_char,
-                    lineno: libc::c_int,
-                    _function: *const libc::c_char) -> libc::c_int {
-    if !filename.is_null() {
-        let slot = data as *mut &mut [FileLine];
-        let buffer = unsafe {ptr::read(slot)};
-
-        // if the buffer is not full, add file:line to the buffer
-        // and adjust the buffer for next possible calls to pcinfo_cb.
-        if !buffer.is_empty() {
-            buffer[0] = (filename, lineno as u32);
-            unsafe { ptr::write(slot, &mut buffer[1..]); }
-        }
-    }
-
-    0
-}
-
-// The libbacktrace API supports creating a state, but it does not
-// support destroying a state. I personally take this to mean that a
-// state is meant to be created and then live forever.
-//
-// I would love to register an at_exit() handler which cleans up this
-// state, but libbacktrace provides no way to do so.
-//
-// With these constraints, this function has a statically cached state
-// that is calculated the first time this is requested. Remember that
-// backtracing all happens serially (one global lock).
-//
-// Things don't work so well on not-Linux since libbacktrace can't track
-// down that executable this is. We at one point used env::current_exe but
-// it turns out that there are some serious security issues with that
-// approach.
-//
-// Specifically, on certain platforms like BSDs, a malicious actor can cause
-// an arbitrary file to be placed at the path returned by current_exe.
-// libbacktrace does not behave defensively in the presence of ill-formed
-// DWARF information, and has been demonstrated to segfault in at least one
-// case. There is no evidence at the moment to suggest that a more carefully
-// constructed file can't cause arbitrary code execution. As a result of all
-// of this, we don't hint libbacktrace with the path to the current process.
-unsafe fn init_state() -> *mut backtrace_state {
-    static mut STATE: *mut backtrace_state = ptr::null_mut();
-    if !STATE.is_null() { return STATE  }
-
-    let filename = match crate::sys::backtrace::gnu::get_executable_filename() {
-        Ok((filename, file)) => {
-            // filename is purposely leaked here since libbacktrace requires
-            // it to stay allocated permanently, file is also leaked so that
-            // the file stays locked
-            let filename_ptr = filename.as_ptr();
-            mem::forget(filename);
-            mem::forget(file);
-            filename_ptr
-        },
-        Err(_) => ptr::null(),
-    };
-
-    STATE = backtrace_sys::backtrace_create_state(
-        filename,
-        0,
-        error_cb,
-        ptr::null_mut(),
-    );
-    STATE
-}
diff --git a/src/libstd/sys_common/gnu/mod.rs b/src/libstd/sys_common/gnu/mod.rs
deleted file mode 100644
index d6959697f2a..00000000000
--- a/src/libstd/sys_common/gnu/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-#![allow(missing_docs)]
-#![allow(non_camel_case_types)]
-#![allow(non_snake_case)]
-
-pub mod libbacktrace;
diff --git a/src/libstd/sys_common/io.rs b/src/libstd/sys_common/io.rs
index 44b0963302d..8789abe55c3 100644
--- a/src/libstd/sys_common/io.rs
+++ b/src/libstd/sys_common/io.rs
@@ -16,7 +16,7 @@ pub mod test {
             p.join(path)
         }
 
-        pub fn path<'a>(&'a self) -> &'a Path {
+        pub fn path(&self) -> &Path {
             let TempDir(ref p) = *self;
             p
         }
diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs
index 78e15994264..9190a3b0d5f 100644
--- a/src/libstd/sys_common/mod.rs
+++ b/src/libstd/sys_common/mod.rs
@@ -65,10 +65,9 @@ pub mod bytestring;
 pub mod process;
 pub mod fs;
 
-cfg_if! {
+cfg_if::cfg_if! {
     if #[cfg(any(target_os = "cloudabi",
                  target_os = "l4re",
-                 target_os = "redox",
                  all(target_arch = "wasm32", not(target_os = "emscripten")),
                  all(target_vendor = "fortanix", target_env = "sgx")))] {
         pub use crate::sys::net;
@@ -77,12 +76,6 @@ cfg_if! {
     }
 }
 
-#[cfg(feature = "backtrace")]
-#[cfg(any(all(unix, not(target_os = "emscripten")),
-          all(windows, target_env = "gnu"),
-          target_os = "redox"))]
-pub mod gnu;
-
 // common error constructors
 
 /// A trait for viewing representations from std types
diff --git a/src/libstd/sys_common/os_str_bytes.rs b/src/libstd/sys_common/os_str_bytes.rs
index a4961974d89..d734f412bf8 100644
--- a/src/libstd/sys_common/os_str_bytes.rs
+++ b/src/libstd/sys_common/os_str_bytes.rs
@@ -18,6 +18,12 @@ pub(crate) struct Buf {
     pub inner: Vec<u8>
 }
 
+// FIXME:
+// `Buf::as_slice` current implementation relies
+// on `Slice` being layout-compatible with `[u8]`.
+// When attribute privacy is implemented, `Slice` should be annotated as `#[repr(transparent)]`.
+// Anyway, `Slice` representation and layout are considered implementation detail, are
+// not documented and must not be relied upon.
 pub(crate) struct Slice {
     pub inner: [u8]
 }
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index bfc1deddf7b..f85b5d632f1 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -2,10 +2,8 @@
 
 #![unstable(feature = "thread_local_internals", issue = "0")]
 
-use crate::cell::UnsafeCell;
+use crate::error::Error;
 use crate::fmt;
-use crate::hint;
-use crate::mem;
 
 /// A thread local storage key which owns its contents.
 ///
@@ -92,10 +90,7 @@ pub struct LocalKey<T: 'static> {
     // trivially devirtualizable by LLVM because the value of `inner` never
     // changes and the constant should be readonly within a crate. This mainly
     // only runs into problems when TLS statics are exported across crates.
-    inner: unsafe fn() -> Option<&'static UnsafeCell<Option<T>>>,
-
-    // initialization routine to invoke to create a value
-    init: fn() -> T,
+    inner: unsafe fn() -> Option<&'static T>,
 }
 
 #[stable(feature = "std_debug", since = "1.16.0")]
@@ -159,10 +154,7 @@ macro_rules! __thread_local_inner {
             #[inline]
             fn __init() -> $t { $init }
 
-            unsafe fn __getit() -> $crate::option::Option<
-                &'static $crate::cell::UnsafeCell<
-                    $crate::option::Option<$t>>>
-            {
+            unsafe fn __getit() -> $crate::option::Option<&'static $t> {
                 #[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
                 static __KEY: $crate::thread::__StaticLocalKeyInner<$t> =
                     $crate::thread::__StaticLocalKeyInner::new();
@@ -182,11 +174,11 @@ macro_rules! __thread_local_inner {
                 static __KEY: $crate::thread::__OsLocalKeyInner<$t> =
                     $crate::thread::__OsLocalKeyInner::new();
 
-                __KEY.get()
+                __KEY.get(__init)
             }
 
             unsafe {
-                $crate::thread::LocalKey::new(__getit, __init)
+                $crate::thread::LocalKey::new(__getit)
             }
         }
     };
@@ -198,6 +190,7 @@ macro_rules! __thread_local_inner {
 
 /// An error returned by [`LocalKey::try_with`](struct.LocalKey.html#method.try_with).
 #[stable(feature = "thread_local_try_with", since = "1.26.0")]
+#[derive(Clone, Copy, Eq, PartialEq)]
 pub struct AccessError {
     _private: (),
 }
@@ -216,16 +209,17 @@ impl fmt::Display for AccessError {
     }
 }
 
+#[stable(feature = "thread_local_try_with", since = "1.26.0")]
+impl Error for AccessError {}
+
 impl<T: 'static> LocalKey<T> {
     #[doc(hidden)]
     #[unstable(feature = "thread_local_internals",
                reason = "recently added to create a key",
                issue = "0")]
-    pub const unsafe fn new(inner: unsafe fn() -> Option<&'static UnsafeCell<Option<T>>>,
-                            init: fn() -> T) -> LocalKey<T> {
+    pub const unsafe fn new(inner: unsafe fn() -> Option<&'static T>) -> LocalKey<T> {
         LocalKey {
             inner,
-            init,
         }
     }
 
@@ -246,37 +240,6 @@ impl<T: 'static> LocalKey<T> {
                                  after it is destroyed")
     }
 
-    unsafe fn init(&self, slot: &UnsafeCell<Option<T>>) -> &T {
-        // Execute the initialization up front, *then* move it into our slot,
-        // just in case initialization fails.
-        let value = (self.init)();
-        let ptr = slot.get();
-
-        // note that this can in theory just be `*ptr = Some(value)`, but due to
-        // the compiler will currently codegen that pattern with something like:
-        //
-        //      ptr::drop_in_place(ptr)
-        //      ptr::write(ptr, Some(value))
-        //
-        // Due to this pattern it's possible for the destructor of the value in
-        // `ptr` (e.g., if this is being recursively initialized) to re-access
-        // TLS, in which case there will be a `&` and `&mut` pointer to the same
-        // value (an aliasing violation). To avoid setting the "I'm running a
-        // destructor" flag we just use `mem::replace` which should sequence the
-        // operations a little differently and make this safe to call.
-        mem::replace(&mut *ptr, Some(value));
-
-        // After storing `Some` we want to get a reference to the contents of
-        // what we just stored. While we could use `unwrap` here and it should
-        // always work it empirically doesn't seem to always get optimized away,
-        // which means that using something like `try_with` can pull in
-        // panicking code and cause a large size bloat.
-        match *ptr {
-            Some(ref x) => x,
-            None => hint::unreachable_unchecked(),
-        }
-    }
-
     /// Acquires a reference to the value in this TLS key.
     ///
     /// This will lazily initialize the value if this thread has not referenced
@@ -293,13 +256,68 @@ impl<T: 'static> LocalKey<T> {
         F: FnOnce(&T) -> R,
     {
         unsafe {
-            let slot = (self.inner)().ok_or(AccessError {
+            let thread_local = (self.inner)().ok_or(AccessError {
                 _private: (),
             })?;
-            Ok(f(match *slot.get() {
-                Some(ref inner) => inner,
-                None => self.init(slot),
-            }))
+            Ok(f(thread_local))
+        }
+    }
+}
+
+mod lazy {
+    use crate::cell::UnsafeCell;
+    use crate::mem;
+    use crate::hint;
+
+    pub struct LazyKeyInner<T> {
+        inner: UnsafeCell<Option<T>>,
+    }
+
+    impl<T> LazyKeyInner<T> {
+        pub const fn new() -> LazyKeyInner<T> {
+            LazyKeyInner {
+                inner: UnsafeCell::new(None),
+            }
+        }
+
+        pub unsafe fn get(&self) -> Option<&'static T> {
+            (*self.inner.get()).as_ref()
+        }
+
+        pub unsafe fn initialize<F: FnOnce() -> T>(&self, init: F) -> &'static T {
+            // Execute the initialization up front, *then* move it into our slot,
+            // just in case initialization fails.
+            let value = init();
+            let ptr = self.inner.get();
+
+            // note that this can in theory just be `*ptr = Some(value)`, but due to
+            // the compiler will currently codegen that pattern with something like:
+            //
+            //      ptr::drop_in_place(ptr)
+            //      ptr::write(ptr, Some(value))
+            //
+            // Due to this pattern it's possible for the destructor of the value in
+            // `ptr` (e.g., if this is being recursively initialized) to re-access
+            // TLS, in which case there will be a `&` and `&mut` pointer to the same
+            // value (an aliasing violation). To avoid setting the "I'm running a
+            // destructor" flag we just use `mem::replace` which should sequence the
+            // operations a little differently and make this safe to call.
+            mem::replace(&mut *ptr, Some(value));
+
+            // After storing `Some` we want to get a reference to the contents of
+            // what we just stored. While we could use `unwrap` here and it should
+            // always work it empirically doesn't seem to always get optimized away,
+            // which means that using something like `try_with` can pull in
+            // panicking code and cause a large size bloat.
+            match *ptr {
+                Some(ref x) => x,
+                None => hint::unreachable_unchecked(),
+            }
+        }
+
+        #[allow(unused)]
+        pub unsafe fn take(&mut self) -> Option<T> {
+            (*self.inner.get()).take()
         }
     }
 }
@@ -309,11 +327,11 @@ impl<T: 'static> LocalKey<T> {
 #[doc(hidden)]
 #[cfg(all(target_arch = "wasm32", not(target_feature = "atomics")))]
 pub mod statik {
-    use crate::cell::UnsafeCell;
+    use super::lazy::LazyKeyInner;
     use crate::fmt;
 
     pub struct Key<T> {
-        inner: UnsafeCell<Option<T>>,
+        inner: LazyKeyInner<T>,
     }
 
     unsafe impl<T> Sync for Key<T> { }
@@ -327,12 +345,16 @@ pub mod statik {
     impl<T> Key<T> {
         pub const fn new() -> Key<T> {
             Key {
-                inner: UnsafeCell::new(None),
+                inner: LazyKeyInner::new(),
             }
         }
 
-        pub unsafe fn get(&self) -> Option<&'static UnsafeCell<Option<T>>> {
-            Some(&*(&self.inner as *const _))
+        pub unsafe fn get(&self, init: fn() -> T) -> Option<&'static T> {
+            let value = match self.inner.get() {
+                Some(ref value) => value,
+                None => self.inner.initialize(init),
+            };
+            Some(value)
         }
     }
 }
@@ -340,19 +362,38 @@ pub mod statik {
 #[doc(hidden)]
 #[cfg(target_thread_local)]
 pub mod fast {
-    use crate::cell::{Cell, UnsafeCell};
+    use super::lazy::LazyKeyInner;
+    use crate::cell::Cell;
     use crate::fmt;
     use crate::mem;
-    use crate::ptr;
-    use crate::sys::fast_thread_local::{register_dtor, requires_move_before_drop};
+    use crate::sys::fast_thread_local::register_dtor;
+
+    #[derive(Copy, Clone)]
+    enum DtorState {
+        Unregistered,
+        Registered,
+        RunningOrHasRun,
+    }
 
+    // This data structure has been carefully constructed so that the fast path
+    // only contains one branch on x86. That optimization is necessary to avoid
+    // duplicated tls lookups on OSX.
+    //
+    // LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
     pub struct Key<T> {
-        inner: UnsafeCell<Option<T>>,
+        // If `LazyKeyInner::get` returns `None`, that indicates either:
+        //   * The value has never been initialized
+        //   * The value is being recursively initialized
+        //   * The value has already been destroyed or is being destroyed
+        // To determine which kind of `None`, check `dtor_state`.
+        //
+        // This is very optimizer friendly for the fast path - initialized but
+        // not yet dropped.
+        inner: LazyKeyInner<T>,
 
         // Metadata to keep track of the state of the destructor. Remember that
-        // these variables are thread-local, not global.
-        dtor_registered: Cell<bool>,
-        dtor_running: Cell<bool>,
+        // this variable is thread-local, not global.
+        dtor_state: Cell<DtorState>,
     }
 
     impl<T> fmt::Debug for Key<T> {
@@ -364,54 +405,75 @@ pub mod fast {
     impl<T> Key<T> {
         pub const fn new() -> Key<T> {
             Key {
-                inner: UnsafeCell::new(None),
-                dtor_registered: Cell::new(false),
-                dtor_running: Cell::new(false)
+                inner: LazyKeyInner::new(),
+                dtor_state: Cell::new(DtorState::Unregistered),
             }
         }
 
-        pub unsafe fn get(&self) -> Option<&'static UnsafeCell<Option<T>>> {
-            if mem::needs_drop::<T>() && self.dtor_running.get() {
-                return None
+        pub unsafe fn get<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
+            match self.inner.get() {
+                Some(val) => Some(val),
+                None => self.try_initialize(init),
             }
-            self.register_dtor();
-            Some(&*(&self.inner as *const _))
         }
 
-        unsafe fn register_dtor(&self) {
-            if !mem::needs_drop::<T>() || self.dtor_registered.get() {
-                return
+        // `try_initialize` is only called once per fast thread local variable,
+        // except in corner cases where thread_local dtors reference other
+        // thread_local's, or it is being recursively initialized.
+        //
+        // Macos: Inlining this function can cause two `tlv_get_addr` calls to
+        // be performed for every call to `Key::get`. The #[cold] hint makes
+        // that less likely.
+        // LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
+        #[cold]
+        unsafe fn try_initialize<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
+            if !mem::needs_drop::<T>() || self.try_register_dtor() {
+                Some(self.inner.initialize(init))
+            } else {
+                None
             }
+        }
 
-            register_dtor(self as *const _ as *mut u8,
-                          destroy_value::<T>);
-            self.dtor_registered.set(true);
+        // `try_register_dtor` is only called once per fast thread local
+        // variable, except in corner cases where thread_local dtors reference
+        // other thread_local's, or it is being recursively initialized.
+        unsafe fn try_register_dtor(&self) -> bool {
+            match self.dtor_state.get() {
+                DtorState::Unregistered => {
+                    // dtor registration happens before initialization.
+                    register_dtor(self as *const _ as *mut u8,
+                                destroy_value::<T>);
+                    self.dtor_state.set(DtorState::Registered);
+                    true
+                }
+                DtorState::Registered => {
+                    // recursively initialized
+                    true
+                }
+                DtorState::RunningOrHasRun => {
+                    false
+                }
+            }
         }
     }
 
     unsafe extern fn destroy_value<T>(ptr: *mut u8) {
         let ptr = ptr as *mut Key<T>;
-        // Right before we run the user destructor be sure to flag the
-        // destructor as running for this thread so calls to `get` will return
-        // `None`.
-        (*ptr).dtor_running.set(true);
 
-        // Some implementations may require us to move the value before we drop
-        // it as it could get re-initialized in-place during destruction.
-        //
-        // Hence, we use `ptr::read` on those platforms (to move to a "safe"
-        // location) instead of drop_in_place.
-        if requires_move_before_drop() {
-            ptr::read((*ptr).inner.get());
-        } else {
-            ptr::drop_in_place((*ptr).inner.get());
-        }
+        // Right before we run the user destructor be sure to set the
+        // `Option<T>` to `None`, and `dtor_state` to `RunningOrHasRun`. This
+        // causes future calls to `get` to run `try_initialize_drop` again,
+        // which will now fail, and return `None`.
+        let value = (*ptr).inner.take();
+        (*ptr).dtor_state.set(DtorState::RunningOrHasRun);
+        drop(value);
     }
 }
 
 #[doc(hidden)]
 pub mod os {
-    use crate::cell::{Cell, UnsafeCell};
+    use super::lazy::LazyKeyInner;
+    use crate::cell::Cell;
     use crate::fmt;
     use crate::marker;
     use crate::ptr;
@@ -432,8 +494,8 @@ pub mod os {
     unsafe impl<T> Sync for Key<T> { }
 
     struct Value<T: 'static> {
+        inner: LazyKeyInner<T>,
         key: &'static Key<T>,
-        value: UnsafeCell<Option<T>>,
     }
 
     impl<T: 'static> Key<T> {
@@ -444,24 +506,43 @@ pub mod os {
             }
         }
 
-        pub unsafe fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
+        pub unsafe fn get(&'static self, init: fn() -> T) -> Option<&'static T> {
             let ptr = self.os.get() as *mut Value<T>;
-            if !ptr.is_null() {
-                if ptr as usize == 1 {
-                    return None
+            if ptr as usize > 1 {
+                match (*ptr).inner.get() {
+                    Some(ref value) => return Some(value),
+                    None => {},
                 }
-                return Some(&(*ptr).value);
             }
+            self.try_initialize(init)
+        }
 
-            // If the lookup returned null, we haven't initialized our own
-            // local copy, so do that now.
-            let ptr: Box<Value<T>> = box Value {
-                key: self,
-                value: UnsafeCell::new(None),
+        // `try_initialize` is only called once per os thread local variable,
+        // except in corner cases where thread_local dtors reference other
+        // thread_local's, or it is being recursively initialized.
+        unsafe fn try_initialize(&'static self, init: fn() -> T) -> Option<&'static T> {
+            let ptr = self.os.get() as *mut Value<T>;
+            if ptr as usize == 1 {
+                // destructor is running
+                return None
+            }
+
+            let ptr = if ptr.is_null() {
+                // If the lookup returned null, we haven't initialized our own
+                // local copy, so do that now.
+                let ptr: Box<Value<T>> = box Value {
+                    inner: LazyKeyInner::new(),
+                    key: self,
+                };
+                let ptr = Box::into_raw(ptr);
+                self.os.set(ptr as *mut u8);
+                ptr
+            } else {
+                // recursive initialization
+                ptr
             };
-            let ptr = Box::into_raw(ptr);
-            self.os.set(ptr as *mut u8);
-            Some(&(*ptr).value)
+
+            Some((*ptr).inner.initialize(init))
         }
     }
 
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index fce28ffd9c3..764041d2f42 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
@@ -1741,6 +1742,6 @@ mod tests {
         assert!(thread::current().id() != spawned_id);
     }
 
-    // NOTE: the corresponding test for stderr is in run-pass/thread-stderr, due
+    // NOTE: the corresponding test for stderr is in ui/thread-stderr, due
     // to the test harness apparently interfering with stderr configuration.
 }
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index dc97f8c04a8..98371b9ba3d 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -396,6 +396,7 @@ impl SystemTime {
     /// This function may fail because measurements taken earlier are not
     /// guaranteed to always be before later measurements (due to anomalies such
     /// as the system clock being adjusted either forwards or backwards).
+    /// [`Instant`] can be used to measure elapsed time without this risk of failure.
     ///
     /// If successful, [`Ok`]`(`[`Duration`]`)` is returned where the duration represents
     /// the amount of time elapsed from the specified measurement to this one.
@@ -406,6 +407,7 @@ impl SystemTime {
     /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
     /// [`Duration`]: ../../std/time/struct.Duration.html
     /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
+    /// [`Instant`]: ../../std/time/struct.Instant.html
     ///
     /// # Examples
     ///
@@ -414,7 +416,7 @@ impl SystemTime {
     ///
     /// let sys_time = SystemTime::now();
     /// let difference = sys_time.duration_since(sys_time)
-    ///                          .expect("SystemTime::duration_since failed");
+    ///                          .expect("Clock may have gone backwards");
     /// println!("{:?}", difference);
     /// ```
     #[stable(feature = "time2", since = "1.8.0")]
@@ -423,7 +425,8 @@ impl SystemTime {
         self.0.sub_time(&earlier.0).map_err(SystemTimeError)
     }
 
-    /// Returns the amount of time elapsed since this system time was created.
+    /// Returns the difference between the clock time when this
+    /// system time was created, and the current clock time.
     ///
     /// This function may fail as the underlying system clock is susceptible to
     /// drift and updates (e.g., the system clock could go backwards), so this
@@ -431,12 +434,15 @@ impl SystemTime {
     /// returned where the duration represents the amount of time elapsed from
     /// this time measurement to the current time.
     ///
+    /// To measure elapsed time reliably, use [`Instant`] instead.
+    ///
     /// Returns an [`Err`] if `self` is later than the current system time, and
     /// the error contains how far from the current system time `self` is.
     ///
     /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
     /// [`Duration`]: ../../std/time/struct.Duration.html
     /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
+    /// [`Instant`]: ../../std/time/struct.Instant.html
     ///
     /// # Examples
     ///