about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.mailmap2
-rw-r--r--Cargo.lock38
-rw-r--r--src/bootstrap/bin/rustc.rs8
-rw-r--r--src/bootstrap/compile.rs2
-rw-r--r--src/bootstrap/tool.rs1
-rw-r--r--src/libcore/intrinsics.rs63
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/mem/mod.rs4
-rw-r--r--src/libcore/num/f32.rs23
-rw-r--r--src/libcore/num/f64.rs23
-rw-r--r--src/libcore/num/mod.rs2
-rw-r--r--src/libcore/ops/range.rs23
-rw-r--r--src/libcore/ptr/non_null.rs2
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/libcore/tests/ops.rs17
-rw-r--r--src/librustc/mir/visit.rs58
-rw-r--r--src/librustc/session/config.rs4
-rw-r--r--src/librustc/session/mod.rs6
-rw-r--r--src/librustc_codegen_llvm/context.rs5
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs4
-rw-r--r--src/librustc_codegen_ssa/mir/analyze.rs85
-rw-r--r--src/librustc_errors/annotate_snippet_emitter_writer.rs (renamed from src/librustc_errors/annotate_rs_emitter.rs)20
-rw-r--r--src/librustc_errors/emitter.rs4
-rw-r--r--src/librustc_errors/lib.rs2
-rw-r--r--src/librustc_mir/monomorphize/collector.rs25
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs79
-rw-r--r--src/librustc_typeck/check/intrinsic.rs7
-rw-r--r--src/libstd/Cargo.toml2
m---------src/tools/clippy18
-rw-r--r--src/tools/rustc-workspace-hack/Cargo.toml9
30 files changed, 324 insertions, 214 deletions
diff --git a/.mailmap b/.mailmap
index 679aa55d314..5673cc5cfbc 100644
--- a/.mailmap
+++ b/.mailmap
@@ -56,6 +56,7 @@ Chris Thorn <chris@thorn.co> Chris Thorn <thorn@thoughtbot.com>
 Chris Vittal <christopher.vittal@gmail.com> Christopher Vittal <christopher.vittal@gmail.com>
 Christian Poveda <christianpoveda@protonmail.com> <cn.poveda.ruiz@gmail.com>
 Christian Poveda <christianpoveda@protonmail.com> <z1mvader@protonmail.com>
+Christian Poveda <christianpoveda@protonmail.com> <cpovedar@fnal.gov>
 Clark Gaebel <cg.wowus.cg@gmail.com> <cgaebel@mozilla.com>
 Clinton Ryan <clint.ryan3@gmail.com>
 Corey Richardson <corey@octayn.net> Elaine "See More" Nemo <corey@octayn.net>
@@ -139,6 +140,7 @@ Kang Seonghoon <kang.seonghoon@mearie.org> <public+git@mearie.org>
 Keegan McAllister <mcallister.keegan@gmail.com> <kmcallister@mozilla.com>
 Kevin Butler <haqkrs@gmail.com>
 Kyeongwoon Lee <kyeongwoon.lee@samsung.com>
+Laurențiu Nicola <lnicola@dend.ro>
 Lee Jeffery <leejeffery@gmail.com> Lee Jeffery <lee@leejeffery.co.uk>
 Lee Wondong <wdlee91@gmail.com>
 Lennart Kudling <github@kudling.de>
diff --git a/Cargo.lock b/Cargo.lock
index 7892bc70695..71932157443 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -25,7 +25,7 @@ dependencies = [
 name = "alloc"
 version = "0.0.0"
 dependencies = [
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -118,7 +118,7 @@ dependencies = [
  "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
@@ -130,7 +130,7 @@ version = "0.1.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
@@ -357,7 +357,7 @@ name = "cfg-if"
 version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
 
@@ -486,7 +486,7 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.15"
+version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -768,7 +768,7 @@ name = "dlmalloc"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
@@ -934,7 +934,7 @@ name = "fortanix-sgx-abi"
 version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
 
@@ -1095,7 +1095,7 @@ name = "hashbrown"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-alloc 1.0.0",
  "rustc-std-workspace-core 1.0.0",
 ]
@@ -1803,7 +1803,7 @@ dependencies = [
 name = "panic_abort"
 version = "0.0.0"
 dependencies = [
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1813,7 +1813,7 @@ name = "panic_unwind"
 version = "0.0.0"
 dependencies = [
  "alloc 0.0.0",
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
  "unwind 0.0.0",
@@ -1998,7 +1998,7 @@ name = "profiler_builtins"
 version = "0.0.0"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -2518,7 +2518,7 @@ name = "rustc-demangle"
 version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
 
@@ -2646,7 +2646,7 @@ dependencies = [
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -2878,7 +2878,7 @@ dependencies = [
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -2941,7 +2941,7 @@ dependencies = [
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -3060,7 +3060,7 @@ dependencies = [
  "alloc 0.0.0",
  "build_helper 0.1.0",
  "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
 ]
 
@@ -3338,7 +3338,7 @@ dependencies = [
  "alloc 0.0.0",
  "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)",
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3936,7 +3936,7 @@ name = "unwind"
 version = "0.0.0"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
  "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -4149,7 +4149,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc"
 "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007"
 "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2"
-"checksum compiler_builtins 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "e899b947d7e71c3d35c0b6194d64025b84946640510e215090c815b20828964e"
+"checksum compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "e79ed19793c99771b386d76e08c3419409bb3d418b81a8b8afc73524247461cf"
 "checksum compiletest_rs 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "f40ecc9332b68270998995c00f8051ee856121764a0d3230e64c9efd059d27b6"
 "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
 "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887"
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index d51961c65b7..f5fb6f0b4d0 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -89,12 +89,16 @@ fn main() {
 
     let mut cmd = Command::new(rustc);
     cmd.args(&args)
-        .arg("--cfg")
-        .arg(format!("stage{}", stage))
         .env(bootstrap::util::dylib_path_var(),
              env::join_paths(&dylib_path).unwrap());
     let mut maybe_crate = None;
 
+    // Non-zero stages must all be treated uniformly to avoid problems when attempting to uplift
+    // compiler libraries and such from stage 1 to 2.
+    if stage == "0" {
+        cmd.arg("--cfg").arg("bootstrap");
+    }
+
     // Print backtrace in case of ICE
     if env::var("RUSTC_BACKTRACE_ON_ICE").is_ok() && env::var("RUST_BACKTRACE").is_err() {
         cmd.env("RUST_BACKTRACE", "1");
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 4515c7d672d..c7fa8e788b5 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -341,7 +341,7 @@ impl Step for StartupObjects {
             if !up_to_date(src_file, dst_file) {
                 let mut cmd = Command::new(&builder.initial_rustc);
                 builder.run(cmd.env("RUSTC_BOOTSTRAP", "1")
-                            .arg("--cfg").arg("stage0")
+                            .arg("--cfg").arg("bootstrap")
                             .arg("--target").arg(target)
                             .arg("--emit=obj")
                             .arg("-o").arg(dst_file)
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 3b6f02c9368..83a897f1ab7 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -84,6 +84,7 @@ impl Step for ToolBuild {
                 | "cargo"
                 | "clippy-driver"
                 | "miri"
+                | "rustfmt"
                 => {}
 
                 _ => return,
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 31a4e380a3d..b609af16ffe 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1051,6 +1051,19 @@ extern "rust-intrinsic" {
     /// Returns the absolute value of an `f64`.
     pub fn fabsf64(x: f64) -> f64;
 
+    /// Returns the minimum of two `f32` values.
+    #[cfg(not(bootstrap))]
+    pub fn minnumf32(x: f32, y: f32) -> f32;
+    /// Returns the minimum of two `f64` values.
+    #[cfg(not(bootstrap))]
+    pub fn minnumf64(x: f64, y: f64) -> f64;
+    /// Returns the maximum of two `f32` values.
+    #[cfg(not(bootstrap))]
+    pub fn maxnumf32(x: f32, y: f32) -> f32;
+    /// Returns the maximum of two `f64` values.
+    #[cfg(not(bootstrap))]
+    pub fn maxnumf64(x: f64, y: f64) -> f64;
+
     /// Copies the sign from `y` to `x` for `f32` values.
     pub fn copysignf32(x: f32, y: f32) -> f32;
     /// Copies the sign from `y` to `x` for `f64` values.
@@ -1242,17 +1255,17 @@ extern "rust-intrinsic" {
 
     /// Returns the result of an unchecked addition, resulting in
     /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`.
-    #[cfg(not(stage0))]
+    #[cfg(not(bootstrap))]
     pub fn unchecked_add<T>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked substraction, resulting in
     /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`.
-    #[cfg(not(stage0))]
+    #[cfg(not(bootstrap))]
     pub fn unchecked_sub<T>(x: T, y: T) -> T;
 
     /// Returns the result of an unchecked multiplication, resulting in
     /// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`.
-    #[cfg(not(stage0))]
+    #[cfg(not(bootstrap))]
     pub fn unchecked_mul<T>(x: T, y: T) -> T;
 
     /// Performs rotate left.
@@ -1561,3 +1574,47 @@ pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
 pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
     real_intrinsics::write_bytes(dst, val, count)
 }
+
+// Simple bootstrap implementations of minnum/maxnum for stage0 compilation.
+
+/// Returns the minimum of two `f32` values.
+#[cfg(bootstrap)]
+pub fn minnumf32(x: f32, y: f32) -> f32 {
+    // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the
+    // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
+    // is either x or y, canonicalized (this means results might differ among implementations).
+    // When either x or y is a signaling NaN, then the result is according to 6.2.
+    //
+    // Since we do not support sNaN in Rust yet, we do not need to handle them.
+    // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
+    // multiplying by 1.0. Should switch to the `canonicalize` when it works.
+    (if x < y || y != y { x } else { y }) * 1.0
+}
+
+/// Returns the minimum of two `f64` values.
+#[cfg(bootstrap)]
+pub fn minnumf64(x: f64, y: f64) -> f64 {
+    // Identical to the `f32` case.
+    (if x < y || y != y { x } else { y }) * 1.0
+}
+
+/// Returns the maximum of two `f32` values.
+#[cfg(bootstrap)]
+pub fn maxnumf32(x: f32, y: f32) -> f32 {
+    // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the
+    // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
+    // is either x or y, canonicalized (this means results might differ among implementations).
+    // When either x or y is a signaling NaN, then the result is according to 6.2.
+    //
+    // Since we do not support sNaN in Rust yet, we do not need to handle them.
+    // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
+    // multiplying by 1.0. Should switch to the `canonicalize` when it works.
+    (if x < y || x != x { y } else { x }) * 1.0
+}
+
+/// Returns the maximum of two `f64` values.
+#[cfg(bootstrap)]
+pub fn maxnumf64(x: f64, y: f64) -> f64 {
+    // Identical to the `f32` case.
+    (if x < y || x != x { y } else { x }) * 1.0
+}
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index ad352048047..af24cbe1c5c 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -70,6 +70,7 @@
 #![feature(arbitrary_self_types)]
 #![feature(asm)]
 #![feature(associated_type_defaults)]
+#![feature(bound_cloned)]
 #![feature(cfg_target_has_atomic)]
 #![feature(concat_idents)]
 #![feature(const_fn)]
diff --git a/src/libcore/mem/mod.rs b/src/libcore/mem/mod.rs
index 91449f09936..b43ba6ac340 100644
--- a/src/libcore/mem/mod.rs
+++ b/src/libcore/mem/mod.rs
@@ -374,13 +374,13 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
 /// will do a single needs_drop check for all the values.
 ///
 /// Types like Vec therefore just `drop_in_place(&mut self[..])` without using
-/// needs_drop explicitly. Types like HashMap, on the other hand, have to drop
+/// needs_drop explicitly. Types like `HashMap`, on the other hand, have to drop
 /// values one at a time and should use this API.
 ///
 ///
 /// # Examples
 ///
-/// Here's an example of how a collection might make use of needs_drop:
+/// Here's an example of how a collection might make use of `needs_drop`:
 ///
 /// ```
 /// use std::{mem, ptr};
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 3f8d142c845..0bcd371b528 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -7,6 +7,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[cfg(not(test))]
+use crate::intrinsics;
+
 use crate::mem;
 use crate::num::FpCategory;
 
@@ -372,15 +375,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn max(self, other: f32) -> f32 {
-        // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the
-        // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
-        // is either x or y, canonicalized (this means results might differ among implementations).
-        // When either x or y is a signalingNaN, then the result is according to 6.2.
-        //
-        // Since we do not support sNaN in Rust yet, we do not need to handle them.
-        // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
-        // multiplying by 1.0. Should switch to the `canonicalize` when it works.
-        (if self.is_nan() || self < other { other } else { self }) * 1.0
+        intrinsics::maxnumf32(self, other)
     }
 
     /// Returns the minimum of the two numbers.
@@ -396,15 +391,7 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn min(self, other: f32) -> f32 {
-        // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the
-        // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
-        // is either x or y, canonicalized (this means results might differ among implementations).
-        // When either x or y is a signalingNaN, then the result is according to 6.2.
-        //
-        // Since we do not support sNaN in Rust yet, we do not need to handle them.
-        // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
-        // multiplying by 1.0. Should switch to the `canonicalize` when it works.
-        (if other.is_nan() || self < other { self } else { other }) * 1.0
+        intrinsics::minnumf32(self, other)
     }
 
     /// Raw transmutation to `u32`.
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 7f19101fe6e..4d4a2c9c5a9 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -7,6 +7,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[cfg(not(test))]
+use crate::intrinsics;
+
 use crate::mem;
 use crate::num::FpCategory;
 
@@ -385,15 +388,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn max(self, other: f64) -> f64 {
-        // IEEE754 says: maxNum(x, y) is the canonicalized number y if x < y, x if y < x, the
-        // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
-        // is either x or y, canonicalized (this means results might differ among implementations).
-        // When either x or y is a signalingNaN, then the result is according to 6.2.
-        //
-        // Since we do not support sNaN in Rust yet, we do not need to handle them.
-        // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
-        // multiplying by 1.0. Should switch to the `canonicalize` when it works.
-        (if self.is_nan() || self < other { other } else { self }) * 1.0
+        intrinsics::maxnumf64(self, other)
     }
 
     /// Returns the minimum of the two numbers.
@@ -409,15 +404,7 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn min(self, other: f64) -> f64 {
-        // IEEE754 says: minNum(x, y) is the canonicalized number x if x < y, y if y < x, the
-        // canonicalized number if one operand is a number and the other a quiet NaN. Otherwise it
-        // is either x or y, canonicalized (this means results might differ among implementations).
-        // When either x or y is a signalingNaN, then the result is according to 6.2.
-        //
-        // Since we do not support sNaN in Rust yet, we do not need to handle them.
-        // FIXME(nagisa): due to https://bugs.llvm.org/show_bug.cgi?id=33303 we canonicalize by
-        // multiplying by 1.0. Should switch to the `canonicalize` when it works.
-        (if other.is_nan() || self < other { self } else { other }) * 1.0
+        intrinsics::minnumf64(self, other)
     }
 
     /// Raw transmutation to `u64`.
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 7145bf1fbc0..dd7090623f5 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -50,7 +50,7 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
                 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
                 #[repr(transparent)]
                 #[rustc_layout_scalar_valid_range_start(1)]
-                #[cfg_attr(not(stage0), rustc_nonnull_optimization_guaranteed)]
+                #[cfg_attr(not(bootstrap), rustc_nonnull_optimization_guaranteed)]
                 pub struct $Ty($Int);
             }
 
diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs
index a707f0cc062..1b4c4218cc1 100644
--- a/src/libcore/ops/range.rs
+++ b/src/libcore/ops/range.rs
@@ -696,6 +696,29 @@ pub enum Bound<T> {
     Unbounded,
 }
 
+impl<T: Clone> Bound<&T> {
+    /// Map a `Bound<&T>` to a `Bound<T>` by cloning the contents of the bound.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(bound_cloned)]
+    /// use std::ops::Bound::*;
+    /// use std::ops::RangeBounds;
+    ///
+    /// assert_eq!((1..12).start_bound(), Included(&1));
+    /// assert_eq!((1..12).start_bound().cloned(), Included(1));
+    /// ```
+    #[unstable(feature = "bound_cloned", issue = "61356")]
+    pub fn cloned(self) -> Bound<T> {
+        match self {
+            Bound::Unbounded => Bound::Unbounded,
+            Bound::Included(x) => Bound::Included(x.clone()),
+            Bound::Excluded(x) => Bound::Excluded(x.clone()),
+        }
+    }
+}
+
 #[stable(feature = "collections_range", since = "1.28.0")]
 /// `RangeBounds` is implemented by Rust's built-in range types, produced
 /// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`.
diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs
index 0a6985e334c..46dde7c1da5 100644
--- a/src/libcore/ptr/non_null.rs
+++ b/src/libcore/ptr/non_null.rs
@@ -38,7 +38,7 @@ use crate::cmp::Ordering;
 #[stable(feature = "nonnull", since = "1.25.0")]
 #[repr(transparent)]
 #[rustc_layout_scalar_valid_range_start(1)]
-#[cfg_attr(not(stage0), rustc_nonnull_optimization_guaranteed)]
+#[cfg_attr(not(bootstrap), rustc_nonnull_optimization_guaranteed)]
 pub struct NonNull<T: ?Sized> {
     pointer: *const T,
 }
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 5050842e409..928bdd7a760 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -1,3 +1,4 @@
+#![feature(bound_cloned)]
 #![feature(box_syntax)]
 #![feature(cell_update)]
 #![feature(core_private_bignum)]
diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs
index 78cf07119e7..48755ae4c16 100644
--- a/src/libcore/tests/ops.rs
+++ b/src/libcore/tests/ops.rs
@@ -1,4 +1,4 @@
-use core::ops::{Range, RangeFull, RangeFrom, RangeTo, RangeInclusive};
+use core::ops::{Bound, Range, RangeFull, RangeFrom, RangeTo, RangeInclusive};
 
 // Test the Range structs without the syntactic sugar.
 
@@ -82,3 +82,18 @@ fn test_range_is_empty() {
     assert!( (NAN ..= EPSILON).is_empty());
     assert!( (NAN ..= NAN).is_empty());
 }
+
+#[test]
+fn test_bound_cloned_unbounded() {
+    assert_eq!(Bound::<&u32>::Unbounded.cloned(), Bound::Unbounded);
+}
+
+#[test]
+fn test_bound_cloned_included() {
+    assert_eq!(Bound::Included(&3).cloned(), Bound::Included(3));
+}
+
+#[test]
+fn test_bound_cloned_excluded() {
+    assert_eq!(Bound::Excluded(&3).cloned(), Bound::Excluded(3));
+}
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index dd33fae0d61..2f19f591830 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -151,17 +151,17 @@ macro_rules! make_mir_visitor {
                 self.super_place(place, context, location);
             }
 
-            fn visit_projection(&mut self,
-                                place: & $($mutability)? Projection<'tcx>,
+            fn visit_place_base(&mut self,
+                                place_base: & $($mutability)? PlaceBase<'tcx>,
                                 context: PlaceContext,
                                 location: Location) {
-                self.super_projection(place, context, location);
+                self.super_place_base(place_base, context, location);
             }
 
-            fn visit_projection_elem(&mut self,
-                                     place: & $($mutability)? PlaceElem<'tcx>,
-                                     location: Location) {
-                self.super_projection_elem(place, location);
+            fn visit_projection(&mut self,
+                                place: & $($mutability)? Projection<'tcx>,
+                                location: Location) {
+                self.super_projection(place, location);
             }
 
             fn visit_constant(&mut self,
@@ -676,36 +676,40 @@ macro_rules! make_mir_visitor {
                             context: PlaceContext,
                             location: Location) {
                 match place {
-                    Place::Base(PlaceBase::Local(local)) => {
-                        self.visit_local(local, context, location);
-                    }
-                    Place::Base(PlaceBase::Static(box Static { kind: _, ty })) => {
-                        self.visit_ty(& $($mutability)? *ty, TyContext::Location(location));
+                    Place::Base(place_base) => {
+                        self.visit_place_base(place_base, context, location);
                     }
                     Place::Projection(proj) => {
-                        self.visit_projection(proj, context, location);
+                        let context = if context.is_mutating_use() {
+                            PlaceContext::MutatingUse(MutatingUseContext::Projection)
+                        } else {
+                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
+                        };
+
+                        self.visit_place(& $($mutability)? proj.base, context, location);
+                        self.visit_projection(proj, location);
                     }
                 }
             }
 
-            fn super_projection(&mut self,
-                                proj: & $($mutability)? Projection<'tcx>,
+            fn super_place_base(&mut self,
+                                place_base: & $($mutability)? PlaceBase<'tcx>,
                                 context: PlaceContext,
                                 location: Location) {
-                let Projection { base, elem } = proj;
-                let context = if context.is_mutating_use() {
-                    PlaceContext::MutatingUse(MutatingUseContext::Projection)
-                } else {
-                    PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
-                };
-                self.visit_place(base, context, location);
-                self.visit_projection_elem(elem, location);
+                match place_base {
+                    PlaceBase::Local(local) => {
+                        self.visit_local(local, context, location);
+                    }
+                    PlaceBase::Static(box Static { kind: _, ty }) => {
+                        self.visit_ty(& $($mutability)? *ty, TyContext::Location(location));
+                    }
+                }
             }
 
-            fn super_projection_elem(&mut self,
-                                     proj: & $($mutability)? PlaceElem<'tcx>,
-                                     location: Location) {
-                match proj {
+            fn super_projection(&mut self,
+                                proj: & $($mutability)? Projection<'tcx>,
+                                location: Location) {
+                match & $($mutability)? proj.elem {
                     ProjectionElem::Deref => {
                     }
                     ProjectionElem::Subslice { from: _, to: _ } => {
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 6a35906d20c..003fdd501a3 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -2003,7 +2003,7 @@ pub fn build_session_options_and_crate_config(
             None |
             Some("human") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
             Some("human-annotate-rs") => {
-                ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateRs(color))
+                ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(color))
             },
             Some("json") => ErrorOutputType::Json { pretty: false, json_rendered },
             Some("pretty-json") => ErrorOutputType::Json { pretty: true, json_rendered },
@@ -2041,7 +2041,7 @@ pub fn build_session_options_and_crate_config(
                 "--error-format=pretty-json is unstable",
             );
         }
-        if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateRs(_)) =
+        if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(_)) =
             error_format {
             early_error(
                 ErrorOutputType::Json { pretty: false, json_rendered },
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index b3a9d764b1d..d04b9ac083c 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -24,7 +24,7 @@ use rustc_data_structures::sync::{
 use errors::{DiagnosticBuilder, DiagnosticId, Applicability};
 use errors::emitter::{Emitter, EmitterWriter};
 use errors::emitter::HumanReadableErrorType;
-use errors::annotate_rs_emitter::{AnnotateRsEmitterWriter};
+use errors::annotate_snippet_emitter_writer::{AnnotateSnippetEmitterWriter};
 use syntax::ast::{self, NodeId};
 use syntax::edition::Edition;
 use syntax::feature_gate::{self, AttributeType};
@@ -1034,8 +1034,8 @@ fn default_emitter(
         (config::ErrorOutputType::HumanReadable(kind), dst) => {
             let (short, color_config) = kind.unzip();
 
-            if let HumanReadableErrorType::AnnotateRs(_) = kind {
-                let emitter = AnnotateRsEmitterWriter::new(
+            if let HumanReadableErrorType::AnnotateSnippet(_) = kind {
+                let emitter = AnnotateSnippetEmitterWriter::new(
                     Some(source_map.clone()),
                     short,
                 );
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index ead9bad656d..2bc46334555 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -645,6 +645,11 @@ impl CodegenCx<'b, 'tcx> {
         ifn!("llvm.fabs.v4f64", fn(t_v4f64) -> t_v4f64);
         ifn!("llvm.fabs.v8f64", fn(t_v8f64) -> t_v8f64);
 
+        ifn!("llvm.minnum.f32", fn(t_f32, t_f32) -> t_f32);
+        ifn!("llvm.minnum.f64", fn(t_f64, t_f64) -> t_f64);
+        ifn!("llvm.maxnum.f32", fn(t_f32, t_f32) -> t_f32);
+        ifn!("llvm.maxnum.f64", fn(t_f64, t_f64) -> t_f64);
+
         ifn!("llvm.floor.f32", fn(t_f32) -> t_f32);
         ifn!("llvm.floor.v2f32", fn(t_v2f32) -> t_v2f32);
         ifn!("llvm.floor.v4f32", fn(t_v4f32) -> t_v4f32);
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index f32dc431265..875f1d0940a 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -55,6 +55,10 @@ fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Valu
         "fmaf64" => "llvm.fma.f64",
         "fabsf32" => "llvm.fabs.f32",
         "fabsf64" => "llvm.fabs.f64",
+        "minnumf32" => "llvm.minnum.f32",
+        "minnumf64" => "llvm.minnum.f64",
+        "maxnumf32" => "llvm.maxnum.f32",
+        "maxnumf64" => "llvm.maxnum.f64",
         "copysignf32" => "llvm.copysign.f32",
         "copysignf64" => "llvm.copysign.f64",
         "floorf32" => "llvm.floor.f32",
diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs
index bb6a13ed15a..549608bf7ee 100644
--- a/src/librustc_codegen_ssa/mir/analyze.rs
+++ b/src/librustc_codegen_ssa/mir/analyze.rs
@@ -154,51 +154,62 @@ impl<'mir, 'a: 'mir, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
                    context: PlaceContext,
                    location: Location) {
         debug!("visit_place(place={:?}, context={:?})", place, context);
+        let mut context = context;
         let cx = self.fx.cx;
 
-        if let mir::Place::Projection(ref proj) = *place {
-            // Allow uses of projections that are ZSTs or from scalar fields.
-            let is_consume = match context {
-                PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
-                PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true,
-                _ => false
-            };
-            if is_consume {
-                let base_ty = proj.base.ty(self.fx.mir, cx.tcx());
-                let base_ty = self.fx.monomorphize(&base_ty);
-
-                // ZSTs don't require any actual memory access.
-                let elem_ty = base_ty
-                    .projection_ty(cx.tcx(), &proj.elem)
-                    .ty;
-                let elem_ty = self.fx.monomorphize(&elem_ty);
-                if cx.layout_of(elem_ty).is_zst() {
-                    return;
-                }
-
-                if let mir::ProjectionElem::Field(..) = proj.elem {
-                    let layout = cx.layout_of(base_ty.ty);
-                    if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
-                        // Recurse with the same context, instead of `Projection`,
-                        // potentially stopping at non-operand projections,
-                        // which would trigger `not_ssa` on locals.
-                        self.visit_place(&proj.base, context, location);
+        place.iterate(|place_base, place_projections| {
+            for proj in place_projections {
+                // Allow uses of projections that are ZSTs or from scalar fields.
+                let is_consume = match context {
+                    PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
+                    PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) => true,
+                    _ => false
+                };
+                if is_consume {
+                    let base_ty = proj.base.ty(self.fx.mir, cx.tcx());
+                    let base_ty = self.fx.monomorphize(&base_ty);
+
+                    // ZSTs don't require any actual memory access.
+                    let elem_ty = base_ty
+                        .projection_ty(cx.tcx(), &proj.elem)
+                        .ty;
+                    let elem_ty = self.fx.monomorphize(&elem_ty);
+                    if cx.layout_of(elem_ty).is_zst() {
                         return;
                     }
+
+                    if let mir::ProjectionElem::Field(..) = proj.elem {
+                        let layout = cx.layout_of(base_ty.ty);
+                        if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
+                            // Recurse with the same context, instead of `Projection`,
+                            // potentially stopping at non-operand projections,
+                            // which would trigger `not_ssa` on locals.
+                            continue;
+                        }
+                    }
                 }
-            }
 
-            // A deref projection only reads the pointer, never needs the place.
-            if let mir::ProjectionElem::Deref = proj.elem {
-                return self.visit_place(
-                    &proj.base,
-                    PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
-                    location
-                );
+                // A deref projection only reads the pointer, never needs the place.
+                if let mir::ProjectionElem::Deref = proj.elem {
+                    return self.visit_place(
+                        &proj.base,
+                        PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
+                        location
+                    );
+                }
+
+                context = if context.is_mutating_use() {
+                    PlaceContext::MutatingUse(MutatingUseContext::Projection)
+                } else {
+                    PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
+                };
             }
-        }
 
-        self.super_place(place, context, location);
+            // Default base visit behavior
+            if let mir::PlaceBase::Local(local) = place_base {
+                self.visit_local(local, context, location);
+            }
+        });
     }
 
     fn visit_local(&mut self,
diff --git a/src/librustc_errors/annotate_rs_emitter.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs
index de42389de74..9f9c7588d97 100644
--- a/src/librustc_errors/annotate_rs_emitter.rs
+++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs
@@ -1,9 +1,9 @@
-/// Emit diagnostics using the `annotate-snippets` library
-///
-/// This is the equivalent of `./emitter.rs` but making use of the
-/// [`annotate-snippets`][annotate_snippets] library instead of building the output ourselves.
-///
-/// [annotate_snippets]: https://docs.rs/crate/annotate-snippets/
+//! Emit diagnostics using the `annotate-snippets` library
+//!
+//! This is the equivalent of `./emitter.rs` but making use of the
+//! [`annotate-snippets`][annotate_snippets] library instead of building the output ourselves.
+//!
+//! [annotate_snippets]: https://docs.rs/crate/annotate-snippets/
 
 use syntax_pos::{SourceFile, MultiSpan, Loc};
 use crate::{
@@ -18,8 +18,8 @@ use annotate_snippets::display_list::DisplayList;
 use annotate_snippets::formatter::DisplayListFormatter;
 
 
-/// Generates diagnostics using annotate-rs
-pub struct AnnotateRsEmitterWriter {
+/// Generates diagnostics using annotate-snippet
+pub struct AnnotateSnippetEmitterWriter {
     source_map: Option<Lrc<SourceMapperDyn>>,
     /// If true, hides the longer explanation text
     short_message: bool,
@@ -27,7 +27,7 @@ pub struct AnnotateRsEmitterWriter {
     ui_testing: bool,
 }
 
-impl Emitter for AnnotateRsEmitterWriter {
+impl Emitter for AnnotateSnippetEmitterWriter {
     /// The entry point for the diagnostics generation
     fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
         let primary_span = db.span.clone();
@@ -158,7 +158,7 @@ impl<'a>  DiagnosticConverter<'a> {
     }
 }
 
-impl AnnotateRsEmitterWriter {
+impl AnnotateSnippetEmitterWriter {
     pub fn new(
         source_map: Option<Lrc<SourceMapperDyn>>,
         short_message: bool
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index fcc0358ea7c..3bf477efe35 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -24,7 +24,7 @@ use termcolor::{WriteColor, Color, Buffer};
 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum HumanReadableErrorType {
     Default(ColorConfig),
-    AnnotateRs(ColorConfig),
+    AnnotateSnippet(ColorConfig),
     Short(ColorConfig),
 }
 
@@ -34,7 +34,7 @@ impl HumanReadableErrorType {
         match self {
             HumanReadableErrorType::Default(cc) => (false, cc),
             HumanReadableErrorType::Short(cc) => (true, cc),
-            HumanReadableErrorType::AnnotateRs(cc) => (false, cc),
+            HumanReadableErrorType::AnnotateSnippet(cc) => (false, cc),
         }
     }
     pub fn new_emitter(
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 7bc7d0ddaf2..1831d58e736 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -33,7 +33,7 @@ use termcolor::{ColorSpec, Color};
 mod diagnostic;
 mod diagnostic_builder;
 pub mod emitter;
-pub mod annotate_rs_emitter;
+pub mod annotate_snippet_emitter_writer;
 mod snippet;
 pub mod registry;
 mod styled_buffer;
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index eed051449e1..91b4af9655a 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -185,7 +185,7 @@ use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind, Instance};
 use rustc::ty::print::obsolete::DefPathBasedNames;
 use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast};
 use rustc::session::config::EntryFnType;
-use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind};
+use rustc::mir::{self, Location, PlaceBase, Promoted, Static, StaticKind};
 use rustc::mir::visit::Visitor as MirVisitor;
 use rustc::mir::mono::{MonoItem, InstantiationMode};
 use rustc::mir::interpret::{Scalar, GlobalId, GlobalAlloc, ErrorHandled};
@@ -655,14 +655,12 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
         self.super_terminator_kind(kind, location);
     }
 
-    fn visit_place(&mut self,
-                    place: &mir::Place<'tcx>,
-                    context: mir::visit::PlaceContext,
-                    location: Location) {
-        match place {
-            Place::Base(
-                PlaceBase::Static(box Static{ kind:StaticKind::Static(def_id), .. })
-            ) => {
+    fn visit_place_base(&mut self,
+                        place_base: &mir::PlaceBase<'tcx>,
+                        _context: mir::visit::PlaceContext,
+                        location: Location) {
+        match place_base {
+            PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) => {
                 debug!("visiting static {:?} @ {:?}", def_id, location);
 
                 let tcx = self.tcx;
@@ -671,10 +669,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
                     self.output.push(MonoItem::Static(*def_id));
                 }
             }
-            _ => {}
+            PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => {
+                // FIXME: should we handle promoteds here instead of eagerly in collect_neighbours?
+            }
+            PlaceBase::Local(_) => {
+                // Locals have no relevance for collector
+            }
         }
-
-        self.super_place(place, context, location);
     }
 }
 
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 8ec8a8fa12e..4e8cc124e50 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -199,11 +199,39 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
     fn visit_place(&mut self,
                     place: &Place<'tcx>,
                     context: PlaceContext,
-                    location: Location) {
-        match place {
-            &Place::Projection(box Projection {
-                ref base, ref elem
-            }) => {
+                    _location: Location) {
+        place.iterate(|place_base, place_projections| {
+            match place_base {
+                PlaceBase::Local(..) => {
+                    // Locals are safe.
+                }
+                PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => {
+                    bug!("unsafety checking should happen before promotion")
+                }
+                PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) => {
+                    if self.tcx.is_mutable_static(*def_id) {
+                        self.require_unsafe("use of mutable static",
+                            "mutable statics can be mutated by multiple threads: aliasing \
+                             violations or data races will cause undefined behavior",
+                             UnsafetyViolationKind::General);
+                    } else if self.tcx.is_foreign_item(*def_id) {
+                        let source_info = self.source_info;
+                        let lint_root =
+                            self.source_scope_local_data[source_info.scope].lint_root;
+                        self.register_violations(&[UnsafetyViolation {
+                            source_info,
+                            description: InternedString::intern("use of extern static"),
+                            details: InternedString::intern(
+                                "extern statics are not controlled by the Rust type system: \
+                                invalid data, aliasing violations or data races will cause \
+                                undefined behavior"),
+                            kind: UnsafetyViolationKind::ExternStatic(lint_root)
+                        }], &[]);
+                    }
+                }
+            }
+
+            for proj in place_projections {
                 if context.is_borrow() {
                     if util::is_disaligned(self.tcx, self.mir, self.param_env, place) {
                         let source_info = self.source_info;
@@ -220,7 +248,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                         }], &[]);
                     }
                 }
-                let is_borrow_of_interior_mut = context.is_borrow() && !base
+                let is_borrow_of_interior_mut = context.is_borrow() && !proj.base
                     .ty(self.mir, self.tcx)
                     .ty
                     .is_freeze(self.tcx, self.param_env, self.source_info.span);
@@ -236,7 +264,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                     );
                 }
                 let old_source_info = self.source_info;
-                if let &Place::Base(PlaceBase::Local(local)) = base {
+                if let Place::Base(PlaceBase::Local(local)) = proj.base {
                     if self.mir.local_decls[local].internal {
                         // Internal locals are used in the `move_val_init` desugaring.
                         // We want to check unsafety against the source info of the
@@ -244,7 +272,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                         self.source_info = self.mir.local_decls[local].source_info;
                     }
                 }
-                let base_ty = base.ty(self.mir, self.tcx).ty;
+                let base_ty = proj.base.ty(self.mir, self.tcx).ty;
                 match base_ty.sty {
                     ty::RawPtr(..) => {
                         self.require_unsafe("dereference of raw pointer",
@@ -260,8 +288,8 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                                     MutatingUseContext::AsmOutput
                                 )
                             {
-                                let elem_ty = match elem {
-                                    &ProjectionElem::Field(_, ty) => ty,
+                                let elem_ty = match proj.elem {
+                                    ProjectionElem::Field(_, ty) => ty,
                                     _ => span_bug!(
                                         self.source_info.span,
                                         "non-field projection {:?} from union?",
@@ -292,36 +320,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                 }
                 self.source_info = old_source_info;
             }
-            &Place::Base(PlaceBase::Local(..)) => {
-                // locals are safe
-            }
-            &Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) => {
-                bug!("unsafety checking should happen before promotion")
-            }
-            &Place::Base(
-                PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. })
-            ) => {
-                if self.tcx.is_mutable_static(def_id) {
-                    self.require_unsafe("use of mutable static",
-                        "mutable statics can be mutated by multiple threads: aliasing violations \
-                         or data races will cause undefined behavior",
-                         UnsafetyViolationKind::General);
-                } else if self.tcx.is_foreign_item(def_id) {
-                    let source_info = self.source_info;
-                    let lint_root =
-                        self.source_scope_local_data[source_info.scope].lint_root;
-                    self.register_violations(&[UnsafetyViolation {
-                        source_info,
-                        description: InternedString::intern("use of extern static"),
-                        details: InternedString::intern(
-                            "extern statics are not controlled by the Rust type system: invalid \
-                            data, aliasing violations or data races will cause undefined behavior"),
-                        kind: UnsafetyViolationKind::ExternStatic(lint_root)
-                    }], &[]);
-                }
-            }
-        };
-        self.super_place(place, context, location);
+        });
     }
 }
 
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 0b14ff1db59..11598ad4c9c 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -70,7 +70,8 @@ pub fn intrisic_operation_unsafety(intrinsic: &str) -> hir::Unsafety {
         "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
         "saturating_add" | "saturating_sub" |
         "rotate_left" | "rotate_right" |
-        "ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse"
+        "ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse" |
+        "minnumf32" | "minnumf64" | "maxnumf32" | "maxnumf64"
         => hir::Unsafety::Normal,
         _ => hir::Unsafety::Unsafe,
     }
@@ -272,6 +273,10 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             }
             "fabsf32"      => (0, vec![ tcx.types.f32 ], tcx.types.f32),
             "fabsf64"      => (0, vec![ tcx.types.f64 ], tcx.types.f64),
+            "minnumf32"    => (0, vec![ tcx.types.f32, tcx.types.f32 ], tcx.types.f32),
+            "minnumf64"    => (0, vec![ tcx.types.f64, tcx.types.f64 ], tcx.types.f64),
+            "maxnumf32"    => (0, vec![ tcx.types.f32, tcx.types.f32 ], tcx.types.f32),
+            "maxnumf64"    => (0, vec![ tcx.types.f64, tcx.types.f64 ], tcx.types.f64),
             "copysignf32"  => (0, vec![ tcx.types.f32, tcx.types.f32 ], tcx.types.f32),
             "copysignf64"  => (0, vec![ tcx.types.f64, tcx.types.f64 ], tcx.types.f64),
             "floorf32"     => (0, vec![ tcx.types.f32 ], tcx.types.f32),
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 816a191a2a9..9abad83fdb0 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -19,7 +19,7 @@ panic_unwind = { path = "../libpanic_unwind", optional = true }
 panic_abort = { path = "../libpanic_abort" }
 core = { path = "../libcore" }
 libc = { version = "0.2.51", default-features = false, features = ['rustc-dep-of-std'] }
-compiler_builtins = { version = "0.1.15" }
+compiler_builtins = { version = "0.1.16" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 hashbrown = { version = "0.4.0", features = ['rustc-dep-of-std'] }
diff --git a/src/tools/clippy b/src/tools/clippy
-Subproject 20da8f45c601d0eec8af8c0897abd536ad57951
+Subproject 71be6f62fa920c0bd10cdf3a29aeb8c6719a807
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index 18d682640db..74720061122 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -26,6 +26,7 @@ features = [
   "basetsd",
   "consoleapi",
   "errhandlingapi",
+  "ioapiset",
   "jobapi",
   "jobapi2",
   "knownfolders",
@@ -33,12 +34,14 @@ features = [
   "memoryapi",
   "minschannel",
   "minwinbase",
+  "namedpipeapi",
+  "ntdef",
   "ntsecapi",
   "ntstatus",
   "objbase",
-  "profileapi",
   "processenv",
   "processthreadsapi",
+  "profileapi",
   "psapi",
   "schannel",
   "securitybaseapi",
@@ -53,6 +56,10 @@ features = [
   "winbase",
   "wincon",
   "wincrypt",
+  "winsock2",
+  "ws2def",
+  "ws2ipdef",
+  "ws2tcpip",
 ]
 
 [dependencies]