about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-03-28 08:56:34 +0000
committerbors <bors@rust-lang.org>2019-03-28 08:56:34 +0000
commit237bf3244fffef501cf37d4bda00e1fce3fcfb46 (patch)
treeca483d5330b97887970dca2110c007a1084e4aa1 /src
parent6bfe4b7b51f47ca014d535506cbc5682f00d8d2a (diff)
parentd403cd787c98610cf5287301820ad3353b35481d (diff)
downloadrust-237bf3244fffef501cf37d4bda00e1fce3fcfb46.tar.gz
rust-237bf3244fffef501cf37d4bda00e1fce3fcfb46.zip
Auto merge of #59478 - Centril:rollup, r=Centril
Rollup of 12 pull requests

Successful merges:

 - #57987 (Fix some AArch64 typos)
 - #58581 (Refactor generic parameter encoder functions)
 - #58803 (fs::copy() unix: set file mode early)
 - #58848 (Prevent cache issues on version updates)
 - #59198 (Do not complain about unmentioned fields in recovered patterns)
 - #59351 (Include llvm-ar with llvm-tools component)
 - #59413 (HirIdify hir::ItemId)
 - #59441 (Remove the block on natvis for lld-link.)
 - #59448 (Use consistent phrasing for all macro summaries)
 - #59456 (Add documentation about `for` used as higher ranked trait bounds)
 - #59472 (Document that `std::io::BufReader` discards contents on drop)
 - #59474 (Fix link capitalization in documentation of std::io::BufWriter.)

Failed merges:

r? @ghost
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/bin/rustdoc.rs11
-rw-r--r--src/bootstrap/doc.rs16
-rw-r--r--src/bootstrap/lib.rs1
-rw-r--r--src/libcore/ffi.rs16
-rw-r--r--src/libcore/macros.rs45
-rw-r--r--src/librustc/hir/intravisit.rs2
-rw-r--r--src/librustc/hir/lowering.rs125
-rw-r--r--src/librustc/hir/map/mod.rs4
-rw-r--r--src/librustc/hir/mod.rs8
-rw-r--r--src/librustc/hir/print.rs4
-rw-r--r--src/librustc/middle/dead.rs2
-rw-r--r--src/librustc/middle/resolve_lifetime.rs7
-rw-r--r--src/librustc_codegen_llvm/va_arg.rs4
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs12
-rw-r--r--src/librustc_metadata/decoder.rs2
-rw-r--r--src/librustc_metadata/encoder.rs75
-rw-r--r--src/librustc_metadata/schema.rs6
-rw-r--r--src/librustc_privacy/lib.rs7
-rw-r--r--src/librustc_typeck/astconv.rs2
-rw-r--r--src/librustc_typeck/check/method/suggest.rs2
-rw-r--r--src/librustdoc/clean/mod.rs18
-rw-r--r--src/librustdoc/visit_ast.rs4
-rw-r--r--src/libstd/io/buffered.rs8
-rw-r--r--src/libstd/keyword_docs.rs17
-rw-r--r--src/libstd/macros.rs46
-rw-r--r--src/libstd/sys/unix/fs.rs129
-rw-r--r--src/libsyntax/parse/parser.rs2
-rw-r--r--src/test/run-pass/paths-containing-nul.rs13
-rw-r--r--src/test/ui/parser/bind-struct-early-modifiers.rs1
-rw-r--r--src/test/ui/parser/bind-struct-early-modifiers.stderr9
-rw-r--r--src/test/ui/parser/issue-10392.rs1
-rw-r--r--src/test/ui/parser/issue-10392.stderr9
-rw-r--r--src/test/ui/resolve/issue-54379.rs2
-rw-r--r--src/test/ui/resolve/issue-54379.stderr9
-rw-r--r--src/tools/error_index_generator/main.rs20
35 files changed, 341 insertions, 298 deletions
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index 085f243785c..1c9f6e1ab28 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -69,6 +69,17 @@ fn main() {
                .arg("unstable-options");
         }
         cmd.arg("--generate-redirect-pages");
+        has_unstable = true;
+    }
+
+    // Needed to be able to run all rustdoc tests.
+    if let Some(ref x) = env::var_os("RUSTDOC_RESOURCE_SUFFIX") {
+        // This "unstable-options" can be removed when `--resource-suffix` is stabilized
+        if !has_unstable {
+            cmd.arg("-Z")
+               .arg("unstable-options");
+        }
+        cmd.arg("--resource-suffix").arg(x);
     }
 
     if verbose > 1 {
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 2ea6be55210..d831d2f1af2 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -343,12 +343,9 @@ fn invoke_rustdoc(
         .arg("--html-before-content").arg(&version_info)
         .arg("--html-in-header").arg(&header)
         .arg("--markdown-no-toc")
-        .arg("--markdown-playground-url")
-        .arg("https://play.rust-lang.org/")
-        .arg("-o").arg(&out)
-        .arg(&path)
-        .arg("--markdown-css")
-        .arg("../rust.css");
+        .arg("--markdown-playground-url").arg("https://play.rust-lang.org/")
+        .arg("-o").arg(&out).arg(&path)
+        .arg("--markdown-css").arg("../rust.css");
 
     builder.run(&mut cmd);
 }
@@ -431,8 +428,7 @@ impl Step for Standalone {
                .arg("--html-in-header").arg(&favicon)
                .arg("--markdown-no-toc")
                .arg("--index-page").arg(&builder.src.join("src/doc/index.md"))
-               .arg("--markdown-playground-url")
-               .arg("https://play.rust-lang.org/")
+               .arg("--markdown-playground-url").arg("https://play.rust-lang.org/")
                .arg("-o").arg(&out)
                .arg(&path);
 
@@ -523,6 +519,7 @@ impl Step for Std {
                  .arg("--markdown-css").arg("rust.css")
                  .arg("--markdown-no-toc")
                  .arg("--generate-redirect-pages")
+                 .arg("--resource-suffix").arg(crate::channel::CFG_RELEASE_NUM)
                  .arg("--index-page").arg(&builder.src.join("src/doc/index.md"));
 
             builder.run(&mut cargo);
@@ -589,6 +586,7 @@ impl Step for Test {
 
         cargo.arg("--no-deps")
              .arg("-p").arg("test")
+             .env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM)
              .env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1");
 
         builder.run(&mut cargo);
@@ -660,6 +658,7 @@ impl Step for WhitelistedRustc {
         // for which docs must be built.
         for krate in &["proc_macro"] {
             cargo.arg("-p").arg(krate)
+                 .env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM)
                  .env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1");
         }
 
@@ -890,6 +889,7 @@ impl Step for ErrorIndex {
         );
         index.arg("html");
         index.arg(out.join("error-index.html"));
+        index.arg(crate::channel::CFG_RELEASE_NUM);
 
         // FIXME: shouldn't have to pass this env var
         index.env("CFG_BUILD", &builder.config.build)
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 0c3daea7a3c..d245b3e98d3 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -190,6 +190,7 @@ const LLVM_TOOLS: &[&str] = &[
     "llvm-readobj", // used to get information from ELFs/objects that the other tools don't provide
     "llvm-size", // used to prints the size of the linker sections of a program
     "llvm-strip", // used to discard symbols from binary files to reduce their size
+    "llvm-ar" // used for creating and modifying archive files
 ];
 
 /// A structure representing a Rust compiler.
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index 5cc9c25c21e..231a1f199bd 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -47,7 +47,7 @@ impl fmt::Debug for c_void {
 /// Basic implementation of a `va_list`.
 #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
               not(target_arch = "x86_64")),
-          all(target_arch = "aarch4", target_os = "ios"),
+          all(target_arch = "aarch64", target_os = "ios"),
           windows))]
 #[unstable(feature = "c_variadic",
            reason = "the `c_variadic` feature has not been properly tested on \
@@ -59,6 +59,7 @@ extern {
 
 #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
               not(target_arch = "x86_64")),
+          all(target_arch = "aarch64", target_os = "ios"),
           windows))]
 impl fmt::Debug for VaListImpl {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -67,11 +68,11 @@ impl fmt::Debug for VaListImpl {
 }
 
 /// AArch64 ABI implementation of a `va_list`. See the
-/// [Aarch64 Procedure Call Standard] for more details.
+/// [AArch64 Procedure Call Standard] for more details.
 ///
 /// [AArch64 Procedure Call Standard]:
 /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf
-#[cfg(all(target_arch = "aarch64", not(windows)))]
+#[cfg(all(target_arch = "aarch64", not(target_os = "ios"), not(windows)))]
 #[repr(C)]
 #[derive(Debug)]
 #[unstable(feature = "c_variadic",
@@ -193,14 +194,14 @@ impl<'a> VaList<'a> {
             where F: for<'copy> FnOnce(VaList<'copy>) -> R {
         #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
                       not(target_arch = "x86_64")),
-                  all(target_arch = "aarch4", target_os = "ios"),
+                  all(target_arch = "aarch64", target_os = "ios"),
                   windows))]
         let mut ap = va_copy(self);
         #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
-                  not(windows)))]
+                  not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))]
         let mut ap_inner = va_copy(self);
         #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
-                  not(windows)))]
+                  not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))]
         let mut ap = VaList(&mut ap_inner);
         let ret = f(VaList(ap.0));
         va_end(&mut ap);
@@ -216,10 +217,11 @@ extern "rust-intrinsic" {
     /// Copies the current location of arglist `src` to the arglist `dst`.
     #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
                   not(target_arch = "x86_64")),
+              all(target_arch = "aarch64", target_os = "ios"),
               windows))]
     fn va_copy<'a>(src: &VaList<'a>) -> VaList<'a>;
     #[cfg(all(any(target_arch = "aarch64", target_arch = "powerpc", target_arch = "x86_64"),
-              not(windows)))]
+              not(windows), not(all(target_arch = "aarch64", target_os = "ios"))))]
     fn va_copy(src: &VaList) -> VaListImpl;
 
     /// Loads an argument of type `T` from the `va_list` `ap` and increment the
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index ad8ce1af1f6..d2ee9b11b36 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -1,4 +1,6 @@
-/// Entry point of thread panic. For details, see `std::macros`.
+/// Panics the current thread.
+///
+/// For details, see `std::macros`.
 #[macro_export]
 #[allow_internal_unstable(core_panic, __rust_unstable_column)]
 #[stable(feature = "core", since = "1.6.0")]
@@ -132,7 +134,7 @@ macro_rules! assert_ne {
     });
 }
 
-/// Ensure that a boolean expression is `true` at runtime.
+/// Asserts that a boolean expression is `true` at runtime.
 ///
 /// This will invoke the [`panic!`] macro if the provided expression cannot be
 /// evaluated to `true` at runtime.
@@ -236,8 +238,7 @@ macro_rules! debug_assert_ne {
     ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_ne!($($arg)*); })
 }
 
-/// Helper macro for reducing boilerplate code for matching `Result` together
-/// with converting downstream errors.
+/// Unwraps a result or propagates its error.
 ///
 /// The `?` operator was added to replace `try!` and should be used instead.
 /// Furthermore, `try` is a reserved word in Rust 2018, so if you must use
@@ -312,7 +313,7 @@ macro_rules! r#try {
     ($expr:expr,) => (r#try!($expr));
 }
 
-/// Write formatted data into a buffer.
+/// Writes formatted data into a buffer.
 ///
 /// This macro accepts a format string, a list of arguments, and a 'writer'. Arguments will be
 /// formatted according to the specified format string and the result will be passed to the writer.
@@ -434,7 +435,7 @@ macro_rules! writeln {
     );
 }
 
-/// A utility macro for indicating unreachable code.
+/// Indicates unreachable code.
 ///
 /// This is useful any time that the compiler can't determine that some code is unreachable. For
 /// example:
@@ -502,7 +503,7 @@ macro_rules! unreachable {
     });
 }
 
-/// A standardized placeholder for marking unfinished code.
+/// Indicates unfinished code.
 ///
 /// This can be useful if you are prototyping and are just looking to have your
 /// code type-check, or if you're implementing a trait that requires multiple
@@ -559,10 +560,10 @@ macro_rules! unimplemented {
     ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
 }
 
-/// A standardized placeholder for marking unfinished code.
+/// Indicates unfinished code.
 ///
 /// This can be useful if you are prototyping and are just looking to have your
-/// code typecheck. `todo!` works exactly like `unimplemented!`, there only
+/// code typecheck. `todo!` works exactly like `unimplemented!`. The only
 /// difference between the two macros is the name.
 ///
 /// # Panics
@@ -618,7 +619,7 @@ macro_rules! todo {
     ($($arg:tt)+) => (panic!("not yet implemented: {}", format_args!($($arg)*)));
 }
 
-/// A macro to create an array of [`MaybeUninit`]
+/// Creates an array of [`MaybeUninit`].
 ///
 /// This macro constructs an uninitialized array of the type `[MaybeUninit<K>; N]`.
 ///
@@ -645,7 +646,7 @@ macro_rules! uninitialized_array {
 #[cfg(rustdoc)]
 mod builtin {
 
-    /// Unconditionally causes compilation to fail with the given error message when encountered.
+    /// Causes compilation to fail with the given error message when encountered.
     ///
     /// For more information, see the documentation for [`std::compile_error!`].
     ///
@@ -657,7 +658,7 @@ mod builtin {
         ($msg:expr,) => ({ /* compiler built-in */ });
     }
 
-    /// The core macro for formatted string creation & output.
+    /// Constructs parameters for the other string-formatting macros.
     ///
     /// For more information, see the documentation for [`std::format_args!`].
     ///
@@ -669,7 +670,7 @@ mod builtin {
         ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
     }
 
-    /// Inspect an environment variable at compile time.
+    /// Inspects an environment variable at compile time.
     ///
     /// For more information, see the documentation for [`std::env!`].
     ///
@@ -681,7 +682,7 @@ mod builtin {
         ($name:expr,) => ({ /* compiler built-in */ });
     }
 
-    /// Optionally inspect an environment variable at compile time.
+    /// Optionally inspects an environment variable at compile time.
     ///
     /// For more information, see the documentation for [`std::option_env!`].
     ///
@@ -693,7 +694,7 @@ mod builtin {
         ($name:expr,) => ({ /* compiler built-in */ });
     }
 
-    /// Concatenate identifiers into one identifier.
+    /// Concatenates identifiers into one identifier.
     ///
     /// For more information, see the documentation for [`std::concat_idents!`].
     ///
@@ -717,7 +718,7 @@ mod builtin {
         ($($e:expr,)*) => ({ /* compiler built-in */ });
     }
 
-    /// A macro which expands to the line number on which it was invoked.
+    /// Expands to the line number on which it was invoked.
     ///
     /// For more information, see the documentation for [`std::line!`].
     ///
@@ -726,7 +727,7 @@ mod builtin {
     #[rustc_doc_only_macro]
     macro_rules! line { () => ({ /* compiler built-in */ }) }
 
-    /// A macro which expands to the column number on which it was invoked.
+    /// Expands to the column number on which it was invoked.
     ///
     /// For more information, see the documentation for [`std::column!`].
     ///
@@ -735,7 +736,7 @@ mod builtin {
     #[rustc_doc_only_macro]
     macro_rules! column { () => ({ /* compiler built-in */ }) }
 
-    /// A macro which expands to the file name from which it was invoked.
+    /// Expands to the file name from which it was invoked.
     ///
     /// For more information, see the documentation for [`std::file!`].
     ///
@@ -744,7 +745,7 @@ mod builtin {
     #[rustc_doc_only_macro]
     macro_rules! file { () => ({ /* compiler built-in */ }) }
 
-    /// A macro which stringifies its arguments.
+    /// Stringifies its arguments.
     ///
     /// For more information, see the documentation for [`std::stringify!`].
     ///
@@ -786,7 +787,7 @@ mod builtin {
     #[rustc_doc_only_macro]
     macro_rules! module_path { () => ({ /* compiler built-in */ }) }
 
-    /// Boolean evaluation of configuration flags, at compile-time.
+    /// Evaluates boolean combinations of configuration flags, at compile-time.
     ///
     /// For more information, see the documentation for [`std::cfg!`].
     ///
@@ -795,7 +796,7 @@ mod builtin {
     #[rustc_doc_only_macro]
     macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) }
 
-    /// Parse a file as an expression or an item according to the context.
+    /// Parses a file as an expression or an item according to the context.
     ///
     /// For more information, see the documentation for [`std::include!`].
     ///
@@ -807,7 +808,7 @@ mod builtin {
         ($file:expr,) => ({ /* compiler built-in */ });
     }
 
-    /// Ensure that a boolean expression is `true` at runtime.
+    /// Asserts that a boolean expression is `true` at runtime.
     ///
     /// For more information, see the documentation for [`std::assert!`].
     ///
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index bce528189ad..39069b66f29 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -163,7 +163,7 @@ pub trait Visitor<'v> : Sized {
     /// but cannot supply a `Map`; see `nested_visit_map` for advice.
     #[allow(unused_variables)]
     fn visit_nested_item(&mut self, id: ItemId) {
-        let opt_item = self.nested_visit_map().inter().map(|map| map.expect_item(id.id));
+        let opt_item = self.nested_visit_map().inter().map(|map| map.expect_item_by_hir_id(id.id));
         if let Some(item) = opt_item {
             self.visit_item(item);
         }
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 891210511ca..7dfb16602a3 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -51,7 +51,6 @@ use rustc_data_structures::thin_vec::ThinVec;
 use rustc_data_structures::sync::Lrc;
 
 use std::collections::{BTreeSet, BTreeMap};
-use std::fmt::Debug;
 use std::mem;
 use smallvec::SmallVec;
 use syntax::attr;
@@ -82,7 +81,7 @@ pub struct LoweringContext<'a> {
     resolver: &'a mut dyn Resolver,
 
     /// The items being lowered are collected here.
-    items: BTreeMap<NodeId, hir::Item>,
+    items: BTreeMap<hir::HirId, hir::Item>,
 
     trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
     impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
@@ -321,7 +320,7 @@ enum AnonymousLifetimeMode {
     PassThrough,
 }
 
-struct ImplTraitTypeIdVisitor<'a> { ids: &'a mut SmallVec<[hir::ItemId; 1]> }
+struct ImplTraitTypeIdVisitor<'a> { ids: &'a mut SmallVec<[NodeId; 1]> }
 
 impl<'a, 'b> Visitor<'a> for ImplTraitTypeIdVisitor<'b> {
     fn visit_ty(&mut self, ty: &'a Ty) {
@@ -330,7 +329,7 @@ impl<'a, 'b> Visitor<'a> for ImplTraitTypeIdVisitor<'b> {
             | TyKind::BareFn(_)
             => return,
 
-            TyKind::ImplTrait(id, _) => self.ids.push(hir::ItemId { id }),
+            TyKind::ImplTrait(id, _) => self.ids.push(id),
             _ => {},
         }
         visit::walk_ty(self, ty);
@@ -361,9 +360,40 @@ impl<'a> LoweringContext<'a> {
             lctx: &'lcx mut LoweringContext<'interner>,
         }
 
+        impl MiscCollector<'_, '_> {
+            fn allocate_use_tree_hir_id_counters(
+                &mut self,
+                tree: &UseTree,
+                owner: DefIndex,
+            ) {
+                match tree.kind {
+                    UseTreeKind::Simple(_, id1, id2) => {
+                        for &id in &[id1, id2] {
+                            self.lctx.resolver.definitions().create_def_with_parent(
+                                owner,
+                                id,
+                                DefPathData::Misc,
+                                DefIndexAddressSpace::High,
+                                Mark::root(),
+                                tree.prefix.span,
+                            );
+                            self.lctx.allocate_hir_id_counter(id);
+                        }
+                    }
+                    UseTreeKind::Glob => (),
+                    UseTreeKind::Nested(ref trees) => {
+                        for &(ref use_tree, id) in trees {
+                            let hir_id = self.lctx.allocate_hir_id_counter(id).hir_id;
+                            self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner);
+                        }
+                    }
+                }
+            }
+        }
+
         impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> {
             fn visit_item(&mut self, item: &'lcx Item) {
-                self.lctx.allocate_hir_id_counter(item.id, item);
+                let hir_id = self.lctx.allocate_hir_id_counter(item.id).hir_id;
 
                 match item.node {
                     ItemKind::Struct(_, ref generics)
@@ -383,18 +413,21 @@ impl<'a> LoweringContext<'a> {
                             .count();
                         self.lctx.type_def_lifetime_params.insert(def_id, count);
                     }
+                    ItemKind::Use(ref use_tree) => {
+                        self.allocate_use_tree_hir_id_counters(use_tree, hir_id.owner);
+                    }
                     _ => {}
                 }
                 visit::walk_item(self, item);
             }
 
             fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
-                self.lctx.allocate_hir_id_counter(item.id, item);
+                self.lctx.allocate_hir_id_counter(item.id);
                 visit::walk_trait_item(self, item);
             }
 
             fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
-                self.lctx.allocate_hir_id_counter(item.id, item);
+                self.lctx.allocate_hir_id_counter(item.id);
                 visit::walk_impl_item(self, item);
             }
         }
@@ -434,17 +467,16 @@ impl<'a> LoweringContext<'a> {
             }
 
             fn visit_item(&mut self, item: &'lcx Item) {
-                let mut item_lowered = true;
+                let mut item_hir_id = None;
                 self.lctx.with_hir_id_owner(item.id, |lctx| {
                     if let Some(hir_item) = lctx.lower_item(item) {
-                        lctx.insert_item(item.id, hir_item);
-                    } else {
-                        item_lowered = false;
+                        item_hir_id = Some(hir_item.hir_id);
+                        lctx.insert_item(hir_item);
                     }
                 });
 
-                if item_lowered {
-                    let item_generics = match self.lctx.items.get(&item.id).unwrap().node {
+                if let Some(hir_id) = item_hir_id {
+                    let item_generics = match self.lctx.items.get(&hir_id).unwrap().node {
                         hir::ItemKind::Impl(_, _, _, ref generics, ..)
                         | hir::ItemKind::Trait(_, _, ref generics, ..) => {
                             generics.params.clone()
@@ -516,20 +548,21 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn insert_item(&mut self, id: NodeId, item: hir::Item) {
+    fn insert_item(&mut self, item: hir::Item) {
+        let id = item.hir_id;
+        // FIXME: Use debug_asset-rt
+        assert_eq!(id.local_id, hir::ItemLocalId::from_u32(0));
         self.items.insert(id, item);
         self.modules.get_mut(&self.current_module).unwrap().items.insert(id);
     }
 
-    fn allocate_hir_id_counter<T: Debug>(&mut self, owner: NodeId, debug: &T) -> LoweredNodeId {
-        if self.item_local_id_counters.insert(owner, 0).is_some() {
-            bug!(
-                "Tried to allocate item_local_id_counter for {:?} twice",
-                debug
-            );
-        }
+    fn allocate_hir_id_counter(&mut self, owner: NodeId) -> LoweredNodeId {
+        // Setup the counter if needed
+        self.item_local_id_counters.entry(owner).or_insert(0);
         // Always allocate the first `HirId` for the owner itself.
-        self.lower_node_id_with_owner(owner, owner)
+        let lowered = self.lower_node_id_with_owner(owner, owner);
+        debug_assert_eq!(lowered.hir_id.local_id.as_u32(), 0);
+        lowered
     }
 
     fn lower_node_id_generic<F>(&mut self, ast_node_id: NodeId, alloc_hir_id: F) -> LoweredNodeId
@@ -1381,7 +1414,7 @@ impl<'a> LoweringContext<'a> {
             .opt_def_index(exist_ty_node_id)
             .unwrap();
 
-        self.allocate_hir_id_counter(exist_ty_node_id, &"existential impl trait");
+        self.allocate_hir_id_counter(exist_ty_node_id);
 
         let hir_bounds = self.with_hir_id_owner(exist_ty_node_id, lower_bounds);
 
@@ -1422,10 +1455,10 @@ impl<'a> LoweringContext<'a> {
             // Insert the item into the global list. This usually happens
             // automatically for all AST items. But this existential type item
             // does not actually exist in the AST.
-            lctx.insert_item(exist_ty_id.node_id, exist_ty_item);
+            lctx.insert_item(exist_ty_item);
 
             // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
-            hir::TyKind::Def(hir::ItemId { id: exist_ty_id.node_id }, lifetimes)
+            hir::TyKind::Def(hir::ItemId { id: exist_ty_id.hir_id }, lifetimes)
         })
     }
 
@@ -2002,9 +2035,9 @@ impl<'a> LoweringContext<'a> {
         )
     }
 
-    fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[hir::ItemId; 1]>) {
+    fn lower_local(&mut self, l: &Local) -> (hir::Local, SmallVec<[NodeId; 1]>) {
         let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(l.id);
-        let mut ids = SmallVec::<[hir::ItemId; 1]>::new();
+        let mut ids = SmallVec::<[NodeId; 1]>::new();
         if self.sess.features_untracked().impl_trait_in_bindings {
             if let Some(ref ty) = l.ty {
                 let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
@@ -3065,7 +3098,6 @@ impl<'a> LoweringContext<'a> {
                     }
                 }
 
-                let parent_def_index = self.current_hir_id_owner.last().unwrap().0;
                 let mut defs = self.expect_full_def_from_use(id);
                 // We want to return *something* from this function, so hold onto the first item
                 // for later.
@@ -3084,14 +3116,6 @@ impl<'a> LoweringContext<'a> {
                         seg.id = self.sess.next_node_id();
                     }
                     let span = path.span;
-                    self.resolver.definitions().create_def_with_parent(
-                        parent_def_index,
-                        new_node_id,
-                        DefPathData::Misc,
-                        DefIndexAddressSpace::High,
-                        Mark::root(),
-                        span);
-                    self.allocate_hir_id_counter(new_node_id, &path);
 
                     self.with_hir_id_owner(new_node_id, |this| {
                         let new_id = this.lower_node_id(new_node_id);
@@ -3114,7 +3138,6 @@ impl<'a> LoweringContext<'a> {
                         let vis = respan(vis.span, vis_kind);
 
                         this.insert_item(
-                            new_id.node_id,
                             hir::Item {
                                 hir_id: new_id.hir_id,
                                 ident,
@@ -3174,8 +3197,6 @@ impl<'a> LoweringContext<'a> {
 
                 // Add all the nested `PathListItem`s to the HIR.
                 for &(ref use_tree, id) in trees {
-                    self.allocate_hir_id_counter(id, &use_tree);
-
                     let LoweredNodeId {
                         node_id: new_id,
                         hir_id: new_hir_id,
@@ -3219,7 +3240,6 @@ impl<'a> LoweringContext<'a> {
                         let vis = respan(vis.span, vis_kind);
 
                         this.insert_item(
-                            new_id,
                             hir::Item {
                                 hir_id: new_hir_id,
                                 ident,
@@ -3443,17 +3463,17 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn lower_item_id(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
-        match i.node {
+        let node_ids = match i.node {
             ItemKind::Use(ref use_tree) => {
-                let mut vec = smallvec![hir::ItemId { id: i.id }];
+                let mut vec = smallvec![i.id];
                 self.lower_item_id_use_tree(use_tree, i.id, &mut vec);
                 vec
             }
             ItemKind::MacroDef(..) => SmallVec::new(),
             ItemKind::Fn(..) |
-            ItemKind::Impl(.., None, _, _) => smallvec![hir::ItemId { id: i.id }],
+            ItemKind::Impl(.., None, _, _) => smallvec![i.id],
             ItemKind::Static(ref ty, ..) => {
-                let mut ids = smallvec![hir::ItemId { id: i.id }];
+                let mut ids = smallvec![i.id];
                 if self.sess.features_untracked().impl_trait_in_bindings {
                     let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
                     visitor.visit_ty(ty);
@@ -3461,25 +3481,29 @@ impl<'a> LoweringContext<'a> {
                 ids
             },
             ItemKind::Const(ref ty, ..) => {
-                let mut ids = smallvec![hir::ItemId { id: i.id }];
+                let mut ids = smallvec![i.id];
                 if self.sess.features_untracked().impl_trait_in_bindings {
                     let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
                     visitor.visit_ty(ty);
                 }
                 ids
             },
-            _ => smallvec![hir::ItemId { id: i.id }],
-        }
+            _ => smallvec![i.id],
+        };
+
+        node_ids.into_iter().map(|node_id| hir::ItemId {
+            id: self.allocate_hir_id_counter(node_id).hir_id
+        }).collect()
     }
 
     fn lower_item_id_use_tree(&mut self,
                               tree: &UseTree,
                               base_id: NodeId,
-                              vec: &mut SmallVec<[hir::ItemId; 1]>)
+                              vec: &mut SmallVec<[NodeId; 1]>)
     {
         match tree.kind {
             UseTreeKind::Nested(ref nested_vec) => for &(ref nested, id) in nested_vec {
-                vec.push(hir::ItemId { id });
+                vec.push(id);
                 self.lower_item_id_use_tree(nested, id, vec);
             },
             UseTreeKind::Glob => {}
@@ -3488,7 +3512,7 @@ impl<'a> LoweringContext<'a> {
                                     .skip(1)
                                     .zip([id1, id2].iter())
                 {
-                    vec.push(hir::ItemId { id });
+                    vec.push(id);
                 }
             },
         }
@@ -4604,6 +4628,7 @@ impl<'a> LoweringContext<'a> {
                 let mut ids: SmallVec<[hir::Stmt; 1]> = item_ids
                     .into_iter()
                     .map(|item_id| {
+                        let item_id = hir::ItemId { id: self.lower_node_id(item_id).hir_id };
                         let LoweredNodeId { node_id: _, hir_id } = self.next_id();
 
                         hir::Stmt {
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 2ffb4959951..f906ff9963d 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -609,7 +609,7 @@ impl<'hir> Map<'hir> {
         let module = &self.forest.krate.modules[&node_id];
 
         for id in &module.items {
-            visitor.visit_item(self.expect_item(*id));
+            visitor.visit_item(self.expect_item_by_hir_id(*id));
         }
 
         for id in &module.trait_items {
@@ -1293,7 +1293,7 @@ pub fn map_crate<'hir>(sess: &crate::session::Session,
 impl<'hir> print::PpAnn for Map<'hir> {
     fn nested(&self, state: &mut print::State<'_>, nested: print::Nested) -> io::Result<()> {
         match nested {
-            Nested::Item(id) => state.print_item(self.expect_item(id.id)),
+            Nested::Item(id) => state.print_item(self.expect_item_by_hir_id(id.id)),
             Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
             Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
             Nested::Body(id) => state.print_expr(&self.body(id).value),
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 1bf7eed71bf..8509ddaccf7 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -698,7 +698,7 @@ pub struct WhereEqPredicate {
 pub struct ModuleItems {
     // Use BTreeSets here so items are in the same order as in the
     // list of all items in Crate
-    pub items: BTreeSet<NodeId>,
+    pub items: BTreeSet<HirId>,
     pub trait_items: BTreeSet<TraitItemId>,
     pub impl_items: BTreeSet<ImplItemId>,
 }
@@ -722,7 +722,7 @@ pub struct Crate {
     // does, because it can affect the order in which errors are
     // detected, which in turn can make compile-fail tests yield
     // slightly different results.
-    pub items: BTreeMap<NodeId, Item>,
+    pub items: BTreeMap<HirId, Item>,
 
     pub trait_items: BTreeMap<TraitItemId, TraitItem>,
     pub impl_items: BTreeMap<ImplItemId, ImplItem>,
@@ -741,7 +741,7 @@ pub struct Crate {
 }
 
 impl Crate {
-    pub fn item(&self, id: NodeId) -> &Item {
+    pub fn item(&self, id: HirId) -> &Item {
         &self.items[&id]
     }
 
@@ -2215,7 +2215,7 @@ impl VariantData {
 // so it can fetched later.
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct ItemId {
-    pub id: NodeId,
+    pub id: HirId,
 }
 
 /// An item
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index cdd4043f4bc..0a65473de8f 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -48,7 +48,7 @@ pub trait PpAnn {
     fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) -> io::Result<()> {
         Ok(())
     }
-    fn try_fetch_item(&self, _: ast::NodeId) -> Option<&hir::Item> {
+    fn try_fetch_item(&self, _: hir::HirId) -> Option<&hir::Item> {
         None
     }
 }
@@ -58,7 +58,7 @@ impl PpAnn for NoAnn {}
 pub const NO_ANN: &dyn PpAnn = &NoAnn;
 
 impl PpAnn for hir::Crate {
-    fn try_fetch_item(&self, item: ast::NodeId) -> Option<&hir::Item> {
+    fn try_fetch_item(&self, item: hir::HirId) -> Option<&hir::Item> {
         Some(self.item(item))
     }
     fn nested(&self, state: &mut State<'_>, nested: Nested) -> io::Result<()> {
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index f12367a89bb..0a0a1dee7f0 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -292,7 +292,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
     fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
         match ty.node {
             TyKind::Def(item_id, _) => {
-                let item = self.tcx.hir().expect_item(item_id.id);
+                let item = self.tcx.hir().expect_item_by_hir_id(item_id.id);
                 intravisit::walk_item(self, item);
             }
             _ => ()
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index ab105360388..73e232a6a4f 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -638,7 +638,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 // `abstract type MyAnonTy<'b>: MyTrait<'b>;`
                 //                          ^            ^ this gets resolved in the scope of
                 //                                         the exist_ty generics
-                let (generics, bounds) = match self.tcx.hir().expect_item(item_id.id).node {
+                let (generics, bounds) = match self.tcx.hir().expect_item_by_hir_id(item_id.id).node
+                {
                     // named existential types are reached via TyKind::Path
                     // this arm is for `impl Trait` in the types of statics, constants and locals
                     hir::ItemKind::Existential(hir::ExistTy {
@@ -678,8 +679,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                                 let parent_impl_id = hir::ImplItemId { hir_id: parent_id };
                                 let parent_trait_id = hir::TraitItemId { hir_id: parent_id };
                                 let krate = self.tcx.hir().forest.krate();
-                                let parent_node_id = self.tcx.hir().hir_to_node_id(parent_id);
-                                if !(krate.items.contains_key(&parent_node_id)
+
+                                if !(krate.items.contains_key(&parent_id)
                                     || krate.impl_items.contains_key(&parent_impl_id)
                                     || krate.trait_items.contains_key(&parent_trait_id))
                                 {
diff --git a/src/librustc_codegen_llvm/va_arg.rs b/src/librustc_codegen_llvm/va_arg.rs
index 7aceaea4510..7fc17d17f99 100644
--- a/src/librustc_codegen_llvm/va_arg.rs
+++ b/src/librustc_codegen_llvm/va_arg.rs
@@ -108,12 +108,12 @@ pub(super) fn emit_va_arg(
             emit_ptr_va_arg(bx, addr, target_ty, false,
                             Align::from_bytes(4).unwrap(), true)
         }
-        // Windows Aarch64
+        // Windows AArch64
         ("aarch64", true) => {
             emit_ptr_va_arg(bx, addr, target_ty, false,
                             Align::from_bytes(8).unwrap(), false)
         }
-        // iOS Aarch64
+        // iOS AArch64
         ("aarch64", _) if target.target_os == "ios" => {
             emit_ptr_va_arg(bx, addr, target_ty, false,
                             Align::from_bytes(8).unwrap(), true)
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index e6470dbb61c..244505976b6 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -596,18 +596,6 @@ impl<'a> Linker for MsvcLinker<'a> {
         // This will cause the Microsoft linker to embed .natvis info into the PDB file
         let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc");
         if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
-            // LLVM 5.0.0's lld-link frontend doesn't yet recognize, and chokes
-            // on, the /NATVIS:... flags.  LLVM 6 (or earlier) should at worst ignore
-            // them, eventually mooting this workaround, per this landed patch:
-            // https://github.com/llvm-mirror/lld/commit/27b9c4285364d8d76bb43839daa100
-            if let Some(ref linker_path) = self.sess.opts.cg.linker {
-                if let Some(linker_name) = Path::new(&linker_path).file_stem() {
-                    if linker_name.to_str().unwrap().to_lowercase() == "lld-link" {
-                        self.sess.warn("not embedding natvis: lld-link may not support the flag");
-                        return;
-                    }
-                }
-            }
             for entry in natvis_dir {
                 match entry {
                     Ok(entry) => {
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index fb519407398..f456a5c1619 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -413,6 +413,8 @@ impl<'tcx> EntryKind<'tcx> {
             EntryKind::ForeignFn(_) => Def::Fn(did),
             EntryKind::Method(_) => Def::Method(did),
             EntryKind::Type => Def::TyAlias(did),
+            EntryKind::TypeParam => Def::TyParam(did),
+            EntryKind::ConstParam => Def::ConstParam(did),
             EntryKind::Existential => Def::Existential(did),
             EntryKind::AssociatedType(_) => Def::AssociatedTy(did),
             EntryKind::AssociatedExistential(_) => Def::AssociatedExistential(did),
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 78a186fbb71..9c908176a6d 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -7,6 +7,7 @@ use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
                             EncodedMetadata, ForeignModule};
 use rustc::hir::def::CtorKind;
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId, LOCAL_CRATE};
+use rustc::hir::GenericParamKind;
 use rustc::hir::map::definitions::DefPathTable;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc::middle::dependency_format::Linkage;
@@ -692,7 +693,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             span: self.lazy(&tcx.def_span(def_id)),
             attributes: self.encode_attributes(attrs),
             children: self.lazy_seq(md.item_ids.iter().map(|item_id| {
-                tcx.hir().local_def_id(item_id.id).index
+                tcx.hir().local_def_id_from_hir_id(item_id.id).index
             })),
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
@@ -1352,25 +1353,22 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
         }
     }
 
-    fn encode_info_for_ty_param(&mut self,
-                                (def_id, Untracked(has_default)): (DefId, Untracked<bool>))
-                                -> Entry<'tcx> {
-        debug!("IsolatedEncoder::encode_info_for_ty_param({:?})", def_id);
+    fn encode_info_for_generic_param(
+        &mut self,
+        def_id: DefId,
+        entry_kind: EntryKind<'tcx>,
+        encode_type: bool,
+    ) -> Entry<'tcx> {
         let tcx = self.tcx;
         Entry {
-            kind: EntryKind::Type,
+            kind: entry_kind,
             visibility: self.lazy(&ty::Visibility::Public),
             span: self.lazy(&tcx.def_span(def_id)),
             attributes: LazySeq::empty(),
             children: LazySeq::empty(),
             stability: None,
             deprecation: None,
-
-            ty: if has_default {
-                Some(self.encode_item_type(def_id))
-            } else {
-                None
-            },
+            ty: if encode_type { Some(self.encode_item_type(def_id)) } else { None },
             inherent_impls: LazySeq::empty(),
             variances: LazySeq::empty(),
             generics: None,
@@ -1381,27 +1379,20 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
         }
     }
 
-    fn encode_info_for_const_param(&mut self, def_id: DefId) -> Entry<'tcx> {
-        debug!("IsolatedEncoder::encode_info_for_const_param({:?})", def_id);
-        let tcx = self.tcx;
-        Entry {
-            kind: EntryKind::Type,
-            visibility: self.lazy(&ty::Visibility::Public),
-            span: self.lazy(&tcx.def_span(def_id)),
-            attributes: LazySeq::empty(),
-            children: LazySeq::empty(),
-            stability: None,
-            deprecation: None,
-
-            ty: Some(self.encode_item_type(def_id)),
-            inherent_impls: LazySeq::empty(),
-            variances: LazySeq::empty(),
-            generics: None,
-            predicates: None,
-            predicates_defined_on: None,
+    fn encode_info_for_ty_param(
+        &mut self,
+        (def_id, Untracked(encode_type)): (DefId, Untracked<bool>),
+    ) -> Entry<'tcx> {
+        debug!("IsolatedEncoder::encode_info_for_ty_param({:?})", def_id);
+        self.encode_info_for_generic_param(def_id, EntryKind::TypeParam, encode_type)
+    }
 
-            mir: None,
-        }
+    fn encode_info_for_const_param(
+        &mut self,
+        def_id: DefId,
+    ) -> Entry<'tcx> {
+        debug!("IsolatedEncoder::encode_info_for_const_param({:?})", def_id);
+        self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true)
     }
 
     fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
@@ -1748,18 +1739,18 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
 
     fn encode_info_for_generics(&mut self, generics: &hir::Generics) {
         for param in &generics.params {
+            let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id);
             match param.kind {
-                hir::GenericParamKind::Lifetime { .. } => {}
-                hir::GenericParamKind::Type { ref default, .. } => {
-                    let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id);
-                    let has_default = Untracked(default.is_some());
-                    let encode_info = IsolatedEncoder::encode_info_for_ty_param;
-                    self.record(def_id, encode_info, (def_id, has_default));
+                GenericParamKind::Lifetime { .. } => continue,
+                GenericParamKind::Type { ref default, .. } => {
+                    self.record(
+                        def_id,
+                        IsolatedEncoder::encode_info_for_ty_param,
+                        (def_id, Untracked(default.is_some())),
+                    );
                 }
-                hir::GenericParamKind::Const { .. } => {
-                    let def_id = self.tcx.hir().local_def_id_from_hir_id(param.hir_id);
-                    let encode_info = IsolatedEncoder::encode_info_for_const_param;
-                    self.record(def_id, encode_info, def_id);
+                GenericParamKind::Const { .. } => {
+                    self.record(def_id, IsolatedEncoder::encode_info_for_const_param, def_id);
                 }
             }
         }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 5b6166ebeaf..fe2ea26c327 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -299,6 +299,8 @@ pub enum EntryKind<'tcx> {
     ForeignType,
     GlobalAsm,
     Type,
+    TypeParam,
+    ConstParam,
     Existential,
     Enum(ReprOptions),
     Field,
@@ -335,7 +337,9 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for EntryKind<'gcx> {
             EntryKind::ForeignType      |
             EntryKind::Field |
             EntryKind::Existential |
-            EntryKind::Type => {
+            EntryKind::Type |
+            EntryKind::TypeParam |
+            EntryKind::ConstParam => {
                 // Nothing else to hash here.
             }
             EntryKind::Const(qualif, ref const_data) => {
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index b532e5c94d5..f155beaaff2 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -472,8 +472,8 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
              {
                 if let hir::ItemKind::Mod(m) = &item.node {
                     for item_id in m.item_ids.as_ref() {
-                        let item = self.tcx.hir().expect_item(item_id.id);
-                        let def_id = self.tcx.hir().local_def_id(item_id.id);
+                        let item = self.tcx.hir().expect_item_by_hir_id(item_id.id);
+                        let def_id = self.tcx.hir().local_def_id_from_hir_id(item_id.id);
                         if !self.tcx.hygienic_eq(segment.ident, item.ident, def_id) { continue; }
                         if let hir::ItemKind::Use(..) = item.node {
                             self.update(item.hir_id, Some(AccessLevel::Exported));
@@ -737,8 +737,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
                 unreachable!()
             };
             for id in &module.item_ids {
-                let hir_id = self.tcx.hir().node_to_hir_id(id.id);
-                self.update(hir_id, level);
+                self.update(id.id, level);
             }
             let def_id = self.tcx.hir().local_def_id_from_hir_id(module_id);
             if let Some(exports) = self.tcx.module_exports(def_id) {
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 3e61b175b76..fba4414c127 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1817,7 +1817,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                 self.def_to_ty(opt_self_ty, path, false)
             }
             hir::TyKind::Def(item_id, ref lifetimes) => {
-                let did = tcx.hir().local_def_id(item_id.id);
+                let did = tcx.hir().local_def_id_from_hir_id(item_id.id);
                 self.impl_trait_ty_to_ty(did, lifetimes)
             },
             hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 7b530c69a88..fde0e47650d 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -853,7 +853,7 @@ impl<'a, 'tcx, 'gcx> hir::intravisit::Visitor<'tcx> for UsePlacementFinder<'a, '
         }
         // Find a `use` statement.
         for item_id in &module.item_ids {
-            let item = self.tcx.hir().expect_item(item_id.id);
+            let item = self.tcx.hir().expect_item_by_hir_id(item_id.id);
             match item.node {
                 hir::ItemKind::Use(..) => {
                     // Don't suggest placing a `use` before the prelude
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 31f757c87b2..396488c981d 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -278,16 +278,16 @@ impl Clean<ExternalCrate> for CrateNum {
         };
         let primitives = if root.is_local() {
             cx.tcx.hir().krate().module.item_ids.iter().filter_map(|&id| {
-                let item = cx.tcx.hir().expect_item(id.id);
+                let item = cx.tcx.hir().expect_item_by_hir_id(id.id);
                 match item.node {
                     hir::ItemKind::Mod(_) => {
-                        as_primitive(Def::Mod(cx.tcx.hir().local_def_id(id.id)))
+                        as_primitive(Def::Mod(cx.tcx.hir().local_def_id_from_hir_id(id.id)))
                     }
                     hir::ItemKind::Use(ref path, hir::UseKind::Single)
                     if item.vis.node.is_pub() => {
                         as_primitive(path.def).map(|(_, prim, attrs)| {
                             // Pretend the primitive is local.
-                            (cx.tcx.hir().local_def_id(id.id), prim, attrs)
+                            (cx.tcx.hir().local_def_id_from_hir_id(id.id), prim, attrs)
                         })
                     }
                     _ => None
@@ -320,15 +320,15 @@ impl Clean<ExternalCrate> for CrateNum {
         };
         let keywords = if root.is_local() {
             cx.tcx.hir().krate().module.item_ids.iter().filter_map(|&id| {
-                let item = cx.tcx.hir().expect_item(id.id);
+                let item = cx.tcx.hir().expect_item_by_hir_id(id.id);
                 match item.node {
                     hir::ItemKind::Mod(_) => {
-                        as_keyword(Def::Mod(cx.tcx.hir().local_def_id(id.id)))
+                        as_keyword(Def::Mod(cx.tcx.hir().local_def_id_from_hir_id(id.id)))
                     }
                     hir::ItemKind::Use(ref path, hir::UseKind::Single)
                     if item.vis.node.is_pub() => {
                         as_keyword(path.def).map(|(_, prim, attrs)| {
-                            (cx.tcx.hir().local_def_id(id.id), prim, attrs)
+                            (cx.tcx.hir().local_def_id_from_hir_id(id.id), prim, attrs)
                         })
                     }
                     _ => None
@@ -2762,7 +2762,7 @@ impl Clean<Type> for hir::Ty {
             },
             TyKind::Tup(ref tys) => Tuple(tys.clean(cx)),
             TyKind::Def(item_id, _) => {
-                let item = cx.tcx.hir().expect_item(item_id.id);
+                let item = cx.tcx.hir().expect_item_by_hir_id(item_id.id);
                 if let hir::ItemKind::Existential(ref ty) = item.node {
                     ImplTrait(ty.bounds.clean(cx))
                 } else {
@@ -4393,10 +4393,10 @@ pub fn path_to_def_local(tcx: &TyCtxt<'_, '_, '_>, path: &[&str]) -> Option<DefI
         let segment = path_it.next()?;
 
         for item_id in mem::replace(&mut items, HirVec::new()).iter() {
-            let item = tcx.hir().expect_item(item_id.id);
+            let item = tcx.hir().expect_item_by_hir_id(item_id.id);
             if item.ident.name == *segment {
                 if path_it.peek().is_none() {
-                    return Some(tcx.hir().local_def_id(item_id.id))
+                    return Some(tcx.hir().local_def_id_from_hir_id(item_id.id))
                 }
 
                 items = match &item.node {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index a7e2b2155e9..4991c53ab46 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -247,7 +247,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         let orig_inside_public_path = self.inside_public_path;
         self.inside_public_path &= vis.node.is_pub();
         for i in &m.item_ids {
-            let item = self.cx.tcx.hir().expect_item(i.id);
+            let item = self.cx.tcx.hir().expect_item_by_hir_id(i.id);
             self.visit_item(item, None, &mut om);
         }
         self.inside_public_path = orig_inside_public_path;
@@ -344,7 +344,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             Node::Item(&hir::Item { node: hir::ItemKind::Mod(ref m), .. }) if glob => {
                 let prev = mem::replace(&mut self.inlining, true);
                 for i in &m.item_ids {
-                    let i = self.cx.tcx.hir().expect_item(i.id);
+                    let i = self.cx.tcx.hir().expect_item_by_hir_id(i.id);
                     self.visit_item(i, None, om);
                 }
                 self.inlining = prev;
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 4668e3ec7ea..441f6b95d0b 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -21,6 +21,10 @@ use crate::memchr;
 /// times. It also provides no advantage when reading from a source that is
 /// already in memory, like a `Vec<u8>`.
 ///
+/// When the `BufReader` is dropped, the contents of its buffer will be
+/// discarded. Creating multiple instances of a `BufReader` on the same
+/// stream can cause data loss.
+///
 /// [`Read`]: ../../std/io/trait.Read.html
 /// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read
 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
@@ -350,7 +354,7 @@ impl<R: Seek> Seek for BufReader<R> {
 ///
 /// It can be excessively inefficient to work directly with something that
 /// implements [`Write`]. For example, every call to
-/// [`write`][`Tcpstream::write`] on [`TcpStream`] results in a system call. A
+/// [`write`][`TcpStream::write`] on [`TcpStream`] results in a system call. A
 /// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying
 /// writer in large, infrequent batches.
 ///
@@ -401,7 +405,7 @@ impl<R: Seek> Seek for BufReader<R> {
 /// the `stream` is dropped.
 ///
 /// [`Write`]: ../../std/io/trait.Write.html
-/// [`Tcpstream::write`]: ../../std/net/struct.TcpStream.html#method.write
+/// [`TcpStream::write`]: ../../std/net/struct.TcpStream.html#method.write
 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
 /// [`flush`]: #method.flush
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index bef6bc92661..7b0d1549e06 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -286,11 +286,16 @@ mod fn_keyword { }
 //
 /// The `for` keyword.
 ///
-/// `for` is primarily used in for-in-loops, but it has a few other pieces of syntactic uses such as
-/// `impl Trait for Type` (see [`impl`] for more info on that). for-in-loops, or to be more
-/// precise, iterator loops, are a simple syntactic sugar over an exceedingly common practice
-/// within Rust, which is to loop over an iterator until that iterator returns `None` (or `break`
-/// is called).
+/// The `for` keyword is used in many syntactic locations:
+///
+/// * `for` is used in for-in-loops (see below).
+/// * `for` is used when implementing traits as in `impl Trait for Type` (see [`impl`] for more info
+///   on that).
+/// * `for` is also used for [higher-ranked trait bounds] as in `for<'a> &'a T: PartialEq<i32>`.
+///
+/// for-in-loops, or to be more precise, iterator loops, are a simple syntactic sugar over a common
+/// practice within Rust, which is to loop over an iterator until that iterator returns `None` (or
+/// `break` is called).
 ///
 /// ```rust
 /// for i in 0..5 {
@@ -347,6 +352,8 @@ mod fn_keyword { }
 /// For more information on for-loops, see the [Rust book] or the [Reference].
 ///
 /// [`impl`]: keyword.impl.html
+/// [higher-ranked trait bounds]:
+/// https://doc.rust-lang.org/nightly/reference/trait-bounds.html#higher-ranked-trait-bounds
 /// [`IntoIterator`]: iter/trait.IntoIterator.html
 /// [Rust book]:
 /// https://doc.rust-lang.org/book/2018-edition/ch03-05-control-flow.html#looping-through-a-collection-with-for
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index d5dc5f7c4f0..d5afd069d7f 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -4,7 +4,7 @@
 //! library. Each macro is available for use when linking against the standard
 //! library.
 
-/// The entry point for panic of Rust threads.
+/// Panics the current thread.
 ///
 /// This allows a program to terminate immediately and provide feedback
 /// to the caller of the program. `panic!` should be used when a program reaches
@@ -70,7 +70,7 @@ macro_rules! panic {
     });
 }
 
-/// Macro for printing to the standard output.
+/// Prints to the standard output.
 ///
 /// Equivalent to the [`println!`] macro except that a newline is not printed at
 /// the end of the message.
@@ -116,7 +116,7 @@ macro_rules! print {
     ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
 }
 
-/// Macro for printing to the standard output, with a newline.
+/// Prints to the standard output, with a newline.
 ///
 /// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
 /// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
@@ -151,7 +151,7 @@ macro_rules! println {
     })
 }
 
-/// Macro for printing to the standard error.
+/// Prints to the standard error.
 ///
 /// Equivalent to the [`print!`] macro, except that output goes to
 /// [`io::stderr`] instead of `io::stdout`. See [`print!`] for
@@ -179,7 +179,7 @@ macro_rules! eprint {
     ($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*)));
 }
 
-/// Macro for printing to the standard error, with a newline.
+/// Prints to the standard error, with a newline.
 ///
 /// Equivalent to the [`println!`] macro, except that output goes to
 /// [`io::stderr`] instead of `io::stdout`. See [`println!`] for
@@ -210,8 +210,10 @@ macro_rules! eprintln {
     })
 }
 
-/// A macro for quick and dirty debugging with which you can inspect
-/// the value of a given expression. An example:
+/// Prints and returns the value of a given expression for quick and dirty
+/// debugging.
+///
+/// An example:
 ///
 /// ```rust
 /// let a = 2;
@@ -328,7 +330,7 @@ macro_rules! dbg {
     }
 }
 
-/// A macro to await on an async call.
+/// Awaits the completion of an async call.
 #[macro_export]
 #[unstable(feature = "await_macro", issue = "50547")]
 #[allow_internal_unstable(gen_future, generators)]
@@ -351,7 +353,7 @@ macro_rules! r#await {
     } }
 }
 
-/// A macro to select an event from a number of receivers.
+/// Selects the first successful receive event from a number of receivers.
 ///
 /// This macro is used to wait for the first event to occur on a number of
 /// receivers. It places no restrictions on the types of receivers given to
@@ -423,7 +425,7 @@ macro_rules! assert_approx_eq {
 #[cfg(rustdoc)]
 mod builtin {
 
-    /// Unconditionally causes compilation to fail with the given error message when encountered.
+    /// Causes compilation to fail with the given error message when encountered.
     ///
     /// This macro should be used when a crate uses a conditional compilation strategy to provide
     /// better error messages for erroneous conditions. It's the compiler-level form of [`panic!`],
@@ -465,7 +467,7 @@ mod builtin {
         ($msg:expr,) => ({ /* compiler built-in */ });
     }
 
-    /// The core macro for formatted string creation & output.
+    /// Constructs parameters for the other string-formatting macros.
     ///
     /// This macro functions by taking a formatting string literal containing
     /// `{}` for each additional argument passed. `format_args!` prepares the
@@ -517,7 +519,7 @@ mod builtin {
         ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
     }
 
-    /// Inspect an environment variable at compile time.
+    /// Inspects an environment variable at compile time.
     ///
     /// This macro will expand to the value of the named environment variable at
     /// compile time, yielding an expression of type `&'static str`.
@@ -555,7 +557,7 @@ mod builtin {
         ($name:expr,) => ({ /* compiler built-in */ });
     }
 
-    /// Optionally inspect an environment variable at compile time.
+    /// Optionally inspects an environment variable at compile time.
     ///
     /// If the named environment variable is present at compile time, this will
     /// expand into an expression of type `Option<&'static str>` whose value is
@@ -581,7 +583,7 @@ mod builtin {
         ($name:expr,) => ({ /* compiler built-in */ });
     }
 
-    /// Concatenate identifiers into one identifier.
+    /// Concatenates identifiers into one identifier.
     ///
     /// This macro takes any number of comma-separated identifiers, and
     /// concatenates them all into one, yielding an expression which is a new
@@ -634,7 +636,7 @@ mod builtin {
         ($($e:expr,)*) => ({ /* compiler built-in */ });
     }
 
-    /// A macro which expands to the line number on which it was invoked.
+    /// Expands to the line number on which it was invoked.
     ///
     /// With [`column!`] and [`file!`], these macros provide debugging information for
     /// developers about the location within the source.
@@ -659,7 +661,7 @@ mod builtin {
     #[rustc_doc_only_macro]
     macro_rules! line { () => ({ /* compiler built-in */ }) }
 
-    /// A macro which expands to the column number on which it was invoked.
+    /// Expands to the column number at which it was invoked.
     ///
     /// With [`line!`] and [`file!`], these macros provide debugging information for
     /// developers about the location within the source.
@@ -684,7 +686,7 @@ mod builtin {
     #[rustc_doc_only_macro]
     macro_rules! column { () => ({ /* compiler built-in */ }) }
 
-    /// A macro which expands to the file name from which it was invoked.
+    /// Expands to the file name in which it was invoked.
     ///
     /// With [`line!`] and [`column!`], these macros provide debugging information for
     /// developers about the location within the source.
@@ -708,7 +710,7 @@ mod builtin {
     #[rustc_doc_only_macro]
     macro_rules! file { () => ({ /* compiler built-in */ }) }
 
-    /// A macro which stringifies its arguments.
+    /// Stringifies its arguments.
     ///
     /// This macro will yield an expression of type `&'static str` which is the
     /// stringification of all the tokens passed to the macro. No restrictions
@@ -822,7 +824,7 @@ mod builtin {
     #[rustc_doc_only_macro]
     macro_rules! module_path { () => ({ /* compiler built-in */ }) }
 
-    /// Boolean evaluation of configuration flags, at compile-time.
+    /// Evaluates boolean combinations of configuration flags at compile-time.
     ///
     /// In addition to the `#[cfg]` attribute, this macro is provided to allow
     /// boolean expression evaluation of configuration flags. This frequently
@@ -844,7 +846,7 @@ mod builtin {
     #[rustc_doc_only_macro]
     macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) }
 
-    /// Parse a file as an expression or an item according to the context.
+    /// Parses a file as an expression or an item according to the context.
     ///
     /// The file is located relative to the current file (similarly to how
     /// modules are found).
@@ -890,7 +892,7 @@ mod builtin {
         ($file:expr,) => ({ /* compiler built-in */ });
     }
 
-    /// Ensure that a boolean expression is `true` at runtime.
+    /// Asserts that a boolean expression is `true` at runtime.
     ///
     /// This will invoke the [`panic!`] macro if the provided expression cannot be
     /// evaluated to `true` at runtime.
@@ -944,7 +946,7 @@ mod builtin {
     }
 }
 
-/// A macro for defining `#[cfg]` if-else statements.
+/// Defines `#[cfg]` if-else statements.
 ///
 /// This is similar to the `if/elif` C preprocessor macro by allowing definition
 /// of a cascade of `#[cfg]` cases, emitting the implementation which matches
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 7ff098bc9e1..c73f7983146 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -827,30 +827,54 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
     Ok(PathBuf::from(OsString::from_vec(buf)))
 }
 
+fn open_and_set_permissions(
+    from: &Path,
+    to: &Path,
+) -> io::Result<(crate::fs::File, crate::fs::File, u64, crate::fs::Metadata)> {
+    use crate::fs::{File, OpenOptions};
+    use crate::os::unix::fs::{OpenOptionsExt, PermissionsExt};
+
+    let reader = File::open(from)?;
+    let (perm, len) = {
+        let metadata = reader.metadata()?;
+        if !metadata.is_file() {
+            return Err(Error::new(
+                ErrorKind::InvalidInput,
+                "the source path is not an existing regular file",
+            ));
+        }
+        (metadata.permissions(), metadata.len())
+    };
+    let writer = OpenOptions::new()
+        // create the file with the correct mode right away
+        .mode(perm.mode())
+        .write(true)
+        .create(true)
+        .truncate(true)
+        .open(to)?;
+    let writer_metadata = writer.metadata()?;
+    if writer_metadata.is_file() {
+        // Set the correct file permissions, in case the file already existed.
+        // Don't set the permissions on already existing non-files like
+        // pipes/FIFOs or device nodes.
+        writer.set_permissions(perm)?;
+    }
+    Ok((reader, writer, len, writer_metadata))
+}
+
 #[cfg(not(any(target_os = "linux",
               target_os = "android",
               target_os = "macos",
               target_os = "ios")))]
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
-    use crate::fs::File;
-    if !from.is_file() {
-        return Err(Error::new(ErrorKind::InvalidInput,
-                              "the source path is not an existing regular file"))
-    }
+    let (mut reader, mut writer, _, _) = open_and_set_permissions(from, to)?;
 
-    let mut reader = File::open(from)?;
-    let mut writer = File::create(to)?;
-    let perm = reader.metadata()?.permissions();
-
-    let ret = io::copy(&mut reader, &mut writer)?;
-    writer.set_permissions(perm)?;
-    Ok(ret)
+    io::copy(&mut reader, &mut writer)
 }
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     use crate::cmp;
-    use crate::fs::File;
     use crate::sync::atomic::{AtomicBool, Ordering};
 
     // Kernel prior to 4.5 don't have copy_file_range
@@ -876,17 +900,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
         )
     }
 
-    if !from.is_file() {
-        return Err(Error::new(ErrorKind::InvalidInput,
-                              "the source path is not an existing regular file"))
-    }
-
-    let mut reader = File::open(from)?;
-    let mut writer = File::create(to)?;
-    let (perm, len) = {
-        let metadata = reader.metadata()?;
-        (metadata.permissions(), metadata.size())
-    };
+    let (mut reader, mut writer, len, _) = open_and_set_permissions(from, to)?;
 
     let has_copy_file_range = HAS_COPY_FILE_RANGE.load(Ordering::Relaxed);
     let mut written = 0u64;
@@ -896,13 +910,14 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
             let copy_result = unsafe {
                 // We actually don't have to adjust the offsets,
                 // because copy_file_range adjusts the file offset automatically
-                cvt(copy_file_range(reader.as_raw_fd(),
-                                    ptr::null_mut(),
-                                    writer.as_raw_fd(),
-                                    ptr::null_mut(),
-                                    bytes_to_copy,
-                                    0)
-                    )
+                cvt(copy_file_range(
+                    reader.as_raw_fd(),
+                    ptr::null_mut(),
+                    writer.as_raw_fd(),
+                    ptr::null_mut(),
+                    bytes_to_copy,
+                    0,
+                ))
             };
             if let Err(ref copy_err) = copy_result {
                 match copy_err.raw_os_error() {
@@ -920,24 +935,25 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
             Ok(ret) => written += ret as u64,
             Err(err) => {
                 match err.raw_os_error() {
-                    Some(os_err) if os_err == libc::ENOSYS
-                                 || os_err == libc::EXDEV
-                                 || os_err == libc::EPERM => {
-                        // Try fallback io::copy if either:
-                        // - Kernel version is < 4.5 (ENOSYS)
-                        // - Files are mounted on different fs (EXDEV)
-                        // - copy_file_range is disallowed, for example by seccomp (EPERM)
-                        assert_eq!(written, 0);
-                        let ret = io::copy(&mut reader, &mut writer)?;
-                        writer.set_permissions(perm)?;
-                        return Ok(ret)
-                    },
+                    Some(os_err)
+                    if os_err == libc::ENOSYS
+                        || os_err == libc::EXDEV
+                        || os_err == libc::EINVAL
+                        || os_err == libc::EPERM =>
+                        {
+                            // Try fallback io::copy if either:
+                            // - Kernel version is < 4.5 (ENOSYS)
+                            // - Files are mounted on different fs (EXDEV)
+                            // - copy_file_range is disallowed, for example by seccomp (EPERM)
+                            // - copy_file_range cannot be used with pipes or device nodes (EINVAL)
+                            assert_eq!(written, 0);
+                            return io::copy(&mut reader, &mut writer);
+                        }
                     _ => return Err(err),
                 }
             }
         }
     }
-    writer.set_permissions(perm)?;
     Ok(written)
 }
 
@@ -960,9 +976,9 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     type copyfile_flags_t = u32;
 
     extern "C" {
-        fn copyfile(
-            from: *const libc::c_char,
-            to: *const libc::c_char,
+        fn fcopyfile(
+            from: libc::c_int,
+            to: libc::c_int,
             state: copyfile_state_t,
             flags: copyfile_flags_t,
         ) -> libc::c_int;
@@ -988,10 +1004,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
         }
     }
 
-    if !from.is_file() {
-        return Err(Error::new(ErrorKind::InvalidInput,
-                              "the source path is not an existing regular file"))
-    }
+    let (reader, writer, _, writer_metadata) = open_and_set_permissions(from, to)?;
 
     // We ensure that `FreeOnDrop` never contains a null pointer so it is
     // always safe to call `copyfile_state_free`
@@ -1003,12 +1016,18 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
         FreeOnDrop(state)
     };
 
+    let flags = if writer_metadata.is_file() {
+        COPYFILE_ALL
+    } else {
+        COPYFILE_DATA
+    };
+
     cvt(unsafe {
-        copyfile(
-            cstr(from)?.as_ptr(),
-            cstr(to)?.as_ptr(),
+        fcopyfile(
+            reader.as_raw_fd(),
+            writer.as_raw_fd(),
             state.0,
-            COPYFILE_ALL,
+            flags,
         )
     })?;
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index d3eadfeceb2..79c1f0cb4cc 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -4734,7 +4734,7 @@ impl<'a> Parser<'a> {
                         let (fields, etc) = self.parse_pat_fields().unwrap_or_else(|mut e| {
                             e.emit();
                             self.recover_stmt();
-                            (vec![], false)
+                            (vec![], true)
                         });
                         self.bump();
                         pat = PatKind::Struct(path, fields, etc);
diff --git a/src/test/run-pass/paths-containing-nul.rs b/src/test/run-pass/paths-containing-nul.rs
index 8c800089d1c..dfcef59aa57 100644
--- a/src/test/run-pass/paths-containing-nul.rs
+++ b/src/test/run-pass/paths-containing-nul.rs
@@ -1,6 +1,7 @@
 #![allow(deprecated)]
 // ignore-cloudabi no files or I/O
 // ignore-wasm32-bare no files or I/O
+// ignore-emscripten no files
 
 use std::fs;
 use std::io;
@@ -22,14 +23,18 @@ fn main() {
     assert_invalid_input("remove_file", fs::remove_file("\0"));
     assert_invalid_input("metadata", fs::metadata("\0"));
     assert_invalid_input("symlink_metadata", fs::symlink_metadata("\0"));
+
+    // If `dummy_file` does not exist, then we might get another unrelated error
+    let dummy_file = std::env::current_exe().unwrap();
+
     assert_invalid_input("rename1", fs::rename("\0", "a"));
-    assert_invalid_input("rename2", fs::rename("a", "\0"));
+    assert_invalid_input("rename2", fs::rename(&dummy_file, "\0"));
     assert_invalid_input("copy1", fs::copy("\0", "a"));
-    assert_invalid_input("copy2", fs::copy("a", "\0"));
+    assert_invalid_input("copy2", fs::copy(&dummy_file, "\0"));
     assert_invalid_input("hard_link1", fs::hard_link("\0", "a"));
-    assert_invalid_input("hard_link2", fs::hard_link("a", "\0"));
+    assert_invalid_input("hard_link2", fs::hard_link(&dummy_file, "\0"));
     assert_invalid_input("soft_link1", fs::soft_link("\0", "a"));
-    assert_invalid_input("soft_link2", fs::soft_link("a", "\0"));
+    assert_invalid_input("soft_link2", fs::soft_link(&dummy_file, "\0"));
     assert_invalid_input("read_link", fs::read_link("\0"));
     assert_invalid_input("canonicalize", fs::canonicalize("\0"));
     assert_invalid_input("create_dir", fs::create_dir("\0"));
diff --git a/src/test/ui/parser/bind-struct-early-modifiers.rs b/src/test/ui/parser/bind-struct-early-modifiers.rs
index c1de0df54e2..c4b1937de10 100644
--- a/src/test/ui/parser/bind-struct-early-modifiers.rs
+++ b/src/test/ui/parser/bind-struct-early-modifiers.rs
@@ -2,7 +2,6 @@ fn main() {
     struct Foo { x: isize }
     match (Foo { x: 10 }) {
         Foo { ref x: ref x } => {}, //~ ERROR expected `,`
-                                    //~| ERROR pattern does not mention field `x`
         _ => {}
     }
 }
diff --git a/src/test/ui/parser/bind-struct-early-modifiers.stderr b/src/test/ui/parser/bind-struct-early-modifiers.stderr
index 50c95b8cf40..03482a41f54 100644
--- a/src/test/ui/parser/bind-struct-early-modifiers.stderr
+++ b/src/test/ui/parser/bind-struct-early-modifiers.stderr
@@ -4,12 +4,5 @@ error: expected `,`
 LL |         Foo { ref x: ref x } => {},
    |                   ^
 
-error[E0027]: pattern does not mention field `x`
-  --> $DIR/bind-struct-early-modifiers.rs:4:9
-   |
-LL |         Foo { ref x: ref x } => {},
-   |         ^^^^^^^^^^^^^^^^^^^^ missing field `x`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0027`.
diff --git a/src/test/ui/parser/issue-10392.rs b/src/test/ui/parser/issue-10392.rs
index dd84af39300..5b0c2fc2be4 100644
--- a/src/test/ui/parser/issue-10392.rs
+++ b/src/test/ui/parser/issue-10392.rs
@@ -4,5 +4,4 @@ fn a() -> A { panic!() }
 
 fn main() {
     let A { , } = a(); //~ ERROR expected ident
-                       //~| ERROR pattern does not mention field `foo`
 }
diff --git a/src/test/ui/parser/issue-10392.stderr b/src/test/ui/parser/issue-10392.stderr
index 7bf5aa93f0a..34991151c1e 100644
--- a/src/test/ui/parser/issue-10392.stderr
+++ b/src/test/ui/parser/issue-10392.stderr
@@ -4,12 +4,5 @@ error: expected identifier, found `,`
 LL |     let A { , } = a();
    |             ^ expected identifier
 
-error[E0027]: pattern does not mention field `foo`
-  --> $DIR/issue-10392.rs:6:9
-   |
-LL |     let A { , } = a();
-   |         ^^^^^^^ missing field `foo`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0027`.
diff --git a/src/test/ui/resolve/issue-54379.rs b/src/test/ui/resolve/issue-54379.rs
index a48f66bf0fd..807c54393f2 100644
--- a/src/test/ui/resolve/issue-54379.rs
+++ b/src/test/ui/resolve/issue-54379.rs
@@ -6,7 +6,7 @@ fn main() {
     let thing = MyStruct { s1: None };
 
     match thing {
-        MyStruct { .., Some(_) } => {}, //~ ERROR pattern does not mention field `s1`
+        MyStruct { .., Some(_) } => {},
         //~^ ERROR expected `,`
         //~| ERROR expected `}`, found `,`
         _ => {}
diff --git a/src/test/ui/resolve/issue-54379.stderr b/src/test/ui/resolve/issue-54379.stderr
index 60a6f904610..2a6b54572de 100644
--- a/src/test/ui/resolve/issue-54379.stderr
+++ b/src/test/ui/resolve/issue-54379.stderr
@@ -13,12 +13,5 @@ error: expected `,`
 LL |         MyStruct { .., Some(_) } => {},
    |                        ^^^^
 
-error[E0027]: pattern does not mention field `s1`
-  --> $DIR/issue-54379.rs:9:9
-   |
-LL |         MyStruct { .., Some(_) } => {},
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ missing field `s1`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0027`.
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index faeeea605a2..04986b59ea0 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -27,9 +27,10 @@ enum OutputFormat {
 }
 
 impl OutputFormat {
-    fn from(format: &str) -> OutputFormat {
+    fn from(format: &str, resource_suffix: &str) -> OutputFormat {
         match &*format.to_lowercase() {
-            "html"     => OutputFormat::HTML(HTMLFormatter(RefCell::new(IdMap::new()))),
+            "html"     => OutputFormat::HTML(HTMLFormatter(RefCell::new(IdMap::new()),
+                                                           resource_suffix.to_owned())),
             "markdown" => OutputFormat::Markdown(MarkdownFormatter),
             s          => OutputFormat::Unknown(s.to_owned()),
         }
@@ -44,7 +45,7 @@ trait Formatter {
     fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
 }
 
-struct HTMLFormatter(RefCell<IdMap>);
+struct HTMLFormatter(RefCell<IdMap>, String);
 struct MarkdownFormatter;
 
 impl Formatter for HTMLFormatter {
@@ -55,7 +56,7 @@ impl Formatter for HTMLFormatter {
 <title>Rust Compiler Error Index</title>
 <meta charset="utf-8">
 <!-- Include rust.css after light.css so its rules take priority. -->
-<link rel="stylesheet" type="text/css" href="light.css"/>
+<link rel="stylesheet" type="text/css" href="light{suffix}.css"/>
 <link rel="stylesheet" type="text/css" href="rust.css"/>
 <style>
 .error-undescribed {{
@@ -64,7 +65,7 @@ impl Formatter for HTMLFormatter {
 </style>
 </head>
 <body>
-"##)?;
+"##, suffix=self.1)?;
         Ok(())
     }
 
@@ -242,9 +243,12 @@ fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Erro
 
 fn parse_args() -> (OutputFormat, PathBuf) {
     let mut args = env::args().skip(1);
-    let format = args.next().map(|a| OutputFormat::from(&a))
-                            .unwrap_or(OutputFormat::from("html"));
-    let dst = args.next().map(PathBuf::from).unwrap_or_else(|| {
+    let format = args.next();
+    let dst = args.next();
+    let resource_suffix = args.next().unwrap_or_else(String::new);
+    let format = format.map(|a| OutputFormat::from(&a, &resource_suffix))
+                       .unwrap_or(OutputFormat::from("html", &resource_suffix));
+    let dst = dst.map(PathBuf::from).unwrap_or_else(|| {
         match format {
             OutputFormat::HTML(..) => PathBuf::from("doc/error-index.html"),
             OutputFormat::Markdown(..) => PathBuf::from("doc/error-index.md"),