From 5e6619edd1a3b5c3f85438166d4d32af49f800fd Mon Sep 17 00:00:00 2001
From: Martin Finkel <martin@videolabs.io>
Date: Wed, 31 Jul 2019 10:56:56 +0700
Subject: [PATCH 01/16] Fix UWP build

---
 src/libstd/sys/windows/c.rs  | 2 +-
 src/libstd/sys/windows/fs.rs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index f706709c9ccf4..b1f9d9766f705 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -714,7 +714,7 @@ if #[cfg(target_vendor = "uwp")] {
     pub struct FILE_STANDARD_INFO {
         pub AllocationSize: LARGE_INTEGER,
         pub EndOfFile: LARGE_INTEGER,
-        pub NumberOfLink: DWORD,
+        pub NumberOfLinks: DWORD,
         pub DeletePending: BOOLEAN,
         pub Directory: BOOLEAN,
     }
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index 5bae6ba4749bd..204f6af5fc1a0 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -357,7 +357,7 @@ impl File {
                                                 size as c::DWORD))?;
             attr.file_size = info.AllocationSize as u64;
             attr.number_of_links = Some(info.NumberOfLinks);
-            if attr.is_reparse_point() {
+            if attr.file_type().is_reparse_point() {
                 let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
                 if let Ok((_, buf)) = self.reparse_point(&mut b) {
                     attr.reparse_tag = buf.ReparseTag;

From 54e268cf5532362ced32329a9327eaee22353829 Mon Sep 17 00:00:00 2001
From: Martin Finkel <martin@videolabs.io>
Date: Wed, 31 Jul 2019 10:58:17 +0700
Subject: [PATCH 02/16] Fix README MSVC URI

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 40df6a4737871..724bc36ecc6fb 100644
--- a/README.md
+++ b/README.md
@@ -144,7 +144,7 @@ then you may need to force rustbuild to use an older version. This can be done
 by manually calling the appropriate vcvars file before running the bootstrap.
 
 ```batch
-> CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
+> CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
 > python x.py build
 ```
 

From 6e4d02369ab30872bf4fa86ed2d2e6f897d0cbd8 Mon Sep 17 00:00:00 2001
From: Martin Finkel <martin@videolabs.io>
Date: Wed, 31 Jul 2019 15:00:34 +0700
Subject: [PATCH 03/16] Add UWP MSVC targets

---
 .../spec/aarch64_uwp_windows_msvc.rs          | 29 ++++++++++++++++
 .../spec/i686_uwp_windows_msvc.rs             | 27 +++++++++++++++
 src/librustc_target/spec/mod.rs               |  4 +++
 .../spec/windows_uwp_msvc_base.rs             | 33 +++++++++++++++++++
 .../spec/x86_64_uwp_windows_msvc.rs           | 27 +++++++++++++++
 5 files changed, 120 insertions(+)
 create mode 100644 src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
 create mode 100644 src/librustc_target/spec/i686_uwp_windows_msvc.rs
 create mode 100644 src/librustc_target/spec/windows_uwp_msvc_base.rs
 create mode 100644 src/librustc_target/spec/x86_64_uwp_windows_msvc.rs

diff --git a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
new file mode 100644
index 0000000000000..cb1e710ed1872
--- /dev/null
+++ b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
@@ -0,0 +1,29 @@
+use crate::spec::{LinkerFlavor, Target, TargetResult, PanicStrategy};
+use std::env;
+
+pub fn target() -> TargetResult {
+    let mut base = super::windows_uwp_msvc_base::opts();
+    base.max_atomic_width = Some(64);
+    base.has_elf_tls = true;
+
+    // FIXME: this shouldn't be panic=abort, it should be panic=unwind
+    base.panic_strategy = PanicStrategy::Abort;
+
+    let lib_root_path = env::var("VCToolsInstallDir").expect("VCToolsInstallDir not found in env");
+    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
+            .push(format!("{}{}{}", "/LIBPATH:".to_string(), lib_root_path, "lib\\arm64\\store".to_string()));
+
+    Ok(Target {
+        llvm_target: "aarch64-pc-windows-msvc".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".to_string(),
+        arch: "aarch64".to_string(),
+        target_os: "windows".to_string(),
+        target_env: "msvc".to_string(),
+        target_vendor: "uwp".to_string(),
+        linker_flavor: LinkerFlavor::Msvc,
+        options: base,
+    })
+}
diff --git a/src/librustc_target/spec/i686_uwp_windows_msvc.rs b/src/librustc_target/spec/i686_uwp_windows_msvc.rs
new file mode 100644
index 0000000000000..d09c9d5d2dbbf
--- /dev/null
+++ b/src/librustc_target/spec/i686_uwp_windows_msvc.rs
@@ -0,0 +1,27 @@
+use crate::spec::{LinkerFlavor, Target, TargetResult};
+use std::env;
+
+pub fn target() -> TargetResult {
+    let mut base = super::windows_uwp_msvc_base::opts();
+    base.cpu = "pentium4".to_string();
+    base.max_atomic_width = Some(64);
+    base.has_elf_tls = true;
+
+    let lib_root_path = env::var("VCToolsInstallDir").expect("VCToolsInstallDir not found in env");
+    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
+            .push(format!("{}{}{}", "/LIBPATH:".to_string(), lib_root_path, "lib\\x86\\store".to_string()));
+
+    Ok(Target {
+        llvm_target: "i686-pc-windows-msvc".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32".to_string(),
+        arch: "x86".to_string(),
+        target_os: "windows".to_string(),
+        target_env: "msvc".to_string(),
+        target_vendor: "uwp".to_string(),
+        linker_flavor: LinkerFlavor::Msvc,
+        options: base,
+    })
+}
\ No newline at end of file
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 54e3cad6a6149..dbb29c595038a 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -61,6 +61,7 @@ mod uefi_base;
 mod windows_base;
 mod windows_msvc_base;
 mod windows_uwp_base;
+mod windows_uwp_msvc_base;
 mod thumb_base;
 mod l4re_base;
 mod fuchsia_base;
@@ -439,8 +440,11 @@ supported_targets! {
     ("x86_64-uwp-windows-gnu", x86_64_uwp_windows_gnu),
 
     ("aarch64-pc-windows-msvc", aarch64_pc_windows_msvc),
+    ("aarch64-uwp-windows-msvc", aarch64_uwp_windows_msvc),
     ("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc),
+    ("x86_64-uwp-windows-msvc", x86_64_uwp_windows_msvc),
     ("i686-pc-windows-msvc", i686_pc_windows_msvc),
+    ("i686-uwp-windows-msvc", i686_uwp_windows_msvc),
     ("i586-pc-windows-msvc", i586_pc_windows_msvc),
     ("thumbv7a-pc-windows-msvc", thumbv7a_pc_windows_msvc),
 
diff --git a/src/librustc_target/spec/windows_uwp_msvc_base.rs b/src/librustc_target/spec/windows_uwp_msvc_base.rs
new file mode 100644
index 0000000000000..e643513a1a7fe
--- /dev/null
+++ b/src/librustc_target/spec/windows_uwp_msvc_base.rs
@@ -0,0 +1,33 @@
+use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
+use std::default::Default;
+
+pub fn opts() -> TargetOptions {
+    let mut args = LinkArgs::new();
+    args.insert(LinkerFlavor::Msvc,
+                vec!["/NOLOGO".to_string(),
+                     "/NXCOMPAT".to_string(),
+                     "/APPCONTAINER".to_string(),
+                     "mincore.lib".to_string()]);
+
+    TargetOptions {
+        function_sections: true,
+        dynamic_linking: true,
+        executables: true,
+        dll_prefix: String::new(),
+        dll_suffix: ".dll".to_string(),
+        exe_suffix: ".exe".to_string(),
+        staticlib_prefix: String::new(),
+        staticlib_suffix: ".lib".to_string(),
+        target_family: Some("windows".to_string()),
+        is_like_windows: true,
+        is_like_msvc: true,
+        pre_link_args: args,
+        crt_static_allows_dylibs: true,
+        crt_static_respected: true,
+        abi_return_struct_as_int: true,
+        emit_debug_gdb_scripts: false,
+        requires_uwtable: true,
+
+        .. Default::default()
+    }
+}
\ No newline at end of file
diff --git a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
new file mode 100644
index 0000000000000..7d89c73a0e234
--- /dev/null
+++ b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
@@ -0,0 +1,27 @@
+use crate::spec::{LinkerFlavor, Target, TargetResult};
+use std::env;
+
+pub fn target() -> TargetResult {
+    let mut base = super::windows_uwp_msvc_base::opts();
+    base.cpu = "x86-64".to_string();
+    base.max_atomic_width = Some(64);
+    base.has_elf_tls = true;
+
+    let lib_root_path = env::var("VCToolsInstallDir").expect("VCToolsInstallDir not found in env");
+    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
+            .push(format!("{}{}{}", "/LIBPATH:".to_string(), lib_root_path, "lib\\x64\\store".to_string()));
+
+    Ok(Target {
+        llvm_target: "x86_64-pc-windows-msvc".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:w-i64:64-f80:128-n8:16:32:64-S128".to_string(),
+        arch: "x86_64".to_string(),
+        target_os: "windows".to_string(),
+        target_env: "msvc".to_string(),
+        target_vendor: "uwp".to_string(),
+        linker_flavor: LinkerFlavor::Msvc,
+        options: base,
+    })
+}
\ No newline at end of file

From 3c6f6f031600dce97d2fd61a51afb17ff7f453ec Mon Sep 17 00:00:00 2001
From: Martin Finkel <martin@videolabs.io>
Date: Wed, 31 Jul 2019 17:15:26 +0700
Subject: [PATCH 04/16] Fix tidy checks

---
 src/librustc_target/spec/aarch64_uwp_windows_msvc.rs |  9 +++++++--
 src/librustc_target/spec/i686_uwp_windows_msvc.rs    | 11 ++++++++---
 src/librustc_target/spec/windows_uwp_msvc_base.rs    |  2 +-
 src/librustc_target/spec/x86_64_uwp_windows_msvc.rs  | 11 ++++++++---
 4 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
index cb1e710ed1872..9309f287dc714 100644
--- a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
+++ b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
@@ -9,9 +9,14 @@ pub fn target() -> TargetResult {
     // FIXME: this shouldn't be panic=abort, it should be panic=unwind
     base.panic_strategy = PanicStrategy::Abort;
 
-    let lib_root_path = env::var("VCToolsInstallDir").expect("VCToolsInstallDir not found in env");
+    let lib_root_path = env::var("VCToolsInstallDir")
+        .expect("VCToolsInstallDir not found in env");
+
     base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
-            .push(format!("{}{}{}", "/LIBPATH:".to_string(), lib_root_path, "lib\\arm64\\store".to_string()));
+        .push(format!("{}{}{}",
+            "/LIBPATH:".to_string(),
+            lib_root_path,
+            "lib\\arm64\\store".to_string()));
 
     Ok(Target {
         llvm_target: "aarch64-pc-windows-msvc".to_string(),
diff --git a/src/librustc_target/spec/i686_uwp_windows_msvc.rs b/src/librustc_target/spec/i686_uwp_windows_msvc.rs
index d09c9d5d2dbbf..d05aee547591f 100644
--- a/src/librustc_target/spec/i686_uwp_windows_msvc.rs
+++ b/src/librustc_target/spec/i686_uwp_windows_msvc.rs
@@ -7,9 +7,14 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(64);
     base.has_elf_tls = true;
 
-    let lib_root_path = env::var("VCToolsInstallDir").expect("VCToolsInstallDir not found in env");
+    let lib_root_path = env::var("VCToolsInstallDir")
+        .expect("VCToolsInstallDir not found in env");
+
     base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
-            .push(format!("{}{}{}", "/LIBPATH:".to_string(), lib_root_path, "lib\\x86\\store".to_string()));
+            .push(format!("{}{}{}",
+            "/LIBPATH:".to_string(),
+            lib_root_path,
+            "lib\\x86\\store".to_string()));
 
     Ok(Target {
         llvm_target: "i686-pc-windows-msvc".to_string(),
@@ -24,4 +29,4 @@ pub fn target() -> TargetResult {
         linker_flavor: LinkerFlavor::Msvc,
         options: base,
     })
-}
\ No newline at end of file
+}
diff --git a/src/librustc_target/spec/windows_uwp_msvc_base.rs b/src/librustc_target/spec/windows_uwp_msvc_base.rs
index e643513a1a7fe..1121916e68f51 100644
--- a/src/librustc_target/spec/windows_uwp_msvc_base.rs
+++ b/src/librustc_target/spec/windows_uwp_msvc_base.rs
@@ -30,4 +30,4 @@ pub fn opts() -> TargetOptions {
 
         .. Default::default()
     }
-}
\ No newline at end of file
+}
diff --git a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
index 7d89c73a0e234..174d13327eb16 100644
--- a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
+++ b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
@@ -7,9 +7,14 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(64);
     base.has_elf_tls = true;
 
-    let lib_root_path = env::var("VCToolsInstallDir").expect("VCToolsInstallDir not found in env");
+    let lib_root_path = env::var("VCToolsInstallDir")
+        .expect("VCToolsInstallDir not found in env");
+
     base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
-            .push(format!("{}{}{}", "/LIBPATH:".to_string(), lib_root_path, "lib\\x64\\store".to_string()));
+            .push(format!("{}{}{}",
+            "/LIBPATH:".to_string(),
+            lib_root_path,
+            "lib\\x64\\store".to_string()));
 
     Ok(Target {
         llvm_target: "x86_64-pc-windows-msvc".to_string(),
@@ -24,4 +29,4 @@ pub fn target() -> TargetResult {
         linker_flavor: LinkerFlavor::Msvc,
         options: base,
     })
-}
\ No newline at end of file
+}

From e3d8b6817ef0369915fb0dc5f2f519e942f8d67f Mon Sep 17 00:00:00 2001
From: Martin Finkel <finkel2804@gmail.com>
Date: Mon, 5 Aug 2019 16:24:20 +0200
Subject: [PATCH 05/16] review feedback: find lib root path from registry

---
 Cargo.lock                                           | 1 +
 src/librustc_target/Cargo.toml                       | 1 +
 src/librustc_target/spec/aarch64_uwp_windows_msvc.rs | 9 ++++++---
 src/librustc_target/spec/i686_uwp_windows_msvc.rs    | 9 ++++++---
 src/librustc_target/spec/x86_64_uwp_windows_msvc.rs  | 9 ++++++---
 5 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index c08d7444d14ea..f2356a2615248 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3126,6 +3126,7 @@ name = "rustc_target"
 version = "0.0.0"
 dependencies = [
  "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_data_structures 0.0.0",
  "serialize 0.0.0",
diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml
index cab1e0e01371d..940acf232ad13 100644
--- a/src/librustc_target/Cargo.toml
+++ b/src/librustc_target/Cargo.toml
@@ -11,6 +11,7 @@ path = "lib.rs"
 [dependencies]
 bitflags = "1.0"
 log = "0.4"
+cc = "1.0.1"
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
index 9309f287dc714..ab1b6705a1da1 100644
--- a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
+++ b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
@@ -1,5 +1,5 @@
 use crate::spec::{LinkerFlavor, Target, TargetResult, PanicStrategy};
-use std::env;
+use cc::windows_registry;
 
 pub fn target() -> TargetResult {
     let mut base = super::windows_uwp_msvc_base::opts();
@@ -9,8 +9,11 @@ pub fn target() -> TargetResult {
     // FIXME: this shouldn't be panic=abort, it should be panic=unwind
     base.panic_strategy = PanicStrategy::Abort;
 
-    let lib_root_path = env::var("VCToolsInstallDir")
-        .expect("VCToolsInstallDir not found in env");
+    let link_tool = windows_registry::find_tool("x86_64-pc-windows-msvc", "link.exe")
+        .expect("no path found for link.exe");
+
+    let original_path = link_tool.path();
+    let lib_root_path = original_path.ancestors().skip(4).next().unwrap().display();
 
     base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
         .push(format!("{}{}{}",
diff --git a/src/librustc_target/spec/i686_uwp_windows_msvc.rs b/src/librustc_target/spec/i686_uwp_windows_msvc.rs
index d05aee547591f..bc5631439d19e 100644
--- a/src/librustc_target/spec/i686_uwp_windows_msvc.rs
+++ b/src/librustc_target/spec/i686_uwp_windows_msvc.rs
@@ -1,5 +1,5 @@
 use crate::spec::{LinkerFlavor, Target, TargetResult};
-use std::env;
+use cc::windows_registry;
 
 pub fn target() -> TargetResult {
     let mut base = super::windows_uwp_msvc_base::opts();
@@ -7,8 +7,11 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(64);
     base.has_elf_tls = true;
 
-    let lib_root_path = env::var("VCToolsInstallDir")
-        .expect("VCToolsInstallDir not found in env");
+    let link_tool = windows_registry::find_tool("x86_64-pc-windows-msvc", "link.exe")
+        .expect("no path found for link.exe");
+
+    let original_path = link_tool.path();
+    let lib_root_path = original_path.ancestors().skip(4).next().unwrap().display();
 
     base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
             .push(format!("{}{}{}",
diff --git a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
index 174d13327eb16..8c15c7c22fcff 100644
--- a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
+++ b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
@@ -1,5 +1,5 @@
 use crate::spec::{LinkerFlavor, Target, TargetResult};
-use std::env;
+use cc::windows_registry;
 
 pub fn target() -> TargetResult {
     let mut base = super::windows_uwp_msvc_base::opts();
@@ -7,8 +7,11 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(64);
     base.has_elf_tls = true;
 
-    let lib_root_path = env::var("VCToolsInstallDir")
-        .expect("VCToolsInstallDir not found in env");
+    let link_tool = windows_registry::find_tool("x86_64-pc-windows-msvc", "link.exe")
+        .expect("no path found for link.exe");
+
+    let original_path = link_tool.path();
+    let lib_root_path = original_path.ancestors().skip(4).next().unwrap().display();
 
     base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
             .push(format!("{}{}{}",

From 89044a908ed602ae3dee74905866cffd63c164b3 Mon Sep 17 00:00:00 2001
From: Martin Finkel <finkel2804@gmail.com>
Date: Wed, 7 Aug 2019 17:49:15 +0200
Subject: [PATCH 06/16] move store lib probing code to librustc_codegen_ssa

---
 Cargo.lock                                         |  1 -
 src/librustc_codegen_ssa/back/link.rs              | 14 ++++++++++++++
 src/librustc_target/Cargo.toml                     |  1 -
 .../spec/aarch64_uwp_windows_msvc.rs               | 13 -------------
 src/librustc_target/spec/i686_uwp_windows_msvc.rs  | 13 -------------
 .../spec/x86_64_uwp_windows_msvc.rs                | 13 -------------
 6 files changed, 14 insertions(+), 41 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index f2356a2615248..c08d7444d14ea 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3126,7 +3126,6 @@ name = "rustc_target"
 version = "0.0.0"
 dependencies = [
  "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_data_structures 0.0.0",
  "serialize 0.0.0",
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 3f6a1a72ea61e..ea8e55145fa62 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -1027,6 +1027,20 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
     let t = &sess.target.target;
 
     cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
+
+    if t.linker_flavor == LinkerFlavor::Msvc && t.target_vendor == "uwp" {
+        let link_tool = windows_registry::find_tool("x86_64-pc-windows-msvc", "link.exe")
+            .expect("no path found for link.exe");
+
+        let original_path = link_tool.path();
+        let root_lib_path = original_path.ancestors().skip(4).next().unwrap();
+        if t.arch == "aarch64".to_string() {
+            cmd.include_path(&root_lib_path.join(format!("lib\\arm64\\store")));
+        } else {
+            cmd.include_path(&root_lib_path.join(format!("lib\\{}\\store", t.arch)));
+        }
+    }
+    
     for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
         cmd.add_object(obj);
     }
diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml
index 940acf232ad13..cab1e0e01371d 100644
--- a/src/librustc_target/Cargo.toml
+++ b/src/librustc_target/Cargo.toml
@@ -11,7 +11,6 @@ path = "lib.rs"
 [dependencies]
 bitflags = "1.0"
 log = "0.4"
-cc = "1.0.1"
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
index ab1b6705a1da1..5d8b829f2ab71 100644
--- a/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
+++ b/src/librustc_target/spec/aarch64_uwp_windows_msvc.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkerFlavor, Target, TargetResult, PanicStrategy};
-use cc::windows_registry;
 
 pub fn target() -> TargetResult {
     let mut base = super::windows_uwp_msvc_base::opts();
@@ -9,18 +8,6 @@ pub fn target() -> TargetResult {
     // FIXME: this shouldn't be panic=abort, it should be panic=unwind
     base.panic_strategy = PanicStrategy::Abort;
 
-    let link_tool = windows_registry::find_tool("x86_64-pc-windows-msvc", "link.exe")
-        .expect("no path found for link.exe");
-
-    let original_path = link_tool.path();
-    let lib_root_path = original_path.ancestors().skip(4).next().unwrap().display();
-
-    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
-        .push(format!("{}{}{}",
-            "/LIBPATH:".to_string(),
-            lib_root_path,
-            "lib\\arm64\\store".to_string()));
-
     Ok(Target {
         llvm_target: "aarch64-pc-windows-msvc".to_string(),
         target_endian: "little".to_string(),
diff --git a/src/librustc_target/spec/i686_uwp_windows_msvc.rs b/src/librustc_target/spec/i686_uwp_windows_msvc.rs
index bc5631439d19e..5e8e8c2a4149c 100644
--- a/src/librustc_target/spec/i686_uwp_windows_msvc.rs
+++ b/src/librustc_target/spec/i686_uwp_windows_msvc.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkerFlavor, Target, TargetResult};
-use cc::windows_registry;
 
 pub fn target() -> TargetResult {
     let mut base = super::windows_uwp_msvc_base::opts();
@@ -7,18 +6,6 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(64);
     base.has_elf_tls = true;
 
-    let link_tool = windows_registry::find_tool("x86_64-pc-windows-msvc", "link.exe")
-        .expect("no path found for link.exe");
-
-    let original_path = link_tool.path();
-    let lib_root_path = original_path.ancestors().skip(4).next().unwrap().display();
-
-    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
-            .push(format!("{}{}{}",
-            "/LIBPATH:".to_string(),
-            lib_root_path,
-            "lib\\x86\\store".to_string()));
-
     Ok(Target {
         llvm_target: "i686-pc-windows-msvc".to_string(),
         target_endian: "little".to_string(),
diff --git a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
index 8c15c7c22fcff..40dd52c159151 100644
--- a/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
+++ b/src/librustc_target/spec/x86_64_uwp_windows_msvc.rs
@@ -1,5 +1,4 @@
 use crate::spec::{LinkerFlavor, Target, TargetResult};
-use cc::windows_registry;
 
 pub fn target() -> TargetResult {
     let mut base = super::windows_uwp_msvc_base::opts();
@@ -7,18 +6,6 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(64);
     base.has_elf_tls = true;
 
-    let link_tool = windows_registry::find_tool("x86_64-pc-windows-msvc", "link.exe")
-        .expect("no path found for link.exe");
-
-    let original_path = link_tool.path();
-    let lib_root_path = original_path.ancestors().skip(4).next().unwrap().display();
-
-    base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap()
-            .push(format!("{}{}{}",
-            "/LIBPATH:".to_string(),
-            lib_root_path,
-            "lib\\x64\\store".to_string()));
-
     Ok(Target {
         llvm_target: "x86_64-pc-windows-msvc".to_string(),
         target_endian: "little".to_string(),

From 30fcd50ba913e579bf01393d25ba85c9c2c5a781 Mon Sep 17 00:00:00 2001
From: Wang Xuerui <git@xen0n.name>
Date: Sun, 28 Jul 2019 11:46:47 +0800
Subject: [PATCH 07/16] rustc_target: add n64 musl targets for MIPS64 arches

Hard-float (unlike mips32 musl targets but consistent with any other
musl target), MIPS64r2, n64 ABI.

The triples are renamed to carry the `abi64` ABI suffix found on all
other MIPS64 targets, for consistency and forward compatibility, should
Rust gain support for the n32 ABI one day.
---
 .../spec/mips64_unknown_linux_muslabi64.rs    | 25 +++++++++++++++++++
 .../spec/mips64el_unknown_linux_muslabi64.rs  | 25 +++++++++++++++++++
 src/librustc_target/spec/mod.rs               |  2 ++
 3 files changed, 52 insertions(+)
 create mode 100644 src/librustc_target/spec/mips64_unknown_linux_muslabi64.rs
 create mode 100644 src/librustc_target/spec/mips64el_unknown_linux_muslabi64.rs

diff --git a/src/librustc_target/spec/mips64_unknown_linux_muslabi64.rs b/src/librustc_target/spec/mips64_unknown_linux_muslabi64.rs
new file mode 100644
index 0000000000000..75f3efa49c4f0
--- /dev/null
+++ b/src/librustc_target/spec/mips64_unknown_linux_muslabi64.rs
@@ -0,0 +1,25 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::linux_musl_base::opts();
+    base.cpu = "mips64r2".to_string();
+    base.features = "+mips64r2".to_string();
+    base.max_atomic_width = Some(64);
+    Ok(Target {
+        // LLVM doesn't recognize "muslabi64" yet.
+        llvm_target: "mips64-unknown-linux-musl".to_string(),
+        target_endian: "big".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
+        arch: "mips64".to_string(),
+        target_os: "linux".to_string(),
+        target_env: "musl".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: TargetOptions {
+            target_mcount: "_mcount".to_string(),
+            .. base
+        },
+    })
+}
diff --git a/src/librustc_target/spec/mips64el_unknown_linux_muslabi64.rs b/src/librustc_target/spec/mips64el_unknown_linux_muslabi64.rs
new file mode 100644
index 0000000000000..a6aad3ddd3d79
--- /dev/null
+++ b/src/librustc_target/spec/mips64el_unknown_linux_muslabi64.rs
@@ -0,0 +1,25 @@
+use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::linux_musl_base::opts();
+    base.cpu = "mips64r2".to_string();
+    base.features = "+mips64r2".to_string();
+    base.max_atomic_width = Some(64);
+    Ok(Target {
+        // LLVM doesn't recognize "muslabi64" yet.
+        llvm_target: "mips64el-unknown-linux-musl".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
+        arch: "mips64".to_string(),
+        target_os: "linux".to_string(),
+        target_env: "musl".to_string(),
+        target_vendor: "unknown".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+        options: TargetOptions {
+            target_mcount: "_mcount".to_string(),
+            .. base
+        },
+    })
+}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index ec72c00c28f61..ebf931cb6942b 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -371,6 +371,8 @@ supported_targets! {
     ("i586-unknown-linux-musl", i586_unknown_linux_musl),
     ("mips-unknown-linux-musl", mips_unknown_linux_musl),
     ("mipsel-unknown-linux-musl", mipsel_unknown_linux_musl),
+    ("mips64-unknown-linux-muslabi64", mips64_unknown_linux_muslabi64),
+    ("mips64el-unknown-linux-muslabi64", mips64el_unknown_linux_muslabi64),
     ("hexagon-unknown-linux-musl", hexagon_unknown_linux_musl),
 
     ("mips-unknown-linux-uclibc", mips_unknown_linux_uclibc),

From 5124f34e504940ad883c9cf00063ff0e915908d6 Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Mon, 12 Aug 2019 13:59:50 +0200
Subject: [PATCH 08/16] Update RLS

This fixes handling default configuration for the `crate_blacklist`
RLS configuration.

Technically this isn't needed, as the VS Code extension can be
configured to accept a predefined blacklist that's equal to the default
one but it's best that it also lands so that we don't need to work
around that.

cc https://github.com/rust-lang/rust/pull/63472
---
 src/tools/rls | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/rls b/src/tools/rls
index 7b0a20bf13b70..496c892752213 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit 7b0a20bf13b7061b1eb31a058117ac5517ff8cc9
+Subproject commit 496c89275221303a4b0c2779cb8203fb3ce2a136

From 532008cad90cb185c472924591d04d90f8b3f78b Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 4 Aug 2019 19:59:59 +0200
Subject: [PATCH 09/16] don't add Retag statements for compound types

---
 src/librustc_mir/transform/add_retag.rs | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index d573423906c2a..524a19e3434f3 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -42,9 +42,8 @@ fn is_stable(
     }
 }
 
-/// Determine whether this type may have a reference in it, recursing below compound types but
-/// not below references.
-fn may_have_reference<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
+/// Determine whether this type may be a reference (or box), and thus needs retagging.
+fn may_be_reference<'tcx>(ty: Ty<'tcx>) -> bool {
     match ty.sty {
         // Primitive types that are not references
         ty::Bool | ty::Char |
@@ -55,15 +54,12 @@ fn may_have_reference<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> bool {
         // References
         ty::Ref(..) => true,
         ty::Adt(..) if ty.is_box() => true,
-        // Compound types
-        ty::Array(ty, ..) | ty::Slice(ty) =>
-            may_have_reference(ty, tcx),
-        ty::Tuple(tys) =>
-            tys.iter().any(|ty| may_have_reference(ty.expect_ty(), tcx)),
-        ty::Adt(adt, substs) =>
-            adt.variants.iter().any(|v| v.fields.iter().any(|f|
-                may_have_reference(f.ty(tcx, substs), tcx)
-            )),
+        // Compound types are not references
+        ty::Array(..) |
+        ty::Slice(..) |
+        ty::Tuple(..) |
+        ty::Adt(..) =>
+            false,
         // Conservative fallback
         _ => true,
     }
@@ -80,7 +76,7 @@ impl MirPass for AddRetag {
             // FIXME: Instead of giving up for unstable places, we should introduce
             // a temporary and retag on that.
             is_stable(place.as_ref())
-                && may_have_reference(place.ty(&*local_decls, tcx).ty, tcx)
+                && may_be_reference(place.ty(&*local_decls, tcx).ty)
         };
 
         // PART 1

From b122be4e489a31f82ae0d06b32fd1142bae8d807 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 5 Aug 2019 22:27:00 +0200
Subject: [PATCH 10/16] test Retag in drop shim

---
 src/test/mir-opt/retag.rs | 37 ++++++++++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/src/test/mir-opt/retag.rs b/src/test/mir-opt/retag.rs
index 33ee0fe61b288..34559a8181da7 100644
--- a/src/test/mir-opt/retag.rs
+++ b/src/test/mir-opt/retag.rs
@@ -11,6 +11,10 @@ impl Test {
     fn foo_shr<'x>(&self, x: &'x i32) -> &'x i32 { x }
 }
 
+impl Drop for Test {
+    fn drop(&mut self) {}
+}
+
 fn main() {
     let mut x = 0;
     {
@@ -60,10 +64,12 @@ fn main() {
 //     ...
 //     bb0: {
 //         ...
-//         _3 = const Test::foo(move _4, move _6) -> bb1;
+//         _3 = const Test::foo(move _4, move _6) -> [return: bb2, unwind: bb3];
 //     }
 //
-//     bb1: {
+//     ...
+//
+//     bb2: {
 //         Retag(_3);
 //         ...
 //         _9 = move _3;
@@ -80,25 +86,20 @@ fn main() {
 //         _12 = move _13 as *mut i32 (Misc);
 //         Retag([raw] _12);
 //         ...
-//         _16 = move _17(move _18) -> bb2;
+//         _16 = move _17(move _18) -> bb5;
 //     }
 //
-//     bb2: {
+//     bb5: {
 //         Retag(_16);
 //         ...
-//         _20 = const Test::foo_shr(move _21, move _23) -> bb3;
-//     }
-//
-//     bb3: {
-//         ...
-//         return;
+//         _20 = const Test::foo_shr(move _21, move _23) -> [return: bb6, unwind: bb7];
 //     }
 //
 //     ...
 // }
 // END rustc.main.EraseRegions.after.mir
 // START rustc.main-{{closure}}.EraseRegions.after.mir
-// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(20), local_id: 72 }], _2: &i32) -> &i32 {
+// fn main::{{closure}}#0(_1: &[closure@HirId { owner: DefIndex(22), local_id: 72 }], _2: &i32) -> &i32 {
 //     ...
 //     bb0: {
 //         Retag([fn entry] _1);
@@ -113,3 +114,17 @@ fn main() {
 //     }
 // }
 // END rustc.main-{{closure}}.EraseRegions.after.mir
+// START rustc.ptr-real_drop_in_place.Test.SimplifyCfg-make_shim.after.mir
+// fn  std::ptr::real_drop_in_place(_1: &mut Test) -> () {
+//     ...
+//     bb0: {
+//         Retag([raw] _1);
+//         _2 = &mut (*_1);
+//         _3 = const <Test as std::ops::Drop>::drop(move _2) -> bb1;
+//     }
+//
+//     bb1: {
+//         return;
+//     }
+// }
+// END rustc.ptr-real_drop_in_place.Test.SimplifyCfg-make_shim.after.mir

From c9da160aadf115314809c653449f355d268e8e2a Mon Sep 17 00:00:00 2001
From: Martin Finkel <finkel2804@gmail.com>
Date: Fri, 9 Aug 2019 15:51:16 +0200
Subject: [PATCH 11/16] review feedback: move uwp link code to get_linker

---
 src/librustc_codegen_ssa/back/link.rs | 41 ++++++++++++++++++---------
 1 file changed, 28 insertions(+), 13 deletions(-)

diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index ea8e55145fa62..076283d521ffb 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -32,6 +32,7 @@ use std::path::{Path, PathBuf};
 use std::process::{Output, Stdio, ExitStatus};
 use std::str;
 use std::env;
+use std::ffi::OsString;
 
 pub use rustc_codegen_utils::link::*;
 
@@ -158,6 +159,33 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB
         }
     };
 
+    let t = &sess.target.target;
+    if t.linker_flavor == LinkerFlavor::Msvc && t.target_vendor == "uwp" {
+        if let Some(ref tool) = msvc_tool {
+            let original_path = tool.path();
+            if let Some(ref root_lib_path) = original_path.ancestors().skip(4).next() {
+                let arch = match t.arch.as_str() {
+                    "x86_64" => Some("x64".to_string()),
+                    "x86" => Some("x86".to_string()),
+                    "aarch64" => Some("arm64".to_string()),
+                    _ => None,
+                };
+                if let Some(ref a) = arch {
+                    let mut arg = OsString::from("/LIBPATH:");
+                    arg.push(format!("{}\\lib\\{}\\store", root_lib_path.display(), a.to_string()));
+                    cmd.arg(&arg);
+                }
+                else {
+                    warn!("arch is not supported");
+                }
+            } else {
+                warn!("MSVC root path lib location not found");
+            }
+        } else {
+            warn!("link.exe not found");
+        }
+    }
+
     // The compiler's sysroot often has some bundled tools, so add it to the
     // PATH for the child.
     let mut new_path = sess.host_filesearch(PathKind::All)
@@ -1028,19 +1056,6 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
 
     cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
 
-    if t.linker_flavor == LinkerFlavor::Msvc && t.target_vendor == "uwp" {
-        let link_tool = windows_registry::find_tool("x86_64-pc-windows-msvc", "link.exe")
-            .expect("no path found for link.exe");
-
-        let original_path = link_tool.path();
-        let root_lib_path = original_path.ancestors().skip(4).next().unwrap();
-        if t.arch == "aarch64".to_string() {
-            cmd.include_path(&root_lib_path.join(format!("lib\\arm64\\store")));
-        } else {
-            cmd.include_path(&root_lib_path.join(format!("lib\\{}\\store", t.arch)));
-        }
-    }
-    
     for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {
         cmd.add_object(obj);
     }

From 1581c43be0dd7ac529e85f0a88f7447a315cb787 Mon Sep 17 00:00:00 2001
From: Martin Finkel <finkel2804@gmail.com>
Date: Tue, 13 Aug 2019 11:11:35 +0200
Subject: [PATCH 12/16] review feedback: add comments and use local flavor
 variable

---
 src/librustc_codegen_ssa/back/link.rs | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 076283d521ffb..3a0d5261d0c86 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -159,8 +159,11 @@ pub fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> (PathB
         }
     };
 
+    // UWP apps have API restrictions enforced during Store submissions.
+    // To comply with the Windows App Certification Kit,
+    // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc).
     let t = &sess.target.target;
-    if t.linker_flavor == LinkerFlavor::Msvc && t.target_vendor == "uwp" {
+    if flavor == LinkerFlavor::Msvc && t.target_vendor == "uwp" {
         if let Some(ref tool) = msvc_tool {
             let original_path = tool.path();
             if let Some(ref root_lib_path) = original_path.ancestors().skip(4).next() {

From 417f9ea90cf9bcccd8a1fa569a11a4fc071e3b8c Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sun, 11 Aug 2019 13:00:32 -0400
Subject: [PATCH 13/16] Utilize -Zbinary-dep-depinfo for dependency tracking

---
 src/bootstrap/builder.rs | 87 ++++++++++------------------------------
 src/bootstrap/check.rs   |  1 -
 src/bootstrap/compile.rs | 35 +---------------
 3 files changed, 23 insertions(+), 100 deletions(-)

diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index e54c9360baece..a38fb2bdc8ebe 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -754,76 +754,20 @@ impl<'a> Builder<'a> {
         let mut cargo = Command::new(&self.initial_cargo);
         let out_dir = self.stage_out(compiler, mode);
 
-        // command specific path, we call clear_if_dirty with this
-        let mut my_out = match cmd {
-            "build" => self.cargo_out(compiler, mode, target),
-
-            // This is the intended out directory for crate documentation.
-            "doc" | "rustdoc" =>  self.crate_doc_out(target),
-
-            _ => self.stage_out(compiler, mode),
-        };
-
-        // This is for the original compiler, but if we're forced to use stage 1, then
-        // std/test/rustc stamps won't exist in stage 2, so we need to get those from stage 1, since
-        // we copy the libs forward.
-        let cmp = self.compiler_for(compiler.stage, compiler.host, target);
-
-        let libstd_stamp = match cmd {
-            "check" | "clippy" | "fix" => check::libstd_stamp(self, cmp, target),
-            _ => compile::libstd_stamp(self, cmp, target),
-        };
-
-        let libtest_stamp = match cmd {
-            "check" | "clippy" | "fix" => check::libtest_stamp(self, cmp, target),
-            _ => compile::libtest_stamp(self, cmp, target),
-        };
-
-        let librustc_stamp = match cmd {
-            "check" | "clippy" | "fix" => check::librustc_stamp(self, cmp, target),
-            _ => compile::librustc_stamp(self, cmp, target),
-        };
+        // Codegen backends are not yet tracked by -Zbinary-dep-depinfo,
+        // so we need to explicitly clear out if they've been updated.
+        for backend in self.codegen_backends(compiler) {
+            self.clear_if_dirty(&out_dir, &backend);
+        }
 
         if cmd == "doc" || cmd == "rustdoc" {
-            if mode == Mode::Rustc || mode == Mode::ToolRustc || mode == Mode::Codegen {
+            let my_out = match mode {
                 // This is the intended out directory for compiler documentation.
-                my_out = self.compiler_doc_out(target);
-            }
+                Mode::Rustc | Mode::ToolRustc | Mode::Codegen => self.compiler_doc_out(target),
+                _ => self.crate_doc_out(target),
+            };
             let rustdoc = self.rustdoc(compiler);
             self.clear_if_dirty(&my_out, &rustdoc);
-        } else if cmd != "test" {
-            match mode {
-                Mode::Std => {
-                    self.clear_if_dirty(&my_out, &self.rustc(compiler));
-                    for backend in self.codegen_backends(compiler) {
-                        self.clear_if_dirty(&my_out, &backend);
-                    }
-                },
-                Mode::Test => {
-                    self.clear_if_dirty(&my_out, &libstd_stamp);
-                },
-                Mode::Rustc => {
-                    self.clear_if_dirty(&my_out, &self.rustc(compiler));
-                    self.clear_if_dirty(&my_out, &libstd_stamp);
-                    self.clear_if_dirty(&my_out, &libtest_stamp);
-                },
-                Mode::Codegen => {
-                    self.clear_if_dirty(&my_out, &librustc_stamp);
-                },
-                Mode::ToolBootstrap => { },
-                Mode::ToolStd => {
-                    self.clear_if_dirty(&my_out, &libstd_stamp);
-                },
-                Mode::ToolTest => {
-                    self.clear_if_dirty(&my_out, &libstd_stamp);
-                    self.clear_if_dirty(&my_out, &libtest_stamp);
-                },
-                Mode::ToolRustc => {
-                    self.clear_if_dirty(&my_out, &libstd_stamp);
-                    self.clear_if_dirty(&my_out, &libtest_stamp);
-                    self.clear_if_dirty(&my_out, &librustc_stamp);
-                },
-            }
         }
 
         cargo
@@ -861,6 +805,19 @@ impl<'a> Builder<'a> {
             },
         }
 
+        // This tells Cargo (and in turn, rustc) to output more complete
+        // dependency information.  Most importantly for rustbuild, this
+        // includes sysroot artifacts, like libstd, which means that we don't
+        // need to track those in rustbuild (an error prone process!). This
+        // feature is currently unstable as there may be some bugs and such, but
+        // it represents a big improvement in rustbuild's reliability on
+        // rebuilds, so we're using it here.
+        //
+        // For some additional context, see #63470 (the PR originally adding
+        // this), as well as #63012 which is the tracking issue for this
+        // feature on the rustc side.
+        cargo.arg("-Zbinary-dep-depinfo");
+
         cargo.arg("-j").arg(self.jobs().to_string());
         // Remove make-related flags to ensure Cargo can correctly set things up
         cargo.env_remove("MAKEFLAGS");
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 11b082ac3f6d8..6e6fea6b831a7 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -245,7 +245,6 @@ impl Step for Rustdoc {
         let libdir = builder.sysroot_libdir(compiler, target);
         let hostdir = builder.sysroot_libdir(compiler, compiler.host);
         add_to_sysroot(&builder, &libdir, &hostdir, &rustdoc_stamp(builder, compiler, target));
-        builder.cargo(compiler, Mode::ToolRustc, target, "clean");
     }
 }
 
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 4cd793adaf574..e0bdfe28390a6 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -15,7 +15,7 @@ use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio, exit};
 use std::str;
 
-use build_helper::{output, mtime, t, up_to_date};
+use build_helper::{output, t, up_to_date};
 use filetime::FileTime;
 use serde::Deserialize;
 use serde_json;
@@ -274,8 +274,6 @@ impl Step for StdLink {
             // for reason why the sanitizers are not built in stage0.
             copy_apple_sanitizer_dylibs(builder, &builder.native_dir(target), "osx", &libdir);
         }
-
-        builder.cargo(target_compiler, Mode::ToolStd, target, "clean");
     }
 }
 
@@ -480,8 +478,6 @@ impl Step for TestLink {
             &builder.sysroot_libdir(target_compiler, compiler.host),
             &libtest_stamp(builder, compiler, target)
         );
-
-        builder.cargo(target_compiler, Mode::ToolTest, target, "clean");
     }
 }
 
@@ -639,7 +635,6 @@ impl Step for RustcLink {
             &builder.sysroot_libdir(target_compiler, compiler.host),
             &librustc_stamp(builder, compiler, target)
         );
-        builder.cargo(target_compiler, Mode::ToolRustc, target, "clean");
     }
 }
 
@@ -1206,41 +1201,13 @@ pub fn run_cargo(builder: &Builder<'_>,
         deps.push((path_to_add.into(), false));
     }
 
-    // Now we want to update the contents of the stamp file, if necessary. First
-    // we read off the previous contents along with its mtime. If our new
-    // contents (the list of files to copy) is different or if any dep's mtime
-    // is newer then we rewrite the stamp file.
     deps.sort();
-    let stamp_contents = fs::read(stamp);
-    let stamp_mtime = mtime(&stamp);
     let mut new_contents = Vec::new();
-    let mut max = None;
-    let mut max_path = None;
     for (dep, proc_macro) in deps.iter() {
-        let mtime = mtime(dep);
-        if Some(mtime) > max {
-            max = Some(mtime);
-            max_path = Some(dep.clone());
-        }
         new_contents.extend(if *proc_macro { b"h" } else { b"t" });
         new_contents.extend(dep.to_str().unwrap().as_bytes());
         new_contents.extend(b"\0");
     }
-    let max = max.unwrap();
-    let max_path = max_path.unwrap();
-    let contents_equal = stamp_contents
-        .map(|contents| contents == new_contents)
-        .unwrap_or_default();
-    if contents_equal && max <= stamp_mtime {
-        builder.verbose(&format!("not updating {:?}; contents equal and {:?} <= {:?}",
-                stamp, max, stamp_mtime));
-        return deps.into_iter().map(|(d, _)| d).collect()
-    }
-    if max > stamp_mtime {
-        builder.verbose(&format!("updating {:?} as {:?} changed", stamp, max_path));
-    } else {
-        builder.verbose(&format!("updating {:?} as deps changed", stamp));
-    }
     t!(fs::write(&stamp, &new_contents));
     deps.into_iter().map(|(d, _)| d).collect()
 }

From c1758d5918b8c5e99b34c83e83266dc5f79b0da7 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Wed, 14 Aug 2019 18:53:22 +0300
Subject: [PATCH 14/16] rustc_codegen_utils: account for 1-indexed anonymous
 lifetimes in v0 mangling.

---
 src/librustc_codegen_utils/symbol_names/v0.rs | 12 ++++++++++--
 src/test/ui/symbol-names/impl1.rs             |  6 +++---
 src/test/ui/symbol-names/impl1.v0.stderr      |  6 +++---
 3 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/src/librustc_codegen_utils/symbol_names/v0.rs b/src/librustc_codegen_utils/symbol_names/v0.rs
index 47601da8b7b23..8d6a1d757e014 100644
--- a/src/librustc_codegen_utils/symbol_names/v0.rs
+++ b/src/librustc_codegen_utils/symbol_names/v0.rs
@@ -198,10 +198,14 @@ impl SymbolMangler<'tcx> {
 
         let lifetimes = regions.into_iter().map(|br| {
             match br {
-                ty::BrAnon(i) => i + 1,
+                ty::BrAnon(i) => {
+                    // FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`.
+                    assert_ne!(i, 0);
+                    i - 1
+                },
                 _ => bug!("symbol_names: non-anonymized region `{:?}` in `{:?}`", br, value),
             }
-        }).max().unwrap_or(0);
+        }).max().map_or(0, |max| max + 1);
 
         self.push_opt_integer_62("G", lifetimes as u64);
         lifetime_depths.end += lifetimes;
@@ -297,6 +301,10 @@ impl Printer<'tcx> for SymbolMangler<'tcx> {
             // Late-bound lifetimes use indices starting at 1,
             // see `BinderLevel` for more details.
             ty::ReLateBound(debruijn, ty::BrAnon(i)) => {
+                // FIXME(eddyb) for some reason, `anonymize_late_bound_regions` starts at `1`.
+                assert_ne!(i, 0);
+                let i = i - 1;
+
                 let binder = &self.binders[self.binders.len() - 1 - debruijn.index()];
                 let depth = binder.lifetime_depths.start + i;
 
diff --git a/src/test/ui/symbol-names/impl1.rs b/src/test/ui/symbol-names/impl1.rs
index 52bb118fa23a0..137b72dcd9c44 100644
--- a/src/test/ui/symbol-names/impl1.rs
+++ b/src/test/ui/symbol-names/impl1.rs
@@ -64,9 +64,9 @@ fn main() {
             //[legacy]~^ ERROR symbol-name(_ZN198_$LT$$u5b$$RF$dyn$u20$impl1..Foo$u2b$Assoc$u20$$u3d$$u20$extern$u20$$u22$C$u22$$u20$fn$LP$$RF$u8$RP$$u2b$impl1..AutoTrait$u3b$$u20$_$u5d$$u20$as$u20$impl1..main..$u7b$$u7b$closure$u7d$$u7d$..Bar$GT$6method
             //[legacy]~| ERROR demangling(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method
             //[legacy]~| ERROR demangling-alt(<[&dyn impl1::Foo+Assoc = extern "C" fn(&u8)+impl1::AutoTrait; _] as impl1::main::{{closure}}::Bar>::method)
-             //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG0_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
-                //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
-                //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
+             //[v0]~^^^^ ERROR symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
+                //[v0]~| ERROR demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
+                //[v0]~| ERROR demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
             #[rustc_def_path]
             //[legacy]~^ ERROR def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method)
                //[v0]~^^ ERROR def-path(<[&dyn Foo<Assoc = for<'r> extern "C" fn(&'r u8)> + AutoTrait; _] as main::{{closure}}#1::Bar>::method)
diff --git a/src/test/ui/symbol-names/impl1.v0.stderr b/src/test/ui/symbol-names/impl1.v0.stderr
index 1c4b256c9e933..e024799df867c 100644
--- a/src/test/ui/symbol-names/impl1.v0.stderr
+++ b/src/test/ui/symbol-names/impl1.v0.stderr
@@ -46,19 +46,19 @@ error: def-path(bar::<impl foo::Foo>::baz)
 LL |         #[rustc_def_path]
    |         ^^^^^^^^^^^^^^^^^
 
-error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG0_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
+error: symbol-name(_RNvXNCNvCs4fqI2P2rA04_5impl14mains_0ARDNtB6_3Foop5AssocFG_KCRL0_hEuNtB6_9AutoTraitEL_j3_NtB2_3Bar6method)
   --> $DIR/impl1.rs:63:13
    |
 LL |             #[rustc_symbol_name]
    |             ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
+error: demangling(<[&dyn impl1[317d481089b8c8fe]::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1[317d481089b8c8fe]::AutoTrait; 3: usize] as impl1[317d481089b8c8fe]::main::{closure#1}::Bar>::method)
   --> $DIR/impl1.rs:63:13
    |
 LL |             #[rustc_symbol_name]
    |             ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a, 'b> extern "C" fn(&'b u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
+error: demangling-alt(<[&dyn impl1::Foo<Assoc = for<'a> extern "C" fn(&'a u8)> + impl1::AutoTrait; 3] as impl1::main::{closure#1}::Bar>::method)
   --> $DIR/impl1.rs:63:13
    |
 LL |             #[rustc_symbol_name]

From ed7317cebe71db1745267f1039960d0c48458f59 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Wed, 14 Aug 2019 22:22:46 +0300
Subject: [PATCH 15/16] remove unused Level::PhaseFatal

---
 src/librustc_errors/annotate_snippet_emitter_writer.rs | 2 +-
 src/librustc_errors/diagnostic.rs                      | 1 -
 src/librustc_errors/lib.rs                             | 7 ++-----
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs
index 96a9b6c5c4f7f..255af3122e70c 100644
--- a/src/librustc_errors/annotate_snippet_emitter_writer.rs
+++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs
@@ -148,7 +148,7 @@ impl<'a>  DiagnosticConverter<'a> {
     /// Maps `Diagnostic::Level` to `snippet::AnnotationType`
     fn annotation_type_for_level(level: Level) -> AnnotationType {
         match level {
-            Level::Bug | Level::Fatal | Level::PhaseFatal | Level::Error => AnnotationType::Error,
+            Level::Bug | Level::Fatal | Level::Error => AnnotationType::Error,
             Level::Warning => AnnotationType::Warning,
             Level::Note => AnnotationType::Note,
             Level::Help => AnnotationType::Help,
diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs
index e11ba75da9866..3f1b91256c468 100644
--- a/src/librustc_errors/diagnostic.rs
+++ b/src/librustc_errors/diagnostic.rs
@@ -94,7 +94,6 @@ impl Diagnostic {
         match self.level {
             Level::Bug |
             Level::Fatal |
-            Level::PhaseFatal |
             Level::Error |
             Level::FailureNote => {
                 true
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 3b6a6a824c86d..f3e524152ffae 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -787,9 +787,6 @@ impl Handler {
 pub enum Level {
     Bug,
     Fatal,
-    // An error which while not immediately fatal, should stop the compiler
-    // progressing beyond the current phase.
-    PhaseFatal,
     Error,
     Warning,
     Note,
@@ -808,7 +805,7 @@ impl Level {
     fn color(self) -> ColorSpec {
         let mut spec = ColorSpec::new();
         match self {
-            Bug | Fatal | PhaseFatal | Error => {
+            Bug | Fatal | Error => {
                 spec.set_fg(Some(Color::Red))
                     .set_intense(true);
             }
@@ -833,7 +830,7 @@ impl Level {
     pub fn to_str(self) -> &'static str {
         match self {
             Bug => "error: internal compiler error",
-            Fatal | PhaseFatal | Error => "error",
+            Fatal | Error => "error",
             Warning => "warning",
             Note => "note",
             Help => "help",

From e5017dec58b73182b21d3dc0b6c93590716d8cc4 Mon Sep 17 00:00:00 2001
From: nivlac <meffij@gmail.com>
Date: Wed, 14 Aug 2019 14:31:54 -0700
Subject: [PATCH 16/16] Test HRTB issue accepted by compiler

---
 src/test/ui/issues/issue-50301.rs | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 src/test/ui/issues/issue-50301.rs

diff --git a/src/test/ui/issues/issue-50301.rs b/src/test/ui/issues/issue-50301.rs
new file mode 100644
index 0000000000000..47ee3e7ad70e8
--- /dev/null
+++ b/src/test/ui/issues/issue-50301.rs
@@ -0,0 +1,31 @@
+// Tests that HRTBs are correctly accepted -- https://github.com/rust-lang/rust/issues/50301
+// check-pass
+trait Trait
+where
+    for<'a> &'a Self::IntoIter: IntoIterator<Item = u32>,
+{
+    type IntoIter;
+    fn get(&self) -> Self::IntoIter;
+}
+
+struct Impl(Vec<u32>);
+
+impl Trait for Impl {
+    type IntoIter = ImplIntoIter;
+    fn get(&self) -> Self::IntoIter {
+        ImplIntoIter(self.0.clone())
+    }
+}
+
+struct ImplIntoIter(Vec<u32>);
+
+impl<'a> IntoIterator for &'a ImplIntoIter {
+    type Item = <Self::IntoIter as Iterator>::Item;
+    type IntoIter = std::iter::Cloned<std::slice::Iter<'a, u32>>;
+    fn into_iter(self) -> Self::IntoIter {
+        (&self.0).into_iter().cloned()
+    }
+}
+
+fn main() {
+}