about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-07-26 16:57:54 +0000
committerbors <bors@rust-lang.org>2019-07-26 16:57:54 +0000
commitc43753f910aae000f8bcb0a502407ea332afc74b (patch)
treead563761b27efd2cbab0ade95c5139aaccb93494 /src
parent1a563362865e6051d4c350544131228e8eff5138 (diff)
parent232d27c306d76d2f973c88b0e0d1883aac8717f4 (diff)
downloadrust-c43753f910aae000f8bcb0a502407ea332afc74b.tar.gz
rust-c43753f910aae000f8bcb0a502407ea332afc74b.zip
Auto merge of #63015 - Centril:rollup-ydhpcas, r=Centril
Rollup of 22 pull requests

Successful merges:

 - #62084 (allow clippy::unreadable_literal in unicode tables)
 - #62120 (Add missing type links in documentation)
 - #62310 (Add missing doc links in boxed module)
 - #62421 (Introduce `as_deref` to Option)
 - #62583 (Implement Unpin for all raw pointers)
 - #62692 (rustc: precompute the largest Niche and store it in LayoutDetails.)
 - #62801 (Remove support for -Zlower-128bit-ops)
 - #62828 (Remove vector fadd/fmul reduction workarounds)
 - #62862 (code cleanup)
 - #62904 (Disable d32 on armv6 hf targets)
 - #62907 (Initialize the MSP430 AsmParser)
 - #62956 (Implement slow-path for FirstSets::first)
 - #62963 (Allow lexer to recover from some homoglyphs)
 - #62964 (clarify and unify some type test names)
 - #62970 (ci: gate toolstate repo pushes on the TOOLSTATE_PUBLISH envvar)
 - #62980 (std: Add more accessors for `Metadata` on Windows)
 - #62983 (Remove needless indirection through Rc)
 - #62985 (librustc_errors: Support ui-testing flag in annotate-snippet emitter)
 - #63002 (error_index_generator should output stdout/stderr when it panics.)
 - #63004 (Add test for issue-54062)
 - #63007 (ci: debug network failures while downloading awscli from PyPI)
 - #63009 (Remove redundant `mut` from variable declaration.)

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/test.rs2
-rwxr-xr-xsrc/ci/docker/x86_64-gnu-tools/checktools.sh2
-rw-r--r--src/liballoc/boxed.rs14
-rw-r--r--src/libcore/cmp.rs2
-rw-r--r--src/libcore/marker.rs6
-rw-r--r--src/libcore/option.rs17
-rw-r--r--src/libcore/pin.rs144
-rw-r--r--src/libcore/result.rs65
-rw-r--r--src/libcore/tests/option.rs30
-rw-r--r--src/libcore/tests/result.rs185
-rw-r--r--src/libcore/unicode/tables.rs2
-rwxr-xr-xsrc/libcore/unicode/unicode.py2
-rw-r--r--src/librustc/hir/print.rs2
-rw-r--r--src/librustc/middle/lang_items.rs28
-rw-r--r--src/librustc/session/config.rs4
-rw-r--r--src/librustc/ty/context.rs36
-rw-r--r--src/librustc/ty/layout.rs227
-rw-r--r--src/librustc/ty/sty.rs4
-rw-r--r--src/librustc_codegen_llvm/builder.rs12
-rw-r--r--src/librustc_codegen_llvm/common.rs19
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs28
-rw-r--r--src/librustc_codegen_llvm/llvm/ffi.rs2
-rw-r--r--src/librustc_errors/Cargo.toml2
-rw-r--r--src/librustc_errors/annotate_snippet_emitter_writer.rs8
-rw-r--r--src/librustc_llvm/build.rs4
-rw-r--r--src/librustc_llvm/lib.rs2
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs2
-rw-r--r--src/librustc_mir/borrow_check/mod.rs2
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs4
-rw-r--r--src/librustc_mir/interpret/intrinsics.rs15
-rw-r--r--src/librustc_mir/transform/inline.rs7
-rw-r--r--src/librustc_mir/transform/lower_128bit.rs230
-rw-r--r--src/librustc_mir/transform/mod.rs3
-rw-r--r--src/librustc_target/abi/mod.rs71
-rw-r--r--src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs2
-rw-r--r--src/librustc_target/spec/arm_unknown_linux_musleabihf.rs2
-rw-r--r--src/librustc_target/spec/armv6_unknown_freebsd.rs2
-rw-r--r--src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs2
-rw-r--r--src/librustc_target/spec/mod.rs5
-rw-r--r--src/librustc_typeck/check/expr.rs4
-rw-r--r--src/librustc_typeck/check/method/suggest.rs2
-rw-r--r--src/librustdoc/html/render.rs10
-rw-r--r--src/libstd/sys/vxworks/alloc.rs30
-rw-r--r--src/libstd/sys/vxworks/android.rs160
-rw-r--r--src/libstd/sys/vxworks/condvar.rs73
-rw-r--r--src/libstd/sys/vxworks/ext/net.rs27
-rw-r--r--src/libstd/sys/vxworks/l4re.rs469
-rw-r--r--src/libstd/sys/vxworks/memchr.rs19
-rw-r--r--src/libstd/sys/vxworks/mod.rs14
-rw-r--r--src/libstd/sys/vxworks/net.rs13
-rw-r--r--src/libstd/sys/vxworks/process/process_common.rs34
-rw-r--r--src/libstd/sys/vxworks/stack_overflow.rs168
-rw-r--r--src/libstd/sys/vxworks/thread.rs36
-rw-r--r--src/libstd/sys/windows/ext/fs.rs30
-rw-r--r--src/libstd/sys/windows/fs.rs55
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs8
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs57
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs24
-rw-r--r--src/libsyntax/parse/lexer/mod.rs14
-rw-r--r--src/libsyntax/parse/lexer/unicode_chars.rs73
-rw-r--r--src/test/mir-opt/lower_128bit_debug_test.rs226
-rw-r--r--src/test/mir-opt/lower_128bit_test.rs149
-rw-r--r--src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs10
-rw-r--r--src/test/ui/annotate-snippet/missing-type.stderr10
-rw-r--r--src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs1
-rw-r--r--src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr11
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr12
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr12
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.stderr12
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr12
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr12
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr12
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr12
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr12
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr12
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr12
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.stderr12
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.rs6
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.stderr12
-rw-r--r--src/test/ui/issues/issue-54062.rs13
-rw-r--r--src/test/ui/issues/issue-54062.stderr16
-rw-r--r--src/test/ui/macros/auxiliary/proc_macro_sequence.rs36
-rw-r--r--src/test/ui/macros/same-sequence-span.rs23
-rw-r--r--src/test/ui/macros/same-sequence-span.stderr34
-rw-r--r--src/test/ui/parser/recover-from-homoglyph.rs4
-rw-r--r--src/test/ui/parser/recover-from-homoglyph.stderr22
-rw-r--r--src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs22
-rw-r--r--src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr46
99 files changed, 1053 insertions, 2302 deletions
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 26fd7585ab5..7d945e20622 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1493,7 +1493,7 @@ impl Step for ErrorIndex {
 
         builder.info(&format!("Testing error-index stage{}", compiler.stage));
         let _time = util::timeit(&builder);
-        builder.run(&mut tool);
+        builder.run_quiet(&mut tool);
         markdown_test(builder, compiler, &output);
     }
 }
diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh
index 9995d2aac7f..2191d5d6e46 100755
--- a/src/ci/docker/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh
@@ -112,7 +112,7 @@ $COMMIT\t$(cat "$TOOLSTATE_FILE")
 }
 
 if [ "$RUST_RELEASE_CHANNEL" = nightly ]; then
-    if [ -n "${TOOLSTATE_REPO_ACCESS_TOKEN+is_set}" ]; then
+    if [ -n "${TOOLSTATE_PUBLISH+is_set}" ]; then
         . "$(dirname $0)/repo.sh"
         MESSAGE_FILE=$(mktemp -t msg.XXXXXX)
         echo "($OS CI update)" > "$MESSAGE_FILE"
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 01dee0a3943..488fda0b247 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -1,6 +1,6 @@
 //! A pointer type for heap allocation.
 //!
-//! `Box<T>`, casually referred to as a 'box', provides the simplest form of
+//! [`Box<T>`], casually referred to as a 'box', provides the simplest form of
 //! heap allocation in Rust. Boxes provide ownership for this allocation, and
 //! drop their contents when they go out of scope.
 //!
@@ -48,7 +48,7 @@
 //!
 //! It wouldn't work. This is because the size of a `List` depends on how many
 //! elements are in the list, and so we don't know how much memory to allocate
-//! for a `Cons`. By introducing a `Box`, which has a defined size, we know how
+//! for a `Cons`. By introducing a [`Box<T>`], which has a defined size, we know how
 //! big `Cons` needs to be.
 //!
 //! # Memory layout
@@ -59,15 +59,19 @@
 //! [`Layout`] used with the allocator is correct for the type. More precisely,
 //! a `value: *mut T` that has been allocated with the [`Global`] allocator
 //! with `Layout::for_value(&*value)` may be converted into a box using
-//! `Box::<T>::from_raw(value)`. Conversely, the memory backing a `value: *mut
-//! T` obtained from `Box::<T>::into_raw` may be deallocated using the
-//! [`Global`] allocator with `Layout::for_value(&*value)`.
+//! [`Box::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut
+//! T` obtained from [`Box::<T>::into_raw`] may be deallocated using the
+//! [`Global`] allocator with [`Layout::for_value(&*value)`].
 //!
 //!
 //! [dereferencing]: ../../std/ops/trait.Deref.html
 //! [`Box`]: struct.Box.html
+//! [`Box<T>`]: struct.Box.html
+//! [`Box::<T>::from_raw(value)`]: struct.Box.html#method.from_raw
+//! [`Box::<T>::into_raw`]: struct.Box.html#method.into_raw
 //! [`Global`]: ../alloc/struct.Global.html
 //! [`Layout`]: ../alloc/struct.Layout.html
+//! [`Layout::for_value(&*value)`]: ../alloc/struct.Layout.html#method.for_value
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 59088e43291..f9613556a1e 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -319,7 +319,7 @@ impl Ordering {
     /// This method can be used to reverse a comparison:
     ///
     /// ```
-    /// let mut data: &mut [_] = &mut [2, 10, 5, 8];
+    /// let data: &mut [_] = &mut [2, 10, 5, 8];
     ///
     /// // sort the array from largest to smallest.
     /// data.sort_by(|a, b| a.cmp(b).reverse());
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 39c390b4df6..79a188dbac9 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -655,6 +655,12 @@ impl<'a, T: ?Sized + 'a> Unpin for &'a T {}
 #[stable(feature = "pin", since = "1.33.0")]
 impl<'a, T: ?Sized + 'a> Unpin for &'a mut T {}
 
+#[stable(feature = "pin_raw", since = "1.38.0")]
+impl<T: ?Sized> Unpin for *const T {}
+
+#[stable(feature = "pin_raw", since = "1.38.0")]
+impl<T: ?Sized> Unpin for *mut T {}
+
 /// Implementations of `Copy` for primitive types.
 ///
 /// Implementations that cannot be described in Rust
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 33d6afdc975..abc8883d398 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -136,7 +136,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::iter::{FromIterator, FusedIterator, TrustedLen};
-use crate::{convert, fmt, hint, mem, ops::{self, Deref}};
+use crate::{convert, fmt, hint, mem, ops::{self, Deref, DerefMut}};
 use crate::pin::Pin;
 
 // Note that this is not a lang item per se, but it has a hidden dependency on
@@ -1104,17 +1104,28 @@ impl<T: Default> Option<T> {
 
 #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
 impl<T: Deref> Option<T> {
-    /// Converts from `&Option<T>` to `Option<&T::Target>`.
+    /// Converts from `Option<T>` (or `&Option<T>`) to `Option<&T::Target>`.
     ///
     /// Leaves the original Option in-place, creating a new one with a reference
     /// to the original one, additionally coercing the contents via [`Deref`].
     ///
     /// [`Deref`]: ../../std/ops/trait.Deref.html
-    pub fn deref(&self) -> Option<&T::Target> {
+    pub fn as_deref(&self) -> Option<&T::Target> {
         self.as_ref().map(|t| t.deref())
     }
 }
 
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T: DerefMut> Option<T> {
+    /// Converts from `Option<T>` (or `&mut Option<T>`) to `Option<&mut T::Target>`.
+    ///
+    /// Leaves the original `Option` in-place, creating a new one containing a mutable reference to
+    /// the inner type's `Deref::Target` type.
+    pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> {
+        self.as_mut().map(|t| t.deref_mut())
+    }
+}
+
 impl<T, E> Option<Result<T, E>> {
     /// Transposes an `Option` of a [`Result`] into a [`Result`] of an `Option`.
     ///
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index c063cee5227..2feaab7a09c 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -11,13 +11,13 @@
 //! until it gets dropped. We say that the pointee is "pinned".
 //!
 //! By default, all types in Rust are movable. Rust allows passing all types by-value,
-//! and common smart-pointer types such as `Box<T>` and `&mut T` allow replacing and
-//! moving the values they contain: you can move out of a `Box<T>`, or you can use [`mem::swap`].
-//! [`Pin<P>`] wraps a pointer type `P`, so `Pin<Box<T>>` functions much like a regular `Box<T>`:
-//! when a `Pin<Box<T>>` gets dropped, so do its contents, and the memory gets deallocated.
-//! Similarly, `Pin<&mut T>` is a lot like `&mut T`. However, [`Pin<P>`] does not let clients
-//! actually obtain a `Box<T>` or `&mut T` to pinned data, which implies that you cannot use
-//! operations such as [`mem::swap`]:
+//! and common smart-pointer types such as [`Box<T>`] and `&mut T` allow replacing and
+//! moving the values they contain: you can move out of a [`Box<T>`], or you can use [`mem::swap`].
+//! [`Pin<P>`] wraps a pointer type `P`, so [`Pin`]`<`[`Box`]`<T>>` functions much like a regular
+//! [`Box<T>`]: when a [`Pin`]`<`[`Box`]`<T>>` gets dropped, so do its contents, and the memory gets
+//! deallocated. Similarly, [`Pin`]`<&mut T>` is a lot like `&mut T`. However, [`Pin<P>`] does
+//! not let clients actually obtain a [`Box<T>`] or `&mut T` to pinned data, which implies that you
+//! cannot use operations such as [`mem::swap`]:
 //!
 //! ```
 //! use std::pin::Pin;
@@ -30,15 +30,15 @@
 //! ```
 //!
 //! It is worth reiterating that [`Pin<P>`] does *not* change the fact that a Rust compiler
-//! considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, `Pin<P>`
-//! prevents certain *values* (pointed to by pointers wrapped in `Pin<P>`) from being
+//! considers all types movable. [`mem::swap`] remains callable for any `T`. Instead, [`Pin<P>`]
+//! prevents certain *values* (pointed to by pointers wrapped in [`Pin<P>`]) from being
 //! moved by making it impossible to call methods that require `&mut T` on them
 //! (like [`mem::swap`]).
 //!
 //! [`Pin<P>`] can be used to wrap any pointer type `P`, and as such it interacts with
-//! [`Deref`] and [`DerefMut`]. A `Pin<P>` where `P: Deref` should be considered
-//! as a "`P`-style pointer" to a pinned `P::Target` -- so, a `Pin<Box<T>>` is
-//! an owned pointer to a pinned `T`, and a `Pin<Rc<T>>` is a reference-counted
+//! [`Deref`] and [`DerefMut`]. A [`Pin<P>`] where `P: Deref` should be considered
+//! as a "`P`-style pointer" to a pinned `P::Target` -- so, a [`Pin`]`<`[`Box`]`<T>>` is
+//! an owned pointer to a pinned `T`, and a [`Pin`]`<`[`Rc`]`<T>>` is a reference-counted
 //! pointer to a pinned `T`.
 //! For correctness, [`Pin<P>`] relies on the implementations of [`Deref`] and
 //! [`DerefMut`] not to move out of their `self` parameter, and only ever to
@@ -48,15 +48,15 @@
 //!
 //! Many types are always freely movable, even when pinned, because they do not
 //! rely on having a stable address. This includes all the basic types (like
-//! `bool`, `i32`, and references) as well as types consisting solely of these
+//! [`bool`], [`i32`], and references) as well as types consisting solely of these
 //! types. Types that do not care about pinning implement the [`Unpin`]
 //! auto-trait, which cancels the effect of [`Pin<P>`]. For `T: Unpin`,
-//! `Pin<Box<T>>` and `Box<T>` function identically, as do `Pin<&mut T>` and
+//! [`Pin`]`<`[`Box`]`<T>>` and [`Box<T>`] function identically, as do [`Pin`]`<&mut T>` and
 //! `&mut T`.
 //!
-//! Note that pinning and `Unpin` only affect the pointed-to type `P::Target`, not the pointer
-//! type `P` itself that got wrapped in `Pin<P>`. For example, whether or not `Box<T>` is
-//! `Unpin` has no effect on the behavior of `Pin<Box<T>>` (here, `T` is the
+//! Note that pinning and [`Unpin`] only affect the pointed-to type `P::Target`, not the pointer
+//! type `P` itself that got wrapped in [`Pin<P>`]. For example, whether or not [`Box<T>`] is
+//! [`Unpin`] has no effect on the behavior of [`Pin`]`<`[`Box`]`<T>>` (here, `T` is the
 //! pointed-to type).
 //!
 //! # Example: self-referential struct
@@ -122,15 +122,15 @@
 //!
 //! To make this work, every element has pointers to its predecessor and successor in
 //! the list. Elements can only be added when they are pinned, because moving the elements
-//! around would invalidate the pointers. Moreover, the `Drop` implementation of a linked
+//! around would invalidate the pointers. Moreover, the [`Drop`] implementation of a linked
 //! list element will patch the pointers of its predecessor and successor to remove itself
 //! from the list.
 //!
-//! Crucially, we have to be able to rely on `drop` being called. If an element
-//! could be deallocated or otherwise invalidated without calling `drop`, the pointers into it
+//! Crucially, we have to be able to rely on [`drop`] being called. If an element
+//! could be deallocated or otherwise invalidated without calling [`drop`], the pointers into it
 //! from its neighbouring elements would become invalid, which would break the data structure.
 //!
-//! Therefore, pinning also comes with a `drop`-related guarantee.
+//! Therefore, pinning also comes with a [`drop`]-related guarantee.
 //!
 //! # `Drop` guarantee
 //!
@@ -139,7 +139,7 @@
 //! otherwise invalidating the memory used to store the data is restricted, too.
 //! Concretely, for pinned data you have to maintain the invariant
 //! that *its memory will not get invalidated or repurposed from the moment it gets pinned until
-//! when `drop` is called*. Memory can be invalidated by deallocation, but also by
+//! when [`drop`] is called*. Memory can be invalidated by deallocation, but also by
 //! replacing a [`Some(v)`] by [`None`], or calling [`Vec::set_len`] to "kill" some elements
 //! off of a vector. It can be repurposed by using [`ptr::write`] to overwrite it without
 //! calling the destructor first.
@@ -148,26 +148,27 @@
 //! section needs to function correctly.
 //!
 //! Notice that this guarantee does *not* mean that memory does not leak! It is still
-//! completely okay not ever to call `drop` on a pinned element (e.g., you can still
-//! call [`mem::forget`] on a `Pin<Box<T>>`). In the example of the doubly-linked
+//! completely okay not ever to call [`drop`] on a pinned element (e.g., you can still
+//! call [`mem::forget`] on a [`Pin`]`<`[`Box`]`<T>>`). In the example of the doubly-linked
 //! list, that element would just stay in the list. However you may not free or reuse the storage
-//! *without calling `drop`*.
+//! *without calling [`drop`]*.
 //!
 //! # `Drop` implementation
 //!
 //! If your type uses pinning (such as the two examples above), you have to be careful
-//! when implementing `Drop`. The `drop` function takes `&mut self`, but this
+//! when implementing [`Drop`]. The [`drop`] function takes `&mut self`, but this
 //! is called *even if your type was previously pinned*! It is as if the
-//! compiler automatically called `get_unchecked_mut`.
+//! compiler automatically called [`Pin::get_unchecked_mut`].
 //!
 //! This can never cause a problem in safe code because implementing a type that
 //! relies on pinning requires unsafe code, but be aware that deciding to make
 //! use of pinning in your type (for example by implementing some operation on
-//! `Pin<&Self>` or `Pin<&mut Self>`) has consequences for your `Drop`
+//! [`Pin`]`<&Self>` or [`Pin`]`<&mut Self>`) has consequences for your [`Drop`]
 //! implementation as well: if an element of your type could have been pinned,
-//! you must treat Drop as implicitly taking `Pin<&mut Self>`.
+//! you must treat [`Drop`] as implicitly taking [`Pin`]`<&mut Self>`.
 //!
 //! For example, you could implement `Drop` as follows:
+//!
 //! ```rust,no_run
 //! # use std::pin::Pin;
 //! # struct Type { }
@@ -182,7 +183,8 @@
 //!     }
 //! }
 //! ```
-//! The function `inner_drop` has the type that `drop` *should* have, so this makes sure that
+//!
+//! The function `inner_drop` has the type that [`drop`] *should* have, so this makes sure that
 //! you do not accidentally use `self`/`this` in a way that is in conflict with pinning.
 //!
 //! Moreover, if your type is `#[repr(packed)]`, the compiler will automatically
@@ -192,10 +194,10 @@
 //! # Projections and Structural Pinning
 //!
 //! When working with pinned structs, the question arises how one can access the
-//! fields of that struct in a method that takes just `Pin<&mut Struct>`.
+//! fields of that struct in a method that takes just [`Pin`]`<&mut Struct>`.
 //! The usual approach is to write helper methods (so called *projections*)
-//! that turn `Pin<&mut Struct>` into a reference to the field, but what
-//! type should that reference have? Is it `Pin<&mut Field>` or `&mut Field`?
+//! that turn [`Pin`]`<&mut Struct>` into a reference to the field, but what
+//! type should that reference have? Is it [`Pin`]`<&mut Field>` or `&mut Field`?
 //! The same question arises with the fields of an `enum`, and also when considering
 //! container/wrapper types such as [`Vec<T>`], [`Box<T>`], or [`RefCell<T>`].
 //! (This question applies to both mutable and shared references, we just
@@ -203,7 +205,7 @@
 //!
 //! It turns out that it is actually up to the author of the data structure
 //! to decide whether the pinned projection for a particular field turns
-//! `Pin<&mut Struct>` into `Pin<&mut Field>` or `&mut Field`. There are some
+//! [`Pin`]`<&mut Struct>` into [`Pin`]`<&mut Field>` or `&mut Field`. There are some
 //! constraints though, and the most important constraint is *consistency*:
 //! every field can be *either* projected to a pinned reference, *or* have
 //! pinning removed as part of the projection. If both are done for the same field,
@@ -218,12 +220,13 @@
 //! ## Pinning *is not* structural for `field`
 //!
 //! It may seem counter-intuitive that the field of a pinned struct might not be pinned,
-//! but that is actually the easiest choice: if a `Pin<&mut Field>` is never created,
+//! but that is actually the easiest choice: if a [`Pin`]`<&mut Field>` is never created,
 //! nothing can go wrong! So, if you decide that some field does not have structural pinning,
 //! all you have to ensure is that you never create a pinned reference to that field.
 //!
 //! Fields without structural pinning may have a projection method that turns
-//! `Pin<&mut Struct>` into `&mut Field`:
+//! [`Pin`]`<&mut Struct>` into `&mut Field`:
+//!
 //! ```rust,no_run
 //! # use std::pin::Pin;
 //! # type Field = i32;
@@ -237,16 +240,17 @@
 //! ```
 //!
 //! You may also `impl Unpin for Struct` *even if* the type of `field`
-//! is not `Unpin`. What that type thinks about pinning is not relevant
-//! when no `Pin<&mut Field>` is ever created.
+//! is not [`Unpin`]. What that type thinks about pinning is not relevant
+//! when no [`Pin`]`<&mut Field>` is ever created.
 //!
 //! ## Pinning *is* structural for `field`
 //!
 //! The other option is to decide that pinning is "structural" for `field`,
 //! meaning that if the struct is pinned then so is the field.
 //!
-//! This allows writing a projection that creates a `Pin<&mut Field>`, thus
+//! This allows writing a projection that creates a [`Pin`]`<&mut Field>`, thus
 //! witnessing that the field is pinned:
+//!
 //! ```rust,no_run
 //! # use std::pin::Pin;
 //! # type Field = i32;
@@ -262,30 +266,30 @@
 //! However, structural pinning comes with a few extra requirements:
 //!
 //! 1.  The struct must only be [`Unpin`] if all the structural fields are
-//!     `Unpin`. This is the default, but `Unpin` is a safe trait, so as the author of
+//!     [`Unpin`]. This is the default, but [`Unpin`] is a safe trait, so as the author of
 //!     the struct it is your responsibility *not* to add something like
 //!     `impl<T> Unpin for Struct<T>`. (Notice that adding a projection operation
-//!     requires unsafe code, so the fact that `Unpin` is a safe trait does not break
+//!     requires unsafe code, so the fact that [`Unpin`] is a safe trait does not break
 //!     the principle that you only have to worry about any of this if you use `unsafe`.)
 //! 2.  The destructor of the struct must not move structural fields out of its argument. This
 //!     is the exact point that was raised in the [previous section][drop-impl]: `drop` takes
 //!     `&mut self`, but the struct (and hence its fields) might have been pinned before.
-//!     You have to guarantee that you do not move a field inside your `Drop` implementation.
+//!     You have to guarantee that you do not move a field inside your [`Drop`] implementation.
 //!     In particular, as explained previously, this means that your struct must *not*
 //!     be `#[repr(packed)]`.
-//!     See that section for how to write `drop` in a way that the compiler can help you
+//!     See that section for how to write [`drop`] in a way that the compiler can help you
 //!     not accidentally break pinning.
 //! 3.  You must make sure that you uphold the [`Drop` guarantee][drop-guarantee]:
 //!     once your struct is pinned, the memory that contains the
 //!     content is not overwritten or deallocated without calling the content's destructors.
-//!     This can be tricky, as witnessed by [`VecDeque<T>`]: the destructor of `VecDeque<T>`
-//!     can fail to call `drop` on all elements if one of the destructors panics. This violates the
-//!     `Drop` guarantee, because it can lead to elements being deallocated without
-//!     their destructor being called. (`VecDeque` has no pinning projections, so this
+//!     This can be tricky, as witnessed by [`VecDeque<T>`]: the destructor of [`VecDeque<T>`]
+//!     can fail to call [`drop`] on all elements if one of the destructors panics. This violates
+//!     the [`Drop`] guarantee, because it can lead to elements being deallocated without
+//!     their destructor being called. ([`VecDeque<T>`] has no pinning projections, so this
 //!     does not cause unsoundness.)
 //! 4.  You must not offer any other operations that could lead to data being moved out of
 //!     the structural fields when your type is pinned. For example, if the struct contains an
-//!     `Option<T>` and there is a `take`-like operation with type
+//!     [`Option<T>`] and there is a `take`-like operation with type
 //!     `fn(Pin<&mut Struct<T>>) -> Option<T>`,
 //!     that operation can be used to move a `T` out of a pinned `Struct<T>` -- which means
 //!     pinning cannot be structural for the field holding this data.
@@ -301,37 +305,39 @@
 //!         let content = &mut *b; // And here we have `&mut T` to the same data.
 //!     }
 //!     ```
-//!     This is catastrophic, it means we can first pin the content of the `RefCell<T>`
+//!     This is catastrophic, it means we can first pin the content of the [`RefCell<T>`]
 //!     (using `RefCell::get_pin_mut`) and then move that content using the mutable
 //!     reference we got later.
 //!
 //! ## Examples
 //!
 //! For a type like [`Vec<T>`], both possibilites (structural pinning or not) make sense.
-//! A `Vec<T>` with structural pinning could have `get_pin`/`get_pin_mut` methods to get
+//! A [`Vec<T>`] with structural pinning could have `get_pin`/`get_pin_mut` methods to get
 //! pinned references to elements. However, it could *not* allow calling
-//! `pop` on a pinned `Vec<T>` because that would move the (structurally pinned) contents!
-//! Nor could it allow `push`, which might reallocate and thus also move the contents.
-//! A `Vec<T>` without structural pinning could `impl<T> Unpin for Vec<T>`, because the contents
-//! are never pinned and the `Vec<T>` itself is fine with being moved as well.
+//! [`pop`][Vec::pop] on a pinned [`Vec<T>`] because that would move the (structurally pinned)
+//! contents! Nor could it allow [`push`][Vec::push], which might reallocate and thus also move the
+//! contents.
+//!
+//! A [`Vec<T>`] without structural pinning could `impl<T> Unpin for Vec<T>`, because the contents
+//! are never pinned and the [`Vec<T>`] itself is fine with being moved as well.
 //! At that point pinning just has no effect on the vector at all.
 //!
 //! In the standard library, pointer types generally do not have structural pinning,
 //! and thus they do not offer pinning projections. This is why `Box<T>: Unpin` holds for all `T`.
 //! It makes sense to do this for pointer types, because moving the `Box<T>`
-//! does not actually move the `T`: the `Box<T>` can be freely movable (aka `Unpin`) even if the `T`
-//! is not. In fact, even `Pin<Box<T>>` and `Pin<&mut T>` are always `Unpin` themselves,
-//! for the same reason: their contents (the `T`) are pinned, but the pointers themselves
-//! can be moved without moving the pinned data. For both `Box<T>` and `Pin<Box<T>>`,
-//! whether the content is pinned is entirely independent of whether the pointer is
-//! pinned, meaning pinning is *not* structural.
+//! does not actually move the `T`: the [`Box<T>`] can be freely movable (aka `Unpin`) even if
+//! the `T` is not. In fact, even [`Pin`]`<`[`Box`]`<T>>` and [`Pin`]`<&mut T>` are always
+//! [`Unpin`] themselves, for the same reason: their contents (the `T`) are pinned, but the
+//! pointers themselves can be moved without moving the pinned data. For both [`Box<T>`] and
+//! [`Pin`]`<`[`Box`]`<T>>`, whether the content is pinned is entirely independent of whether the
+//! pointer is pinned, meaning pinning is *not* structural.
 //!
 //! When implementing a [`Future`] combinator, you will usually need structural pinning
-//! for the nested futures, as you need to get pinned references to them to call `poll`.
+//! for the nested futures, as you need to get pinned references to them to call [`poll`].
 //! But if your combinator contains any other data that does not need to be pinned,
 //! you can make those fields not structural and hence freely access them with a
-//! mutable reference even when you just have `Pin<&mut Self>` (such as in your own
-//! `poll` implementation).
+//! mutable reference even when you just have [`Pin`]`<&mut Self>` (such as in your own
+//! [`poll`] implementation).
 //!
 //! [`Pin<P>`]: struct.Pin.html
 //! [`Unpin`]: ../marker/trait.Unpin.html
@@ -342,6 +348,16 @@
 //! [`Box<T>`]: ../../std/boxed/struct.Box.html
 //! [`Vec<T>`]: ../../std/vec/struct.Vec.html
 //! [`Vec::set_len`]: ../../std/vec/struct.Vec.html#method.set_len
+//! [`Pin`]: struct.Pin.html
+//! [`Box`]: ../../std/boxed/struct.Box.html
+//! [Vec::pop]: ../../std/vec/struct.Vec.html#method.pop
+//! [Vec::push]: ../../std/vec/struct.Vec.html#method.push
+//! [`Rc`]: ../../std/rc/struct.Rc.html
+//! [`RefCell<T>`]: ../../std/cell/struct.RefCell.html
+//! [`Drop`]: ../../std/ops/trait.Drop.html
+//! [`drop`]: ../../std/ops/trait.Drop.html#tymethod.drop
+//! [`VecDeque<T>`]: ../../std/collections/struct.VecDeque.html
+//! [`Option<T>`]: ../../std/option/enum.Option.html
 //! [`VecDeque<T>`]: ../../std/collections/struct.VecDeque.html
 //! [`RefCell<T>`]: ../cell/struct.RefCell.html
 //! [`None`]: ../option/enum.Option.html#variant.None
@@ -350,6 +366,8 @@
 //! [`Future`]: ../future/trait.Future.html
 //! [drop-impl]: #drop-implementation
 //! [drop-guarantee]: #drop-guarantee
+//! [`poll`]: ../../std/future/trait.Future.html#tymethod.poll
+//! [`Pin::get_unchecked_mut`]: struct.Pin.html#method.get_unchecked_mut
 
 #![stable(feature = "pin", since = "1.33.0")]
 
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 3a38b66ad01..cb6bc058730 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -232,7 +232,7 @@
 
 use crate::fmt;
 use crate::iter::{FromIterator, FusedIterator, TrustedLen};
-use crate::ops::{self, Deref};
+use crate::ops::{self, Deref, DerefMut};
 
 /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]).
 ///
@@ -981,24 +981,22 @@ impl<T: Default, E> Result<T, E> {
 
 #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
 impl<T: Deref, E> Result<T, E> {
-    /// Converts from `&Result<T, E>` to `Result<&T::Target, &E>`.
+    /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T::Target, &E>`.
     ///
-    /// Leaves the original Result in-place, creating a new one with a reference
-    /// to the original one, additionally coercing the `Ok` arm of the Result via
-    /// `Deref`.
-    pub fn deref_ok(&self) -> Result<&T::Target, &E> {
+    /// Leaves the original `Result` in-place, creating a new one containing a reference to the
+    /// `Ok` type's `Deref::Target` type.
+    pub fn as_deref_ok(&self) -> Result<&T::Target, &E> {
         self.as_ref().map(|t| t.deref())
     }
 }
 
 #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
 impl<T, E: Deref> Result<T, E> {
-    /// Converts from `&Result<T, E>` to `Result<&T, &E::Target>`.
+    /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T, &E::Target>`.
     ///
-    /// Leaves the original Result in-place, creating a new one with a reference
-    /// to the original one, additionally coercing the `Err` arm of the Result via
-    /// `Deref`.
-    pub fn deref_err(&self) -> Result<&T, &E::Target>
+    /// Leaves the original `Result` in-place, creating a new one containing a reference to the
+    /// `Err` type's `Deref::Target` type.
+    pub fn as_deref_err(&self) -> Result<&T, &E::Target>
     {
         self.as_ref().map_err(|e| e.deref())
     }
@@ -1006,17 +1004,52 @@ impl<T, E: Deref> Result<T, E> {
 
 #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
 impl<T: Deref, E: Deref> Result<T, E> {
-    /// Converts from `&Result<T, E>` to `Result<&T::Target, &E::Target>`.
+    /// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T::Target, &E::Target>`.
     ///
-    /// Leaves the original Result in-place, creating a new one with a reference
-    /// to the original one, additionally coercing both the `Ok` and `Err` arms
-    /// of the Result via `Deref`.
-    pub fn deref(&self) -> Result<&T::Target, &E::Target>
+    /// Leaves the original `Result` in-place, creating a new one containing a reference to both
+    /// the `Ok` and `Err` types' `Deref::Target` types.
+    pub fn as_deref(&self) -> Result<&T::Target, &E::Target>
     {
         self.as_ref().map(|t| t.deref()).map_err(|e| e.deref())
     }
 }
 
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T: DerefMut, E> Result<T, E> {
+    /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut T::Target, &mut E>`.
+    ///
+    /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to
+    /// the `Ok` type's `Deref::Target` type.
+    pub fn as_deref_mut_ok(&mut self) -> Result<&mut T::Target, &mut E> {
+        self.as_mut().map(|t| t.deref_mut())
+    }
+}
+
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T, E: DerefMut> Result<T, E> {
+    /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut T, &mut E::Target>`.
+    ///
+    /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to
+    /// the `Err` type's `Deref::Target` type.
+    pub fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target>
+    {
+        self.as_mut().map_err(|e| e.deref_mut())
+    }
+}
+
+#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
+impl<T: DerefMut, E: DerefMut> Result<T, E> {
+    /// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to
+    /// `Result<&mut T::Target, &mut E::Target>`.
+    ///
+    /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to
+    /// both the `Ok` and `Err` types' `Deref::Target` types.
+    pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E::Target>
+    {
+        self.as_mut().map(|t| t.deref_mut()).map_err(|e| e.deref_mut())
+    }
+}
+
 impl<T, E> Result<Option<T>, E> {
     /// Transposes a `Result` of an `Option` into an `Option` of a `Result`.
     ///
diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs
index b059b134868..ff43fc49f71 100644
--- a/src/libcore/tests/option.rs
+++ b/src/libcore/tests/option.rs
@@ -1,6 +1,8 @@
 use core::option::*;
 use core::mem;
 use core::clone::Clone;
+use core::array::FixedSizeArray;
+use core::ops::DerefMut;
 
 #[test]
 fn test_get_ptr() {
@@ -310,20 +312,38 @@ fn test_try() {
 }
 
 #[test]
-fn test_option_deref() {
+fn test_option_as_deref() {
     // Some: &Option<T: Deref>::Some(T) -> Option<&T::Deref::Target>::Some(&*T)
     let ref_option = &Some(&42);
-    assert_eq!(ref_option.deref(), Some(&42));
+    assert_eq!(ref_option.as_deref(), Some(&42));
 
     let ref_option = &Some(String::from("a result"));
-    assert_eq!(ref_option.deref(), Some("a result"));
+    assert_eq!(ref_option.as_deref(), Some("a result"));
 
     let ref_option = &Some(vec![1, 2, 3, 4, 5]);
-    assert_eq!(ref_option.deref(), Some(&[1, 2, 3, 4, 5][..]));
+    assert_eq!(ref_option.as_deref(), Some([1, 2, 3, 4, 5].as_slice()));
 
     // None: &Option<T: Deref>>::None -> None
     let ref_option: &Option<&i32> = &None;
-    assert_eq!(ref_option.deref(), None);
+    assert_eq!(ref_option.as_deref(), None);
+}
+
+#[test]
+fn test_option_as_deref_mut() {
+    // Some: &mut Option<T: Deref>::Some(T) -> Option<&mut T::Deref::Target>::Some(&mut *T)
+    let mut val = 42;
+    let ref_option = &mut Some(&mut val);
+    assert_eq!(ref_option.as_deref_mut(), Some(&mut 42));
+
+    let ref_option = &mut Some(String::from("a result"));
+    assert_eq!(ref_option.as_deref_mut(), Some(String::from("a result").deref_mut()));
+
+    let ref_option = &mut Some(vec![1, 2, 3, 4, 5]);
+    assert_eq!(ref_option.as_deref_mut(), Some([1, 2, 3, 4, 5].as_mut_slice()));
+
+    // None: &mut Option<T: Deref>>::None -> None
+    let ref_option: &mut Option<&mut i32> = &mut None;
+    assert_eq!(ref_option.as_deref_mut(), None);
 }
 
 #[test]
diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs
index 1fab07526a0..163f8d0ab37 100644
--- a/src/libcore/tests/result.rs
+++ b/src/libcore/tests/result.rs
@@ -1,4 +1,6 @@
 use core::option::*;
+use core::array::FixedSizeArray;
+use core::ops::DerefMut;
 
 fn op1() -> Result<isize, &'static str> { Ok(666) }
 fn op2() -> Result<isize, &'static str> { Err("sadface") }
@@ -225,94 +227,213 @@ fn test_try() {
 }
 
 #[test]
-fn test_result_deref() {
-    // &Result<T: Deref, E>::Ok(T).deref_ok() ->
+fn test_result_as_deref() {
+    // &Result<T: Deref, E>::Ok(T).as_deref_ok() ->
     //      Result<&T::Deref::Target, &E>::Ok(&*T)
     let ref_ok = &Result::Ok::<&i32, u8>(&42);
     let expected_result = Result::Ok::<&i32, &u8>(&42);
-    assert_eq!(ref_ok.deref_ok(), expected_result);
+    assert_eq!(ref_ok.as_deref_ok(), expected_result);
 
     let ref_ok = &Result::Ok::<String, u32>(String::from("a result"));
     let expected_result = Result::Ok::<&str, &u32>("a result");
-    assert_eq!(ref_ok.deref_ok(), expected_result);
+    assert_eq!(ref_ok.as_deref_ok(), expected_result);
 
     let ref_ok = &Result::Ok::<Vec<i32>, u32>(vec![1, 2, 3, 4, 5]);
-    let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]);
-    assert_eq!(ref_ok.deref_ok(), expected_result);
+    let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
+    assert_eq!(ref_ok.as_deref_ok(), expected_result);
 
-    // &Result<T: Deref, E: Deref>::Ok(T).deref() ->
+    // &Result<T: Deref, E: Deref>::Ok(T).as_deref() ->
     //      Result<&T::Deref::Target, &E::Deref::Target>::Ok(&*T)
     let ref_ok = &Result::Ok::<&i32, &u8>(&42);
     let expected_result = Result::Ok::<&i32, &u8>(&42);
-    assert_eq!(ref_ok.deref(), expected_result);
+    assert_eq!(ref_ok.as_deref(), expected_result);
 
     let ref_ok = &Result::Ok::<String, &u32>(String::from("a result"));
     let expected_result = Result::Ok::<&str, &u32>("a result");
-    assert_eq!(ref_ok.deref(), expected_result);
+    assert_eq!(ref_ok.as_deref(), expected_result);
 
     let ref_ok = &Result::Ok::<Vec<i32>, &u32>(vec![1, 2, 3, 4, 5]);
-    let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]);
-    assert_eq!(ref_ok.deref(), expected_result);
+    let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
+    assert_eq!(ref_ok.as_deref(), expected_result);
 
-    // &Result<T, E: Deref>::Err(T).deref_err() ->
+    // &Result<T, E: Deref>::Err(T).as_deref_err() ->
     //      Result<&T, &E::Deref::Target>::Err(&*E)
     let ref_err = &Result::Err::<u8, &i32>(&41);
     let expected_result = Result::Err::<&u8, &i32>(&41);
-    assert_eq!(ref_err.deref_err(), expected_result);
+    assert_eq!(ref_err.as_deref_err(), expected_result);
 
     let ref_err = &Result::Err::<u32, String>(String::from("an error"));
     let expected_result = Result::Err::<&u32, &str>("an error");
-    assert_eq!(ref_err.deref_err(), expected_result);
+    assert_eq!(ref_err.as_deref_err(), expected_result);
 
     let ref_err = &Result::Err::<u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
-    let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]);
-    assert_eq!(ref_err.deref_err(), expected_result);
+    let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice());
+    assert_eq!(ref_err.as_deref_err(), expected_result);
 
-    // &Result<T: Deref, E: Deref>::Err(T).deref_err() ->
+    // &Result<T: Deref, E: Deref>::Err(T).as_deref_err() ->
     //      Result<&T, &E::Deref::Target>::Err(&*E)
     let ref_err = &Result::Err::<&u8, &i32>(&41);
     let expected_result = Result::Err::<&u8, &i32>(&41);
-    assert_eq!(ref_err.deref(), expected_result);
+    assert_eq!(ref_err.as_deref(), expected_result);
 
     let ref_err = &Result::Err::<&u32, String>(String::from("an error"));
     let expected_result = Result::Err::<&u32, &str>("an error");
-    assert_eq!(ref_err.deref(), expected_result);
+    assert_eq!(ref_err.as_deref(), expected_result);
 
     let ref_err = &Result::Err::<&u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
-    let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]);
-    assert_eq!(ref_err.deref(), expected_result);
+    let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice());
+    assert_eq!(ref_err.as_deref(), expected_result);
 
-    // The following cases test calling deref_* with the wrong variant (i.e.
-    // `deref_ok()` with a `Result::Err()`, or `deref_err()` with a `Result::Ok()`.
-    // While unusual, these cases are supported to ensure that an `inner_deref`
+    // The following cases test calling `as_deref_*` with the wrong variant (i.e.
+    // `as_deref_ok()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`.
+    // While uncommon, these cases are supported to ensure that an `as_deref_*`
     // call can still be made even when one of the Result types does not implement
     // `Deref` (for example, std::io::Error).
 
-    // &Result<T, E: Deref>::Ok(T).deref_err() ->
+    // &Result<T, E: Deref>::Ok(T).as_deref_err() ->
     //      Result<&T, &E::Deref::Target>::Ok(&T)
     let ref_ok = &Result::Ok::<i32, &u8>(42);
     let expected_result = Result::Ok::<&i32, &u8>(&42);
-    assert_eq!(ref_ok.deref_err(), expected_result);
+    assert_eq!(ref_ok.as_deref_err(), expected_result);
 
     let ref_ok = &Result::Ok::<&str, &u32>("a result");
     let expected_result = Result::Ok::<&&str, &u32>(&"a result");
-    assert_eq!(ref_ok.deref_err(), expected_result);
+    assert_eq!(ref_ok.as_deref_err(), expected_result);
 
     let ref_ok = &Result::Ok::<[i32; 5], &u32>([1, 2, 3, 4, 5]);
     let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]);
-    assert_eq!(ref_ok.deref_err(), expected_result);
+    assert_eq!(ref_ok.as_deref_err(), expected_result);
 
-    // &Result<T: Deref, E>::Err(E).deref_ok() ->
+    // &Result<T: Deref, E>::Err(E).as_deref_ok() ->
     //      Result<&T::Deref::Target, &E>::Err(&E)
     let ref_err = &Result::Err::<&u8, i32>(41);
     let expected_result = Result::Err::<&u8, &i32>(&41);
-    assert_eq!(ref_err.deref_ok(), expected_result);
+    assert_eq!(ref_err.as_deref_ok(), expected_result);
 
     let ref_err = &Result::Err::<&u32, &str>("an error");
     let expected_result = Result::Err::<&u32, &&str>(&"an error");
-    assert_eq!(ref_err.deref_ok(), expected_result);
+    assert_eq!(ref_err.as_deref_ok(), expected_result);
 
     let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]);
     let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]);
-    assert_eq!(ref_err.deref_ok(), expected_result);
+    assert_eq!(ref_err.as_deref_ok(), expected_result);
+}
+
+#[test]
+fn test_result_as_deref_mut() {
+    // &mut Result<T: Deref, E>::Ok(T).as_deref_mut_ok() ->
+    //      Result<&mut T::Deref::Target, &mut E>::Ok(&mut *T)
+    let mut val = 42;
+    let mut expected_val = 42;
+    let mut_ok = &mut Result::Ok::<&mut i32, u8>(&mut val);
+    let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
+    assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);
+
+    let mut expected_string = String::from("a result");
+    let mut_ok = &mut Result::Ok::<String, u32>(expected_string.clone());
+    let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut());
+    assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);
+
+    let mut expected_vec = vec![1, 2, 3, 4, 5];
+    let mut_ok = &mut Result::Ok::<Vec<i32>, u32>(expected_vec.clone());
+    let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
+    assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);
+
+    // &mut Result<T: Deref, E: Deref>::Ok(T).as_deref_mut() ->
+    //      Result<&mut T::Deref::Target, &mut E::Deref::Target>::Ok(&mut *T)
+    let mut val = 42;
+    let mut expected_val = 42;
+    let mut_ok = &mut Result::Ok::<&mut i32, &mut u8>(&mut val);
+    let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
+    assert_eq!(mut_ok.as_deref_mut(), expected_result);
+
+    let mut expected_string = String::from("a result");
+    let mut_ok = &mut Result::Ok::<String, &mut u32>(expected_string.clone());
+    let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut());
+    assert_eq!(mut_ok.as_deref_mut(), expected_result);
+
+    let mut expected_vec = vec![1, 2, 3, 4, 5];
+    let mut_ok = &mut Result::Ok::<Vec<i32>, &mut u32>(expected_vec.clone());
+    let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
+    assert_eq!(mut_ok.as_deref_mut(), expected_result);
+
+    // &mut Result<T, E: Deref>::Err(T).as_deref_mut_err() ->
+    //      Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
+    let mut val = 41;
+    let mut expected_val = 41;
+    let mut_err = &mut Result::Err::<u8, &mut i32>(&mut val);
+    let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
+    assert_eq!(mut_err.as_deref_mut_err(), expected_result);
+
+    let mut expected_string = String::from("an error");
+    let mut_err = &mut Result::Err::<u32, String>(expected_string.clone());
+    let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.deref_mut());
+    assert_eq!(mut_err.as_deref_mut_err(), expected_result);
+
+    let mut expected_vec = vec![5, 4, 3, 2, 1];
+    let mut_err = &mut Result::Err::<u32, Vec<i32>>(expected_vec.clone());
+    let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice());
+    assert_eq!(mut_err.as_deref_mut_err(), expected_result);
+
+    // &mut Result<T: Deref, E: Deref>::Err(T).as_deref_mut_err() ->
+    //      Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
+    let mut val = 41;
+    let mut expected_val = 41;
+    let mut_err = &mut Result::Err::<&mut u8, &mut i32>(&mut val);
+    let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
+    assert_eq!(mut_err.as_deref_mut(), expected_result);
+
+    let mut expected_string = String::from("an error");
+    let mut_err = &mut Result::Err::<&mut u32, String>(expected_string.clone());
+    let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.as_mut_str());
+    assert_eq!(mut_err.as_deref_mut(), expected_result);
+
+    let mut expected_vec = vec![5, 4, 3, 2, 1];
+    let mut_err = &mut Result::Err::<&mut u32, Vec<i32>>(expected_vec.clone());
+    let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice());
+    assert_eq!(mut_err.as_deref_mut(), expected_result);
+
+    // The following cases test calling `as_deref_mut_*` with the wrong variant (i.e.
+    // `as_deref_mut_ok()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`.
+    // While uncommon, these cases are supported to ensure that an `as_deref_mut_*`
+    // call can still be made even when one of the Result types does not implement
+    // `Deref` (for example, std::io::Error).
+
+    // &mut Result<T, E: Deref>::Ok(T).as_deref_mut_err() ->
+    //      Result<&mut T, &mut E::Deref::Target>::Ok(&mut T)
+    let mut expected_val = 42;
+    let mut_ok = &mut Result::Ok::<i32, &mut u8>(expected_val.clone());
+    let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
+    assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
+
+    let string = String::from("a result");
+    let expected_string = string.clone();
+    let mut ref_str = expected_string.as_ref();
+    let mut_ok = &mut Result::Ok::<&str, &mut u32>(string.as_str());
+    let expected_result = Result::Ok::<&mut &str, &mut u32>(&mut ref_str);
+    assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
+
+    let mut expected_arr = [1, 2, 3, 4, 5];
+    let mut_ok = &mut Result::Ok::<[i32; 5], &mut u32>(expected_arr.clone());
+    let expected_result = Result::Ok::<&mut [i32; 5], &mut u32>(&mut expected_arr);
+    assert_eq!(mut_ok.as_deref_mut_err(), expected_result);
+
+    // &mut Result<T: Deref, E>::Err(E).as_deref_mut_ok() ->
+    //      Result<&mut T::Deref::Target, &mut E>::Err(&mut E)
+    let mut expected_val = 41;
+    let mut_err = &mut Result::Err::<&mut u8, i32>(expected_val.clone());
+    let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
+    assert_eq!(mut_err.as_deref_mut_ok(), expected_result);
+
+    let string = String::from("an error");
+    let expected_string = string.clone();
+    let mut ref_str = expected_string.as_ref();
+    let mut_err = &mut Result::Err::<&mut u32, &str>(string.as_str());
+    let expected_result = Result::Err::<&mut u32, &mut &str>(&mut ref_str);
+    assert_eq!(mut_err.as_deref_mut_ok(), expected_result);
+
+    let mut expected_arr = [5, 4, 3, 2, 1];
+    let mut_err = &mut Result::Err::<&mut u32, [i32; 5]>(expected_arr.clone());
+    let expected_result = Result::Err::<&mut u32, &mut [i32; 5]>(&mut expected_arr);
+    assert_eq!(mut_err.as_deref_mut_ok(), expected_result);
 }
diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs
index a793ac3eb74..bfe784afaa4 100644
--- a/src/libcore/unicode/tables.rs
+++ b/src/libcore/unicode/tables.rs
@@ -1,6 +1,6 @@
 // NOTE: The following code was generated by "./unicode.py", do not edit directly
 
-#![allow(missing_docs, non_upper_case_globals, non_snake_case)]
+#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)]
 
 use crate::unicode::version::UnicodeVersion;
 use crate::unicode::bool_trie::{BoolTrie, SmallBoolTrie};
diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index 3a20d0548c1..5389d1cf803 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -79,7 +79,7 @@ FETCH_URL_VERSION = "ftp://ftp.unicode.org/Public/{version}/ucd/{filename}"
 PREAMBLE = """\
 // NOTE: The following code was generated by "./unicode.py", do not edit directly
 
-#![allow(missing_docs, non_upper_case_globals, non_snake_case)]
+#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)]
 
 use crate::unicode::version::UnicodeVersion;
 use crate::unicode::bool_trie::{{BoolTrie, SmallBoolTrie}};
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 3e571baaa4e..da4a25e0860 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -941,7 +941,7 @@ impl<'a> State<'a> {
         self.maybe_print_comment(st.span.lo());
         match st.node {
             hir::StmtKind::Local(ref loc) => {
-                self.print_local(loc.init.deref(), |this| this.print_local_decl(&loc));
+                self.print_local(loc.init.as_deref(), |this| this.print_local_decl(&loc));
             }
             hir::StmtKind::Item(item) => {
                 self.ann.nested(self, Nested::Item(item))
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index bdd48b34474..cc09a0b20cf 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -367,34 +367,6 @@ language_item_table! {
 
     DebugTraitLangItem,          "debug_trait",        debug_trait,             Target::Trait;
 
-    // A lang item for each of the 128-bit operators we can optionally lower.
-    I128AddFnLangItem,           "i128_add",           i128_add_fn,             Target::Fn;
-    U128AddFnLangItem,           "u128_add",           u128_add_fn,             Target::Fn;
-    I128SubFnLangItem,           "i128_sub",           i128_sub_fn,             Target::Fn;
-    U128SubFnLangItem,           "u128_sub",           u128_sub_fn,             Target::Fn;
-    I128MulFnLangItem,           "i128_mul",           i128_mul_fn,             Target::Fn;
-    U128MulFnLangItem,           "u128_mul",           u128_mul_fn,             Target::Fn;
-    I128DivFnLangItem,           "i128_div",           i128_div_fn,             Target::Fn;
-    U128DivFnLangItem,           "u128_div",           u128_div_fn,             Target::Fn;
-    I128RemFnLangItem,           "i128_rem",           i128_rem_fn,             Target::Fn;
-    U128RemFnLangItem,           "u128_rem",           u128_rem_fn,             Target::Fn;
-    I128ShlFnLangItem,           "i128_shl",           i128_shl_fn,             Target::Fn;
-    U128ShlFnLangItem,           "u128_shl",           u128_shl_fn,             Target::Fn;
-    I128ShrFnLangItem,           "i128_shr",           i128_shr_fn,             Target::Fn;
-    U128ShrFnLangItem,           "u128_shr",           u128_shr_fn,             Target::Fn;
-    // And overflow versions for the operators that are checkable.
-    // While MIR calls these Checked*, they return (T,bool), not Option<T>.
-    I128AddoFnLangItem,          "i128_addo",          i128_addo_fn,            Target::Fn;
-    U128AddoFnLangItem,          "u128_addo",          u128_addo_fn,            Target::Fn;
-    I128SuboFnLangItem,          "i128_subo",          i128_subo_fn,            Target::Fn;
-    U128SuboFnLangItem,          "u128_subo",          u128_subo_fn,            Target::Fn;
-    I128MuloFnLangItem,          "i128_mulo",          i128_mulo_fn,            Target::Fn;
-    U128MuloFnLangItem,          "u128_mulo",          u128_mulo_fn,            Target::Fn;
-    I128ShloFnLangItem,          "i128_shlo",          i128_shlo_fn,            Target::Fn;
-    U128ShloFnLangItem,          "u128_shlo",          u128_shlo_fn,            Target::Fn;
-    I128ShroFnLangItem,          "i128_shro",          i128_shro_fn,            Target::Fn;
-    U128ShroFnLangItem,          "u128_shro",          u128_shro_fn,            Target::Fn;
-
     // Align offset for stride != 1, must not panic.
     AlignOffsetLangItem,         "align_offset",       align_offset_fn,         Target::Fn;
 
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 9a8429733d1..74653d4fbda 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1406,10 +1406,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
     saturating_float_casts: bool = (false, parse_bool, [TRACKED],
         "make float->int casts UB-free: numbers outside the integer type's range are clipped to \
          the max/min integer respectively, and NaN is mapped to 0"),
-    lower_128bit_ops: Option<bool> = (None, parse_opt_bool, [TRACKED],
-        "rewrite operators on i128 and u128 into lang item calls (typically provided \
-         by compiler-builtins) so codegen doesn't need to support them,
-         overriding the default for the current target"),
     human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
         "generate human-readable, predictable names for codegen units"),
     dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED],
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index f1550b9d756..46b8114030f 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -21,7 +21,7 @@ use crate::middle::cstore::EncodedMetadata;
 use crate::middle::lang_items;
 use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
 use crate::middle::stability;
-use crate::mir::{self, Body, interpret, ProjectionKind};
+use crate::mir::{Body, interpret, ProjectionKind};
 use crate::mir::interpret::{ConstValue, Allocation, Scalar};
 use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst};
 use crate::ty::ReprOptions;
@@ -1297,40 +1297,6 @@ impl<'tcx> TyCtxt<'tcx> {
         self.get_lang_items(LOCAL_CRATE)
     }
 
-    /// Due to missing llvm support for lowering 128 bit math to software emulation
-    /// (on some targets), the lowering can be done in MIR.
-    ///
-    /// This function only exists until said support is implemented.
-    pub fn is_binop_lang_item(&self, def_id: DefId) -> Option<(mir::BinOp, bool)> {
-        let items = self.lang_items();
-        let def_id = Some(def_id);
-        if items.i128_add_fn() == def_id { Some((mir::BinOp::Add, false)) }
-        else if items.u128_add_fn() == def_id { Some((mir::BinOp::Add, false)) }
-        else if items.i128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) }
-        else if items.u128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) }
-        else if items.i128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) }
-        else if items.u128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) }
-        else if items.i128_div_fn() == def_id { Some((mir::BinOp::Div, false)) }
-        else if items.u128_div_fn() == def_id { Some((mir::BinOp::Div, false)) }
-        else if items.i128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) }
-        else if items.u128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) }
-        else if items.i128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) }
-        else if items.u128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) }
-        else if items.i128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) }
-        else if items.u128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) }
-        else if items.i128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) }
-        else if items.u128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) }
-        else if items.i128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) }
-        else if items.u128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) }
-        else if items.i128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) }
-        else if items.u128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) }
-        else if items.i128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) }
-        else if items.u128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) }
-        else if items.i128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) }
-        else if items.u128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) }
-        else { None }
-    }
-
     pub fn stability(self) -> &'tcx stability::Index<'tcx> {
         self.stability_index(LOCAL_CRATE)
     }
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 4ed52a1e966..3b4b814c92a 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -246,6 +246,14 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         let align = a.value.align(dl).max(b_align).max(dl.aggregate_align);
         let b_offset = a.value.size(dl).align_to(b_align.abi);
         let size = (b_offset + b.value.size(dl)).align_to(align.abi);
+
+        // HACK(nox): We iter on `b` and then `a` because `max_by_key`
+        // returns the last maximum.
+        let largest_niche = Niche::from_scalar(dl, b_offset, b.clone())
+            .into_iter()
+            .chain(Niche::from_scalar(dl, Size::ZERO, a.clone()))
+            .max_by_key(|niche| niche.available(dl));
+
         LayoutDetails {
             variants: Variants::Single { index: VariantIdx::new(0) },
             fields: FieldPlacement::Arbitrary {
@@ -253,6 +261,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 memory_index: vec![0, 1]
             },
             abi: Abi::ScalarPair(a, b),
+            largest_niche,
             align,
             size
         }
@@ -321,6 +330,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
 
 
         let mut offset = Size::ZERO;
+        let mut largest_niche = None;
+        let mut largest_niche_available = 0;
 
         if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
             let prefix_align = if packed {
@@ -355,6 +366,15 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             debug!("univariant offset: {:?} field: {:#?}", offset, field);
             offsets[i as usize] = offset;
 
+            if let Some(mut niche) = field.largest_niche.clone() {
+                let available = niche.available(dl);
+                if available > largest_niche_available {
+                    largest_niche_available = available;
+                    niche.offset += offset;
+                    largest_niche = Some(niche);
+                }
+            }
+
             offset = offset.checked_add(field.size, dl)
                 .ok_or(LayoutError::SizeOverflow(ty))?;
         }
@@ -466,6 +486,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 memory_index
             },
             abi,
+            largest_niche,
             align,
             size
         })
@@ -525,6 +546,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     variants: Variants::Single { index: VariantIdx::new(0) },
                     fields: FieldPlacement::Union(0),
                     abi: Abi::Uninhabited,
+                    largest_niche: None,
                     align: dl.i8_align,
                     size: Size::ZERO
                 })
@@ -583,6 +605,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     Abi::Aggregate { sized: true }
                 };
 
+                let largest_niche = if count != 0 {
+                    element.largest_niche.clone()
+                } else {
+                    None
+                };
+
                 tcx.intern_layout(LayoutDetails {
                     variants: Variants::Single { index: VariantIdx::new(0) },
                     fields: FieldPlacement::Array {
@@ -590,6 +618,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         count
                     },
                     abi,
+                    largest_niche,
                     align: element.align,
                     size
                 })
@@ -603,6 +632,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         count: 0
                     },
                     abi: Abi::Aggregate { sized: false },
+                    largest_niche: None,
                     align: element.align,
                     size: Size::ZERO
                 })
@@ -615,6 +645,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         count: 0
                     },
                     abi: Abi::Aggregate { sized: false },
+                    largest_niche: None,
                     align: dl.i8_align,
                     size: Size::ZERO
                 })
@@ -683,6 +714,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         element: scalar,
                         count
                     },
+                    largest_niche: element.largest_niche.clone(),
                     size,
                     align,
                 })
@@ -768,6 +800,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         variants: Variants::Single { index },
                         fields: FieldPlacement::Union(variants[index].len()),
                         abi,
+                        largest_niche: None,
                         align,
                         size: size.align_to(align.abi)
                     }));
@@ -829,14 +862,38 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                             // `#[rustc_layout_scalar_valid_range(n)]`
                             // attribute to widen the range of anything as that would probably
                             // result in UB somewhere
+                            // FIXME(eddyb) the asserts are probably not needed,
+                            // as larger validity ranges would result in missed
+                            // optimizations, *not* wrongly assuming the inner
+                            // value is valid. e.g. unions enlarge validity ranges,
+                            // because the values may be uninitialized.
                             if let Bound::Included(start) = start {
+                                // FIXME(eddyb) this might be incorrect - it doesn't
+                                // account for wrap-around (end < start) ranges.
                                 assert!(*scalar.valid_range.start() <= start);
                                 scalar.valid_range = start..=*scalar.valid_range.end();
                             }
                             if let Bound::Included(end) = end {
+                                // FIXME(eddyb) this might be incorrect - it doesn't
+                                // account for wrap-around (end < start) ranges.
                                 assert!(*scalar.valid_range.end() >= end);
                                 scalar.valid_range = *scalar.valid_range.start()..=end;
                             }
+
+                            // Update `largest_niche` if we have introduced a larger niche.
+                            let niche = Niche::from_scalar(dl, Size::ZERO, scalar.clone());
+                            if let Some(niche) = niche {
+                                match &st.largest_niche {
+                                    Some(largest_niche) => {
+                                        // Replace the existing niche even if they're equal,
+                                        // because this one is at a lower offset.
+                                        if largest_niche.available(dl) <= niche.available(dl) {
+                                            st.largest_niche = Some(niche);
+                                        }
+                                    }
+                                    None => st.largest_niche = Some(niche),
+                                }
+                            }
                         }
                         _ => assert!(
                             start == Bound::Unbounded && end == Bound::Unbounded,
@@ -845,6 +902,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                             st,
                         ),
                     }
+
                     return Ok(tcx.intern_layout(st));
                 }
 
@@ -886,8 +944,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         let count = (
                             niche_variants.end().as_u32() - niche_variants.start().as_u32() + 1
                         ) as u128;
+                        // FIXME(#62691) use the largest niche across all fields,
+                        // not just the first one.
                         for (field_index, &field) in variants[i].iter().enumerate() {
-                            let niche = match self.find_niche(field)? {
+                            let niche = match &field.largest_niche {
                                 Some(niche) => niche,
                                 _ => continue,
                             };
@@ -937,6 +997,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                                 abi = Abi::Uninhabited;
                             }
 
+
+                            let largest_niche =
+                                Niche::from_scalar(dl, offset, niche_scalar.clone());
+
                             return Ok(tcx.intern_layout(LayoutDetails {
                                 variants: Variants::Multiple {
                                     discr: niche_scalar,
@@ -953,6 +1017,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                                     memory_index: vec![0]
                                 },
                                 abi,
+                                largest_niche,
                                 size,
                                 align,
                             }));
@@ -1164,6 +1229,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     abi = Abi::Uninhabited;
                 }
 
+                let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag.clone());
+
                 tcx.intern_layout(LayoutDetails {
                     variants: Variants::Multiple {
                         discr: tag,
@@ -1175,6 +1242,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         offsets: vec![Size::ZERO],
                         memory_index: vec![0]
                     },
+                    largest_niche,
                     abi,
                     align,
                     size
@@ -1332,16 +1400,31 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         // locals as part of the prefix. We compute the layout of all of
         // these fields at once to get optimal packing.
         let discr_index = substs.prefix_tys(def_id, tcx).count();
-        let promoted_tys =
-            ineligible_locals.iter().map(|local| subst_field(info.field_tys[local]));
-        let prefix_tys = substs.prefix_tys(def_id, tcx)
-            .chain(iter::once(substs.discr_ty(tcx)))
-            .chain(promoted_tys);
-        let prefix = self.univariant_uninterned(
+        // FIXME(eddyb) set the correct vaidity range for the discriminant.
+        let discr_layout = self.layout_of(substs.discr_ty(tcx))?;
+        let discr = match &discr_layout.abi {
+            Abi::Scalar(s) => s.clone(),
+            _ => bug!(),
+        };
+        // FIXME(eddyb) wrap each promoted type in `MaybeUninit` so that they
+        // don't poison the `largest_niche` or `abi` fields of `prefix`.
+        let promoted_layouts = ineligible_locals.iter()
+            .map(|local| subst_field(info.field_tys[local]))
+            .map(|ty| self.layout_of(ty));
+        let prefix_layouts = substs.prefix_tys(def_id, tcx)
+            .map(|ty| self.layout_of(ty))
+            .chain(iter::once(Ok(discr_layout)))
+            .chain(promoted_layouts)
+            .collect::<Result<Vec<_>, _>>()?;
+        let mut prefix = self.univariant_uninterned(
             ty,
-            &prefix_tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
+            &prefix_layouts,
             &ReprOptions::default(),
-            StructKind::AlwaysSized)?;
+            StructKind::AlwaysSized,
+        )?;
+        // FIXME(eddyb) need `MaybeUninit` around promoted types (see above).
+        prefix.largest_niche = None;
+
         let (prefix_size, prefix_align) = (prefix.size, prefix.align);
 
         // Split the prefix layout into the "outer" fields (upvars and
@@ -1463,10 +1546,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         } else {
             Abi::Aggregate { sized: true }
         };
-        let discr = match &self.layout_of(substs.discr_ty(tcx))?.abi {
-            Abi::Scalar(s) => s.clone(),
-            _ => bug!(),
-        };
 
         let layout = tcx.intern_layout(LayoutDetails {
             variants: Variants::Multiple {
@@ -1477,6 +1556,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             },
             fields: outer_fields,
             abi,
+            largest_niche: prefix.largest_niche,
             size,
             align,
         });
@@ -1950,6 +2030,7 @@ where
                     variants: Variants::Single { index: variant_index },
                     fields: FieldPlacement::Union(fields),
                     abi: Abi::Uninhabited,
+                    largest_niche: None,
                     align: tcx.data_layout.i8_align,
                     size: Size::ZERO
                 })
@@ -2222,120 +2303,6 @@ where
     }
 }
 
-struct Niche {
-    offset: Size,
-    scalar: Scalar,
-    available: u128,
-}
-
-impl Niche {
-    fn reserve<'tcx>(
-        &self,
-        cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
-        count: u128,
-    ) -> Option<(u128, Scalar)> {
-        if count > self.available {
-            return None;
-        }
-        let Scalar { value, valid_range: ref v } = self.scalar;
-        let bits = value.size(cx).bits();
-        assert!(bits <= 128);
-        let max_value = !0u128 >> (128 - bits);
-        let start = v.end().wrapping_add(1) & max_value;
-        let end = v.end().wrapping_add(count) & max_value;
-        Some((start, Scalar { value, valid_range: *v.start()..=end }))
-    }
-}
-
-impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
-    /// Find the offset of a niche leaf field, starting from
-    /// the given type and recursing through aggregates.
-    // FIXME(eddyb) traverse already optimized enums.
-    fn find_niche(&self, layout: TyLayout<'tcx>) -> Result<Option<Niche>, LayoutError<'tcx>> {
-        let scalar_niche = |scalar: &Scalar, offset| {
-            let Scalar { value, valid_range: ref v } = *scalar;
-
-            let bits = value.size(self).bits();
-            assert!(bits <= 128);
-            let max_value = !0u128 >> (128 - bits);
-
-            // Find out how many values are outside the valid range.
-            let available = if v.start() <= v.end() {
-                v.start() + (max_value - v.end())
-            } else {
-                v.start() - v.end() - 1
-            };
-
-            // Give up if there is no niche value available.
-            if available == 0 {
-                return None;
-            }
-
-            Some(Niche { offset, scalar: scalar.clone(), available })
-        };
-
-        // Locals variables which live across yields are stored
-        // in the generator type as fields. These may be uninitialized
-        // so we don't look for niches there.
-        if let ty::Generator(..) = layout.ty.sty {
-            return Ok(None);
-        }
-
-        match layout.abi {
-            Abi::Scalar(ref scalar) => {
-                return Ok(scalar_niche(scalar, Size::ZERO));
-            }
-            Abi::ScalarPair(ref a, ref b) => {
-                // HACK(nox): We iter on `b` and then `a` because `max_by_key`
-                // returns the last maximum.
-                let niche = iter::once(
-                    (b, a.value.size(self).align_to(b.value.align(self).abi))
-                )
-                    .chain(iter::once((a, Size::ZERO)))
-                    .filter_map(|(scalar, offset)| scalar_niche(scalar, offset))
-                    .max_by_key(|niche| niche.available);
-                return Ok(niche);
-            }
-            Abi::Vector { ref element, .. } => {
-                return Ok(scalar_niche(element, Size::ZERO));
-            }
-            _ => {}
-        }
-
-        // Perhaps one of the fields is non-zero, let's recurse and find out.
-        if let FieldPlacement::Union(_) = layout.fields {
-            // Only Rust enums have safe-to-inspect fields
-            // (a discriminant), other unions are unsafe.
-            if let Variants::Single { .. } = layout.variants {
-                return Ok(None);
-            }
-        }
-        if let FieldPlacement::Array { count: original_64_bit_count, .. } = layout.fields {
-            // rust-lang/rust#57038: avoid ICE within FieldPlacement::count when count too big
-            if original_64_bit_count > usize::max_value() as u64 {
-                return Err(LayoutError::SizeOverflow(layout.ty));
-            }
-            if layout.fields.count() > 0 {
-                return self.find_niche(layout.field(self, 0)?);
-            } else {
-                return Ok(None);
-            }
-        }
-        let mut niche = None;
-        let mut available = 0;
-        for i in 0..layout.fields.count() {
-            if let Some(mut c) = self.find_niche(layout.field(self, i)?)? {
-                if c.available > available {
-                    available = c.available;
-                    c.offset += layout.fields.offset(i);
-                    niche = Some(c);
-                }
-            }
-        }
-        Ok(niche)
-    }
-}
-
 impl<'a> HashStable<StableHashingContext<'a>> for Variants {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
@@ -2456,10 +2423,16 @@ impl<'a> HashStable<StableHashingContext<'a>> for Scalar {
     }
 }
 
+impl_stable_hash_for!(struct crate::ty::layout::Niche {
+    offset,
+    scalar
+});
+
 impl_stable_hash_for!(struct crate::ty::layout::LayoutDetails {
     variants,
     fields,
     abi,
+    largest_niche,
     size,
     align
 });
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 49a0fd827fb..77b8ebba216 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -1847,7 +1847,7 @@ impl<'tcx> TyS<'tcx> {
     }
 
     #[inline]
-    pub fn is_mutable_pointer(&self) -> bool {
+    pub fn is_mutable_ptr(&self) -> bool {
         match self.sty {
             RawPtr(TypeAndMut { mutbl: hir::Mutability::MutMutable, .. }) |
             Ref(_, _, hir::Mutability::MutMutable) => true,
@@ -2002,7 +2002,7 @@ impl<'tcx> TyS<'tcx> {
     }
 
     #[inline]
-    pub fn is_pointer_sized(&self) -> bool {
+    pub fn is_ptr_sized_integral(&self) -> bool {
         match self.sty {
             Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => true,
             _ => false,
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index 5ac1cf8c36f..894e5c2fd3d 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -1153,11 +1153,14 @@ impl Builder<'a, 'll, 'tcx> {
         }
     }
 
+    pub fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
+        unsafe { llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) }
+    }
+    pub fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
+        unsafe { llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) }
+    }
     pub fn vector_reduce_fadd_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
         unsafe {
-            // FIXME: add a non-fast math version once
-            // https://bugs.llvm.org/show_bug.cgi?id=36732
-            // is fixed.
             let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src);
             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
             instr
@@ -1165,9 +1168,6 @@ impl Builder<'a, 'll, 'tcx> {
     }
     pub fn vector_reduce_fmul_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
         unsafe {
-            // FIXME: add a non-fast math version once
-            // https://bugs.llvm.org/show_bug.cgi?id=36732
-            // is fixed.
             let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src);
             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
             instr
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index e9f25e6344b..f00624f3811 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -166,25 +166,6 @@ impl CodegenCx<'ll, 'tcx> {
             r
         }
     }
-
-    pub fn const_get_real(&self, v: &'ll Value) -> Option<(f64, bool)> {
-        unsafe {
-            if self.is_const_real(v) {
-                let mut loses_info: llvm::Bool = 0;
-                let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info);
-                let loses_info = if loses_info == 1 { true } else { false };
-                Some((r, loses_info))
-            } else {
-                None
-            }
-        }
-    }
-
-    fn is_const_real(&self, v: &'ll Value) -> bool {
-        unsafe {
-            llvm::LLVMIsAConstantFP(v).is_some()
-        }
-    }
 }
 
 impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index dd6cfd7e29e..44b3eff2ac5 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -1640,29 +1640,11 @@ fn generic_simd_intrinsic(
                         }
                     },
                     ty::Float(f) => {
-                        // ordered arithmetic reductions take an accumulator
                         let acc = if $ordered {
-                            let acc = args[1].immediate();
-                            // FIXME: https://bugs.llvm.org/show_bug.cgi?id=36734
-                            // * if the accumulator of the fadd isn't 0, incorrect
-                            //   code is generated
-                            // * if the accumulator of the fmul isn't 1, incorrect
-                            //   code is generated
-                            match bx.const_get_real(acc) {
-                                None => return_error!("accumulator of {} is not a constant", $name),
-                                Some((v, loses_info)) => {
-                                    if $name.contains("mul") && v != 1.0_f64 {
-                                        return_error!("accumulator of {} is not 1.0", $name);
-                                    } else if $name.contains("add") && v != 0.0_f64 {
-                                        return_error!("accumulator of {} is not 0.0", $name);
-                                    } else if loses_info {
-                                        return_error!("accumulator of {} loses information", $name);
-                                    }
-                                }
-                            }
-                            acc
+                            // ordered arithmetic reductions take an accumulator
+                            args[1].immediate()
                         } else {
-                            // unordered arithmetic reductions do not:
+                            // unordered arithmetic reductions use the identity accumulator
                             let identity_acc = if $name.contains("mul") { 1.0 } else { 0.0 };
                             match f.bit_width() {
                                 32 => bx.const_real(bx.type_f32(), identity_acc),
@@ -1688,8 +1670,8 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
         }
     }
 
-    arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd_fast, true);
-    arith_red!("simd_reduce_mul_ordered": vector_reduce_mul, vector_reduce_fmul_fast, true);
+    arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd, true);
+    arith_red!("simd_reduce_mul_ordered": vector_reduce_mul, vector_reduce_fmul, true);
     arith_red!("simd_reduce_add_unordered": vector_reduce_add, vector_reduce_fadd_fast, false);
     arith_red!("simd_reduce_mul_unordered": vector_reduce_mul, vector_reduce_fmul_fast, false);
 
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 5d82698d8ef..8c6ea00eb8c 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -719,7 +719,6 @@ extern "C" {
     pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong;
     pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool,
                                   high: &mut u64, low: &mut u64) -> bool;
-    pub fn LLVMConstRealGetDouble (ConstantVal: &Value, losesInfo: &mut Bool) -> f64;
 
 
     // Operations on composite constants
@@ -1663,7 +1662,6 @@ extern "C" {
     pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString);
 
     pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>;
-    pub fn LLVMIsAConstantFP(value_ref: &Value) -> Option<&Value>;
 
     pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind;
     pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>;
diff --git a/src/librustc_errors/Cargo.toml b/src/librustc_errors/Cargo.toml
index 5a192e472aa..32f121f18f6 100644
--- a/src/librustc_errors/Cargo.toml
+++ b/src/librustc_errors/Cargo.toml
@@ -17,4 +17,4 @@ rustc_data_structures = { path = "../librustc_data_structures" }
 unicode-width = "0.1.4"
 atty = "0.2"
 termcolor = "1.0"
-annotate-snippets = "0.5.0"
+annotate-snippets = "0.6.1"
diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs
index 3641d355ef1..96a9b6c5c4f 100644
--- a/src/librustc_errors/annotate_snippet_emitter_writer.rs
+++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs
@@ -23,7 +23,7 @@ pub struct AnnotateSnippetEmitterWriter {
     source_map: Option<Lrc<SourceMapperDyn>>,
     /// If true, hides the longer explanation text
     short_message: bool,
-    /// If true, will normalize line numbers with LL to prevent noise in UI test diffs.
+    /// If true, will normalize line numbers with `LL` to prevent noise in UI test diffs.
     ui_testing: bool,
 }
 
@@ -173,10 +173,6 @@ impl AnnotateSnippetEmitterWriter {
     /// Allows to modify `Self` to enable or disable the `ui_testing` flag.
     ///
     /// If this is set to true, line numbers will be normalized as `LL` in the output.
-    // FIXME(#59346): This method is used via the public interface, but setting the `ui_testing`
-    // flag currently does not anonymize line numbers. We would have to add the `maybe_anonymized`
-    // method from `emitter.rs` and implement rust-lang/annotate-snippets-rs#2 in order to
-    // anonymize line numbers.
     pub fn ui_testing(mut self, ui_testing: bool) -> Self {
         self.ui_testing = ui_testing;
         self
@@ -202,7 +198,7 @@ impl AnnotateSnippetEmitterWriter {
         };
         if let Some(snippet) = converter.to_annotation_snippet() {
             let dl = DisplayList::from(snippet);
-            let dlf = DisplayListFormatter::new(true);
+            let dlf = DisplayListFormatter::new(true, self.ui_testing);
             // FIXME(#59346): Figure out if we can _always_ print to stderr or not.
             // `emitter.rs` has the `Destination` enum that lists various possible output
             // destinations.
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
index 3def2d8232f..16cdbb7dd4d 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -112,6 +112,10 @@ fn main() {
         println!("cargo:rustc-cfg=llvm_component=\"{}\"", component);
     }
 
+    if major >= 9 {
+        println!("cargo:rustc-cfg=llvm_has_msp430_asm_parser");
+    }
+
     // Link in our own LLVM shims, compiled with the same flags as LLVM
     let mut cmd = Command::new(&llvm_config);
     cmd.arg("--cxxflags");
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index bdf6b091857..dea7e6ae0a2 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -76,6 +76,8 @@ pub fn initialize_available_targets() {
                  LLVMInitializeMSP430Target,
                  LLVMInitializeMSP430TargetMC,
                  LLVMInitializeMSP430AsmPrinter);
+    init_target!(all(llvm_component = "msp430", llvm_has_msp430_asm_parser),
+                 LLVMInitializeMSP430AsmParser);
     init_target!(llvm_component = "riscv",
                  LLVMInitializeRISCVTargetInfo,
                  LLVMInitializeRISCVTarget,
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index a05c77aad67..c767279dd8c 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -536,7 +536,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let base_ty = Place::ty_from(deref_base.base, deref_base.projection, self.body, tcx).ty;
         if base_ty.is_unsafe_ptr() {
             BorrowedContentSource::DerefRawPointer
-        } else if base_ty.is_mutable_pointer() {
+        } else if base_ty.is_mutable_ptr() {
             BorrowedContentSource::DerefMutableRef
         } else {
             BorrowedContentSource::DerefSharedRef
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 92285c47db4..92774bbb7a6 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -1329,7 +1329,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 base: PlaceBase::Local(local),
                 projection: None,
             }) if self.body.local_decls[local].is_user_variable.is_none() => {
-                if self.body.local_decls[local].ty.is_mutable_pointer() {
+                if self.body.local_decls[local].ty.is_mutable_ptr() {
                     // The variable will be marked as mutable by the borrow.
                     return;
                 }
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index d356194c003..567bac777d2 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -1171,7 +1171,7 @@ pub fn is_useful<'p, 'a, 'tcx>(
         // For privately empty and non-exhaustive enums, we work as if there were an "extra"
         // `_` constructor for the type, so we can never match over all constructors.
         let is_non_exhaustive = is_privately_empty || is_declared_nonexhaustive ||
-            (pcx.ty.is_pointer_sized() && !cx.tcx.features().precise_pointer_size_matching);
+            (pcx.ty.is_ptr_sized_integral() && !cx.tcx.features().precise_pointer_size_matching);
 
         if cheap_missing_ctors == MissingCtors::Empty && !is_non_exhaustive {
             split_grouped_constructors(cx.tcx, all_ctors, matrix, pcx.ty).into_iter().map(|c| {
@@ -1488,7 +1488,7 @@ fn should_treat_range_exhaustively(tcx: TyCtxt<'tcx>, ctor: &Constructor<'tcx>)
         _ => return false,
     };
     if let ty::Char | ty::Int(_) | ty::Uint(_) = ty.sty {
-        !ty.is_pointer_sized() || tcx.features().precise_pointer_size_matching
+        !ty.is_ptr_sized_integral() || tcx.features().precise_pointer_size_matching
     } else {
         false
     }
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 6623661f938..6a5b933e4a5 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -230,21 +230,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         &mut self,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, M::PointerTag>],
-        dest: Option<PlaceTy<'tcx, M::PointerTag>>,
+        _dest: Option<PlaceTy<'tcx, M::PointerTag>>,
     ) -> InterpResult<'tcx, bool> {
         let def_id = instance.def_id();
-        // Some fn calls are actually BinOp intrinsics
-        if let Some((op, oflo)) = self.tcx.is_binop_lang_item(def_id) {
-            let dest = dest.expect("128 lowerings can't diverge");
-            let l = self.read_immediate(args[0])?;
-            let r = self.read_immediate(args[1])?;
-            if oflo {
-                self.binop_with_overflow(op, l, r, dest)?;
-            } else {
-                self.binop_ignore_overflow(op, l, r, dest)?;
-            }
-            return Ok(true);
-        } else if Some(def_id) == self.tcx.lang_items().panic_fn() {
+        if Some(def_id) == self.tcx.lang_items().panic_fn() {
             assert!(args.len() == 1);
             // &(&'static str, &'static str, u32, u32)
             let place = self.deref_operand(args[0])?;
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 343832fe4a7..40cb1fbdc57 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -232,13 +232,6 @@ impl Inliner<'tcx> {
             return false;
         }
 
-        // Do not inline {u,i}128 lang items, codegen const eval depends
-        // on detecting calls to these lang items and intercepting them
-        if tcx.is_binop_lang_item(callsite.callee).is_some() {
-            debug!("    not inlining 128bit integer lang item");
-            return false;
-        }
-
         let codegen_fn_attrs = tcx.codegen_fn_attrs(callsite.callee);
 
         let hinted = match codegen_fn_attrs.inline {
diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs
deleted file mode 100644
index f09a77d486c..00000000000
--- a/src/librustc_mir/transform/lower_128bit.rs
+++ /dev/null
@@ -1,230 +0,0 @@
-//! Replaces 128-bit operators with lang item calls
-
-use rustc::hir::def_id::DefId;
-use rustc::middle::lang_items::LangItem;
-use rustc::mir::*;
-use rustc::ty::{self, List, Ty, TyCtxt};
-use rustc_data_structures::indexed_vec::{Idx};
-use crate::transform::{MirPass, MirSource};
-
-pub struct Lower128Bit;
-
-impl MirPass for Lower128Bit {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
-        let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops;
-        let target_default = tcx.sess.host.options.i128_lowering;
-        if !debugging_override.unwrap_or(target_default) {
-            return
-        }
-
-        self.lower_128bit_ops(tcx, body);
-}
-}
-
-impl Lower128Bit {
-    fn lower_128bit_ops<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        let mut new_blocks = Vec::new();
-        let cur_len = body.basic_blocks().len();
-
-        let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
-        for block in basic_blocks.iter_mut() {
-            for i in (0..block.statements.len()).rev() {
-                let (lang_item, rhs_kind) =
-                    if let Some((lang_item, rhs_kind)) =
-                        lower_to(&block.statements[i], local_decls, tcx)
-                    {
-                        (lang_item, rhs_kind)
-                    } else {
-                        continue;
-                    };
-
-                let rhs_override_ty = rhs_kind.ty(tcx);
-                let cast_local =
-                    match rhs_override_ty {
-                        None => None,
-                        Some(ty) => {
-                            let local_decl = LocalDecl::new_internal(
-                                ty, block.statements[i].source_info.span);
-                            Some(local_decls.push(local_decl))
-                        },
-                    };
-
-                let storage_dead = cast_local.map(|local| {
-                    Statement {
-                        source_info: block.statements[i].source_info,
-                        kind: StatementKind::StorageDead(local),
-                    }
-                });
-                let after_call = BasicBlockData {
-                    statements: storage_dead.into_iter()
-                        .chain(block.statements.drain((i+1)..)).collect(),
-                    is_cleanup: block.is_cleanup,
-                    terminator: block.terminator.take(),
-                };
-
-                let bin_statement = block.statements.pop().unwrap();
-                let source_info = bin_statement.source_info;
-                let (place, lhs, mut rhs) = match bin_statement.kind {
-                    StatementKind::Assign(place, box rvalue) => {
-                        match rvalue {
-                            Rvalue::BinaryOp(_, lhs, rhs)
-                            | Rvalue::CheckedBinaryOp(_, lhs, rhs) => (place, lhs, rhs),
-                            _ => bug!(),
-                        }
-                    }
-                    _ => bug!()
-                };
-
-                if let Some(local) = cast_local {
-                    block.statements.push(Statement {
-                        source_info: source_info,
-                        kind: StatementKind::StorageLive(local),
-                    });
-                    block.statements.push(Statement {
-                        source_info: source_info,
-                        kind: StatementKind::Assign(
-                            Place::from(local),
-                            box Rvalue::Cast(
-                                CastKind::Misc,
-                                rhs,
-                                rhs_override_ty.unwrap())),
-                    });
-                    rhs = Operand::Move(Place::from(local));
-                }
-
-                let call_did = check_lang_item_type(
-                    lang_item, &place, &lhs, &rhs, local_decls, tcx);
-
-                let bb = BasicBlock::new(cur_len + new_blocks.len());
-                new_blocks.push(after_call);
-
-                block.terminator =
-                    Some(Terminator {
-                        source_info,
-                        kind: TerminatorKind::Call {
-                            func: Operand::function_handle(tcx, call_did,
-                                List::empty(), source_info.span),
-                            args: vec![lhs, rhs],
-                            destination: Some((place, bb)),
-                            cleanup: None,
-                            from_hir_call: false,
-                        },
-                    });
-            }
-        }
-
-        basic_blocks.extend(new_blocks);
-    }
-}
-
-fn check_lang_item_type<'tcx, D>(
-    lang_item: LangItem,
-    place: &Place<'tcx>,
-    lhs: &Operand<'tcx>,
-    rhs: &Operand<'tcx>,
-    local_decls: &D,
-    tcx: TyCtxt<'tcx>,
-) -> DefId
-where
-    D: HasLocalDecls<'tcx>,
-{
-    let did = tcx.require_lang_item(lang_item);
-    let poly_sig = tcx.fn_sig(did);
-    let sig = poly_sig.no_bound_vars().unwrap();
-    let lhs_ty = lhs.ty(local_decls, tcx);
-    let rhs_ty = rhs.ty(local_decls, tcx);
-    let place_ty = place.ty(local_decls, tcx).ty;
-    let expected = [lhs_ty, rhs_ty, place_ty];
-    assert_eq!(sig.inputs_and_output[..], expected,
-        "lang item `{}`", tcx.def_path_str(did));
-    did
-}
-
-fn lower_to<'tcx, D>(
-    statement: &Statement<'tcx>,
-    local_decls: &D,
-    tcx: TyCtxt<'tcx>,
-) -> Option<(LangItem, RhsKind)>
-where
-    D: HasLocalDecls<'tcx>,
-{
-    match statement.kind {
-        StatementKind::Assign(_, box Rvalue::BinaryOp(bin_op, ref lhs, _)) => {
-            let ty = lhs.ty(local_decls, tcx);
-            if let Some(is_signed) = sign_of_128bit(ty) {
-                return item_for_op(bin_op, is_signed);
-            }
-        },
-        StatementKind::Assign(_, box Rvalue::CheckedBinaryOp(bin_op, ref lhs, _)) => {
-            let ty = lhs.ty(local_decls, tcx);
-            if let Some(is_signed) = sign_of_128bit(ty) {
-                return item_for_checked_op(bin_op, is_signed);
-            }
-        },
-        _ => {},
-    }
-    None
-}
-
-#[derive(Copy, Clone)]
-enum RhsKind {
-    Unchanged,
-    ForceU128,
-    ForceU32,
-}
-
-impl RhsKind {
-    fn ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<Ty<'tcx>> {
-        match *self {
-            RhsKind::Unchanged => None,
-            RhsKind::ForceU128 => Some(tcx.types.u128),
-            RhsKind::ForceU32 => Some(tcx.types.u32),
-        }
-    }
-}
-
-fn sign_of_128bit(ty: Ty<'_>) -> Option<bool> {
-    match ty.sty {
-        ty::Int(syntax::ast::IntTy::I128) => Some(true),
-        ty::Uint(syntax::ast::UintTy::U128) => Some(false),
-        _ => None,
-    }
-}
-
-fn item_for_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> {
-    let i = match (bin_op, is_signed) {
-        (BinOp::Add, true) => (LangItem::I128AddFnLangItem, RhsKind::Unchanged),
-        (BinOp::Add, false) => (LangItem::U128AddFnLangItem, RhsKind::Unchanged),
-        (BinOp::Sub, true) => (LangItem::I128SubFnLangItem, RhsKind::Unchanged),
-        (BinOp::Sub, false) => (LangItem::U128SubFnLangItem, RhsKind::Unchanged),
-        (BinOp::Mul, true) => (LangItem::I128MulFnLangItem, RhsKind::Unchanged),
-        (BinOp::Mul, false) => (LangItem::U128MulFnLangItem, RhsKind::Unchanged),
-        (BinOp::Div, true) => (LangItem::I128DivFnLangItem, RhsKind::Unchanged),
-        (BinOp::Div, false) => (LangItem::U128DivFnLangItem, RhsKind::Unchanged),
-        (BinOp::Rem, true) => (LangItem::I128RemFnLangItem, RhsKind::Unchanged),
-        (BinOp::Rem, false) => (LangItem::U128RemFnLangItem, RhsKind::Unchanged),
-        (BinOp::Shl, true) => (LangItem::I128ShlFnLangItem, RhsKind::ForceU32),
-        (BinOp::Shl, false) => (LangItem::U128ShlFnLangItem, RhsKind::ForceU32),
-        (BinOp::Shr, true) => (LangItem::I128ShrFnLangItem, RhsKind::ForceU32),
-        (BinOp::Shr, false) => (LangItem::U128ShrFnLangItem, RhsKind::ForceU32),
-        _ => return None,
-    };
-    Some(i)
-}
-
-fn item_for_checked_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> {
-    let i = match (bin_op, is_signed) {
-        (BinOp::Add, true) => (LangItem::I128AddoFnLangItem, RhsKind::Unchanged),
-        (BinOp::Add, false) => (LangItem::U128AddoFnLangItem, RhsKind::Unchanged),
-        (BinOp::Sub, true) => (LangItem::I128SuboFnLangItem, RhsKind::Unchanged),
-        (BinOp::Sub, false) => (LangItem::U128SuboFnLangItem, RhsKind::Unchanged),
-        (BinOp::Mul, true) => (LangItem::I128MuloFnLangItem, RhsKind::Unchanged),
-        (BinOp::Mul, false) => (LangItem::U128MuloFnLangItem, RhsKind::Unchanged),
-        (BinOp::Shl, true) => (LangItem::I128ShloFnLangItem, RhsKind::ForceU128),
-        (BinOp::Shl, false) => (LangItem::U128ShloFnLangItem, RhsKind::ForceU128),
-        (BinOp::Shr, true) => (LangItem::I128ShroFnLangItem, RhsKind::ForceU128),
-        (BinOp::Shr, false) => (LangItem::U128ShroFnLangItem, RhsKind::ForceU128),
-        _ => bug!("That should be all the checked ones?"),
-    };
-    Some(i)
-}
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 195a652b0a2..61d0b1f3485 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -34,7 +34,6 @@ pub mod copy_prop;
 pub mod const_prop;
 pub mod generator;
 pub mod inline;
-pub mod lower_128bit;
 pub mod uniform_array_move_out;
 
 pub(crate) fn provide(providers: &mut Providers<'_>) {
@@ -272,8 +271,6 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> {
         // From here on out, regions are gone.
         &erase_regions::EraseRegions,
 
-        &lower_128bit::Lower128Bit,
-
 
         // Optimizations begin.
         &uniform_array_move_out::RestoreSubsliceArrayMoveOut,
diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs
index 01586e92aeb..4a4c6799c00 100644
--- a/src/librustc_target/abi/mod.rs
+++ b/src/librustc_target/abi/mod.rs
@@ -878,23 +878,94 @@ pub enum DiscriminantKind {
     },
 }
 
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+pub struct Niche {
+    pub offset: Size,
+    pub scalar: Scalar,
+}
+
+impl Niche {
+    pub fn from_scalar<C: HasDataLayout>(cx: &C, offset: Size, scalar: Scalar) -> Option<Self> {
+        let niche = Niche {
+            offset,
+            scalar,
+        };
+        if niche.available(cx) > 0 {
+            Some(niche)
+        } else {
+            None
+        }
+    }
+
+    pub fn available<C: HasDataLayout>(&self, cx: &C) -> u128 {
+        let Scalar { value, valid_range: ref v } = self.scalar;
+        let bits = value.size(cx).bits();
+        assert!(bits <= 128);
+        let max_value = !0u128 >> (128 - bits);
+
+        // Find out how many values are outside the valid range.
+        let niche = v.end().wrapping_add(1)..*v.start();
+        niche.end.wrapping_sub(niche.start) & max_value
+    }
+
+    pub fn reserve<C: HasDataLayout>(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> {
+        assert!(count > 0);
+
+        let Scalar { value, valid_range: ref v } = self.scalar;
+        let bits = value.size(cx).bits();
+        assert!(bits <= 128);
+        let max_value = !0u128 >> (128 - bits);
+
+        if count > max_value {
+            return None;
+        }
+
+        // Compute the range of invalid values being reserved.
+        let start = v.end().wrapping_add(1) & max_value;
+        let end = v.end().wrapping_add(count) & max_value;
+
+        // If the `end` of our range is inside the valid range,
+        // then we ran out of invalid values.
+        // FIXME(eddyb) abstract this with a wraparound range type.
+        let valid_range_contains = |x| {
+            if v.start() <= v.end() {
+                *v.start() <= x && x <= *v.end()
+            } else {
+                *v.start() <= x || x <= *v.end()
+            }
+        };
+        if valid_range_contains(end) {
+            return None;
+        }
+
+        Some((start, Scalar { value, valid_range: *v.start()..=end }))
+    }
+}
+
 #[derive(PartialEq, Eq, Hash, Debug)]
 pub struct LayoutDetails {
     pub variants: Variants,
     pub fields: FieldPlacement,
     pub abi: Abi,
+
+    /// The leaf scalar with the largest number of invalid values
+    /// (i.e. outside of its `valid_range`), if it exists.
+    pub largest_niche: Option<Niche>,
+
     pub align: AbiAndPrefAlign,
     pub size: Size
 }
 
 impl LayoutDetails {
     pub fn scalar<C: HasDataLayout>(cx: &C, scalar: Scalar) -> Self {
+        let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar.clone());
         let size = scalar.value.size(cx);
         let align = scalar.value.align(cx);
         LayoutDetails {
             variants: Variants::Single { index: VariantIdx::new(0) },
             fields: FieldPlacement::Union(0),
             abi: Abi::Scalar(scalar),
+            largest_niche,
             size,
             align,
         }
diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs
index 8eb19a6518a..3c63371d121 100644
--- a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs
+++ b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs
@@ -16,7 +16,7 @@ pub fn target() -> TargetResult {
         linker_flavor: LinkerFlavor::Gcc,
 
         options: TargetOptions {
-            features: "+strict-align,+v6,+vfp2".to_string(),
+            features: "+strict-align,+v6,+vfp2,-d32".to_string(),
             abi_blacklist: super::arm_base::abi_blacklist(),
             target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
             .. base
diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs
index 496a0c4a43a..fb5a16f74c0 100644
--- a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs
+++ b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs
@@ -5,7 +5,7 @@ pub fn target() -> TargetResult {
 
     // Most of these settings are copied from the arm_unknown_linux_gnueabihf
     // target.
-    base.features = "+strict-align,+v6,+vfp2".to_string();
+    base.features = "+strict-align,+v6,+vfp2,-d32".to_string();
     base.max_atomic_width = Some(64);
     Ok(Target {
         // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
diff --git a/src/librustc_target/spec/armv6_unknown_freebsd.rs b/src/librustc_target/spec/armv6_unknown_freebsd.rs
index efbbee959ed..06233f7caa3 100644
--- a/src/librustc_target/spec/armv6_unknown_freebsd.rs
+++ b/src/librustc_target/spec/armv6_unknown_freebsd.rs
@@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
         linker_flavor: LinkerFlavor::Gcc,
 
         options: TargetOptions {
-            features: "+v6,+vfp2".to_string(),
+            features: "+v6,+vfp2,-d32".to_string(),
             max_atomic_width: Some(64),
             abi_blacklist: super::arm_base::abi_blacklist(),
             target_mcount: "\u{1}__gnu_mcount_nc".to_string(),
diff --git a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs
index b76c39ac75b..40411befcfc 100644
--- a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs
+++ b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs
@@ -16,7 +16,7 @@ pub fn target() -> TargetResult {
         linker_flavor: LinkerFlavor::Gcc,
 
         options: TargetOptions {
-            features: "+v6,+vfp2".to_string(),
+            features: "+v6,+vfp2,-d32".to_string(),
             abi_blacklist: super::arm_base::abi_blacklist(),
             target_mcount: "__mcount".to_string(),
             .. base
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index f80e58f9538..54e3cad6a61 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -736,10 +736,6 @@ pub struct TargetOptions {
     /// for this target unconditionally.
     pub no_builtins: bool,
 
-    /// Whether to lower 128-bit operations to compiler_builtins calls. Use if
-    /// your backend only supports 64-bit and smaller math.
-    pub i128_lowering: bool,
-
     /// The codegen backend to use for this target, typically "llvm"
     pub codegen_backend: String,
 
@@ -855,7 +851,6 @@ impl Default for TargetOptions {
             requires_lto: false,
             singlethread: false,
             no_builtins: false,
-            i128_lowering: false,
             codegen_backend: "llvm".to_string(),
             default_hidden_visibility: false,
             embed_bitcode: false,
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index f2dbceb31b9..8d2160c0ec7 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -225,7 +225,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 tcx.mk_unit()
             }
             ExprKind::Break(destination, ref expr_opt) => {
-                self.check_expr_break(destination, expr_opt.deref(), expr)
+                self.check_expr_break(destination, expr_opt.as_deref(), expr)
             }
             ExprKind::Continue(destination) => {
                 if destination.target_id.is_ok() {
@@ -236,7 +236,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
             ExprKind::Ret(ref expr_opt) => {
-                self.check_expr_return(expr_opt.deref(), expr)
+                self.check_expr_return(expr_opt.as_deref(), expr)
             }
             ExprKind::Assign(ref lhs, ref rhs) => {
                 self.check_expr_assign(expr, expected, lhs, rhs)
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index d48ba74f9f2..408c267555c 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -86,7 +86,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 trait_name,
                 item_name,
                 if rcvr_ty.is_region_ptr() && args.is_some() {
-                    if rcvr_ty.is_mutable_pointer() {
+                    if rcvr_ty.is_mutable_ptr() {
                         "&mut "
                     } else {
                         "&"
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 3cd520fd4b5..6270ed37859 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1173,7 +1173,7 @@ themePicker.onblur = handleThemeButtonsBlur;
                 title: "Index of crates",
                 css_class: "mod",
                 root_path: "./",
-                static_root_path: cx.shared.static_root_path.deref(),
+                static_root_path: cx.shared.static_root_path.as_deref(),
                 description: "List of crates",
                 keywords: BASIC_KEYWORDS,
                 resource_suffix: &cx.shared.resource_suffix,
@@ -1513,7 +1513,7 @@ impl<'a> SourceCollector<'a> {
             title: &title,
             css_class: "source",
             root_path: &root_path,
-            static_root_path: self.scx.static_root_path.deref(),
+            static_root_path: self.scx.static_root_path.as_deref(),
             description: &desc,
             keywords: BASIC_KEYWORDS,
             resource_suffix: &self.scx.resource_suffix,
@@ -2110,7 +2110,7 @@ impl Context {
             title: "List of all items in this crate",
             css_class: "mod",
             root_path: "../",
-            static_root_path: self.shared.static_root_path.deref(),
+            static_root_path: self.shared.static_root_path.as_deref(),
             description: "List of all items in this crate",
             keywords: BASIC_KEYWORDS,
             resource_suffix: &self.shared.resource_suffix,
@@ -2137,7 +2137,7 @@ impl Context {
         self.shared.fs.write(&final_file, &v)?;
 
         // Generating settings page.
-        let settings = Settings::new(self.shared.static_root_path.deref().unwrap_or("./"),
+        let settings = Settings::new(self.shared.static_root_path.as_deref().unwrap_or("./"),
                                      &self.shared.resource_suffix);
         page.title = "Rustdoc settings";
         page.description = "Settings of Rustdoc";
@@ -2195,7 +2195,7 @@ impl Context {
         let page = layout::Page {
             css_class: tyname,
             root_path: &self.root_path(),
-            static_root_path: self.shared.static_root_path.deref(),
+            static_root_path: self.shared.static_root_path.as_deref(),
             title: &title,
             description: &desc,
             keywords: &keywords,
diff --git a/src/libstd/sys/vxworks/alloc.rs b/src/libstd/sys/vxworks/alloc.rs
index c60d1b8dab8..e0c560b9214 100644
--- a/src/libstd/sys/vxworks/alloc.rs
+++ b/src/libstd/sys/vxworks/alloc.rs
@@ -41,36 +41,6 @@ unsafe impl GlobalAlloc for System {
     }
 }
 
-#[cfg(any(target_os = "android",
-          target_os = "hermit",
-          target_os = "redox",
-          target_os = "solaris"))]
-#[inline]
-unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
-    // On android we currently target API level 9 which unfortunately
-    // doesn't have the `posix_memalign` API used below. Instead we use
-    // `memalign`, but this unfortunately has the property on some systems
-    // where the memory returned cannot be deallocated by `free`!
-    //
-    // Upon closer inspection, however, this appears to work just fine with
-    // Android, so for this platform we should be fine to call `memalign`
-    // (which is present in API level 9). Some helpful references could
-    // possibly be chromium using memalign [1], attempts at documenting that
-    // memalign + free is ok [2] [3], or the current source of chromium
-    // which still uses memalign on android [4].
-    //
-    // [1]: https://codereview.chromium.org/10796020/
-    // [2]: https://code.google.com/p/android/issues/detail?id=35391
-    // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579
-    // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/
-    //                                       /memory/aligned_memory.cc
-    libc::memalign(layout.align(), layout.size()) as *mut u8
-}
-
-#[cfg(not(any(target_os = "android",
-              target_os = "hermit",
-              target_os = "redox",
-              target_os = "solaris")))]
 #[inline]
 unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
     let mut out = ptr::null_mut();
diff --git a/src/libstd/sys/vxworks/android.rs b/src/libstd/sys/vxworks/android.rs
deleted file mode 100644
index 6774160bb25..00000000000
--- a/src/libstd/sys/vxworks/android.rs
+++ /dev/null
@@ -1,160 +0,0 @@
-//! Android ABI-compatibility module
-//!
-//! The ABI of Android has changed quite a bit over time, and libstd attempts to
-//! be both forwards and backwards compatible as much as possible. We want to
-//! always work with the most recent version of Android, but we also want to
-//! work with older versions of Android for whenever projects need to.
-//!
-//! Our current minimum supported Android version is `android-9`, e.g., Android
-//! with API level 9. We then in theory want to work on that and all future
-//! versions of Android!
-//!
-//! Some of the detection here is done at runtime via `dlopen` and
-//! introspection. Other times no detection is performed at all and we just
-//! provide a fallback implementation as some versions of Android we support
-//! don't have the function.
-//!
-//! You'll find more details below about why each compatibility shim is needed.
-
-#![cfg(target_os = "android")]
-
-use libc::{c_int, c_void, sighandler_t, size_t, ssize_t};
-use libc::{ftruncate, pread, pwrite};
-
-use crate::io;
-use super::{cvt, cvt_r};
-
-// The `log2` and `log2f` functions apparently appeared in android-18, or at
-// least you can see they're not present in the android-17 header [1] and they
-// are present in android-18 [2].
-//
-// [1]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms
-//                                       /android-17/arch-arm/usr/include/math.h
-// [2]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms
-//                                       /android-18/arch-arm/usr/include/math.h
-//
-// Note that these shims are likely less precise than directly calling `log2`,
-// but hopefully that should be enough for now...
-//
-// Note that mathematically, for any arbitrary `y`:
-//
-//      log_2(x) = log_y(x) / log_y(2)
-//               = log_y(x) / (1 / log_2(y))
-//               = log_y(x) * log_2(y)
-//
-// Hence because `ln` (log_e) is available on all Android we just choose `y = e`
-// and get:
-//
-//      log_2(x) = ln(x) * log_2(e)
-
-#[cfg(not(test))]
-pub fn log2f32(f: f32) -> f32 {
-    f.ln() * crate::f32::consts::LOG2_E
-}
-
-#[cfg(not(test))]
-pub fn log2f64(f: f64) -> f64 {
-    f.ln() * crate::f64::consts::LOG2_E
-}
-
-// Back in the day [1] the `signal` function was just an inline wrapper
-// around `bsd_signal`, but starting in API level android-20 the `signal`
-// symbols was introduced [2]. Finally, in android-21 the API `bsd_signal` was
-// removed [3].
-//
-// Basically this means that if we want to be binary compatible with multiple
-// Android releases (oldest being 9 and newest being 21) then we need to check
-// for both symbols and not actually link against either.
-//
-// [1]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms
-//                                       /android-18/arch-arm/usr/include/signal.h
-// [2]: https://chromium.googlesource.com/android_tools/+/fbd420/ndk_experimental
-//                                       /platforms/android-20/arch-arm
-//                                       /usr/include/signal.h
-// [3]: https://chromium.googlesource.com/android_tools/+/20ee6d/ndk/platforms
-//                                       /android-21/arch-arm/usr/include/signal.h
-pub unsafe fn signal(signum: c_int, handler: sighandler_t) -> sighandler_t {
-    weak!(fn signal(c_int, sighandler_t) -> sighandler_t);
-    weak!(fn bsd_signal(c_int, sighandler_t) -> sighandler_t);
-
-    let f = signal.get().or_else(|| bsd_signal.get());
-    let f = f.expect("neither `signal` nor `bsd_signal` symbols found");
-    f(signum, handler)
-}
-
-// The `ftruncate64` symbol apparently appeared in android-12, so we do some
-// dynamic detection to see if we can figure out whether `ftruncate64` exists.
-//
-// If it doesn't we just fall back to `ftruncate`, generating an error for
-// too-large values.
-#[cfg(target_pointer_width = "32")]
-pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
-    weak!(fn ftruncate64(c_int, i64) -> c_int);
-
-    unsafe {
-        match ftruncate64.get() {
-            Some(f) => cvt_r(|| f(fd, size as i64)).map(|_| ()),
-            None => {
-                if size > i32::max_value() as u64 {
-                    Err(io::Error::new(io::ErrorKind::InvalidInput,
-                                       "cannot truncate >2GB"))
-                } else {
-                    cvt_r(|| ftruncate(fd, size as i32)).map(|_| ())
-                }
-            }
-        }
-    }
-}
-
-#[cfg(target_pointer_width = "64")]
-pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> {
-    unsafe {
-        cvt_r(|| ftruncate(fd, size as i64)).map(|_| ())
-    }
-}
-
-#[cfg(target_pointer_width = "32")]
-pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64)
-    -> io::Result<ssize_t>
-{
-    use crate::convert::TryInto;
-    weak!(fn pread64(c_int, *mut c_void, size_t, i64) -> ssize_t);
-    pread64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
-        if let Ok(o) = offset.try_into() {
-            cvt(pread(fd, buf, count, o))
-        } else {
-            Err(io::Error::new(io::ErrorKind::InvalidInput,
-                               "cannot pread >2GB"))
-        }
-    })
-}
-
-#[cfg(target_pointer_width = "32")]
-pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64)
-    -> io::Result<ssize_t>
-{
-    use crate::convert::TryInto;
-    weak!(fn pwrite64(c_int, *const c_void, size_t, i64) -> ssize_t);
-    pwrite64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| {
-        if let Ok(o) = offset.try_into() {
-            cvt(pwrite(fd, buf, count, o))
-        } else {
-            Err(io::Error::new(io::ErrorKind::InvalidInput,
-                               "cannot pwrite >2GB"))
-        }
-    })
-}
-
-#[cfg(target_pointer_width = "64")]
-pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64)
-    -> io::Result<ssize_t>
-{
-    cvt(pread(fd, buf, count, offset))
-}
-
-#[cfg(target_pointer_width = "64")]
-pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64)
-    -> io::Result<ssize_t>
-{
-    cvt(pwrite(fd, buf, count, offset))
-}
diff --git a/src/libstd/sys/vxworks/condvar.rs b/src/libstd/sys/vxworks/condvar.rs
index 4d221264f23..783c3eb7c76 100644
--- a/src/libstd/sys/vxworks/condvar.rs
+++ b/src/libstd/sys/vxworks/condvar.rs
@@ -62,10 +62,6 @@ impl Condvar {
     // 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.
-    #[cfg(not(any(target_os = "macos",
-                  target_os = "ios",
-                  target_os = "android",
-                  target_os = "hermit")))]
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
         use crate::mem;
 
@@ -92,78 +88,9 @@ impl Condvar {
     }
 
 
-    // This implementation is modeled after libcxx's condition_variable
-    // https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46
-    // https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367
-    #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android", target_os = "hermit"))]
-    pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool {
-        use crate::ptr;
-        use crate::time::Instant;
-
-        // 1000 years
-        let max_dur = Duration::from_secs(1000 * 365 * 86400);
-
-        if dur > max_dur {
-            // OSX implementation of `pthread_cond_timedwait` is buggy
-            // with super long durations. When duration is greater than
-            // 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait`
-            // in macOS Sierra return error 316.
-            //
-            // This program demonstrates the issue:
-            // https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c
-            //
-            // To work around this issue, and possible bugs of other OSes, timeout
-            // is clamped to 1000 years, which is allowable per the API of `wait_timeout`
-            // because of spurious wakeups.
-
-            dur = max_dur;
-        }
-
-        // First, figure out what time it currently is, in both system and
-        // stable time.  pthread_cond_timedwait uses system time, but we want to
-        // report timeout based on stable time.
-        let mut sys_now = libc::timeval { tv_sec: 0, tv_usec: 0 };
-        let stable_now = Instant::now();
-        let r = libc::gettimeofday(&mut sys_now, ptr::null_mut());
-        debug_assert_eq!(r, 0);
-
-        let nsec = dur.subsec_nanos() as libc::c_long +
-                   (sys_now.tv_usec * 1000) as libc::c_long;
-        let extra = (nsec / 1_000_000_000) as libc::time_t;
-        let nsec = nsec % 1_000_000_000;
-        let seconds = saturating_cast_to_time_t(dur.as_secs());
-
-        let timeout = sys_now.tv_sec.checked_add(extra).and_then(|s| {
-            s.checked_add(seconds)
-        }).map(|s| {
-            libc::timespec { tv_sec: s, tv_nsec: nsec }
-        }).unwrap_or(TIMESPEC_MAX);
-
-        // And wait!
-        let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
-                                            &timeout);
-        debug_assert!(r == libc::ETIMEDOUT || r == 0);
-
-        // ETIMEDOUT is not a totally reliable method of determining timeout due
-        // to clock shifts, so do the check ourselves
-        stable_now.elapsed() < dur
-    }
-
     #[inline]
-    #[cfg(not(target_os = "dragonfly"))]
     pub unsafe fn destroy(&self) {
         let r = libc::pthread_cond_destroy(self.inner.get());
         debug_assert_eq!(r, 0);
     }
-
-    #[inline]
-    #[cfg(target_os = "dragonfly")]
-    pub unsafe fn destroy(&self) {
-        let r = libc::pthread_cond_destroy(self.inner.get());
-        // On DragonFly pthread_cond_destroy() returns EINVAL if called on
-        // a condvar that was just initialized with
-        // libc::PTHREAD_COND_INITIALIZER. Once it is used or
-        // pthread_cond_init() is called, this behaviour no longer occurs.
-        debug_assert!(r == 0 || r == libc::EINVAL);
-    }
 }
diff --git a/src/libstd/sys/vxworks/ext/net.rs b/src/libstd/sys/vxworks/ext/net.rs
index 41090caee84..3f0a7e9e843 100644
--- a/src/libstd/sys/vxworks/ext/net.rs
+++ b/src/libstd/sys/vxworks/ext/net.rs
@@ -5,16 +5,6 @@
 #[cfg(unix)]
 use libc;
 
-// FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here?
-#[cfg(not(unix))]
-mod libc {
-    pub use libc::c_int;
-    pub type socklen_t = u32;
-    pub struct sockaddr;
-    #[derive(Clone)]
-    pub struct sockaddr_un;
-}
-
 use crate::ascii;
 use crate::ffi::OsStr;
 use crate::fmt;
@@ -29,15 +19,6 @@ use crate::sys::{self, cvt};
 use crate::sys::net::Socket;
 use crate::sys_common::{self, AsInner, FromInner, IntoInner};
 
-#[cfg(any(target_os = "linux", target_os = "android",
-          target_os = "dragonfly", target_os = "freebsd",
-          target_os = "openbsd", target_os = "netbsd",
-          target_os = "haiku"))]
-use libc::MSG_NOSIGNAL;
-#[cfg(not(any(target_os = "linux", target_os = "android",
-              target_os = "dragonfly", target_os = "freebsd",
-              target_os = "openbsd", target_os = "netbsd",
-              target_os = "haiku")))]
 const MSG_NOSIGNAL: libc::c_int = 0x0;
 
 fn sun_path_offset(addr: &libc::sockaddr_un) -> usize {
@@ -202,13 +183,7 @@ impl SocketAddr {
         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
-        if len == 0
-            || (cfg!(not(any(target_os = "linux", target_os = "android")))
-                && self.addr.sun_path[0] == 0)
-        {
-            AddressKind::Unnamed
-        } else if self.addr.sun_path[0] == 0 {
+        if self.addr.sun_path[0] == 0 {
             AddressKind::Abstract(&path[1..len])
         } else {
             AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref())
diff --git a/src/libstd/sys/vxworks/l4re.rs b/src/libstd/sys/vxworks/l4re.rs
deleted file mode 100644
index b3dd1cf6aaa..00000000000
--- a/src/libstd/sys/vxworks/l4re.rs
+++ /dev/null
@@ -1,469 +0,0 @@
-macro_rules! unimpl {
-    () => (return Err(io::Error::new(io::ErrorKind::Other, "No networking available on L4Re."));)
-}
-
-pub mod net {
-    #![allow(warnings)]
-    use crate::fmt;
-    use crate::io::{self, IoVec, IoVecMut};
-    use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
-    use crate::sys_common::{AsInner, FromInner, IntoInner};
-    use crate::sys::fd::FileDesc;
-    use crate::time::Duration;
-    use crate::convert::TryFrom;
-
-    #[allow(unused_extern_crates)]
-    pub extern crate libc as netc;
-
-    pub struct Socket(FileDesc);
-    impl Socket {
-        pub fn new(_: &SocketAddr, _: libc::c_int) -> io::Result<Socket> {
-            unimpl!();
-        }
-
-        pub fn new_raw(_: libc::c_int, _: libc::c_int) -> io::Result<Socket> {
-            unimpl!();
-        }
-
-        pub fn new_pair(_: libc::c_int, _: libc::c_int) -> io::Result<(Socket, Socket)> {
-            unimpl!();
-        }
-
-        pub fn connect_timeout(&self, _: &SocketAddr, _: Duration) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn accept(&self, _: *mut libc::sockaddr, _: *mut libc::socklen_t)
-                  -> io::Result<Socket> {
-            unimpl!();
-        }
-
-        pub fn duplicate(&self) -> io::Result<Socket> {
-            unimpl!();
-        }
-
-        pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn read_vectored(&self, _: &mut [IoVecMut<'_>]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-            unimpl!();
-        }
-
-        pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-            unimpl!();
-        }
-
-        pub fn write(&self, _: &[u8]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn write_vectored(&self, _: &[IoVec<'_>]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn set_timeout(&self, _: Option<Duration>, _: libc::c_int) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn timeout(&self, _: libc::c_int) -> io::Result<Option<Duration>> {
-            unimpl!();
-        }
-
-        pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn nodelay(&self) -> io::Result<bool> {
-            unimpl!();
-        }
-
-        pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-            unimpl!();
-        }
-    }
-
-    impl AsInner<libc::c_int> for Socket {
-        fn as_inner(&self) -> &libc::c_int { self.0.as_inner() }
-    }
-
-    impl FromInner<libc::c_int> for Socket {
-        fn from_inner(fd: libc::c_int) -> Socket { Socket(FileDesc::new(fd)) }
-    }
-
-    impl IntoInner<libc::c_int> for Socket {
-        fn into_inner(self) -> libc::c_int { self.0.into_raw() }
-    }
-
-    pub struct TcpStream {
-        inner: Socket,
-    }
-
-    impl TcpStream {
-        pub fn connect(_: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
-            unimpl!();
-        }
-
-        pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result<TcpStream> {
-            unimpl!();
-        }
-
-        pub fn socket(&self) -> &Socket { &self.inner }
-
-        pub fn into_socket(self) -> Socket { self.inner }
-
-        pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-            unimpl!();
-        }
-
-        pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-            unimpl!();
-        }
-
-        pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn read(&self, _: &mut [u8]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn read_vectored(&self, _: &mut [IoVecMut<'_>]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn write(&self, _: &[u8]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn write_vectored(&self, _: &[IoVec<'_>]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-            unimpl!();
-        }
-
-        pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-            unimpl!();
-        }
-
-        pub fn shutdown(&self, _: Shutdown) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn duplicate(&self) -> io::Result<TcpStream> {
-            unimpl!();
-        }
-
-        pub fn set_nodelay(&self, _: bool) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn nodelay(&self) -> io::Result<bool> {
-            unimpl!();
-        }
-
-        pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn ttl(&self) -> io::Result<u32> {
-            unimpl!();
-        }
-
-        pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-            unimpl!();
-        }
-
-        pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-            unimpl!();
-        }
-    }
-
-    impl FromInner<Socket> for TcpStream {
-        fn from_inner(socket: Socket) -> TcpStream {
-            TcpStream { inner: socket }
-        }
-    }
-
-    impl fmt::Debug for TcpStream {
-        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-            write!(f, "No networking support available on L4Re")
-        }
-    }
-
-    pub struct TcpListener {
-        inner: Socket,
-    }
-
-    impl TcpListener {
-        pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
-            unimpl!();
-        }
-
-        pub fn socket(&self) -> &Socket { &self.inner }
-
-        pub fn into_socket(self) -> Socket { self.inner }
-
-        pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-            unimpl!();
-        }
-
-        pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
-            unimpl!();
-        }
-
-        pub fn duplicate(&self) -> io::Result<TcpListener> {
-            unimpl!();
-        }
-
-        pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn ttl(&self) -> io::Result<u32> {
-            unimpl!();
-        }
-
-        pub fn set_only_v6(&self, _: bool) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn only_v6(&self) -> io::Result<bool> {
-            unimpl!();
-        }
-
-        pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-            unimpl!();
-        }
-
-        pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-            unimpl!();
-        }
-    }
-
-    impl FromInner<Socket> for TcpListener {
-        fn from_inner(socket: Socket) -> TcpListener {
-            TcpListener { inner: socket }
-        }
-    }
-
-    impl fmt::Debug for TcpListener {
-        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-            write!(f, "No networking support available on L4Re.")
-        }
-    }
-
-    pub struct UdpSocket {
-        inner: Socket,
-    }
-
-    impl UdpSocket {
-        pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
-            unimpl!();
-        }
-
-        pub fn socket(&self) -> &Socket { &self.inner }
-
-        pub fn into_socket(self) -> Socket { self.inner }
-
-        pub fn peer_addr(&self) -> io::Result<SocketAddr> {
-            unimpl!();
-        }
-
-        pub fn socket_addr(&self) -> io::Result<SocketAddr> {
-            unimpl!();
-        }
-
-        pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-            unimpl!();
-        }
-
-        pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
-            unimpl!();
-        }
-
-        pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn duplicate(&self) -> io::Result<UdpSocket> {
-            unimpl!();
-        }
-
-        pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
-            unimpl!();
-        }
-
-        pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
-            unimpl!();
-        }
-
-        pub fn set_broadcast(&self, _: bool) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn broadcast(&self) -> io::Result<bool> {
-            unimpl!();
-        }
-
-        pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn multicast_loop_v4(&self) -> io::Result<bool> {
-            unimpl!();
-        }
-
-        pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
-            unimpl!();
-        }
-
-        pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn multicast_loop_v6(&self) -> io::Result<bool> {
-            unimpl!();
-        }
-
-        pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
-                             -> io::Result<()> {
-                                 unimpl!();
-        }
-
-        pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32)
-                             -> io::Result<()> {
-                                 unimpl!();
-        }
-
-        pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr)
-                              -> io::Result<()> {
-                                  unimpl!();
-        }
-
-        pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32)
-                              -> io::Result<()> {
-                                  unimpl!();
-        }
-
-        pub fn set_ttl(&self, _: u32) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn ttl(&self) -> io::Result<u32> {
-            unimpl!();
-        }
-
-        pub fn take_error(&self) -> io::Result<Option<io::Error>> {
-            unimpl!();
-        }
-
-        pub fn set_nonblocking(&self, _: bool) -> io::Result<()> {
-            unimpl!();
-        }
-
-        pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn send(&self, _: &[u8]) -> io::Result<usize> {
-            unimpl!();
-        }
-
-        pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> {
-            unimpl!();
-        }
-    }
-
-    impl FromInner<Socket> for UdpSocket {
-        fn from_inner(socket: Socket) -> UdpSocket {
-            UdpSocket { inner: socket }
-        }
-    }
-
-    impl fmt::Debug for UdpSocket {
-        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-            write!(f, "No networking support on L4Re available.")
-        }
-    }
-
-    pub struct LookupHost {
-        original: *mut libc::addrinfo,
-        cur: *mut libc::addrinfo,
-    }
-
-    impl Iterator for LookupHost {
-        type Item = SocketAddr;
-        fn next(&mut self) -> Option<SocketAddr> {
-            None
-        }
-    }
-
-    impl LookupHost {
-        pub fn port(&self) -> u16 {
-            unimpl!();
-        }
-    }
-
-    unsafe impl Sync for LookupHost {}
-    unsafe impl Send for LookupHost {}
-
-
-    impl TryFrom<&str> for LookupHost {
-        type Error = io::Error;
-
-        fn try_from(_v: &str) -> io::Result<LookupHost> {
-            unimpl!();
-        }
-    }
-
-    impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
-        type Error = io::Error;
-
-        fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> {
-            unimpl!();
-        }
-    }
-}
diff --git a/src/libstd/sys/vxworks/memchr.rs b/src/libstd/sys/vxworks/memchr.rs
index 1984678bdde..b5b4e6d9c13 100644
--- a/src/libstd/sys/vxworks/memchr.rs
+++ b/src/libstd/sys/vxworks/memchr.rs
@@ -16,25 +16,6 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
 }
 
 pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
-
-    #[cfg(target_os = "linux")]
-    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
-        // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
-        if haystack.is_empty() {return None}
-        let p = unsafe {
-            libc::memrchr(
-                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))
-        }
-    }
-
-    #[cfg(not(target_os = "linux"))]
     fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
         core::slice::memchr::memrchr(needle, haystack)
     }
diff --git a/src/libstd/sys/vxworks/mod.rs b/src/libstd/sys/vxworks/mod.rs
index b01bea03c1b..1eff4fbcd83 100644
--- a/src/libstd/sys/vxworks/mod.rs
+++ b/src/libstd/sys/vxworks/mod.rs
@@ -7,14 +7,8 @@ pub use crate::os::vxworks as platform;
 pub use self::rand::hashmap_random_keys;
 pub use libc::strlen;
 
-#[macro_use]
-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;
@@ -25,12 +19,7 @@ pub mod fs;
 pub mod memchr;
 pub mod io;
 pub mod mutex;
-#[cfg(not(target_os = "l4re"))]
 pub mod net;
-#[cfg(target_os = "l4re")]
-mod l4re;
-#[cfg(target_os = "l4re")]
-pub use self::l4re::net;
 pub mod os;
 pub mod path;
 pub mod pipe;
@@ -61,9 +50,6 @@ pub fn init() {
     unsafe fn reset_sigpipe() { }
 }
 
-#[cfg(target_os = "android")]
-pub use crate::sys::android::signal;
-#[cfg(not(target_os = "android"))]
 pub use libc::signal;
 
 pub fn decode_error_kind(errno: i32) -> ErrorKind {
diff --git a/src/libstd/sys/vxworks/net.rs b/src/libstd/sys/vxworks/net.rs
index 686cea49a6e..aa6b93c8600 100644
--- a/src/libstd/sys/vxworks/net.rs
+++ b/src/libstd/sys/vxworks/net.rs
@@ -58,19 +58,6 @@ impl Socket {
 
     pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
         unsafe {
-            // On linux we first attempt to pass the SOCK_CLOEXEC flag to
-            // atomically create the socket and set it as CLOEXEC. Support for
-            // this option, however, was added in 2.6.27, and we still support
-            // 2.6.18 as a kernel, so if the returned error is EINVAL we
-            // fallthrough to the fallback.
-            if cfg!(target_os = "linux") {
-                match cvt(libc::socket(fam, ty | SOCK_CLOEXEC, 0)) {
-                    Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
-                    Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
-                    Err(e) => return Err(e),
-                }
-            }
-
             let fd = cvt(libc::socket(fam, ty, 0))?;
             let fd = FileDesc::new(fd);
             fd.set_cloexec()?;
diff --git a/src/libstd/sys/vxworks/process/process_common.rs b/src/libstd/sys/vxworks/process/process_common.rs
index db4e80c216c..9fce5f5811f 100644
--- a/src/libstd/sys/vxworks/process/process_common.rs
+++ b/src/libstd/sys/vxworks/process/process_common.rs
@@ -422,46 +422,12 @@ mod tests {
         }
     }
 
-    // Android with api less than 21 define sig* functions inline, so it is not
-    // available for dynamic link. Implementing sigemptyset and sigaddset allow us
-    // to support older Android version (independent of libc version).
-    // The following implementations are based on https://git.io/vSkNf
-
-    #[cfg(not(target_os = "android"))]
     extern {
-        #[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")]
         fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int;
-
-        #[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")]
         fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int;
     }
 
-    #[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>());
-        return 0;
-    }
-
-    #[cfg(target_os = "android")]
-    unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
-        use crate::slice;
-
-        let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
-        let bit = (signum - 1) as usize;
-        raw[bit / 8] |= 1 << (bit % 8);
-        return 0;
-    }
-
-    // See #14232 for more information, but it appears that signal delivery to a
-    // newly spawned process may just be raced in the macOS, so to prevent this
-    // test from being flaky we ignore it on macOS.
     #[test]
-    #[cfg_attr(target_os = "macos", ignore)]
-    // When run under our current QEMU emulation test suite this test fails,
-    // although the reason isn't very clear as to why. For now this test is
-    // ignored there.
-    #[cfg_attr(target_arch = "arm", ignore)]
-    #[cfg_attr(target_arch = "aarch64", ignore)]
     fn test_process_mask() {
         unsafe {
             // Test to make sure that a signal mask does not get inherited.
diff --git a/src/libstd/sys/vxworks/stack_overflow.rs b/src/libstd/sys/vxworks/stack_overflow.rs
index 561279e8278..08e7b310ca1 100644
--- a/src/libstd/sys/vxworks/stack_overflow.rs
+++ b/src/libstd/sys/vxworks/stack_overflow.rs
@@ -23,174 +23,6 @@ impl Drop for Handler {
     }
 }
 
-#[cfg(any(target_os = "linux",
-          target_os = "macos",
-          target_os = "bitrig",
-          target_os = "dragonfly",
-          target_os = "freebsd",
-          target_os = "solaris",
-          all(target_os = "netbsd", not(target_vendor = "rumprun")),
-          target_os = "openbsd"))]
-mod imp {
-    use super::Handler;
-    use crate::mem;
-    use crate::ptr;
-
-    use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE};
-    use libc::{sigaction, SIGBUS, SIG_DFL,
-               SA_SIGINFO, SA_ONSTACK, sighandler_t};
-    use libc::{mmap, munmap};
-    use libc::{SIGSEGV, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON};
-    use libc::MAP_FAILED;
-
-    use crate::sys_common::thread_info;
-
-
-    #[cfg(any(target_os = "linux", target_os = "android"))]
-    unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
-        #[repr(C)]
-        struct siginfo_t {
-            a: [libc::c_int; 3], // si_signo, si_errno, si_code
-            si_addr: *mut libc::c_void,
-        }
-
-        (*(info as *const siginfo_t)).si_addr as usize
-    }
-
-    #[cfg(not(any(target_os = "linux", target_os = "android")))]
-    unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
-        (*info).si_addr as usize
-    }
-
-    // Signal handler for the SIGSEGV and SIGBUS handlers. We've got guard pages
-    // (unmapped pages) at the end of every thread's stack, so if a thread ends
-    // up running into the guard page it'll trigger this handler. We want to
-    // detect these cases and print out a helpful error saying that the stack
-    // has overflowed. All other signals, however, should go back to what they
-    // were originally supposed to do.
-    //
-    // This handler currently exists purely to print an informative message
-    // whenever a thread overflows its stack. We then abort to exit and
-    // indicate a crash, but to avoid a misleading SIGSEGV that might lead
-    // users to believe that unsafe code has accessed an invalid pointer; the
-    // SIGSEGV encountered when overflowing the stack is expected and
-    // well-defined.
-    //
-    // If this is not a stack overflow, the handler un-registers itself and
-    // then returns (to allow the original signal to be delivered again).
-    // Returning from this kind of signal handler is technically not defined
-    // to work when reading the POSIX spec strictly, but in practice it turns
-    // out many large systems and all implementations allow returning from a
-    // signal handler to work. For a more detailed explanation see the
-    // comments on #26458.
-    unsafe extern fn signal_handler(signum: libc::c_int,
-                                    info: *mut libc::siginfo_t,
-                                    _data: *mut libc::c_void) {
-        use crate::sys_common::util::report_overflow;
-
-        let guard = thread_info::stack_guard().unwrap_or(0..0);
-        let addr = siginfo_si_addr(info);
-
-        // If the faulting address is within the guard page, then we print a
-        // message saying so and abort.
-        if guard.start <= addr && addr < guard.end {
-            report_overflow();
-            rtabort!("stack overflow");
-        } else {
-            // Unregister ourselves by reverting back to the default behavior.
-            let mut action: sigaction = mem::zeroed();
-            action.sa_sigaction = SIG_DFL;
-            sigaction(signum, &action, ptr::null_mut());
-
-            // See comment above for why this function returns.
-        }
-    }
-
-    static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut();
-
-    pub unsafe fn init() {
-        let mut action: sigaction = mem::zeroed();
-        action.sa_flags = SA_SIGINFO | SA_ONSTACK;
-        action.sa_sigaction = signal_handler as sighandler_t;
-        sigaction(SIGSEGV, &action, ptr::null_mut());
-        sigaction(SIGBUS, &action, ptr::null_mut());
-
-        let handler = make_handler();
-        MAIN_ALTSTACK = handler._data;
-        mem::forget(handler);
-    }
-
-    pub unsafe fn cleanup() {
-        Handler { _data: MAIN_ALTSTACK };
-    }
-
-    unsafe fn get_stackp() -> *mut libc::c_void {
-        let stackp = mmap(ptr::null_mut(),
-                          SIGSTKSZ,
-                          PROT_READ | PROT_WRITE,
-                          MAP_PRIVATE | MAP_ANON,
-                          -1,
-                          0);
-        if stackp == MAP_FAILED {
-            panic!("failed to allocate an alternative stack");
-        }
-        stackp
-    }
-
-    #[cfg(any(target_os = "linux",
-              target_os = "macos",
-              target_os = "bitrig",
-              target_os = "freebsd",
-              target_os = "netbsd",
-              target_os = "openbsd",
-              target_os = "solaris"))]
-    unsafe fn get_stack() -> libc::stack_t {
-        libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ }
-    }
-
-    #[cfg(target_os = "dragonfly")]
-    unsafe fn get_stack() -> libc::stack_t {
-        libc::stack_t { ss_sp: get_stackp() as *mut i8, ss_flags: 0, ss_size: SIGSTKSZ }
-    }
-
-    pub unsafe fn make_handler() -> Handler {
-        let mut stack = mem::zeroed();
-        sigaltstack(ptr::null(), &mut stack);
-        // Configure alternate signal stack, if one is not already set.
-        if stack.ss_flags & SS_DISABLE != 0 {
-            stack = get_stack();
-            sigaltstack(&stack, ptr::null_mut());
-            Handler { _data: stack.ss_sp as *mut libc::c_void }
-        } else {
-            Handler { _data: ptr::null_mut() }
-        }
-    }
-
-    pub unsafe fn drop_handler(handler: &mut Handler) {
-        if !handler._data.is_null() {
-            let stack =  libc::stack_t {
-                ss_sp: ptr::null_mut(),
-                ss_flags: SS_DISABLE,
-                // Workaround for bug in macOS implementation of sigaltstack
-                // UNIX2003 which returns ENOMEM when disabling a stack while
-                // passing ss_size smaller than MINSIGSTKSZ. According to POSIX
-                // both ss_sp and ss_size should be ignored in this case.
-                ss_size: SIGSTKSZ,
-            };
-            sigaltstack(&stack, ptr::null_mut());
-            munmap(handler._data, SIGSTKSZ);
-        }
-    }
-}
-
-#[cfg(not(any(target_os = "linux",
-              target_os = "macos",
-              target_os = "bitrig",
-              target_os = "dragonfly",
-              target_os = "freebsd",
-              target_os = "solaris",
-              all(target_os = "netbsd", not(target_vendor = "rumprun")),
-              target_os = "openbsd")))]
 mod imp {
     use crate::ptr;
 
diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs
index 810dbad7284..58af8cbe48e 100644
--- a/src/libstd/sys/vxworks/thread.rs
+++ b/src/libstd/sys/vxworks/thread.rs
@@ -1,4 +1,3 @@
-//use crate::boxed::FnBox;
 use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
@@ -9,10 +8,7 @@ use crate::time::Duration;
 
 use crate::sys_common::thread::*;
 
-#[cfg(not(target_os = "l4re"))]
 pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
-#[cfg(target_os = "l4re")]
-pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024;
 
 pub struct Thread {
     id: libc::pthread_t,
@@ -25,18 +21,11 @@ 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.
-#[cfg(not(target_os = "emscripten"))]
 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)
 }
 
-#[cfg(target_os = "emscripten")]
-unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t,
-                                    _stack_size: libc::size_t) -> libc::c_int {
-    panic!()
-}
-
 impl Thread {
     // unsafe: see thread::Builder::spawn_unchecked for safety requirements
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>)
@@ -149,31 +138,6 @@ pub mod guard {
     pub unsafe fn deinit() {}
 }
 
-// glibc >= 2.15 has a __pthread_get_minstack() function that returns
-// PTHREAD_STACK_MIN plus however many bytes are needed for thread-local
-// storage.  We need that information to avoid blowing up when a small stack
-// is created in an application with big thread-local storage requirements.
-// See #6233 for rationale and details.
-#[cfg(target_os = "linux")]
-#[allow(deprecated)]
-fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
-    weak!(fn __pthread_get_minstack(*const libc::pthread_attr_t) -> libc::size_t);
-
-    match __pthread_get_minstack.get() {
-        None => libc::PTHREAD_STACK_MIN,
-        Some(f) => unsafe { f(attr) },
-    }
-}
-
-// No point in looking up __pthread_get_minstack() on non-glibc
-// platforms.
-#[cfg(all(not(target_os = "linux"),
-          not(target_os = "netbsd")))]
 fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
     libc::PTHREAD_STACK_MIN
 }
-
-#[cfg(target_os = "netbsd")]
-fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
-    2048 // just a guess
-}
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/fs.rs b/src/libstd/sys/windows/fs.rs
index 2f158c01406..5bae6ba4749 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,
         })
     }
 }
@@ -291,23 +297,26 @@ impl File {
     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 {
-                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),
-                reparse_tag: 0,
-            };
-            if attr.is_reparse_point() {
+            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) {
-                    attr.reparse_tag = buf.ReparseTag;
+                    reparse_tag = buf.ReparseTag;
                 }
             }
-            Ok(attr)
+            Ok(FileAttr {
+                attributes: info.dwFileAttributes,
+                creation_time: info.ftCreationTime,
+                last_access_time: info.ftLastAccessTime,
+                last_write_time: info.ftLastWriteTime,
+                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)),
+            })
         }
     }
 
@@ -336,6 +345,9 @@ impl File {
                 },
                 file_size: 0,
                 reparse_tag: 0,
+                volume_serial_number: None,
+                number_of_links: None,
+                file_index: None,
             };
             let mut info: c::FILE_STANDARD_INFO = mem::zeroed();
             let size = mem::size_of_val(&info);
@@ -344,6 +356,7 @@ impl File {
                                                 &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.is_reparse_point() {
                 let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
                 if let Ok((_, buf)) = self.reparse_point(&mut b) {
@@ -507,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)
@@ -537,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
     }
 }
 
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index ae1979540ff..dbf14daa30e 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -92,7 +92,6 @@ use rustc_data_structures::sync::Lrc;
 use std::collections::hash_map::Entry::{Occupied, Vacant};
 use std::mem;
 use std::ops::{Deref, DerefMut};
-use std::rc::Rc;
 
 // To avoid costly uniqueness checks, we require that `MatchSeq` always has a nonempty body.
 
@@ -280,7 +279,7 @@ pub enum ParseResult<T> {
 
 /// A `ParseResult` where the `Success` variant contains a mapping of `Ident`s to `NamedMatch`es.
 /// This represents the mapping of metavars to the token trees they bind to.
-pub type NamedParseResult = ParseResult<FxHashMap<Ident, Rc<NamedMatch>>>;
+pub type NamedParseResult = ParseResult<FxHashMap<Ident, NamedMatch>>;
 
 /// Count how many metavars are named in the given matcher `ms`.
 pub fn count_names(ms: &[TokenTree]) -> usize {
@@ -373,7 +372,7 @@ fn nameize<I: Iterator<Item = NamedMatch>>(
         sess: &ParseSess,
         m: &TokenTree,
         res: &mut I,
-        ret_val: &mut FxHashMap<Ident, Rc<NamedMatch>>,
+        ret_val: &mut FxHashMap<Ident, NamedMatch>,
     ) -> Result<(), (syntax_pos::Span, String)> {
         match *m {
             TokenTree::Sequence(_, ref seq) => for next_m in &seq.tts {
@@ -390,8 +389,7 @@ fn nameize<I: Iterator<Item = NamedMatch>>(
             TokenTree::MetaVarDecl(sp, bind_name, _) => {
                 match ret_val.entry(bind_name) {
                     Vacant(spot) => {
-                        // FIXME(simulacrum): Don't construct Rc here
-                        spot.insert(Rc::new(res.next().unwrap()));
+                        spot.insert(res.next().unwrap());
                     }
                     Occupied(..) => {
                         return Err((sp, format!("duplicated bind name: {}", bind_name)))
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 4503cea0f10..817d8547e87 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -308,7 +308,7 @@ pub fn compile(
     let mut valid = true;
 
     // Extract the arguments:
-    let lhses = match *argument_map[&lhs_nm] {
+    let lhses = match argument_map[&lhs_nm] {
         MatchedSeq(ref s, _) => s
             .iter()
             .map(|m| {
@@ -335,7 +335,7 @@ pub fn compile(
         _ => sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"),
     };
 
-    let rhses = match *argument_map[&rhs_nm] {
+    let rhses = match argument_map[&rhs_nm] {
         MatchedSeq(ref s, _) => s
             .iter()
             .map(|m| {
@@ -625,38 +625,37 @@ impl FirstSets {
                     return first;
                 }
                 TokenTree::Sequence(sp, ref seq_rep) => {
-                    match self.first.get(&sp.entire()) {
-                        Some(&Some(ref subfirst)) => {
-                            // If the sequence contents can be empty, then the first
-                            // token could be the separator token itself.
-
-                            if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) {
-                                first.add_one_maybe(TokenTree::Token(sep.clone()));
-                            }
-
-                            assert!(first.maybe_empty);
-                            first.add_all(subfirst);
-                            if subfirst.maybe_empty
-                                || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore
-                                || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne
-                            {
-                                // continue scanning for more first
-                                // tokens, but also make sure we
-                                // restore empty-tracking state
-                                first.maybe_empty = true;
-                                continue;
-                            } else {
-                                return first;
-                            }
-                        }
-
+                    let subfirst_owned;
+                    let subfirst = match self.first.get(&sp.entire()) {
+                        Some(&Some(ref subfirst)) => subfirst,
                         Some(&None) => {
-                            panic!("assume all sequences have (unique) spans for now");
+                            subfirst_owned = self.first(&seq_rep.tts[..]);
+                            &subfirst_owned
                         }
-
                         None => {
                             panic!("We missed a sequence during FirstSets construction");
                         }
+                    };
+
+                    // If the sequence contents can be empty, then the first
+                    // token could be the separator token itself.
+                    if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) {
+                        first.add_one_maybe(TokenTree::Token(sep.clone()));
+                    }
+
+                    assert!(first.maybe_empty);
+                    first.add_all(subfirst);
+                    if subfirst.maybe_empty
+                        || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore
+                        || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne
+                    {
+                        // Continue scanning for more first
+                        // tokens, but also make sure we
+                        // restore empty-tracking state.
+                        first.maybe_empty = true;
+                        continue;
+                    } else {
+                        return first;
                     }
                 }
             }
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index fa93c5a904e..214e721fd15 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -12,7 +12,6 @@ use smallvec::{smallvec, SmallVec};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
 use std::mem;
-use std::rc::Rc;
 
 /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
 enum Frame {
@@ -65,9 +64,9 @@ impl Iterator for Frame {
 /// `transcribe` would return a `TokenStream` containing `println!("{}", stringify!(bar));`.
 ///
 /// Along the way, we do some additional error checking.
-pub fn transcribe(
+pub(super) fn transcribe(
     cx: &ExtCtxt<'_>,
-    interp: &FxHashMap<Ident, Rc<NamedMatch>>,
+    interp: &FxHashMap<Ident, NamedMatch>,
     src: Vec<quoted::TokenTree>,
 ) -> TokenStream {
     // Nothing for us to transcribe...
@@ -212,7 +211,7 @@ pub fn transcribe(
                 // Find the matched nonterminal from the macro invocation, and use it to replace
                 // the meta-var.
                 if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
-                    if let MatchedNonterminal(ref nt) = *cur_matched {
+                    if let MatchedNonterminal(ref nt) = cur_matched {
                         // FIXME #2887: why do we apply a mark when matching a token tree meta-var
                         // (e.g. `$x:tt`), but not when we are matching any other type of token
                         // tree?
@@ -273,18 +272,17 @@ pub fn transcribe(
 /// See the definition of `repeats` in the `transcribe` function. `repeats` is used to descend
 /// into the right place in nested matchers. If we attempt to descend too far, the macro writer has
 /// made a mistake, and we return `None`.
-fn lookup_cur_matched(
+fn lookup_cur_matched<'a>(
     ident: Ident,
-    interpolations: &FxHashMap<Ident, Rc<NamedMatch>>,
+    interpolations: &'a FxHashMap<Ident, NamedMatch>,
     repeats: &[(usize, usize)],
-) -> Option<Rc<NamedMatch>> {
+) -> Option<&'a NamedMatch> {
     interpolations.get(&ident).map(|matched| {
-        let mut matched = matched.clone();
+        let mut matched = matched;
         for &(idx, _) in repeats {
-            let m = matched.clone();
-            match *m {
+            match matched {
                 MatchedNonterminal(_) => break,
-                MatchedSeq(ref ads, _) => matched = Rc::new(ads[idx].clone()),
+                MatchedSeq(ref ads, _) => matched = ads.get(idx).unwrap(),
             }
         }
 
@@ -343,7 +341,7 @@ impl LockstepIterSize {
 /// multiple nested matcher sequences.
 fn lockstep_iter_size(
     tree: &quoted::TokenTree,
-    interpolations: &FxHashMap<Ident, Rc<NamedMatch>>,
+    interpolations: &FxHashMap<Ident, NamedMatch>,
     repeats: &[(usize, usize)],
 ) -> LockstepIterSize {
     use quoted::TokenTree;
@@ -360,7 +358,7 @@ fn lockstep_iter_size(
         }
         TokenTree::MetaVar(_, name) | TokenTree::MetaVarDecl(_, name, _) => {
             match lookup_cur_matched(name, interpolations, repeats) {
-                Some(matched) => match *matched {
+                Some(matched) => match matched {
                     MatchedNonterminal(_) => LockstepIterSize::Unconstrained,
                     MatchedSeq(ref ads, _) => LockstepIterSize::Constraint(ads.len(), name),
                 },
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index b97801a50d4..52f65e1b474 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -389,8 +389,18 @@ impl<'a> StringReader<'a> {
                                                           self.pos,
                                                           "unknown start of token",
                                                           c);
-                unicode_chars::check_for_substitution(self, start, c, &mut err);
-                return Err(err)
+                // FIXME: the lexer could be used to turn the ASCII version of unicode homoglyphs,
+                // instead of keeping a table in `check_for_substitution`into the token. Ideally,
+                // this should be inside `rustc_lexer`. However, we should first remove compound
+                // tokens like `<<` from `rustc_lexer`, and then add fancier error recovery to it,
+                // as there will be less overall work to do this way.
+                return match unicode_chars::check_for_substitution(self, start, c, &mut err) {
+                    Some(token) => {
+                        err.emit();
+                        Ok(token)
+                    }
+                    None => Err(err),
+                }
             }
         };
         Ok(kind)
diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs
index b728a9e1988..eaa736c6a35 100644
--- a/src/libsyntax/parse/lexer/unicode_chars.rs
+++ b/src/libsyntax/parse/lexer/unicode_chars.rs
@@ -3,7 +3,8 @@
 
 use super::StringReader;
 use errors::{Applicability, DiagnosticBuilder};
-use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION};
+use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION, symbol::kw};
+use crate::parse::token;
 
 #[rustfmt::skip] // for line breaks
 const UNICODE_ARRAY: &[(char, &str, char)] = &[
@@ -297,32 +298,38 @@ const UNICODE_ARRAY: &[(char, &str, char)] = &[
     ('>', "Fullwidth Greater-Than Sign", '>'),
 ];
 
-const ASCII_ARRAY: &[(char, &str)] = &[
-    (' ', "Space"),
-    ('_', "Underscore"),
-    ('-', "Minus/Hyphen"),
-    (',', "Comma"),
-    (';', "Semicolon"),
-    (':', "Colon"),
-    ('!', "Exclamation Mark"),
-    ('?', "Question Mark"),
-    ('.', "Period"),
-    ('\'', "Single Quote"),
-    ('"', "Quotation Mark"),
-    ('(', "Left Parenthesis"),
-    (')', "Right Parenthesis"),
-    ('[', "Left Square Bracket"),
-    (']', "Right Square Bracket"),
-    ('{', "Left Curly Brace"),
-    ('}', "Right Curly Brace"),
-    ('*', "Asterisk"),
-    ('/', "Slash"),
-    ('\\', "Backslash"),
-    ('&', "Ampersand"),
-    ('+', "Plus Sign"),
-    ('<', "Less-Than Sign"),
-    ('=', "Equals Sign"),
-    ('>', "Greater-Than Sign"),
+// FIXME: the lexer could be used to turn the ASCII version of unicode homoglyphs, instead of
+// keeping the substitution token in this table. Ideally, this should be inside `rustc_lexer`.
+// However, we should first remove compound tokens like `<<` from `rustc_lexer`, and then add
+// fancier error recovery to it, as there will be less overall work to do this way.
+const ASCII_ARRAY: &[(char, &str, Option<token::TokenKind>)] = &[
+    (' ', "Space", Some(token::Whitespace)),
+    ('_', "Underscore", Some(token::Ident(kw::Underscore, false))),
+    ('-', "Minus/Hyphen", Some(token::BinOp(token::Minus))),
+    (',', "Comma", Some(token::Comma)),
+    (';', "Semicolon", Some(token::Semi)),
+    (':', "Colon", Some(token::Colon)),
+    ('!', "Exclamation Mark", Some(token::Not)),
+    ('?', "Question Mark", Some(token::Question)),
+    ('.', "Period", Some(token::Dot)),
+    ('(', "Left Parenthesis", Some(token::OpenDelim(token::Paren))),
+    (')', "Right Parenthesis", Some(token::CloseDelim(token::Paren))),
+    ('[', "Left Square Bracket", Some(token::OpenDelim(token::Bracket))),
+    (']', "Right Square Bracket", Some(token::CloseDelim(token::Bracket))),
+    ('{', "Left Curly Brace", Some(token::OpenDelim(token::Brace))),
+    ('}', "Right Curly Brace", Some(token::CloseDelim(token::Brace))),
+    ('*', "Asterisk", Some(token::BinOp(token::Star))),
+    ('/', "Slash", Some(token::BinOp(token::Slash))),
+    ('\\', "Backslash", None),
+    ('&', "Ampersand", Some(token::BinOp(token::And))),
+    ('+', "Plus Sign", Some(token::BinOp(token::Plus))),
+    ('<', "Less-Than Sign", Some(token::Lt)),
+    ('=', "Equals Sign", Some(token::Eq)),
+    ('>', "Greater-Than Sign", Some(token::Gt)),
+    // FIXME: Literals are already lexed by this point, so we can't recover gracefully just by
+    // spitting the correct token out.
+    ('\'', "Single Quote", None),
+    ('"', "Quotation Mark", None),
 ];
 
 crate fn check_for_substitution<'a>(
@@ -330,20 +337,20 @@ crate fn check_for_substitution<'a>(
     pos: BytePos,
     ch: char,
     err: &mut DiagnosticBuilder<'a>,
-) -> bool {
+) -> Option<token::TokenKind> {
     let (u_name, ascii_char) = match UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch) {
         Some(&(_u_char, u_name, ascii_char)) => (u_name, ascii_char),
-        None => return false,
+        None => return None,
     };
 
     let span = Span::new(pos, pos + Pos::from_usize(ch.len_utf8()), NO_EXPANSION);
 
-    let ascii_name = match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) {
-        Some((_ascii_char, ascii_name)) => ascii_name,
+    let (ascii_name, token) = match ASCII_ARRAY.iter().find(|&&(c, _, _)| c == ascii_char) {
+        Some((_ascii_char, ascii_name, token)) => (ascii_name, token),
         None => {
             let msg = format!("substitution character not found for '{}'", ch);
             reader.sess.span_diagnostic.span_bug_no_panic(span, &msg);
-            return false;
+            return None;
         }
     };
 
@@ -371,7 +378,7 @@ crate fn check_for_substitution<'a>(
         );
         err.span_suggestion(span, &msg, ascii_char.to_string(), Applicability::MaybeIncorrect);
     }
-    true
+    token.clone()
 }
 
 /// Extract string if found at current position with given delimiters
diff --git a/src/test/mir-opt/lower_128bit_debug_test.rs b/src/test/mir-opt/lower_128bit_debug_test.rs
deleted file mode 100644
index 1d23bac4ee2..00000000000
--- a/src/test/mir-opt/lower_128bit_debug_test.rs
+++ /dev/null
@@ -1,226 +0,0 @@
-// asmjs can't even pass i128 as arguments or return values, so ignore it.
-// this will hopefully be fixed by the LLVM 5 upgrade (#43370)
-// ignore-asmjs
-// ignore-emscripten
-
-// compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=yes
-
-static TEST_SIGNED: i128 = const_signed(-222);
-static TEST_UNSIGNED: u128 = const_unsigned(200);
-
-const fn const_signed(mut x: i128) -> i128 {
-    ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7
-}
-
-const fn const_unsigned(mut x: u128) -> u128 {
-    ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7
-}
-
-fn test_signed(mut x: i128) -> i128 {
-    x += 1;
-    x -= 2;
-    x *= 3;
-    x /= 4;
-    x %= 5;
-    x <<= 6;
-    x >>= 7;
-    x
-}
-
-fn test_unsigned(mut x: u128) -> u128 {
-    x += 1;
-    x -= 2;
-    x *= 3;
-    x /= 4;
-    x %= 5;
-    x <<= 6;
-    x >>= 7;
-    x
-}
-
-fn check(x: i128, y: u128) {
-    assert_eq!(test_signed(x), -1);
-    assert_eq!(const_signed(x), -1);
-    assert_eq!(TEST_SIGNED, -1);
-    assert_eq!(test_unsigned(y), 2);
-    assert_eq!(const_unsigned(y), 2);
-    assert_eq!(TEST_UNSIGNED, 2);
-}
-
-fn main() {
-    check(-222, 200);
-}
-
-// END RUST SOURCE
-
-// START rustc.const_signed.Lower128Bit.after.mir
-//     _8 = _1;
-//     _9 = const compiler_builtins::int::addsub::rust_i128_addo(move _8, const 1i128) -> bb10;
-//     ...
-//     _7 = move (_9.0: i128);
-//     ...
-//     _10 = const compiler_builtins::int::addsub::rust_i128_subo(move _7, const 2i128) -> bb11;
-//     ...
-//     _6 = move (_10.0: i128);
-//     ...
-//     _11 = const compiler_builtins::int::mul::rust_i128_mulo(move _6, const 3i128) -> bb12;
-//     ...
-//     _5 = move (_11.0: i128);
-//     ...
-//     _12 = Eq(const 4i128, const 0i128);
-//     assert(!move _12, "attempt to divide by zero") -> bb4;
-//     ...
-//     _13 = Eq(const 4i128, const -1i128);
-//     _14 = Eq(_5, const -170141183460469231731687303715884105728i128);
-//     _15 = BitAnd(move _13, move _14);
-//     assert(!move _15, "attempt to divide with overflow") -> bb5;
-//     ...
-//     _4 = const compiler_builtins::int::sdiv::rust_i128_div(move _5, const 4i128) -> bb13;
-//     ...
-//     _17 = Eq(const 5i128, const -1i128);
-//     _18 = Eq(_4, const -170141183460469231731687303715884105728i128);
-//     _19 = BitAnd(move _17, move _18);
-//     assert(!move _19, "attempt to calculate the remainder with overflow") -> bb7;
-//     ...
-//     _3 = const compiler_builtins::int::sdiv::rust_i128_rem(move _4, const 5i128) -> bb15;
-//     ...
-//     _2 = move (_20.0: i128);
-//     ...
-//     _23 = const 7i32 as u128 (Misc);
-//     _21 = const compiler_builtins::int::shift::rust_i128_shro(move _2, move _23) -> bb16;
-//     ...
-//     _0 = move (_21.0: i128);
-//     ...
-//     assert(!move (_9.1: bool), "attempt to add with overflow") -> bb1;
-//     ...
-//     assert(!move (_10.1: bool), "attempt to subtract with overflow") -> bb2;
-//     ...
-//     assert(!move (_11.1: bool), "attempt to multiply with overflow") -> bb3;
-//     ...
-//     _16 = Eq(const 5i128, const 0i128);
-//     assert(!move _16, "attempt to calculate the remainder with a divisor of zero") -> bb6;
-//     ...
-//     assert(!move (_20.1: bool), "attempt to shift left with overflow") -> bb8;
-//     ...
-//     _22 = const 6i32 as u128 (Misc);
-//     _20 = const compiler_builtins::int::shift::rust_i128_shlo(move _3, move _22) -> bb14;
-//     ...
-//     assert(!move (_21.1: bool), "attempt to shift right with overflow") -> bb9;
-// END rustc.const_signed.Lower128Bit.after.mir
-
-// START rustc.const_unsigned.Lower128Bit.after.mir
-//     _8 = _1;
-//     _9 = const compiler_builtins::int::addsub::rust_u128_addo(move _8, const 1u128) -> bb8;
-//     ...
-//     _7 = move (_9.0: u128);
-//     ...
-//     _10 = const compiler_builtins::int::addsub::rust_u128_subo(move _7, const 2u128) -> bb9;
-//     ...
-//     _6 = move (_10.0: u128);
-//     ...
-//     _11 = const compiler_builtins::int::mul::rust_u128_mulo(move _6, const 3u128) -> bb10;
-//     ...
-//     _5 = move (_11.0: u128);
-//     ...
-//     _12 = Eq(const 4u128, const 0u128);
-//     assert(!move _12, "attempt to divide by zero") -> bb4;
-//     ...
-//     _4 = const compiler_builtins::int::udiv::rust_u128_div(move _5, const 4u128) -> bb11;
-//     ...
-//     _3 = const compiler_builtins::int::udiv::rust_u128_rem(move _4, const 5u128) -> bb13;
-//     ...
-//     _2 = move (_14.0: u128);
-//     ...
-//     _17 = const 7i32 as u128 (Misc);
-//     _15 = const compiler_builtins::int::shift::rust_u128_shro(move _2, move _17) -> bb14;
-//     ...
-//     _0 = move (_15.0: u128);
-//     ...
-//     assert(!move (_9.1: bool), "attempt to add with overflow") -> bb1;
-//     ...
-//     assert(!move (_10.1: bool), "attempt to subtract with overflow") -> bb2;
-//     ...
-//     assert(!move (_11.1: bool), "attempt to multiply with overflow") -> bb3;
-//     ...
-//     _13 = Eq(const 5u128, const 0u128);
-//     assert(!move _13, "attempt to calculate the remainder with a divisor of zero") -> bb5;
-//     ...
-//     assert(!move (_14.1: bool), "attempt to shift left with overflow") -> bb6;
-//     ...
-//     _16 = const 6i32 as u128 (Misc);
-//     _14 = const compiler_builtins::int::shift::rust_u128_shlo(move _3, move _16) -> bb12;
-//     ...
-//     assert(!move (_15.1: bool), "attempt to shift right with overflow") -> bb7;
-// END rustc.const_unsigned.Lower128Bit.after.mir
-
-// START rustc.test_signed.Lower128Bit.after.mir
-//     _2 = const compiler_builtins::int::addsub::rust_i128_addo(_1, const 1i128) -> bb10;
-//     ...
-//     _1 = move (_2.0: i128);
-//     _3 = const compiler_builtins::int::addsub::rust_i128_subo(_1, const 2i128) -> bb11;
-//     ...
-//     _1 = move (_3.0: i128);
-//     _4 = const compiler_builtins::int::mul::rust_i128_mulo(_1, const 3i128) -> bb12;
-//     ...
-//     _1 = move (_4.0: i128);
-//     ...
-//     _1 = const compiler_builtins::int::sdiv::rust_i128_div(_1, const 4i128) -> bb13;
-//     ...
-//     _1 = const compiler_builtins::int::sdiv::rust_i128_rem(_1, const 5i128) -> bb15;
-//     ...
-//     _1 = move (_13.0: i128);
-//     ...
-//     _16 = const 7i32 as u128 (Misc);
-//     _14 = const compiler_builtins::int::shift::rust_i128_shro(_1, move _16) -> bb16;
-//     ...
-//     _1 = move (_14.0: i128);
-//     ...
-//     assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1;
-//     ...
-//     assert(!move (_3.1: bool), "attempt to subtract with overflow") -> bb2;
-//     ...
-//     assert(!move (_4.1: bool), "attempt to multiply with overflow") -> bb3;
-//     ...
-//     assert(!move (_13.1: bool), "attempt to shift left with overflow") -> bb8;
-//     ...
-//     _15 = const 6i32 as u128 (Misc);
-//     _13 = const compiler_builtins::int::shift::rust_i128_shlo(_1, move _15) -> bb14;
-//     ...
-//     assert(!move (_14.1: bool), "attempt to shift right with overflow") -> bb9;
-// END rustc.test_signed.Lower128Bit.after.mir
-
-// START rustc.test_unsigned.Lower128Bit.after.mir
-//     _2 = const compiler_builtins::int::addsub::rust_u128_addo(_1, const 1u128) -> bb8;
-//     ...
-//     _1 = move (_2.0: u128);
-//     _3 = const compiler_builtins::int::addsub::rust_u128_subo(_1, const 2u128) -> bb9;
-//     ...
-//     _1 = move (_3.0: u128);
-//     _4 = const compiler_builtins::int::mul::rust_u128_mulo(_1, const 3u128) -> bb10;
-//     ...
-//     _1 = move (_4.0: u128);
-//     ...
-//     _1 = const compiler_builtins::int::udiv::rust_u128_div(_1, const 4u128) -> bb11;
-//     ...
-//     _1 = const compiler_builtins::int::udiv::rust_u128_rem(_1, const 5u128) -> bb13;
-//     ...
-//     _1 = move (_7.0: u128);
-//     ...
-//     _10 = const 7i32 as u128 (Misc);
-//     _8 = const compiler_builtins::int::shift::rust_u128_shro(_1, move _10) -> bb14;
-//     ...
-//     _1 = move (_8.0: u128);
-//     ...
-//     assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1;
-//     ...
-//     assert(!move (_3.1: bool), "attempt to subtract with overflow") -> bb2;
-//     ...
-//     assert(!move (_4.1: bool), "attempt to multiply with overflow") -> bb3;
-//     ...
-//     assert(!move (_7.1: bool), "attempt to shift left with overflow") -> bb6;
-//     ...
-//     _9 = const 6i32 as u128 (Misc);
-//     _7 = const compiler_builtins::int::shift::rust_u128_shlo(_1, move _9) -> bb12;
-//     ...
-//     assert(!move (_8.1: bool), "attempt to shift right with overflow") -> bb7;
-// END rustc.test_unsigned.Lower128Bit.after.mir
diff --git a/src/test/mir-opt/lower_128bit_test.rs b/src/test/mir-opt/lower_128bit_test.rs
deleted file mode 100644
index 7528330b030..00000000000
--- a/src/test/mir-opt/lower_128bit_test.rs
+++ /dev/null
@@ -1,149 +0,0 @@
-// ignore-emscripten
-
-// compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=no -O
-
-static TEST_SIGNED: i128 = const_signed(-222);
-static TEST_UNSIGNED: u128 = const_unsigned(200);
-
-const fn const_signed(mut x: i128) -> i128 {
-    ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7
-}
-
-const fn const_unsigned(mut x: u128) -> u128 {
-    ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7
-}
-
-fn test_signed(mut x: i128) -> i128 {
-    x += 1;
-    x -= 2;
-    x *= 3;
-    x /= 4;
-    x %= 5;
-    x <<= 6;
-    x >>= 7;
-    x
-}
-
-fn test_unsigned(mut x: u128) -> u128 {
-    x += 1;
-    x -= 2;
-    x *= 3;
-    x /= 4;
-    x %= 5;
-    x <<= 6;
-    x >>= 7;
-    x
-}
-
-fn check(x: i128, y: u128) {
-    assert_eq!(test_signed(x), -1);
-    assert_eq!(const_signed(x), -1);
-    assert_eq!(TEST_SIGNED, -1);
-    assert_eq!(test_unsigned(y), 2);
-    assert_eq!(const_unsigned(y), 2);
-    assert_eq!(TEST_UNSIGNED, 2);
-}
-
-fn main() {
-    check(-222, 200);
-}
-
-// END RUST SOURCE
-
-// START rustc.const_signed.Lower128Bit.after.mir
-// _7 = const compiler_builtins::int::addsub::rust_i128_add(move _8, const 1i128) -> bb7;
-// ...
-// _10 = Eq(const 4i128, const -1i128);
-// _11 = Eq(_5, const -170141183460469231731687303715884105728i128);
-// _12 = BitAnd(move _10, move _11);
-// assert(!move _12, "attempt to divide with overflow") -> bb2;
-// ...
-// _4 = const compiler_builtins::int::sdiv::rust_i128_div(move _5, const 4i128) -> bb8;
-// ...
-// _14 = Eq(const 5i128, const -1i128);
-// _15 = Eq(_4, const -170141183460469231731687303715884105728i128);
-// _16 = BitAnd(move _14, move _15);
-// assert(!move _16, "attempt to calculate the remainder with overflow") -> bb4;
-// ...
-// _3 = const compiler_builtins::int::sdiv::rust_i128_rem(move _4, const 5i128) -> bb11;
-// ...
-// _9 = Eq(const 4i128, const 0i128);
-// assert(!move _9, "attempt to divide by zero") -> bb1;
-// ...
-// _5 = const compiler_builtins::int::mul::rust_i128_mul(move _6, const 3i128) -> bb5;
-// ...
-// _6 = const compiler_builtins::int::addsub::rust_i128_sub(move _7, const 2i128) -> bb6;
-// ...
-// _13 = Eq(const 5i128, const 0i128);
-// assert(!move _13, "attempt to calculate the remainder with a divisor of zero") -> bb3;
-// ...
-// _17 = const 7i32 as u32 (Misc);
-// _0 = const compiler_builtins::int::shift::rust_i128_shr(move _2, move _17) -> bb9;
-// ...
-// _18 = const 6i32 as u32 (Misc);
-// _2 = const compiler_builtins::int::shift::rust_i128_shl(move _3, move _18) -> bb10;
-// END rustc.const_signed.Lower128Bit.after.mir
-
-// START rustc.const_unsigned.Lower128Bit.after.mir
-// _8 = _1;
-// _7 = const compiler_builtins::int::addsub::rust_u128_add(move _8, const 1u128) -> bb5;
-// ...
-// _4 = const compiler_builtins::int::udiv::rust_u128_div(move _5, const 4u128) -> bb6;
-// ...
-// _3 = const compiler_builtins::int::udiv::rust_u128_rem(move _4, const 5u128) -> bb9;
-// ...
-// _9 = Eq(const 4u128, const 0u128);
-// assert(!move _9, "attempt to divide by zero") -> bb1;
-// ...
-// _5 = const compiler_builtins::int::mul::rust_u128_mul(move _6, const 3u128) -> bb3;
-// ...
-// _6 = const compiler_builtins::int::addsub::rust_u128_sub(move _7, const 2u128) -> bb4;
-// ...
-// _10 = Eq(const 5u128, const 0u128);
-// assert(!move _10, "attempt to calculate the remainder with a divisor of zero") -> bb2;
-// ...
-// return;
-// ...
-// _11 = const 7i32 as u32 (Misc);
-// _0 = const compiler_builtins::int::shift::rust_u128_shr(move _2, move _11) -> bb7;
-// ...
-// _12 = const 6i32 as u32 (Misc);
-// _2 = const compiler_builtins::int::shift::rust_u128_shl(move _3, move _12) -> bb8;
-
-// END rustc.const_unsigned.Lower128Bit.after.mir
-
-// START rustc.test_signed.Lower128Bit.after.mir
-//     _1 = const compiler_builtins::int::addsub::rust_i128_add(_1, const 1i128) -> bb7;
-//     ...
-//     _1 = const compiler_builtins::int::sdiv::rust_i128_div(_1, const 4i128) -> bb8;
-//     ...
-//     _1 = const compiler_builtins::int::sdiv::rust_i128_rem(_1, const 5i128) -> bb11;
-//     ...
-//     _1 = const compiler_builtins::int::mul::rust_i128_mul(_1, const 3i128) -> bb5;
-//     ...
-//     _1 = const compiler_builtins::int::addsub::rust_i128_sub(_1, const 2i128) -> bb6;
-//     ...
-//     _10 = const 7i32 as u32 (Misc);
-//     _1 = const compiler_builtins::int::shift::rust_i128_shr(_1, move _10) -> bb9;
-//     ...
-//     _11 = const 6i32 as u32 (Misc);
-//     _1 = const compiler_builtins::int::shift::rust_i128_shl(_1, move _11) -> bb10;
-// END rustc.test_signed.Lower128Bit.after.mir
-
-// START rustc.test_unsigned.Lower128Bit.after.mir
-//     _1 = const compiler_builtins::int::addsub::rust_u128_add(_1, const 1u128) -> bb5;
-//     ...
-//     _1 = const compiler_builtins::int::udiv::rust_u128_div(_1, const 4u128) -> bb6;
-//     ...
-//     _1 = const compiler_builtins::int::udiv::rust_u128_rem(_1, const 5u128) -> bb9;
-//     ...
-//     _1 = const compiler_builtins::int::mul::rust_u128_mul(_1, const 3u128) -> bb3;
-//     ...
-//     _1 = const compiler_builtins::int::addsub::rust_u128_sub(_1, const 2u128) -> bb4;
-//     ...
-//     _4 = const 7i32 as u32 (Misc);
-//     _1 = const compiler_builtins::int::shift::rust_u128_shr(_1, move _4) -> bb7;
-//     ...
-//     _5 = const 6i32 as u32 (Misc);
-//     _1 = const compiler_builtins::int::shift::rust_u128_shl(_1, move _5) -> bb8;
-// END rustc.test_unsigned.Lower128Bit.after.mir
diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs
index e3faa7c625c..4195444a73f 100644
--- a/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs
+++ b/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs
@@ -2,7 +2,7 @@
 #![allow(non_camel_case_types)]
 
 // ignore-emscripten
-// ignore-aarch64 FIXME: https://github.com/rust-lang/rust/issues/54510
+// min-system-llvm-version: 9.0
 
 // Test that the simd_reduce_{op} intrinsics produce the correct results.
 
@@ -124,14 +124,14 @@ fn main() {
         assert_eq!(r, 6_f32);
         let r: f32 = simd_reduce_mul_unordered(x);
         assert_eq!(r, -24_f32);
-        // FIXME: only works correctly for accumulator, 0:
-        // https://bugs.llvm.org/show_bug.cgi?id=36734
         let r: f32 = simd_reduce_add_ordered(x, 0.);
         assert_eq!(r, 6_f32);
-        // FIXME: only works correctly for accumulator, 1:
-        // https://bugs.llvm.org/show_bug.cgi?id=36734
         let r: f32 = simd_reduce_mul_ordered(x, 1.);
         assert_eq!(r, -24_f32);
+        let r: f32 = simd_reduce_add_ordered(x, 1.);
+        assert_eq!(r, 7_f32);
+        let r: f32 = simd_reduce_mul_ordered(x, 2.);
+        assert_eq!(r, -48_f32);
 
         let r: f32 = simd_reduce_min(x);
         assert_eq!(r, -2_f32);
diff --git a/src/test/ui/annotate-snippet/missing-type.stderr b/src/test/ui/annotate-snippet/missing-type.stderr
index 8857ae7d850..806acf0bed5 100644
--- a/src/test/ui/annotate-snippet/missing-type.stderr
+++ b/src/test/ui/annotate-snippet/missing-type.stderr
@@ -1,6 +1,6 @@
 error[E0412]: cannot find type `Iter` in this scope
- --> $DIR/missing-type.rs:4:11
-  |
-4 |     let x: Iter;
-  |            ^^^^ not found in this scope
-  |
+  --> $DIR/missing-type.rs:4:11
+   |
+LL |     let x: Iter;
+   |            ^^^^ not found in this scope
+   |
diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs
index 5c2c3b8ec61..66d562d2eb5 100644
--- a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs
+++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs
@@ -1,5 +1,6 @@
 const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻²
 //~^ ERROR expected at least one digit in exponent
 //~| ERROR unknown start of token: \u{2212}
+//~| ERROR cannot subtract `{integer}` from `{float}`
 
 fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr
index 07653c791db..9ee86adec52 100644
--- a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr
+++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr
@@ -14,5 +14,14 @@ help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it
 LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻²
    |                                                     ^
 
-error: aborting due to 2 previous errors
+error[E0277]: cannot subtract `{integer}` from `{float}`
+  --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53
+   |
+LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻²
+   |                                                     ^ no implementation for `{float} - {integer}`
+   |
+   = help: the trait `std::ops::Sub<{integer}>` is not implemented for `{float}`
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs
new file mode 100644
index 00000000000..67feb3ff6ae
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs
@@ -0,0 +1,6 @@
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &Some(42).as_deref();
+//~^ ERROR no method named `as_deref` found for type `std::option::Option<{integer}>`
+}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr
new file mode 100644
index 00000000000..345f91437b8
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `as_deref` found for type `std::option::Option<{integer}>` in the current scope
+  --> $DIR/option-as_deref.rs:4:29
+   |
+LL |     let _result = &Some(42).as_deref();
+   |                             ^^^^^^^^ help: there is a method with a similar name: `as_ref`
+   |
+   = note: the method `as_deref` exists but the following trait bounds were not satisfied:
+           `{integer} : std::ops::Deref`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs
new file mode 100644
index 00000000000..56aead8d0e0
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs
@@ -0,0 +1,6 @@
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &mut Some(42).as_deref_mut();
+//~^ ERROR no method named `as_deref_mut` found for type `std::option::Option<{integer}>`
+}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
new file mode 100644
index 00000000000..2c3a18be67c
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `as_deref_mut` found for type `std::option::Option<{integer}>` in the current scope
+  --> $DIR/option-as_deref_mut.rs:4:33
+   |
+LL |     let _result = &mut Some(42).as_deref_mut();
+   |                                 ^^^^^^^^^^^^
+   |
+   = note: the method `as_deref_mut` exists but the following trait bounds were not satisfied:
+           `{integer} : std::ops::DerefMut`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.rs
deleted file mode 100644
index f82eafcaffa..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(inner_deref)]
-
-fn main() {
-    let _result = &Some(42).deref();
-//~^ ERROR no method named `deref` found for type `std::option::Option<{integer}>`
-}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.stderr
deleted file mode 100644
index e916b7d7d34..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0599]: no method named `deref` found for type `std::option::Option<{integer}>` in the current scope
-  --> $DIR/option-deref.rs:4:29
-   |
-LL |     let _result = &Some(42).deref();
-   |                             ^^^^^
-   |
-   = note: the method `deref` exists but the following trait bounds were not satisfied:
-           `{integer} : std::ops::Deref`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs
new file mode 100644
index 00000000000..1d5eabd6170
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs
@@ -0,0 +1,6 @@
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &Ok(42).as_deref();
+//~^ ERROR no method named `as_deref` found
+}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
new file mode 100644
index 00000000000..5e016748770
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `as_deref` found for type `std::result::Result<{integer}, _>` in the current scope
+  --> $DIR/result-as_deref.rs:4:27
+   |
+LL |     let _result = &Ok(42).as_deref();
+   |                           ^^^^^^^^ help: there is a method with a similar name: `as_ref`
+   |
+   = note: the method `as_deref` exists but the following trait bounds were not satisfied:
+           `{integer} : std::ops::Deref`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs
new file mode 100644
index 00000000000..104aa3bcadf
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs
@@ -0,0 +1,6 @@
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &Err(41).as_deref_err();
+//~^ ERROR no method named `as_deref_err` found
+}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr
new file mode 100644
index 00000000000..6dc13da548b
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `as_deref_err` found for type `std::result::Result<_, {integer}>` in the current scope
+  --> $DIR/result-as_deref_err.rs:4:28
+   |
+LL |     let _result = &Err(41).as_deref_err();
+   |                            ^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_ok`
+   |
+   = note: the method `as_deref_err` exists but the following trait bounds were not satisfied:
+           `{integer} : std::ops::Deref`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs
new file mode 100644
index 00000000000..c897ab3531f
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs
@@ -0,0 +1,6 @@
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &mut Ok(42).as_deref_mut();
+//~^ ERROR no method named `as_deref_mut` found
+}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
new file mode 100644
index 00000000000..f21e97388b6
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `as_deref_mut` found for type `std::result::Result<{integer}, _>` in the current scope
+  --> $DIR/result-as_deref_mut.rs:4:31
+   |
+LL |     let _result = &mut Ok(42).as_deref_mut();
+   |                               ^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_err`
+   |
+   = note: the method `as_deref_mut` exists but the following trait bounds were not satisfied:
+           `{integer} : std::ops::DerefMut`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs
new file mode 100644
index 00000000000..b7849ecb6d2
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs
@@ -0,0 +1,6 @@
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &mut Err(41).as_deref_mut_err();
+//~^ ERROR no method named `as_deref_mut_err` found
+}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr
new file mode 100644
index 00000000000..44c0c954eee
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `as_deref_mut_err` found for type `std::result::Result<_, {integer}>` in the current scope
+  --> $DIR/result-as_deref_mut_err.rs:4:32
+   |
+LL |     let _result = &mut Err(41).as_deref_mut_err();
+   |                                ^^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut_ok`
+   |
+   = note: the method `as_deref_mut_err` exists but the following trait bounds were not satisfied:
+           `{integer} : std::ops::DerefMut`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs
new file mode 100644
index 00000000000..54b695a0865
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs
@@ -0,0 +1,6 @@
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &mut Ok(42).as_deref_mut_ok();
+//~^ ERROR no method named `as_deref_mut_ok` found
+}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr
new file mode 100644
index 00000000000..b8369c9b82e
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `as_deref_mut_ok` found for type `std::result::Result<{integer}, _>` in the current scope
+  --> $DIR/result-as_deref_mut_ok.rs:4:31
+   |
+LL |     let _result = &mut Ok(42).as_deref_mut_ok();
+   |                               ^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut_err`
+   |
+   = note: the method `as_deref_mut_ok` exists but the following trait bounds were not satisfied:
+           `{integer} : std::ops::DerefMut`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs
new file mode 100644
index 00000000000..ebb0500e819
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs
@@ -0,0 +1,6 @@
+#![feature(inner_deref)]
+
+fn main() {
+    let _result = &Ok(42).as_deref_ok();
+//~^ ERROR no method named `as_deref_ok` found
+}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr
new file mode 100644
index 00000000000..b26705a99e3
--- /dev/null
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `as_deref_ok` found for type `std::result::Result<{integer}, _>` in the current scope
+  --> $DIR/result-as_deref_ok.rs:4:27
+   |
+LL |     let _result = &Ok(42).as_deref_ok();
+   |                           ^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_err`
+   |
+   = note: the method `as_deref_ok` exists but the following trait bounds were not satisfied:
+           `{integer} : std::ops::Deref`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.rs
deleted file mode 100644
index 4be2000f058..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(inner_deref)]
-
-fn main() {
-    let _result = &Err(41).deref_err();
-//~^ ERROR no method named `deref_err` found
-}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr
deleted file mode 100644
index 333036127ea..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0599]: no method named `deref_err` found for type `std::result::Result<_, {integer}>` in the current scope
-  --> $DIR/result-deref-err.rs:4:28
-   |
-LL |     let _result = &Err(41).deref_err();
-   |                            ^^^^^^^^^ help: there is a method with a similar name: `deref_ok`
-   |
-   = note: the method `deref_err` exists but the following trait bounds were not satisfied:
-           `{integer} : std::ops::Deref`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.rs
deleted file mode 100644
index a706cde7348..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(inner_deref)]
-
-fn main() {
-    let _result = &Ok(42).deref_ok();
-//~^ ERROR no method named `deref_ok` found
-}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.stderr
deleted file mode 100644
index 59370512354..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0599]: no method named `deref_ok` found for type `std::result::Result<{integer}, _>` in the current scope
-  --> $DIR/result-deref-ok.rs:4:27
-   |
-LL |     let _result = &Ok(42).deref_ok();
-   |                           ^^^^^^^^
-   |
-   = note: the method `deref_ok` exists but the following trait bounds were not satisfied:
-           `{integer} : std::ops::Deref`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.rs
deleted file mode 100644
index 43a68e37dd0..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![feature(inner_deref)]
-
-fn main() {
-    let _result = &Ok(42).deref();
-//~^ ERROR no method named `deref` found
-}
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.stderr
deleted file mode 100644
index 05baa7907fa..00000000000
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0599]: no method named `deref` found for type `std::result::Result<{integer}, _>` in the current scope
-  --> $DIR/result-deref.rs:4:27
-   |
-LL |     let _result = &Ok(42).deref();
-   |                           ^^^^^
-   |
-   = note: the method `deref` exists but the following trait bounds were not satisfied:
-           `{integer} : std::ops::Deref`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/issues/issue-54062.rs b/src/test/ui/issues/issue-54062.rs
new file mode 100644
index 00000000000..495b7343f20
--- /dev/null
+++ b/src/test/ui/issues/issue-54062.rs
@@ -0,0 +1,13 @@
+use std::sync::Mutex;
+
+struct Test {
+    comps: Mutex<String>,
+}
+
+fn main() {}
+
+fn testing(test: Test) {
+    let _ = test.comps.inner.lock().unwrap();
+    //~^ ERROR: field `inner` of struct `std::sync::Mutex` is private
+    //~| ERROR: no method named `unwrap` found
+}
diff --git a/src/test/ui/issues/issue-54062.stderr b/src/test/ui/issues/issue-54062.stderr
new file mode 100644
index 00000000000..082ac91edb1
--- /dev/null
+++ b/src/test/ui/issues/issue-54062.stderr
@@ -0,0 +1,16 @@
+error[E0616]: field `inner` of struct `std::sync::Mutex` is private
+  --> $DIR/issue-54062.rs:10:13
+   |
+LL |     let _ = test.comps.inner.lock().unwrap();
+   |             ^^^^^^^^^^^^^^^^
+
+error[E0599]: no method named `unwrap` found for type `std::sys_common::mutex::MutexGuard<'_>` in the current scope
+  --> $DIR/issue-54062.rs:10:37
+   |
+LL |     let _ = test.comps.inner.lock().unwrap();
+   |                                     ^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0599, E0616.
+For more information about an error, try `rustc --explain E0599`.
diff --git a/src/test/ui/macros/auxiliary/proc_macro_sequence.rs b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs
new file mode 100644
index 00000000000..b50ed7ca92a
--- /dev/null
+++ b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs
@@ -0,0 +1,36 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+#![feature(proc_macro_span, proc_macro_hygiene, proc_macro_quote)]
+
+extern crate proc_macro;
+
+use proc_macro::{quote, Span, TokenStream};
+
+fn assert_same_span(a: Span, b: Span) {
+    assert_eq!(a.start(), b.start());
+    assert_eq!(a.end(), b.end());
+}
+
+// This macro generates a macro with the same macro definition as `manual_foo` in
+// `same-sequence-span.rs` but with the same span for all sequences.
+#[proc_macro]
+pub fn make_foo(_: TokenStream) -> TokenStream {
+    let result = quote! {
+        macro_rules! generated_foo {
+            (1 $$x:expr $$($$y:tt,)* $$(= $$z:tt)*) => {};
+        }
+    };
+
+    // Check that all spans are equal.
+    let mut span = None;
+    for tt in result.clone() {
+        match span {
+            None => span = Some(tt.span()),
+            Some(span) => assert_same_span(tt.span(), span),
+        }
+    }
+
+    result
+}
diff --git a/src/test/ui/macros/same-sequence-span.rs b/src/test/ui/macros/same-sequence-span.rs
new file mode 100644
index 00000000000..a4f70b6b68d
--- /dev/null
+++ b/src/test/ui/macros/same-sequence-span.rs
@@ -0,0 +1,23 @@
+// aux-build:proc_macro_sequence.rs
+
+// Regression test for issue #62831: Check that multiple sequences with the same span in the
+// left-hand side of a macro definition behave as if they had unique spans, and in particular that
+// they don't crash the compiler.
+
+#![feature(proc_macro_hygiene)]
+#![allow(unused_macros)]
+
+extern crate proc_macro_sequence;
+
+// When ignoring spans, this macro has the same macro definition as `generated_foo` in
+// `proc_macro_sequence.rs`.
+macro_rules! manual_foo {
+    (1 $x:expr $($y:tt,)*   //~ERROR `$x:expr` may be followed by `$y:tt`
+               $(= $z:tt)*  //~ERROR `$x:expr` may be followed by `=`
+    ) => {};
+}
+
+proc_macro_sequence::make_foo!(); //~ERROR `$x:expr` may be followed by `$y:tt`
+                                  //~^ERROR `$x:expr` may be followed by `=`
+
+fn main() {}
diff --git a/src/test/ui/macros/same-sequence-span.stderr b/src/test/ui/macros/same-sequence-span.stderr
new file mode 100644
index 00000000000..aee1b4c9c5d
--- /dev/null
+++ b/src/test/ui/macros/same-sequence-span.stderr
@@ -0,0 +1,34 @@
+error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
+  --> $DIR/same-sequence-span.rs:15:18
+   |
+LL |     (1 $x:expr $($y:tt,)*
+   |                  ^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
+
+error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments
+  --> $DIR/same-sequence-span.rs:16:18
+   |
+LL |                $(= $z:tt)*
+   |                  ^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
+
+error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
+  --> $DIR/same-sequence-span.rs:20:1
+   |
+LL | proc_macro_sequence::make_foo!();
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
+
+error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments
+  --> $DIR/same-sequence-span.rs:20:1
+   |
+LL | proc_macro_sequence::make_foo!();
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments
+   |
+   = note: allowed there are: `=>`, `,` or `;`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/parser/recover-from-homoglyph.rs b/src/test/ui/parser/recover-from-homoglyph.rs
new file mode 100644
index 00000000000..99ce0d1a630
--- /dev/null
+++ b/src/test/ui/parser/recover-from-homoglyph.rs
@@ -0,0 +1,4 @@
+fn main() {
+    println!(""); //~ ERROR unknown start of token: \u{37e}
+    let x: usize = (); //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/recover-from-homoglyph.stderr b/src/test/ui/parser/recover-from-homoglyph.stderr
new file mode 100644
index 00000000000..424d492b7ba
--- /dev/null
+++ b/src/test/ui/parser/recover-from-homoglyph.stderr
@@ -0,0 +1,22 @@
+error: unknown start of token: \u{37e}
+  --> $DIR/recover-from-homoglyph.rs:2:17
+   |
+LL |     println!("");
+   |                 ^
+help: Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not
+   |
+LL |     println!("");
+   |                 ^
+
+error[E0308]: mismatched types
+  --> $DIR/recover-from-homoglyph.rs:3:20
+   |
+LL |     let x: usize = ();
+   |                    ^^ expected usize, found ()
+   |
+   = note: expected type `usize`
+              found type `()`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs
index 8e67c27ef22..9a6dbe9d9ab 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs
@@ -30,13 +30,10 @@ fn main() {
     let z = f32x4(0.0, 0.0, 0.0, 0.0);
 
     unsafe {
-        simd_reduce_add_ordered(z, 0_f32);
-        simd_reduce_mul_ordered(z, 1_f32);
-
-        simd_reduce_add_ordered(z, 2_f32);
-        //~^ ERROR accumulator of simd_reduce_add_ordered is not 0.0
-        simd_reduce_mul_ordered(z, 3_f32);
-        //~^ ERROR accumulator of simd_reduce_mul_ordered is not 1.0
+        simd_reduce_add_ordered(z, 0);
+        //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32`
+        simd_reduce_mul_ordered(z, 1);
+        //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32`
 
         let _: f32 = simd_reduce_and(x);
         //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32`
@@ -56,16 +53,5 @@ fn main() {
         //~^ ERROR unsupported simd_reduce_all from `f32x4` with element `f32` to `bool`
         let _: bool = simd_reduce_any(z);
         //~^ ERROR unsupported simd_reduce_any from `f32x4` with element `f32` to `bool`
-
-        foo(0_f32);
     }
 }
-
-#[inline(never)]
-unsafe fn foo(x: f32) {
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
-    simd_reduce_add_ordered(z, x);
-    //~^ ERROR accumulator of simd_reduce_add_ordered is not a constant
-    simd_reduce_mul_ordered(z, x);
-    //~^ ERROR accumulator of simd_reduce_mul_ordered is not a constant
-}
diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr
index 144571cb263..3863eeac3f3 100644
--- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr
+++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr
@@ -1,74 +1,62 @@
-error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: accumulator of simd_reduce_add_ordered is not 0.0
-  --> $DIR/simd-intrinsic-generic-reduction.rs:36:9
+error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
+  --> $DIR/simd-intrinsic-generic-reduction.rs:33:9
    |
-LL |         simd_reduce_add_ordered(z, 2_f32);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         simd_reduce_add_ordered(z, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: accumulator of simd_reduce_mul_ordered is not 1.0
-  --> $DIR/simd-intrinsic-generic-reduction.rs:38:9
+error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32`
+  --> $DIR/simd-intrinsic-generic-reduction.rs:35:9
    |
-LL |         simd_reduce_mul_ordered(z, 3_f32);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         simd_reduce_mul_ordered(z, 1);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:41:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:38:22
    |
 LL |         let _: f32 = simd_reduce_and(x);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:43:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:40:22
    |
 LL |         let _: f32 = simd_reduce_or(x);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:45:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:42:22
    |
 LL |         let _: f32 = simd_reduce_xor(x);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: unsupported simd_reduce_and from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:48:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:45:22
    |
 LL |         let _: f32 = simd_reduce_and(z);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: unsupported simd_reduce_or from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:50:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:47:22
    |
 LL |         let _: f32 = simd_reduce_or(z);
    |                      ^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:52:22
+  --> $DIR/simd-intrinsic-generic-reduction.rs:49:22
    |
 LL |         let _: f32 = simd_reduce_xor(z);
    |                      ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_all` intrinsic: unsupported simd_reduce_all from `f32x4` with element `f32` to `bool`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:55:23
+  --> $DIR/simd-intrinsic-generic-reduction.rs:52:23
    |
 LL |         let _: bool = simd_reduce_all(z);
    |                       ^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_reduce_any` intrinsic: unsupported simd_reduce_any from `f32x4` with element `f32` to `bool`
-  --> $DIR/simd-intrinsic-generic-reduction.rs:57:23
+  --> $DIR/simd-intrinsic-generic-reduction.rs:54:23
    |
 LL |         let _: bool = simd_reduce_any(z);
    |                       ^^^^^^^^^^^^^^^^^^
 
-error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: accumulator of simd_reduce_add_ordered is not a constant
-  --> $DIR/simd-intrinsic-generic-reduction.rs:67:5
-   |
-LL |     simd_reduce_add_ordered(z, x);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: accumulator of simd_reduce_mul_ordered is not a constant
-  --> $DIR/simd-intrinsic-generic-reduction.rs:69:5
-   |
-LL |     simd_reduce_mul_ordered(z, x);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 12 previous errors
+error: aborting due to 10 previous errors