about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/bootstrap/builder.rs2
-rw-r--r--src/bootstrap/flags.rs15
-rw-r--r--src/bootstrap/test.rs4
-rw-r--r--src/libcore/ffi.rs2
-rw-r--r--src/libcore/num/mod.rs24
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/libcore/tests/nonzero.rs26
-rw-r--r--src/librustc/dep_graph/dep_node.rs78
-rw-r--r--src/librustc/dep_graph/graph.rs41
-rw-r--r--src/librustc/hir/map/mod.rs2
-rw-r--r--src/librustc/middle/dead.rs4
-rw-r--r--src/librustc/middle/expr_use_visitor.rs3
-rw-r--r--src/librustc/middle/reachable.rs2
-rw-r--r--src/librustc/session/config.rs12
-rw-r--r--src/librustc/ty/context.rs9
-rw-r--r--src/librustc/ty/query/plumbing.rs10
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs3
-rw-r--r--src/librustc_codegen_ssa/back/link.rs19
-rw-r--r--src/librustc_codegen_ssa/back/linker.rs77
-rw-r--r--src/librustc_lint/unused.rs2
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs47
-rw-r--r--src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs18
-rw-r--r--src/librustc_mir/hair/cx/expr.rs6
-rw-r--r--src/librustc_passes/rvalue_promotion.rs3
-rw-r--r--src/librustc_privacy/lib.rs6
-rw-r--r--src/librustc_save_analysis/lib.rs4
-rw-r--r--src/librustc_target/spec/mod.rs1
-rw-r--r--src/librustc_target/spec/wasm32_base.rs123
-rw-r--r--src/librustc_target/spec/wasm32_unknown_unknown.rs80
-rw-r--r--src/librustc_typeck/check/mod.rs4
-rw-r--r--src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs2
-rw-r--r--src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-doc-alias-ice.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-link-span-ice-55723.stderr2
-rw-r--r--src/test/rustdoc-ui/intra-links-warning-crlf.stderr8
-rw-r--r--src/test/rustdoc-ui/intra-links-warning.stderr44
-rw-r--r--src/test/rustdoc-ui/invalid-syntax.stderr22
-rw-r--r--src/test/rustdoc-ui/lint-group.stderr2
-rw-r--r--src/test/ui/augmented-assignments.nll.stderr17
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-4.rs2
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-4.stderr22
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-5.rs2
-rw-r--r--src/test/ui/c-variadic/variadic-ffi-5.stderr12
-rw-r--r--src/test/ui/cast_char.stderr4
-rw-r--r--src/test/ui/error-codes/E0648.stderr2
-rw-r--r--src/test/ui/fmt/format-string-error-2.stderr50
-rw-r--r--src/test/ui/fmt/format-string-error.stderr6
-rw-r--r--src/test/ui/issues/issue-13727.stderr2
-rw-r--r--src/test/ui/macros/format-foreign.stderr8
-rw-r--r--src/test/ui/macros/macro-backtrace-println.stderr2
-rw-r--r--src/test/ui/parser/ascii-only-character-escape.stderr12
-rw-r--r--src/test/ui/parser/bad-char-literals.stderr6
-rw-r--r--src/test/ui/parser/byte-literals.stderr10
-rw-r--r--src/test/ui/parser/byte-string-literals.stderr8
-rw-r--r--src/test/ui/parser/issue-23620-invalid-escapes.stderr46
-rw-r--r--src/test/ui/parser/issue-43692.stderr2
-rw-r--r--src/test/ui/parser/lex-bad-char-literals-1.stderr12
-rw-r--r--src/test/ui/parser/lex-bad-char-literals-5.stderr8
-rw-r--r--src/test/ui/parser/lex-bad-token.stderr2
-rw-r--r--src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr8
-rw-r--r--src/test/ui/parser/lex-stray-backslash.stderr4
-rw-r--r--src/test/ui/parser/new-unicode-escapes-1.stderr2
-rw-r--r--src/test/ui/parser/new-unicode-escapes-2.stderr2
-rw-r--r--src/test/ui/parser/new-unicode-escapes-3.stderr4
-rw-r--r--src/test/ui/parser/new-unicode-escapes-4.stderr2
-rw-r--r--src/test/ui/parser/raw-byte-string-literals.stderr2
-rw-r--r--src/test/ui/parser/trailing-carriage-return-in-string.stderr4
-rw-r--r--src/test/ui/parser/unicode-chars.stderr2
-rw-r--r--src/test/ui/parser/unicode-quote-chars.stderr2
-rw-r--r--src/test/ui/parser/wrong-escape-of-curly-braces.stderr4
-rw-r--r--src/test/ui/regions/region-bound-on-closure-outlives-call.nll.stderr9
-rw-r--r--src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr1
-rw-r--r--src/test/ui/suggestions/borrow-for-loop-head.nll.stderr9
-rw-r--r--src/tools/compiletest/src/common.rs5
-rw-r--r--src/tools/compiletest/src/main.rs20
-rw-r--r--src/tools/compiletest/src/runtest.rs130
76 files changed, 714 insertions, 443 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index f93f3e72f83..7851ea3e363 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1856,6 +1856,7 @@ mod __test {
             doc_tests: DocTests::No,
             bless: false,
             compare_mode: None,
+            rustfix_coverage: false,
         };
 
         let build = Build::new(config);
@@ -1897,6 +1898,7 @@ mod __test {
             doc_tests: DocTests::No,
             bless: false,
             compare_mode: None,
+            rustfix_coverage: false,
         };
 
         let build = Build::new(config);
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 0f9a4271ac0..a1f89d6c86f 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -56,6 +56,7 @@ pub enum Subcommand {
         rustc_args: Vec<String>,
         fail_fast: bool,
         doc_tests: DocTests,
+        rustfix_coverage: bool,
     },
     Bench {
         paths: Vec<PathBuf>,
@@ -188,6 +189,12 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`"
                     "mode describing what file the actual ui output will be compared to",
                     "COMPARE MODE",
                 );
+                opts.optflag(
+                    "",
+                    "rustfix-coverage",
+                    "enable this to generate a Rustfix coverage file, which is saved in \
+                        `/<build_base>/rustfix_missing_coverage.txt`",
+                );
             }
             "bench" => {
                 opts.optmulti("", "test-args", "extra arguments", "ARGS");
@@ -363,6 +370,7 @@ Arguments:
                 test_args: matches.opt_strs("test-args"),
                 rustc_args: matches.opt_strs("rustc-args"),
                 fail_fast: !matches.opt_present("no-fail-fast"),
+                rustfix_coverage: matches.opt_present("rustfix-coverage"),
                 doc_tests: if matches.opt_present("doc") {
                     DocTests::Only
                 } else if matches.opt_present("no-doc") {
@@ -467,6 +475,13 @@ impl Subcommand {
         }
     }
 
+    pub fn rustfix_coverage(&self) -> bool {
+        match *self {
+            Subcommand::Test { rustfix_coverage, .. } => rustfix_coverage,
+            _ => false,
+        }
+    }
+
     pub fn compare_mode(&self) -> Option<&str> {
         match *self {
             Subcommand::Test {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index bbe1872d395..41c73f307b6 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1284,6 +1284,10 @@ impl Step for Compiletest {
             cmd.arg("--android-cross-path").arg("");
         }
 
+        if builder.config.cmd.rustfix_coverage() {
+            cmd.arg("--rustfix-coverage");
+        }
+
         builder.ci_env.force_coloring_in_ci(&mut cmd);
 
         let _folder = builder.fold_output(|| format!("test_{}", suite));
diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs
index 231a1f199bd..89671060964 100644
--- a/src/libcore/ffi.rs
+++ b/src/libcore/ffi.rs
@@ -190,7 +190,7 @@ impl<'a> VaList<'a> {
                reason = "the `c_variadic` feature has not been properly tested on \
                          all supported platforms",
                issue = "44930")]
-    pub unsafe fn copy<F, R>(&self, f: F) -> R
+    pub unsafe fn with_copy<F, R>(&self, f: F) -> R
             where F: for<'copy> FnOnce(VaList<'copy>) -> R {
         #[cfg(any(all(not(target_arch = "aarch64"), not(target_arch = "powerpc"),
                       not(target_arch = "x86_64")),
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 3fcae6b94b0..01da5518868 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -112,6 +112,24 @@ nonzero_integers! {
     #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
 }
 
+macro_rules! from_str_radix_nzint_impl {
+    ($($t:ty)*) => {$(
+        #[stable(feature = "nonzero_parse", since = "1.35.0")]
+        impl FromStr for $t {
+            type Err = ParseIntError;
+            fn from_str(src: &str) -> Result<Self, Self::Err> {
+                Self::new(from_str_radix(src, 10)?)
+                    .ok_or(ParseIntError {
+                        kind: IntErrorKind::Zero
+                    })
+            }
+        }
+    )*}
+}
+
+from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
+                             NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
+
 /// Provides intentionally-wrapped arithmetic on `T`.
 ///
 /// Operations like `+` on `u32` values is intended to never overflow,
@@ -4768,6 +4786,11 @@ pub enum IntErrorKind {
     Overflow,
     /// Integer is too small to store in target integer type.
     Underflow,
+    /// Value was Zero
+    ///
+    /// This variant will be emitted when the parsing string has a value of zero, which
+    /// would be illegal for non-zero types.
+    Zero,
 }
 
 impl ParseIntError {
@@ -4790,6 +4813,7 @@ impl ParseIntError {
             IntErrorKind::InvalidDigit => "invalid digit found in string",
             IntErrorKind::Overflow => "number too large to fit in target type",
             IntErrorKind::Underflow => "number too small to fit in target type",
+            IntErrorKind::Zero => "number would be zero for non-zero type",
         }
     }
 }
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 08dda4bcc3d..2ed25a34102 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -31,6 +31,7 @@
 #![feature(slice_internals)]
 #![feature(slice_partition_dedup)]
 #![feature(copy_within)]
+#![feature(int_error_matching)]
 
 extern crate core;
 extern crate test;
diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs
index 4532568ee0c..77e484601bc 100644
--- a/src/libcore/tests/nonzero.rs
+++ b/src/libcore/tests/nonzero.rs
@@ -1,6 +1,5 @@
-use core::num::{NonZeroU32, NonZeroI32};
-use core::option::Option;
-use core::option::Option::{Some, None};
+use core::num::{IntErrorKind, NonZeroI32, NonZeroI8, NonZeroU32, NonZeroU8};
+use core::option::Option::{self, None, Some};
 use std::mem::size_of;
 
 #[test]
@@ -126,3 +125,24 @@ fn test_from_signed_nonzero() {
     let num: i32 = nz.into();
     assert_eq!(num, 1i32);
 }
+
+#[test]
+fn test_from_str() {
+    assert_eq!("123".parse::<NonZeroU8>(), Ok(NonZeroU8::new(123).unwrap()));
+    assert_eq!(
+        "0".parse::<NonZeroU8>().err().map(|e| e.kind().clone()),
+        Some(IntErrorKind::Zero)
+    );
+    assert_eq!(
+        "-1".parse::<NonZeroU8>().err().map(|e| e.kind().clone()),
+        Some(IntErrorKind::InvalidDigit)
+    );
+    assert_eq!(
+        "-129".parse::<NonZeroI8>().err().map(|e| e.kind().clone()),
+        Some(IntErrorKind::Underflow)
+    );
+    assert_eq!(
+        "257".parse::<NonZeroU8>().err().map(|e| e.kind().clone()),
+        Some(IntErrorKind::Overflow)
+    );
+}
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 9c6d03af9f5..1f4f7d34424 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -85,11 +85,6 @@ macro_rules! is_anon_attr {
     ($attr:ident) => (false);
 }
 
-macro_rules! is_input_attr {
-    (input) => (true);
-    ($attr:ident) => (false);
-}
-
 macro_rules! is_eval_always_attr {
     (eval_always) => (true);
     ($attr:ident) => (false);
@@ -99,10 +94,6 @@ macro_rules! contains_anon_attr {
     ($($attr:ident),*) => ({$(is_anon_attr!($attr) | )* false});
 }
 
-macro_rules! contains_input_attr {
-    ($($attr:ident),*) => ({$(is_input_attr!($attr) | )* false});
-}
-
 macro_rules! contains_eval_always_attr {
     ($($attr:ident),*) => ({$(is_eval_always_attr!($attr) | )* false});
 }
@@ -151,7 +142,7 @@ macro_rules! define_dep_nodes {
                 }
             }
 
-            // FIXME: Make `is_anon`, `is_input`, `is_eval_always` and `has_params` properties
+            // FIXME: Make `is_anon`, `is_eval_always` and `has_params` properties
             // of queries
             #[inline(always)]
             pub fn is_anon(&self) -> bool {
@@ -163,15 +154,6 @@ macro_rules! define_dep_nodes {
             }
 
             #[inline(always)]
-            pub fn is_input(&self) -> bool {
-                match *self {
-                    $(
-                        DepKind :: $variant => { contains_input_attr!($($attr),*) }
-                    )*
-                }
-            }
-
-            #[inline(always)]
             pub fn is_eval_always(&self) -> bool {
                 match *self {
                     $(
@@ -438,17 +420,17 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     // suitable wrapper, you can use `tcx.dep_graph.ignore()` to gain
     // access to the krate, but you must remember to add suitable
     // edges yourself for the individual items that you read.
-    [input] Krate,
+    [eval_always] Krate,
 
     // Represents the body of a function or method. The def-id is that of the
     // function/method.
-    [input] HirBody(DefId),
+    [eval_always] HirBody(DefId),
 
     // Represents the HIR node with the given node-id
-    [input] Hir(DefId),
+    [eval_always] Hir(DefId),
 
     // Represents metadata from an extern crate.
-    [input] CrateMetadata(CrateNum),
+    [eval_always] CrateMetadata(CrateNum),
 
     // Represents different phases in the compiler.
     [] RegionScopeTree(DefId),
@@ -481,7 +463,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [] CollectModItemTypes(DefId),
 
     [] Reachability,
-    [eval_always] CrateVariances,
+    [] CrateVariances,
 
     // Nodes representing bits of computed IR in the tcx. Each shared
     // table in the tcx (or elsewhere) maps to one of these
@@ -534,7 +516,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     // The set of impls for a given trait.
     [] TraitImpls(DefId),
 
-    [input] AllLocalTraitImpls,
+    [eval_always] AllLocalTraitImpls,
 
     [anon] TraitSelect,
 
@@ -546,7 +528,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     // to make type debuginfo to be source location independent. Declaring
     // DefSpan an input makes sure that changes to these are always detected
     // regardless of HIR hashing.
-    [input] DefSpan(DefId),
+    [eval_always] DefSpan(DefId),
     [] LookupStability(DefId),
     [] LookupDeprecationEntry(DefId),
     [] ConstIsRvaluePromotableToStatic(DefId),
@@ -564,10 +546,10 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [] IsCompilerBuiltins(CrateNum),
     [] HasGlobalAllocator(CrateNum),
     [] HasPanicHandler(CrateNum),
-    [input] ExternCrate(DefId),
+    [eval_always] ExternCrate(DefId),
     [] Specializes { impl1: DefId, impl2: DefId },
-    [input] InScopeTraits(DefIndex),
-    [input] ModuleExports(DefId),
+    [eval_always] InScopeTraits(DefIndex),
+    [eval_always] ModuleExports(DefId),
     [] IsSanitizerRuntime(CrateNum),
     [] IsProfilerRuntime(CrateNum),
     [] GetPanicStrategy(CrateNum),
@@ -580,10 +562,10 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [] EntryFn(CrateNum),
     [] PluginRegistrarFn(CrateNum),
     [] ProcMacroDeclsStatic(CrateNum),
-    [input] CrateDisambiguator(CrateNum),
-    [input] CrateHash(CrateNum),
-    [input] OriginalCrateName(CrateNum),
-    [input] ExtraFileName(CrateNum),
+    [eval_always] CrateDisambiguator(CrateNum),
+    [eval_always] CrateHash(CrateNum),
+    [eval_always] OriginalCrateName(CrateNum),
+    [eval_always] ExtraFileName(CrateNum),
 
     [] ImplementationsOfTrait { krate: CrateNum, trait_id: DefId },
     [] AllTraitImplementations(CrateNum),
@@ -592,7 +574,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [] IsDllimportForeignItem(DefId),
     [] IsStaticallyIncludedForeignItem(DefId),
     [] NativeLibraryKind(DefId),
-    [input] LinkArgs,
+    [eval_always] LinkArgs,
 
     [] ResolveLifetimes(CrateNum),
     [] NamedRegion(DefIndex),
@@ -600,8 +582,8 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [] ObjectLifetimeDefaults(DefIndex),
 
     [] Visibility(DefId),
-    [input] DepKind(CrateNum),
-    [input] CrateName(CrateNum),
+    [eval_always] DepKind(CrateNum),
+    [eval_always] CrateName(CrateNum),
     [] ItemChildren(DefId),
     [] ExternModStmtCnum(DefId),
     [eval_always] GetLibFeatures,
@@ -610,24 +592,24 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [] DefinedLangItems(CrateNum),
     [] MissingLangItems(CrateNum),
     [] VisibleParentMap,
-    [input] MissingExternCrateItem(CrateNum),
-    [input] UsedCrateSource(CrateNum),
-    [input] PostorderCnums,
-
-    [input] Freevars(DefId),
-    [input] MaybeUnusedTraitImport(DefId),
-    [input] MaybeUnusedExternCrates,
-    [input] NamesImportedByGlobUse(DefId),
+    [eval_always] MissingExternCrateItem(CrateNum),
+    [eval_always] UsedCrateSource(CrateNum),
+    [eval_always] PostorderCnums,
+
+    [eval_always] Freevars(DefId),
+    [eval_always] MaybeUnusedTraitImport(DefId),
+    [eval_always] MaybeUnusedExternCrates,
+    [eval_always] NamesImportedByGlobUse(DefId),
     [eval_always] StabilityIndex,
     [eval_always] AllTraits,
-    [input] AllCrateNums,
+    [eval_always] AllCrateNums,
     [] ExportedSymbols(CrateNum),
     [eval_always] CollectAndPartitionMonoItems,
     [] IsCodegenedItem(DefId),
     [] CodegenUnit(InternedString),
     [] BackendOptimizationLevel(CrateNum),
     [] CompileCodegenUnit(InternedString),
-    [input] OutputFilenames,
+    [eval_always] OutputFilenames,
     [] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>),
     [] NormalizeTyAfterErasingRegions(ParamEnvAnd<'tcx, Ty<'tcx>>),
     [] ImpliedOutlivesBounds(CanonicalTyGoal<'tcx>),
@@ -646,11 +628,11 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [] SubstituteNormalizeAndTestPredicates { key: (DefId, SubstsRef<'tcx>) },
     [] MethodAutoderefSteps(CanonicalTyGoal<'tcx>),
 
-    [input] TargetFeaturesWhitelist,
+    [eval_always] TargetFeaturesWhitelist,
 
     [] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> },
 
-    [input] Features,
+    [eval_always] Features,
 
     [] ForeignModules(CrateNum),
 
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 8a2f79e6793..db81a9d826f 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -388,10 +388,7 @@ impl DepGraph {
             |_| None,
             |data, key, fingerprint, _| {
                 let mut current = data.borrow_mut();
-                let krate_idx = current.node_to_node_index[
-                    &DepNode::new_no_params(DepKind::Krate)
-                ];
-                current.alloc_node(key, smallvec![krate_idx], fingerprint)
+                current.alloc_node(key, smallvec![], fingerprint)
             },
             hash_result)
     }
@@ -576,7 +573,7 @@ impl DepGraph {
         tcx: TyCtxt<'_, '_, '_>,
         dep_node: &DepNode
     ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> {
-        debug_assert!(!dep_node.kind.is_input());
+        debug_assert!(!dep_node.kind.is_eval_always());
 
         // Return None if the dep graph is disabled
         let data = self.data.as_ref()?;
@@ -620,8 +617,8 @@ impl DepGraph {
             debug_assert!(data.colors.get(prev_dep_node_index).is_none());
         }
 
-        // We never try to mark inputs as green
-        debug_assert!(!dep_node.kind.is_input());
+        // We never try to mark eval_always nodes as green
+        debug_assert!(!dep_node.kind.is_eval_always());
 
         debug_assert_eq!(data.previous.index_to_node(prev_dep_node_index), *dep_node);
 
@@ -658,8 +655,8 @@ impl DepGraph {
                     let dep_dep_node = &data.previous.index_to_node(dep_dep_node_index);
 
                     // We don't know the state of this dependency. If it isn't
-                    // an input node, let's try to mark it green recursively.
-                    if !dep_dep_node.kind.is_input() {
+                    // an eval_always node, let's try to mark it green recursively.
+                    if !dep_dep_node.kind.is_eval_always() {
                          debug!("try_mark_previous_green({:?}) --- state of dependency {:?} \
                                  is unknown, trying to mark it green", dep_node,
                                  dep_dep_node);
@@ -694,7 +691,7 @@ impl DepGraph {
                                 }
                             }
                             _ => {
-                                // For other kinds of inputs it's OK to be
+                                // For other kinds of nodes it's OK to be
                                 // forced.
                             }
                         }
@@ -1017,33 +1014,11 @@ impl CurrentDepGraph {
         task_deps: TaskDeps,
         fingerprint: Fingerprint
     ) -> DepNodeIndex {
-        // If this is an input node, we expect that it either has no
-        // dependencies, or that it just depends on DepKind::CrateMetadata
-        // or DepKind::Krate. This happens for some "thin wrapper queries"
-        // like `crate_disambiguator` which sometimes have zero deps (for
-        // when called for LOCAL_CRATE) or they depend on a CrateMetadata
-        // node.
-        if cfg!(debug_assertions) {
-            if node.kind.is_input() && task_deps.reads.len() > 0 &&
-                // FIXME(mw): Special case for DefSpan until Spans are handled
-                //            better in general.
-                node.kind != DepKind::DefSpan &&
-                task_deps.reads.iter().any(|&i| {
-                    !(self.data[i].node.kind == DepKind::CrateMetadata ||
-                        self.data[i].node.kind == DepKind::Krate)
-                })
-            {
-                bug!("Input node {:?} with unexpected reads: {:?}",
-                    node,
-                    task_deps.reads.iter().map(|&i| self.data[i].node).collect::<Vec<_>>())
-            }
-        }
-
         self.alloc_node(node, task_deps.reads, fingerprint)
     }
 
     fn complete_anon_task(&mut self, kind: DepKind, task_deps: TaskDeps) -> DepNodeIndex {
-        debug_assert!(!kind.is_input());
+        debug_assert!(!kind.is_eval_always());
 
         let mut fingerprint = self.anon_id_seed;
         let mut hasher = StableHasher::new();
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index f906ff9963d..c0579ef0f7a 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -153,7 +153,7 @@ impl Forest {
         &self.krate
     }
 
-    /// This is internally in the depedency tracking system.
+    /// This is used internally in the dependency tracking system.
     /// Use the `krate` method to ensure your dependency on the
     /// crate is tracked.
     pub fn untracked_krate<'hir>(&'hir self) -> &'hir Crate {
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 0a0a1dee7f0..8e8543dd334 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -98,8 +98,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
     }
 
     fn lookup_and_handle_method(&mut self, id: hir::HirId) {
-        if let Some(def) = self.tables.type_dependent_defs().get(id) {
-            self.check_def_id(def.def_id());
+        if let Some(def_id) = self.tables.type_dependent_def_id(id) {
+            self.check_def_id(def_id);
         } else {
             bug!("no type-dependent def for method");
         }
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 6c8d9fe29d7..01e57273e54 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -559,8 +559,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
             }
             ty::Error => { }
             _ => {
-                if let Some(def) = self.mc.tables.type_dependent_defs().get(call.hir_id) {
-                    let def_id = def.def_id();
+                if let Some(def_id) = self.mc.tables.type_dependent_def_id(call.hir_id) {
                     let call_scope = region::Scope {
                         id: call.hir_id.local_id,
                         data: region::ScopeData::Node
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index b57f96f2d46..b55e840596b 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -97,7 +97,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
                 Some(self.tables.qpath_def(qpath, expr.hir_id))
             }
             hir::ExprKind::MethodCall(..) => {
-                self.tables.type_dependent_defs().get(expr.hir_id).cloned()
+                self.tables.type_dependent_def(expr.hir_id)
             }
             _ => None
         };
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 0ae7c10cf56..eb629dc44c1 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1706,6 +1706,12 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
             "Specify the name of the crate being built",
             "NAME",
         ),
+        opt::opt_s(
+            "",
+            "edition",
+            "Specify which edition of the compiler to use when compiling code.",
+            EDITION_NAME_LIST,
+        ),
         opt::multi_s(
             "",
             "emit",
@@ -1808,12 +1814,6 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
                   `expanded,identified` (fully parenthesized, AST nodes with IDs).",
             "TYPE",
         ),
-        opt::opt_s(
-            "",
-            "edition",
-            "Specify which edition of the compiler to use when compiling code.",
-            EDITION_NAME_LIST,
-        ),
         opt::multi_s(
             "",
             "remap-path-prefix",
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 6de0a39c91b..ea003ba1ac7 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -482,6 +482,15 @@ impl<'tcx> TypeckTables<'tcx> {
         }
     }
 
+    pub fn type_dependent_def(&self, id: HirId) -> Option<Def> {
+        validate_hir_id_for_typeck_tables(self.local_id_root, id, false);
+        self.type_dependent_defs.get(&id.local_id).cloned()
+    }
+
+    pub fn type_dependent_def_id(&self, id: HirId) -> Option<DefId> {
+        self.type_dependent_def(id).map(|def| def.def_id())
+    }
+
     pub fn type_dependent_defs_mut(&mut self) -> LocalTableInContextMut<'_, Def> {
         LocalTableInContextMut {
             local_id_root: self.local_id_root,
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index b2b141fd0f5..c35cea7883f 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -414,7 +414,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             return result;
         }
 
-        if !dep_node.kind.is_input() {
+        if !dep_node.kind.is_eval_always() {
             // The diagnostics for this query will be
             // promoted to the current session during
             // try_mark_green(), so we can ignore them here.
@@ -601,9 +601,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub(super) fn ensure_query<Q: QueryDescription<'gcx>>(self, key: Q::Key) -> () {
         let dep_node = Q::to_dep_node(self, &key);
 
-        // Ensuring an "input" or anonymous query makes no sense
+        if dep_node.kind.is_eval_always() {
+            let _ = self.get_query::<Q>(DUMMY_SP, key);
+            return;
+        }
+
+        // Ensuring an anonymous query makes no sense
         assert!(!dep_node.kind.is_anon());
-        assert!(!dep_node.kind.is_input());
         if self.dep_graph.try_mark_green_and_read(self, &dep_node).is_none() {
             // A None return from `try_mark_green_and_read` means that this is either
             // a new dep node or that the dep node has already been marked red.
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 8efa025e3dd..042a8c60cfa 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -22,6 +22,7 @@ use rustc::hir::CodegenFnAttrFlags;
 use rustc::hir::def::CtorKind;
 use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
 use rustc::ich::NodeIdHashingMode;
+use rustc::mir::interpret::truncate;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc::ty::Instance;
 use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
@@ -1368,7 +1369,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
                             let value = (i.as_u32() as u128)
                                 .wrapping_sub(niche_variants.start().as_u32() as u128)
                                 .wrapping_add(niche_start);
-                            let value = value & ((1u128 << niche.value.size(cx).bits()) - 1);
+                            let value = truncate(value, niche.value.size(cx));
                             Some(value as u64)
                         };
 
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 7f1aebace8f..a0e2dcd646d 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -152,17 +152,20 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
                 LinkerFlavor::PtxLinker => "rust-ptx-linker",
             }), flavor)),
             (Some(linker), None) => {
-                let stem = if linker.extension().and_then(|ext| ext.to_str()) == Some("exe") {
-                    linker.file_stem().and_then(|stem| stem.to_str())
-                } else {
-                    linker.to_str()
-                }.unwrap_or_else(|| {
-                    sess.fatal("couldn't extract file stem from specified linker");
-                }).to_owned();
+                let stem = linker
+                    .file_stem()
+                    .and_then(|stem| stem.to_str())
+                    .unwrap_or_else(|| {
+                        sess.fatal("couldn't extract file stem from specified linker")
+                    });
 
                 let flavor = if stem == "emcc" {
                     LinkerFlavor::Em
-                } else if stem == "gcc" || stem.ends_with("-gcc") {
+                } else if stem == "gcc"
+                    || stem.ends_with("-gcc")
+                    || stem == "clang"
+                    || stem.ends_with("-clang")
+                {
                     LinkerFlavor::Gcc
                 } else if stem == "ld" || stem == "ld.lld" || stem.ends_with("-ld") {
                     LinkerFlavor::Ld
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index 244505976b6..c99fc17dd89 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -160,7 +160,16 @@ impl<'a> GccLinker<'a> {
     }
 
     fn takes_hints(&self) -> bool {
-        !self.sess.target.target.options.is_like_osx
+        // Really this function only returns true if the underlying linker
+        // configured for a compiler is binutils `ld.bfd` and `ld.gold`. We
+        // don't really have a foolproof way to detect that, so rule out some
+        // platforms where currently this is guaranteed to *not* be the case:
+        //
+        // * On OSX they have their own linker, not binutils'
+        // * For WebAssembly the only functional linker is LLD, which doesn't
+        //   support hint flags
+        !self.sess.target.target.options.is_like_osx &&
+            self.sess.target.target.arch != "wasm32"
     }
 
     // Some platforms take hints about whether a library is static or dynamic.
@@ -375,6 +384,13 @@ impl<'a> Linker for GccLinker<'a> {
             return
         }
 
+        // Symbol visibility takes care of this for the WebAssembly.
+        // Additionally the only known linker, LLD, doesn't support the script
+        // arguments just yet
+        if self.sess.target.target.arch == "wasm32" {
+            return;
+        }
+
         let mut arg = OsString::new();
         let path = tmpdir.join("list");
 
@@ -441,13 +457,13 @@ impl<'a> Linker for GccLinker<'a> {
     }
 
     fn group_start(&mut self) {
-        if !self.sess.target.target.options.is_like_osx {
+        if self.takes_hints() {
             self.linker_arg("--start-group");
         }
     }
 
     fn group_end(&mut self) {
-        if !self.sess.target.target.options.is_like_osx {
+        if self.takes_hints() {
             self.linker_arg("--end-group");
         }
     }
@@ -862,59 +878,7 @@ pub struct WasmLd<'a> {
 }
 
 impl<'a> WasmLd<'a> {
-    fn new(mut cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> {
-        // There have been reports in the wild (rustwasm/wasm-bindgen#119) of
-        // using threads causing weird hangs and bugs. Disable it entirely as
-        // this isn't yet the bottleneck of compilation at all anyway.
-        cmd.arg("--no-threads");
-
-        // By default LLD only gives us one page of stack (64k) which is a
-        // little small. Default to a larger stack closer to other PC platforms
-        // (1MB) and users can always inject their own link-args to override this.
-        cmd.arg("-z").arg("stack-size=1048576");
-
-        // By default LLD's memory layout is:
-        //
-        // 1. First, a blank page
-        // 2. Next, all static data
-        // 3. Finally, the main stack (which grows down)
-        //
-        // This has the unfortunate consequence that on stack overflows you
-        // corrupt static data and can cause some exceedingly weird bugs. To
-        // help detect this a little sooner we instead request that the stack is
-        // placed before static data.
-        //
-        // This means that we'll generate slightly larger binaries as references
-        // to static data will take more bytes in the ULEB128 encoding, but
-        // stack overflow will be guaranteed to trap as it underflows instead of
-        // corrupting static data.
-        cmd.arg("--stack-first");
-
-        // FIXME we probably shouldn't pass this but instead pass an explicit
-        // whitelist of symbols we'll allow to be undefined. Unfortunately
-        // though we can't handle symbols like `log10` that LLVM injects at a
-        // super late date without actually parsing object files. For now let's
-        // stick to this and hopefully fix it before stabilization happens.
-        cmd.arg("--allow-undefined");
-
-        // For now we just never have an entry symbol
-        cmd.arg("--no-entry");
-
-        // Rust code should never have warnings, and warnings are often
-        // indicative of bugs, let's prevent them.
-        cmd.arg("--fatal-warnings");
-
-        // The symbol visibility story is a bit in flux right now with LLD.
-        // It's... not entirely clear to me what's going on, but this looks to
-        // make everything work when `export_symbols` isn't otherwise called for
-        // things like executables.
-        cmd.arg("--export-dynamic");
-
-        // LLD only implements C++-like demangling, which doesn't match our own
-        // mangling scheme. Tell LLD to not demangle anything and leave it up to
-        // us to demangle these symbols later.
-        cmd.arg("--no-demangle");
-
+    fn new(cmd: Command, sess: &'a Session, info: &'a LinkerInfo) -> WasmLd<'a> {
         WasmLd { cmd, sess, info }
     }
 }
@@ -1010,6 +974,7 @@ impl<'a> Linker for WasmLd<'a> {
     }
 
     fn build_dylib(&mut self, _out_filename: &Path) {
+        self.cmd.arg("--no-entry");
     }
 
     fn export_symbols(&mut self, _tmpdir: &Path, crate_type: CrateType) {
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index ebbd2779841..37c147d93d8 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -112,7 +112,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                 }
             },
             hir::ExprKind::MethodCall(..) => {
-                cx.tables.type_dependent_defs().get(expr.hir_id).cloned()
+                cx.tables.type_dependent_def(expr.hir_id)
             },
             _ => None
         };
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index fac75989aa5..95701204cab 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -19,6 +19,7 @@ use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use syntax_pos::Span;
+use syntax::source_map::CompilerDesugaringKind;
 
 use super::borrow_set::BorrowData;
 use super::{Context, MirBorrowckCtxt};
@@ -154,6 +155,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                         span,
                         format!("value moved{} here, in previous iteration of loop", move_msg),
                     );
+                    if Some(CompilerDesugaringKind::ForLoop) == span.compiler_desugaring_kind() {
+                        if let Ok(snippet) = self.infcx.tcx.sess.source_map()
+                            .span_to_snippet(span)
+                        {
+                            err.span_suggestion(
+                                move_span,
+                                "consider borrowing this to avoid moving it into the for loop",
+                                format!("&{}", snippet),
+                                Applicability::MaybeIncorrect,
+                            );
+                        }
+                    }
                     is_loop_move = true;
                 } else if move_site.traversed_back_edge {
                     err.span_label(
@@ -291,8 +304,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             format!("move occurs due to use{}", move_spans.describe())
         );
 
-        self.explain_why_borrow_contains_point(context, borrow, None)
-            .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+        self.explain_why_borrow_contains_point(
+            context,
+            borrow,
+            None,
+        ).add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", Some(borrow_span));
         err.buffer(&mut self.errors_buffer);
     }
 
@@ -329,7 +345,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         });
 
         self.explain_why_borrow_contains_point(context, borrow, None)
-            .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+            .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
         err.buffer(&mut self.errors_buffer);
     }
 
@@ -542,8 +558,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             ));
         }
 
-        explanation
-            .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, first_borrow_desc);
+        explanation.add_explanation_to_diagnostic(
+            self.infcx.tcx,
+            self.mir,
+            &mut err,
+            first_borrow_desc,
+            None,
+        );
 
         err.buffer(&mut self.errors_buffer);
     }
@@ -866,7 +887,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
 
             if let BorrowExplanation::MustBeValidFor { .. } = explanation {
             } else {
-                explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+                explanation.add_explanation_to_diagnostic(
+                    self.infcx.tcx,
+                    self.mir,
+                    &mut err,
+                    "",
+                    None,
+                );
             }
         } else {
             err.span_label(borrow_span, "borrowed value does not live long enough");
@@ -886,7 +913,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 format!("value captured here{}", within),
             );
 
-            explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+            explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
         }
 
         err
@@ -946,7 +973,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             _ => {}
         }
 
-        explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+        explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
 
         err.buffer(&mut self.errors_buffer);
     }
@@ -1027,7 +1054,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             }
             _ => {}
         }
-        explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+        explanation.add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
 
         let within = if borrow_spans.for_generator() {
             " by generator"
@@ -1367,7 +1394,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         );
 
         self.explain_why_borrow_contains_point(context, loan, None)
-            .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "");
+            .add_explanation_to_diagnostic(self.infcx.tcx, self.mir, &mut err, "", None);
 
         err.buffer(&mut self.errors_buffer);
     }
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
index dfa5af444d3..67b77605f3c 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -56,17 +56,23 @@ impl BorrowExplanation {
         mir: &Mir<'tcx>,
         err: &mut DiagnosticBuilder<'_>,
         borrow_desc: &str,
+        borrow_span: Option<Span>,
     ) {
         match *self {
             BorrowExplanation::UsedLater(later_use_kind, var_or_use_span) => {
                 let message = match later_use_kind {
-                    LaterUseKind::TraitCapture => "borrow later captured here by trait object",
-                    LaterUseKind::ClosureCapture => "borrow later captured here by closure",
-                    LaterUseKind::Call => "borrow later used by call",
-                    LaterUseKind::FakeLetRead => "borrow later stored here",
-                    LaterUseKind::Other => "borrow later used here",
+                    LaterUseKind::TraitCapture => "captured here by trait object",
+                    LaterUseKind::ClosureCapture => "captured here by closure",
+                    LaterUseKind::Call => "used by call",
+                    LaterUseKind::FakeLetRead => "stored here",
+                    LaterUseKind::Other => "used here",
                 };
-                err.span_label(var_or_use_span, format!("{}{}", borrow_desc, message));
+                if !borrow_span.map(|sp| sp.overlaps(var_or_use_span)).unwrap_or(false) {
+                    err.span_label(
+                        var_or_use_span,
+                        format!("{}borrow later {}", borrow_desc, message),
+                    );
+                }
             }
             BorrowExplanation::UsedLaterInLoop(later_use_kind, var_or_use_span) => {
                 let message = match later_use_kind {
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 2ca44ecaba2..e4f92f81e9f 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -834,13 +834,11 @@ fn method_callee<'a, 'gcx, 'tcx>(
     let (def_id, substs, user_ty) = match overloaded_callee {
         Some((def_id, substs)) => (def_id, substs, None),
         None => {
-            let type_dependent_defs = cx.tables().type_dependent_defs();
-            let def = type_dependent_defs
-                .get(expr.hir_id)
+            let def = cx.tables().type_dependent_def(expr.hir_id)
                 .unwrap_or_else(|| {
                     span_bug!(expr.span, "no type-dependent def for method callee")
                 });
-            let user_ty = user_substs_applied_to_def(cx, expr.hir_id, def);
+            let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def);
             debug!("method_callee: user_ty={:?}", user_ty);
             (def.def_id(), cx.tables().node_substs(expr.hir_id), user_ty)
         }
diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs
index 71eb6ed7e05..a0a0d7be1b9 100644
--- a/src/librustc_passes/rvalue_promotion.rs
+++ b/src/librustc_passes/rvalue_promotion.rs
@@ -405,8 +405,7 @@ fn check_expr_kind<'a, 'tcx>(
             for index in hirvec.iter() {
                 method_call_result &= v.check_expr(index);
             }
-            if let Some(def) = v.tables.type_dependent_defs().get(e.hir_id) {
-                let def_id = def.def_id();
+            if let Some(def_id) = v.tables.type_dependent_def_id(e.hir_id) {
                 match v.tcx.associated_item(def_id).container {
                     ty::ImplContainer(_) => method_call_result & v.handle_const_fn_call(def_id),
                     ty::TraitContainer(_) => NotPromotable,
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index f155beaaff2..adb1a4b1308 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -1053,8 +1053,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
             hir::ExprKind::MethodCall(_, span, _) => {
                 // Method calls have to be checked specially.
                 self.span = span;
-                if let Some(def) = self.tables.type_dependent_defs().get(expr.hir_id) {
-                    if self.visit(self.tcx.type_of(def.def_id())) {
+                if let Some(def_id) = self.tables.type_dependent_def_id(expr.hir_id) {
+                    if self.visit(self.tcx.type_of(def_id)) {
                         return;
                     }
                 } else {
@@ -1083,7 +1083,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
                 _ => None,
             }
             hir::QPath::TypeRelative(..) => {
-                self.tables.type_dependent_defs().get(id).cloned()
+                self.tables.type_dependent_def(id)
             }
         };
         if let Some(def) = def {
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 828ef802dd7..898ea62046d 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -573,8 +573,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             }
             ast::ExprKind::MethodCall(ref seg, ..) => {
                 let expr_hir_id = self.tcx.hir().definitions().node_to_hir_id(expr.id);
-                let method_id = match self.tables.type_dependent_defs().get(expr_hir_id) {
-                    Some(id) => id.def_id(),
+                let method_id = match self.tables.type_dependent_def_id(expr_hir_id) {
+                    Some(id) => id,
                     None => {
                         debug!("Could not resolve method id for {:?}", expr);
                         return None;
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index fdb1db645c3..401b81ee987 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -66,6 +66,7 @@ mod l4re_base;
 mod fuchsia_base;
 mod redox_base;
 mod riscv_base;
+mod wasm32_base;
 
 #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash,
          RustcEncodable, RustcDecodable)]
diff --git a/src/librustc_target/spec/wasm32_base.rs b/src/librustc_target/spec/wasm32_base.rs
new file mode 100644
index 00000000000..c7e75b4fa09
--- /dev/null
+++ b/src/librustc_target/spec/wasm32_base.rs
@@ -0,0 +1,123 @@
+use std::collections::BTreeMap;
+use super::{LldFlavor, TargetOptions, PanicStrategy, LinkerFlavor};
+
+pub fn options() -> TargetOptions {
+    let mut lld_args = Vec::new();
+    let mut clang_args = Vec::new();
+    let mut arg = |arg: &str| {
+        lld_args.push(arg.to_string());
+        clang_args.push(format!("-Wl,{}", arg));
+    };
+
+    // There have been reports in the wild (rustwasm/wasm-bindgen#119) of
+    // using threads causing weird hangs and bugs. Disable it entirely as
+    // this isn't yet the bottleneck of compilation at all anyway.
+    //
+    // FIXME: we should file an upstream issue with LLD about this
+    arg("--no-threads");
+
+    // By default LLD only gives us one page of stack (64k) which is a
+    // little small. Default to a larger stack closer to other PC platforms
+    // (1MB) and users can always inject their own link-args to override this.
+    arg("-z");
+    arg("stack-size=1048576");
+
+    // By default LLD's memory layout is:
+    //
+    // 1. First, a blank page
+    // 2. Next, all static data
+    // 3. Finally, the main stack (which grows down)
+    //
+    // This has the unfortunate consequence that on stack overflows you
+    // corrupt static data and can cause some exceedingly weird bugs. To
+    // help detect this a little sooner we instead request that the stack is
+    // placed before static data.
+    //
+    // This means that we'll generate slightly larger binaries as references
+    // to static data will take more bytes in the ULEB128 encoding, but
+    // stack overflow will be guaranteed to trap as it underflows instead of
+    // corrupting static data.
+    arg("--stack-first");
+
+    // FIXME we probably shouldn't pass this but instead pass an explicit
+    // whitelist of symbols we'll allow to be undefined. We don't currently have
+    // a mechanism of knowing, however, which symbols are intended to be
+    // imported from the environment and which are intended to be imported from
+    // other objects linked elsewhere. This is a coarse approximation but is
+    // sure to hide some bugs and frustrate someone at some point, so we should
+    // ideally work towards a world where we can explicitly list symbols that
+    // are supposed to be imported and have all other symbols generate errors if
+    // they remain undefined.
+    arg("--allow-undefined");
+
+    // Rust code should never have warnings, and warnings are often
+    // indicative of bugs, let's prevent them.
+    arg("--fatal-warnings");
+
+    // LLD only implements C++-like demangling, which doesn't match our own
+    // mangling scheme. Tell LLD to not demangle anything and leave it up to
+    // us to demangle these symbols later. Currently rustc does not perform
+    // further demangling, but tools like twiggy and wasm-bindgen are intended
+    // to do so.
+    arg("--no-demangle");
+
+    // The symbol visibility story is a bit in flux right now with LLD.
+    // It's... not entirely clear to me what's going on, but this looks to
+    // make everything work when `export_symbols` isn't otherwise called for
+    // things like executables.
+    //
+    // This is really only here to get things working. If it can be removed and
+    // basic tests still work, then sounds like it should be removed!
+    arg("--export-dynamic");
+
+    let mut pre_link_args = BTreeMap::new();
+    pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Wasm), lld_args);
+    pre_link_args.insert(LinkerFlavor::Gcc, clang_args);
+
+    TargetOptions {
+        // we allow dynamic linking, but only cdylibs. Basically we allow a
+        // final library artifact that exports some symbols (a wasm module) but
+        // we don't allow intermediate `dylib` crate types
+        dynamic_linking: true,
+        only_cdylib: true,
+
+        // This means we'll just embed a `start` function in the wasm module
+        executables: true,
+
+        // relatively self-explanatory!
+        exe_suffix: ".wasm".to_string(),
+        dll_prefix: String::new(),
+        dll_suffix: ".wasm".to_string(),
+        linker_is_gnu: false,
+
+        max_atomic_width: Some(64),
+
+        // Unwinding doesn't work right now, so the whole target unconditionally
+        // defaults to panic=abort. Note that this is guaranteed to change in
+        // the future once unwinding is implemented. Don't rely on this as we're
+        // basically guaranteed to change it once WebAssembly supports
+        // exceptions.
+        panic_strategy: PanicStrategy::Abort,
+
+        // Wasm doesn't have atomics yet, so tell LLVM that we're in a single
+        // threaded model which will legalize atomics to normal operations.
+        singlethread: true,
+
+        // no dynamic linking, no need for default visibility!
+        default_hidden_visibility: true,
+
+        // we use the LLD shipped with the Rust toolchain by default
+        linker: Some("rust-lld".to_owned()),
+        lld_flavor: LldFlavor::Wasm,
+
+        // No need for indirection here, simd types can always be passed by
+        // value as the whole module either has simd or not, which is different
+        // from x86 (for example) where programs can have functions that don't
+        // enable simd features.
+        simd_types_indirect: false,
+
+        pre_link_args,
+
+        .. Default::default()
+    }
+}
diff --git a/src/librustc_target/spec/wasm32_unknown_unknown.rs b/src/librustc_target/spec/wasm32_unknown_unknown.rs
index ee2160c4720..909527d2b61 100644
--- a/src/librustc_target/spec/wasm32_unknown_unknown.rs
+++ b/src/librustc_target/spec/wasm32_unknown_unknown.rs
@@ -1,70 +1,48 @@
-// The wasm32-unknown-unknown target is currently an experimental version of a
-// wasm-based target which does *not* use the Emscripten toolchain. Instead
-// this toolchain is based purely on LLVM's own toolchain, using LLVM's native
-// WebAssembly backend as well as LLD for a native linker.
-//
-// There's some trickery below on crate types supported and various defaults
-// (aka panic=abort by default), but otherwise this is in general a relatively
-// standard target.
-
-use super::{LldFlavor, LinkerFlavor, Target, TargetOptions, PanicStrategy};
+//! A "bare wasm" target representing a WebAssembly output that makes zero
+//! assumptions about its environment.
+//!
+//! The `wasm32-unknown-unknown` target is intended to encapsulate use cases
+//! that do not rely on any imported functionality. The binaries generated are
+//! entirely self-contained by default when using the standard library. Although
+//! the standard library is available, most of it returns an error immediately
+//! (e.g. trying to create a TCP stream or something like that).
+//!
+//! This target is more or less managed by the Rust and WebAssembly Working
+//! Group nowadays at https://github.com/rustwasm.
+
+use super::{LldFlavor, LinkerFlavor, Target};
+use super::wasm32_base;
 
 pub fn target() -> Result<Target, String> {
-    let opts = TargetOptions {
-        // we allow dynamic linking, but only cdylibs. Basically we allow a
-        // final library artifact that exports some symbols (a wasm module) but
-        // we don't allow intermediate `dylib` crate types
-        dynamic_linking: true,
-        only_cdylib: true,
-
-        // This means we'll just embed a `start` function in the wasm module
-        executables: true,
-
-        // relatively self-explanatory!
-        exe_suffix: ".wasm".to_string(),
-        dll_prefix: String::new(),
-        dll_suffix: ".wasm".to_string(),
-        linker_is_gnu: false,
-
-        max_atomic_width: Some(64),
-
-        // Unwinding doesn't work right now, so the whole target unconditionally
-        // defaults to panic=abort. Note that this is guaranteed to change in
-        // the future once unwinding is implemented. Don't rely on this.
-        panic_strategy: PanicStrategy::Abort,
-
-        // Wasm doesn't have atomics yet, so tell LLVM that we're in a single
-        // threaded model which will legalize atomics to normal operations.
-        singlethread: true,
+    let mut options = wasm32_base::options();
+    let clang_args = options.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap();
 
-        // no dynamic linking, no need for default visibility!
-        default_hidden_visibility: true,
+    // Make sure clang uses LLD as its linker and is configured appropriately
+    // otherwise
+    clang_args.push("--target=wasm32-unknown-unknown".to_string());
 
-        // we use the LLD shipped with the Rust toolchain by default
-        linker: Some("rust-lld".to_owned()),
-        lld_flavor: LldFlavor::Wasm,
+    // Disable attempting to link crt1.o since it typically isn't present and
+    // isn't needed currently.
+    clang_args.push("-nostdlib".to_string());
 
-        // No need for indirection here, simd types can always be passed by
-        // value as the whole module either has simd or not, which is different
-        // from x86 (for example) where programs can have functions that don't
-        // enable simd features.
-        simd_types_indirect: false,
+    // For now this target just never has an entry symbol no matter the output
+    // type, so unconditionally pass this.
+    clang_args.push("-Wl,--no-entry".to_string());
+    options.pre_link_args.get_mut(&LinkerFlavor::Lld(LldFlavor::Wasm))
+        .unwrap()
+        .push("--no-entry".to_string());
 
-        .. Default::default()
-    };
     Ok(Target {
         llvm_target: "wasm32-unknown-unknown".to_string(),
         target_endian: "little".to_string(),
         target_pointer_width: "32".to_string(),
         target_c_int_width: "32".to_string(),
-        // This is basically guaranteed to change in the future, don't rely on
-        // this. Use `not(target_os = "emscripten")` for now.
         target_os: "unknown".to_string(),
         target_env: String::new(),
         target_vendor: "unknown".to_string(),
         data_layout: "e-m:e-p:32:32-i64:64-n32:64-S128".to_string(),
         arch: "wasm32".to_string(),
         linker_flavor: LinkerFlavor::Lld(LldFlavor::Wasm),
-        options: opts,
+        options,
     })
 }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 3d904d518ca..5c498923379 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4802,10 +4802,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 (self.to_ty(qself), qself, segment)
             }
         };
-        if let Some(cached_def) = self.tables.borrow().type_dependent_defs().get(hir_id) {
+        if let Some(cached_def) = self.tables.borrow().type_dependent_def(hir_id) {
             // Return directly on cache hit. This is useful to avoid doubly reporting
             // errors with default match binding modes. See #44614.
-            return (*cached_def, Some(ty), slice::from_ref(&**item_segment))
+            return (cached_def, Some(ty), slice::from_ref(&**item_segment))
         }
         let item_name = item_segment.ident;
         let def = match self.resolve_ufcs(span, item_name, ty, hir_id) {
diff --git a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs
index 96a238afaec..163d50c4e4b 100644
--- a/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs
+++ b/src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs
@@ -62,7 +62,7 @@ pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize {
     continue_if!(ap.arg::<c_int>() == 16);
     continue_if!(ap.arg::<c_char>() == 'A' as c_char);
     continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!"));
-    ap.copy(|mut ap| {
+    ap.with_copy(|mut ap| {
         if compare_c_str(ap.arg::<*const c_char>(), "Correct") {
             0
         } else {
diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
index e0e45d55a9e..1a120dcb186 100644
--- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
+++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr
@@ -9,7 +9,7 @@ note: lint level defined here
    |
 LL | #![deny(intra_doc_link_resolution_failure)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr
index d273ec01975..cebb14cba7c 100644
--- a/src/test/rustdoc-ui/intra-doc-alias-ice.stderr
+++ b/src/test/rustdoc-ui/intra-doc-alias-ice.stderr
@@ -9,7 +9,7 @@ note: lint level defined here
    |
 LL | #![deny(intra_doc_link_resolution_failure)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr
index 93c05a0c4dd..7ee9ca47923 100644
--- a/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr
+++ b/src/test/rustdoc-ui/intra-link-span-ice-55723.stderr
@@ -9,7 +9,7 @@ note: lint level defined here
    |
 LL | #![deny(intra_doc_link_resolution_failure)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 error: aborting due to previous error
 
diff --git a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr
index 62537f2ce2d..8ccc04a4c0b 100644
--- a/src/test/rustdoc-ui/intra-links-warning-crlf.stderr
+++ b/src/test/rustdoc-ui/intra-links-warning-crlf.stderr
@@ -5,7 +5,7 @@ LL | /// [error]
    |      ^^^^^ cannot be resolved, ignoring
    |
    = note: #[warn(intra_doc_link_resolution_failure)] on by default
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error1]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning-crlf.rs:12:11
@@ -13,7 +13,7 @@ warning: `[error1]` cannot be resolved, ignoring it...
 LL | /// docs [error1]
    |           ^^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error2]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning-crlf.rs:14:11
@@ -21,7 +21,7 @@ warning: `[error2]` cannot be resolved, ignoring it...
 LL | /// docs [error2]
    |           ^^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning-crlf.rs:21:20
@@ -29,5 +29,5 @@ warning: `[error]` cannot be resolved, ignoring it...
 LL |  * It also has an [error].
    |                    ^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
diff --git a/src/test/rustdoc-ui/intra-links-warning.stderr b/src/test/rustdoc-ui/intra-links-warning.stderr
index 60fc131dbda..1eec3c57b68 100644
--- a/src/test/rustdoc-ui/intra-links-warning.stderr
+++ b/src/test/rustdoc-ui/intra-links-warning.stderr
@@ -5,7 +5,7 @@ LL |        //! Test with [Foo::baz], [Bar::foo], ...
    |                       ^^^^^^^^ cannot be resolved, ignoring
    |
    = note: #[warn(intra_doc_link_resolution_failure)] on by default
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[Bar::foo]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:3:35
@@ -13,7 +13,7 @@ warning: `[Bar::foo]` cannot be resolved, ignoring it...
 LL |        //! Test with [Foo::baz], [Bar::foo], ...
    |                                   ^^^^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[Uniooon::X]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:4:13
@@ -21,7 +21,7 @@ warning: `[Uniooon::X]` cannot be resolved, ignoring it...
 LL |      //! , [Uniooon::X] and [Qux::Z].
    |             ^^^^^^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[Qux::Z]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:4:30
@@ -29,7 +29,7 @@ warning: `[Qux::Z]` cannot be resolved, ignoring it...
 LL |      //! , [Uniooon::X] and [Qux::Z].
    |                              ^^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[Uniooon::X]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:6:14
@@ -37,7 +37,7 @@ warning: `[Uniooon::X]` cannot be resolved, ignoring it...
 LL |       //! , [Uniooon::X] and [Qux::Z].
    |              ^^^^^^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[Qux::Z]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:6:31
@@ -45,7 +45,7 @@ warning: `[Qux::Z]` cannot be resolved, ignoring it...
 LL |       //! , [Uniooon::X] and [Qux::Z].
    |                               ^^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[Qux:Y]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:8:13
@@ -53,7 +53,7 @@ warning: `[Qux:Y]` cannot be resolved, ignoring it...
 LL |        /// [Qux:Y]
    |             ^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:51:30
@@ -61,7 +61,7 @@ warning: `[error]` cannot be resolved, ignoring it...
 LL |  * time to introduce a link [error]*/
    |                              ^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:57:30
@@ -69,7 +69,7 @@ warning: `[error]` cannot be resolved, ignoring it...
 LL |  * time to introduce a link [error]
    |                              ^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:61:1
@@ -81,19 +81,19 @@ LL | #[doc = "single line [error]"]
            
            single line [error]
                         ^^^^^
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:64:1
    |
-LL | #[doc = "single line with /"escaping/" [error]"]
+LL | #[doc = "single line with \"escaping\" [error]"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the link appears in this line:
            
            single line with "escaping" [error]
                                         ^^^^^
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:67:1
@@ -107,7 +107,7 @@ LL | | /// [error]
            
            [error]
             ^^^^^
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error1]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:73:11
@@ -115,7 +115,7 @@ warning: `[error1]` cannot be resolved, ignoring it...
 LL | /// docs [error1]
    |           ^^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[error2]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:75:11
@@ -123,7 +123,7 @@ warning: `[error2]` cannot be resolved, ignoring it...
 LL | /// docs [error2]
    |           ^^^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[BarA]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:14:10
@@ -131,7 +131,7 @@ warning: `[BarA]` cannot be resolved, ignoring it...
 LL | /// bar [BarA] bar
    |          ^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[BarB]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:20:9
@@ -139,7 +139,7 @@ warning: `[BarB]` cannot be resolved, ignoring it...
 LL |  * bar [BarB] bar
    |         ^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[BarC]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:27:6
@@ -147,19 +147,19 @@ warning: `[BarC]` cannot be resolved, ignoring it...
 LL | bar [BarC] bar
    |      ^^^^ cannot be resolved, ignoring
    |
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[BarD]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:38:1
    |
-LL | #[doc = "Foo/nbar [BarD] bar/nbaz"]
+LL | #[doc = "Foo\nbar [BarD] bar\nbaz"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the link appears in this line:
            
            bar [BarD] bar
                 ^^^^
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 warning: `[BarF]` cannot be resolved, ignoring it...
   --> $DIR/intra-links-warning.rs:43:9
@@ -167,12 +167,12 @@ warning: `[BarF]` cannot be resolved, ignoring it...
 LL |         #[doc = $f]
    |         ^^^^^^^^^^^
 ...
-LL | f!("Foo/nbar [BarF] bar/nbaz");
+LL | f!("Foo\nbar [BarF] bar\nbaz");
    | ------------------------------- in this macro invocation
    |
    = note: the link appears in this line:
            
            bar [BarF] bar
                 ^^^^
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr
index 10800380a05..b4ed747b44c 100644
--- a/src/test/rustdoc-ui/invalid-syntax.stderr
+++ b/src/test/rustdoc-ui/invalid-syntax.stderr
@@ -3,11 +3,11 @@ warning: could not parse code block as Rust code
    |
 LL |   /// ```
    |  _____^
-LL | | /// /__________pkt->size___________/          /_result->size_/ /__pkt->size__/
+LL | | /// \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
 LL | | /// ```
    | |_______^
    |
-   = note: error from rustc: unknown start of token: /
+   = note: error from rustc: unknown start of token: \
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
@@ -35,11 +35,11 @@ warning: could not parse code block as Rust code
    |
 LL |   /// ```
    |  _____^
-LL | | /// /_
+LL | | /// \_
 LL | | /// ```
    | |_______^
    |
-   = note: error from rustc: unknown start of token: /
+   = note: error from rustc: unknown start of token: \
 help: mark blocks that do not contain Rust code as text
    |
 LL | /// ```text
@@ -50,21 +50,21 @@ warning: could not parse code block as Rust code
    |
 LL |   /// ```rust
    |  _____^
-LL | | /// /_
+LL | | /// \_
 LL | | /// ```
    | |_______^
    |
-   = note: error from rustc: unknown start of token: /
+   = note: error from rustc: unknown start of token: \
 
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:41:9
    |
 LL |   ///     code with bad syntax
    |  _________^
-LL | | ///     /_
+LL | | ///     \_
    | |__________^
    |
-   = note: error from rustc: unknown start of token: /
+   = note: error from rustc: unknown start of token: \
 
 warning: could not parse code block as Rust code
   --> $DIR/invalid-syntax.rs:55:9
@@ -79,17 +79,17 @@ warning: could not parse code block as Rust code
    |
 LL |   /// ```edition2018
    |  _____^
-LL | | /// /_
+LL | | /// \_
 LL | | /// ```
    | |_______^
    |
-   = note: error from rustc: unknown start of token: /
+   = note: error from rustc: unknown start of token: \
 
 warning: doc comment contains an invalid Rust code block
   --> $DIR/invalid-syntax.rs:63:1
    |
 LL | / #[doc = "```"]
-LL | | /// /_
+LL | | /// \_
 LL | | #[doc = "```"]
    | |______________^
    |
diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr
index 76a9133147e..24db3453ec5 100644
--- a/src/test/rustdoc-ui/lint-group.stderr
+++ b/src/test/rustdoc-ui/lint-group.stderr
@@ -27,7 +27,7 @@ note: lint level defined here
 LL | #![deny(rustdoc)]
    |         ^^^^^^^
    = note: #[deny(intra_doc_link_resolution_failure)] implied by #[deny(rustdoc)]
-   = help: to escape `[` and `]` characters, just add '/' before them like `/[` or `/]`
+   = help: to escape `[` and `]` characters, just add '\' before them like `\[` or `\]`
 
 error: Missing code example in this documentation
   --> $DIR/lint-group.rs:16:1
diff --git a/src/test/ui/augmented-assignments.nll.stderr b/src/test/ui/augmented-assignments.nll.stderr
index 08f06e90162..e205e2a8781 100644
--- a/src/test/ui/augmented-assignments.nll.stderr
+++ b/src/test/ui/augmented-assignments.nll.stderr
@@ -1,18 +1,11 @@
 error[E0505]: cannot move out of `x` because it is borrowed
   --> $DIR/augmented-assignments.rs:16:5
    |
-LL |       x
-   |       -
-   |       |
-   |  _____borrow of `x` occurs here
-   | |
-LL | |
-LL | |     +=
-LL | |     x;
-   | |     ^
-   | |     |
-   | |_____move out of `x` occurs here
-   |       borrow later used here
+LL |     x
+   |     - borrow of `x` occurs here
+...
+LL |     x;
+   |     ^ move out of `x` occurs here
 
 error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
   --> $DIR/augmented-assignments.rs:21:5
diff --git a/src/test/ui/c-variadic/variadic-ffi-4.rs b/src/test/ui/c-variadic/variadic-ffi-4.rs
index 9101be56456..1c77479d02f 100644
--- a/src/test/ui/c-variadic/variadic-ffi-4.rs
+++ b/src/test/ui/c-variadic/variadic-ffi-4.rs
@@ -13,7 +13,7 @@ pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> {
 }
 
 pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) {
-    let _ = ap.copy(|ap| { ap }); //~ ERROR: cannot infer an appropriate lifetime
+    let _ = ap.with_copy(|ap| { ap }); //~ ERROR: cannot infer an appropriate lifetime
 }
 
 pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaList, mut ap1: ...) {
diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr
index a3e3f81b73d..311e2173702 100644
--- a/src/test/ui/c-variadic/variadic-ffi-4.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr
@@ -15,29 +15,29 @@ LL |     ap
    |     ^^ lifetime `'static` required
 
 error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
-  --> $DIR/variadic-ffi-4.rs:16:28
+  --> $DIR/variadic-ffi-4.rs:16:33
    |
-LL |     let _ = ap.copy(|ap| { ap });
-   |                            ^^
+LL |     let _ = ap.with_copy(|ap| { ap });
+   |                                 ^^
    |
-note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 16:21...
-  --> $DIR/variadic-ffi-4.rs:16:21
+note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 16:26...
+  --> $DIR/variadic-ffi-4.rs:16:26
    |
-LL |     let _ = ap.copy(|ap| { ap });
-   |                     ^^^^^^^^^^^
+LL |     let _ = ap.with_copy(|ap| { ap });
+   |                          ^^^^^^^^^^^
    = note: ...so that the expression is assignable:
            expected core::ffi::VaList<'_>
               found core::ffi::VaList<'_>
 note: but, the lifetime must be valid for the method call at 16:13...
   --> $DIR/variadic-ffi-4.rs:16:13
    |
-LL |     let _ = ap.copy(|ap| { ap });
-   |             ^^^^^^^^^^^^^^^^^^^^
+LL |     let _ = ap.with_copy(|ap| { ap });
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...so type `core::ffi::VaList<'_>` of expression is valid during the expression
   --> $DIR/variadic-ffi-4.rs:16:13
    |
-LL |     let _ = ap.copy(|ap| { ap });
-   |             ^^^^^^^^^^^^^^^^^^^^
+LL |     let _ = ap.with_copy(|ap| { ap });
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/variadic-ffi-4.rs:20:12
diff --git a/src/test/ui/c-variadic/variadic-ffi-5.rs b/src/test/ui/c-variadic/variadic-ffi-5.rs
index d96482ff4d1..fcc80d9b0cc 100644
--- a/src/test/ui/c-variadic/variadic-ffi-5.rs
+++ b/src/test/ui/c-variadic/variadic-ffi-5.rs
@@ -16,7 +16,7 @@ pub unsafe extern "C" fn no_escape1(_: usize, ap: ...) -> VaList<'static> {
 }
 
 pub unsafe extern "C" fn no_escape2(_: usize, ap: ...) {
-    let _ = ap.copy(|ap| { ap }); //~ ERROR: lifetime may not live long enough
+    let _ = ap.with_copy(|ap| { ap }); //~ ERROR: lifetime may not live long enough
 }
 
 pub unsafe extern "C" fn no_escape3(_: usize, ap0: &mut VaList, mut ap1: ...) {
diff --git a/src/test/ui/c-variadic/variadic-ffi-5.stderr b/src/test/ui/c-variadic/variadic-ffi-5.stderr
index 2ad1964b6fc..8f1dfe8ba9b 100644
--- a/src/test/ui/c-variadic/variadic-ffi-5.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-5.stderr
@@ -15,13 +15,13 @@ LL |     ap
    |     ^^ lifetime `'static` required
 
 error: lifetime may not live long enough
-  --> $DIR/variadic-ffi-5.rs:19:28
+  --> $DIR/variadic-ffi-5.rs:19:33
    |
-LL |     let _ = ap.copy(|ap| { ap });
-   |                      ---   ^^ returning this value requires that `'1` must outlive `'2`
-   |                      | |
-   |                      | return type of closure is core::ffi::VaList<'2>
-   |                      has type `core::ffi::VaList<'1>`
+LL |     let _ = ap.with_copy(|ap| { ap });
+   |                           ---   ^^ returning this value requires that `'1` must outlive `'2`
+   |                           | |
+   |                           | return type of closure is core::ffi::VaList<'2>
+   |                           has type `core::ffi::VaList<'1>`
 
 error: lifetime may not live long enough
   --> $DIR/variadic-ffi-5.rs:23:5
diff --git a/src/test/ui/cast_char.stderr b/src/test/ui/cast_char.stderr
index 570ca7cba86..f0c9b898890 100644
--- a/src/test/ui/cast_char.stderr
+++ b/src/test/ui/cast_char.stderr
@@ -2,7 +2,7 @@ error: only u8 can be cast into char
   --> $DIR/cast_char.rs:4:23
    |
 LL |     const XYZ: char = 0x1F888 as char;
-   |                       ^^^^^^^^^^^^^^^ help: use a char literal instead: `'/u{1F888}'`
+   |                       ^^^^^^^^^^^^^^^ help: use a char literal instead: `'\u{1F888}'`
    |
 note: lint level defined here
   --> $DIR/cast_char.rs:1:9
@@ -14,7 +14,7 @@ error: only u8 can be cast into char
   --> $DIR/cast_char.rs:6:22
    |
 LL |     const XY: char = 129160 as char;
-   |                      ^^^^^^^^^^^^^^ help: use a char literal instead: `'/u{1F888}'`
+   |                      ^^^^^^^^^^^^^^ help: use a char literal instead: `'\u{1F888}'`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/error-codes/E0648.stderr b/src/test/ui/error-codes/E0648.stderr
index f682b4f41e5..1a65825c7b6 100644
--- a/src/test/ui/error-codes/E0648.stderr
+++ b/src/test/ui/error-codes/E0648.stderr
@@ -1,7 +1,7 @@
 error[E0648]: `export_name` may not contain null characters
   --> $DIR/E0648.rs:1:1
    |
-LL | #[export_name="/0foo"]
+LL | #[export_name="\0foo"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/fmt/format-string-error-2.stderr b/src/test/ui/fmt/format-string-error-2.stderr
index baab8529940..66d35a1b854 100644
--- a/src/test/ui/fmt/format-string-error-2.stderr
+++ b/src/test/ui/fmt/format-string-error-2.stderr
@@ -1,10 +1,10 @@
 error: incorrect unicode escape sequence
   --> $DIR/format-string-error-2.rs:77:20
    |
-LL |     println!("/x7B}/u8 {", 1);
+LL |     println!("\x7B}\u8 {", 1);
    |                    ^^-
    |                    |
-   |                    help: format of unicode escape sequences uses braces: `/u{8}`
+   |                    help: format of unicode escape sequences uses braces: `\u{8}`
 
 error: invalid format string: expected `'}'`, found `'a'`
   --> $DIR/format-string-error-2.rs:5:5
@@ -19,7 +19,7 @@ LL |     a");
 error: invalid format string: expected `'}'`, found `'b'`
   --> $DIR/format-string-error-2.rs:9:5
    |
-LL |     format!("{ /
+LL |     format!("{ \
    |              - because of this opening brace
 LL | 
 LL |     b");
@@ -27,20 +27,20 @@ LL |     b");
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'/'`
+error: invalid format string: expected `'}'`, found `'\'`
   --> $DIR/format-string-error-2.rs:11:18
    |
-LL |     format!(r#"{ /
+LL |     format!(r#"{ \
    |                - ^ expected `}` in format string
    |                |
    |                because of this opening brace
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'/'`
+error: invalid format string: expected `'}'`, found `'\'`
   --> $DIR/format-string-error-2.rs:15:18
    |
-LL |     format!(r#"{ /n
+LL |     format!(r#"{ \n
    |                - ^ expected `}` in format string
    |                |
    |                because of this opening brace
@@ -50,9 +50,9 @@ LL |     format!(r#"{ /n
 error: invalid format string: expected `'}'`, found `'e'`
   --> $DIR/format-string-error-2.rs:21:5
    |
-LL |     format!("{ /n
+LL |     format!("{ \n
    |              - because of this opening brace
-LL | /n
+LL | \n
 LL |     e");
    |     ^ expected `}` in format string
    |
@@ -81,9 +81,9 @@ LL |     a
 error: invalid format string: expected `'}'`, found `'b'`
   --> $DIR/format-string-error-2.rs:35:5
    |
-LL |     { /
+LL |     { \
    |     - because of this opening brace
-LL |         /
+LL |         \
 LL |     b");
    |     ^ expected `}` in format string
    |
@@ -92,28 +92,28 @@ LL |     b");
 error: invalid format string: expected `'}'`, found `'b'`
   --> $DIR/format-string-error-2.rs:40:5
    |
-LL |     { /
+LL |     { \
    |     - because of this opening brace
-LL |         /
-LL |     b /
+LL |         \
+LL |     b \
    |     ^ expected `}` in format string
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'/'`
+error: invalid format string: expected `'}'`, found `'\'`
   --> $DIR/format-string-error-2.rs:45:8
    |
-LL | raw  { /
+LL | raw  { \
    |      - ^ expected `}` in format string
    |      |
    |      because of this opening brace
    |
    = note: if you intended to print `{`, you can escape it using `{{`
 
-error: invalid format string: expected `'}'`, found `'/'`
+error: invalid format string: expected `'}'`, found `'\'`
   --> $DIR/format-string-error-2.rs:50:8
    |
-LL | raw  { /n
+LL | raw  { \n
    |      - ^ expected `}` in format string
    |      |
    |      because of this opening brace
@@ -123,9 +123,9 @@ LL | raw  { /n
 error: invalid format string: expected `'}'`, found `'e'`
   --> $DIR/format-string-error-2.rs:57:5
    |
-LL |   { /n
+LL |   { \n
    |   - because of this opening brace
-LL | /n
+LL | \n
 LL |     e");
    |     ^ expected `}` in format string
    |
@@ -144,13 +144,13 @@ LL |     asdf}
 error: 1 positional argument in format string, but no arguments were given
   --> $DIR/format-string-error-2.rs:70:17
    |
-LL |     println!("/t{}");
+LL |     println!("\t{}");
    |                 ^^
 
 error: invalid format string: expected `'}'` but string was terminated
   --> $DIR/format-string-error-2.rs:74:27
    |
-LL |     println!("/x7B}/u{8} {", 1);
+LL |     println!("\x7B}\u{8} {", 1);
    |                          -^ expected `'}'` in format string
    |                          |
    |                          because of this opening brace
@@ -160,7 +160,7 @@ LL |     println!("/x7B}/u{8} {", 1);
 error: argument never used
   --> $DIR/format-string-error-2.rs:77:28
    |
-LL |     println!("/x7B}/u8 {", 1);
+LL |     println!("\x7B}\u8 {", 1);
    |              ------------  ^ argument never used
    |              |
    |              formatting specifier missing
@@ -168,7 +168,7 @@ LL |     println!("/x7B}/u8 {", 1);
 error: invalid format string: unmatched `}` found
   --> $DIR/format-string-error-2.rs:82:21
    |
-LL |     println!(r#"/x7B}/u{8} {"#, 1);
+LL |     println!(r#"\x7B}\u{8} {"#, 1);
    |                     ^ unmatched `}` in format string
    |
    = note: if you intended to print `}`, you can escape it using `}}`
@@ -176,7 +176,7 @@ LL |     println!(r#"/x7B}/u{8} {"#, 1);
 error: invalid format string: unmatched `}` found
   --> $DIR/format-string-error-2.rs:85:21
    |
-LL |     println!(r#"/x7B}/u8 {"#, 1);
+LL |     println!(r#"\x7B}\u8 {"#, 1);
    |                     ^ unmatched `}` in format string
    |
    = note: if you intended to print `}`, you can escape it using `}}`
diff --git a/src/test/ui/fmt/format-string-error.stderr b/src/test/ui/fmt/format-string-error.stderr
index 86ab163591e..3dc122a7399 100644
--- a/src/test/ui/fmt/format-string-error.stderr
+++ b/src/test/ui/fmt/format-string-error.stderr
@@ -50,10 +50,10 @@ LL |     let _ = format!("}");
    |
    = note: if you intended to print `}`, you can escape it using `}}`
 
-error: invalid format string: expected `'}'`, found `'/'`
+error: invalid format string: expected `'}'`, found `'\'`
   --> $DIR/format-string-error.rs:17:23
    |
-LL |     let _ = format!("{/}");
+LL |     let _ = format!("{\}");
    |                      -^ expected `}` in format string
    |                      |
    |                      because of this opening brace
@@ -63,7 +63,7 @@ LL |     let _ = format!("{/}");
 error: invalid format string: expected `'}'` but string was terminated
   --> $DIR/format-string-error.rs:19:35
    |
-LL |     let _ = format!("/n/n/n{/n/n/n");
+LL |     let _ = format!("\n\n\n{\n\n\n");
    |                            -      ^ expected `'}'` in format string
    |                            |
    |                            because of this opening brace
diff --git a/src/test/ui/issues/issue-13727.stderr b/src/test/ui/issues/issue-13727.stderr
index 0c2ce9f8b48..4d106651624 100644
--- a/src/test/ui/issues/issue-13727.stderr
+++ b/src/test/ui/issues/issue-13727.stderr
@@ -1,7 +1,7 @@
 error: unreachable pattern
   --> $DIR/issue-13727.rs:7:5
    |
-LL |     512 => print!("0b1111/n"),
+LL |     512 => print!("0b1111\n"),
    |     ^^^
    |
 note: lint level defined here
diff --git a/src/test/ui/macros/format-foreign.stderr b/src/test/ui/macros/format-foreign.stderr
index 87cadada3c7..e2f2f14dce3 100644
--- a/src/test/ui/macros/format-foreign.stderr
+++ b/src/test/ui/macros/format-foreign.stderr
@@ -1,7 +1,7 @@
 error: multiple unused formatting arguments
   --> $DIR/format-foreign.rs:2:30
    |
-LL |     println!("%.*3$s %s!/n", "Hello,", "World", 4);
+LL |     println!("%.*3$s %s!\n", "Hello,", "World", 4);
    |              --------------  ^^^^^^^^  ^^^^^^^  ^ argument never used
    |              |               |         |
    |              |               |         argument never used
@@ -11,7 +11,7 @@ LL |     println!("%.*3$s %s!/n", "Hello,", "World", 4);
    = note: printf formatting not supported; see the documentation for `std::fmt`
 help: format specifiers use curly braces
    |
-LL |     println!("{:.2$} {}!/n", "Hello,", "World", 4);
+LL |     println!("{:.2$} {}!\n", "Hello,", "World", 4);
    |               ^^^^^^ ^^
 
 error: argument never used
@@ -29,7 +29,7 @@ error: multiple unused formatting arguments
    |
 LL |       println!(r###"%.*3$s
    |  ______________-
-LL | |         %s!/n
+LL | |         %s!\n
 LL | | "###, "Hello,", "World", 4);
    | |    -  ^^^^^^^^  ^^^^^^^  ^ argument never used
    | |    |  |         |
@@ -41,7 +41,7 @@ LL | | "###, "Hello,", "World", 4);
 help: format specifiers use curly braces
    |
 LL |     println!(r###"{:.2$}
-LL |         {}!/n
+LL |         {}!\n
    |
 
 error: argument never used
diff --git a/src/test/ui/macros/macro-backtrace-println.stderr b/src/test/ui/macros/macro-backtrace-println.stderr
index 573184b63b1..209ff09aea4 100644
--- a/src/test/ui/macros/macro-backtrace-println.stderr
+++ b/src/test/ui/macros/macro-backtrace-println.stderr
@@ -1,7 +1,7 @@
 error: 1 positional argument in format string, but no arguments were given
   --> $DIR/macro-backtrace-println.rs:14:30
    |
-LL |     ($fmt:expr) => (myprint!(concat!($fmt, "/n")));
+LL |     ($fmt:expr) => (myprint!(concat!($fmt, "\n")));
    |                              ^^^^^^^^^^^^^^^^^^^
 ...
 LL |     myprintln!("{}");
diff --git a/src/test/ui/parser/ascii-only-character-escape.stderr b/src/test/ui/parser/ascii-only-character-escape.stderr
index 7524c4eccd9..8a981e8d62e 100644
--- a/src/test/ui/parser/ascii-only-character-escape.stderr
+++ b/src/test/ui/parser/ascii-only-character-escape.stderr
@@ -1,19 +1,19 @@
-error: this form of character escape may only be used with characters in the range [/x00-/x7f]
+error: this form of character escape may only be used with characters in the range [\x00-\x7f]
   --> $DIR/ascii-only-character-escape.rs:4:16
    |
-LL |     let x = "/x80";
+LL |     let x = "\x80";
    |                ^^
 
-error: this form of character escape may only be used with characters in the range [/x00-/x7f]
+error: this form of character escape may only be used with characters in the range [\x00-\x7f]
   --> $DIR/ascii-only-character-escape.rs:5:16
    |
-LL |     let y = "/xff";
+LL |     let y = "\xff";
    |                ^^
 
-error: this form of character escape may only be used with characters in the range [/x00-/x7f]
+error: this form of character escape may only be used with characters in the range [\x00-\x7f]
   --> $DIR/ascii-only-character-escape.rs:6:16
    |
-LL |     let z = "/xe2";
+LL |     let z = "\xe2";
    |                ^^
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/parser/bad-char-literals.stderr b/src/test/ui/parser/bad-char-literals.stderr
index eb048b08c71..8e96ea22771 100644
--- a/src/test/ui/parser/bad-char-literals.stderr
+++ b/src/test/ui/parser/bad-char-literals.stderr
@@ -4,7 +4,7 @@ error: character constant must be escaped: '
 LL |     ''';
    |      ^
 
-error: character constant must be escaped: /n
+error: character constant must be escaped: \n
   --> $DIR/bad-char-literals.rs:11:6
    |
 LL |       '
@@ -12,13 +12,13 @@ LL |       '
 LL | | ';
    | |_
 
-error: character constant must be escaped: /r
+error: character constant must be escaped: \r
   --> $DIR/bad-char-literals.rs:16:6
    |
 LL |     '
';
    |      ^
 
-error: character constant must be escaped: /t
+error: character constant must be escaped: \t
   --> $DIR/bad-char-literals.rs:19:6
    |
 LL |     '    ';
diff --git a/src/test/ui/parser/byte-literals.stderr b/src/test/ui/parser/byte-literals.stderr
index 4edeccfe475..28385f34f2a 100644
--- a/src/test/ui/parser/byte-literals.stderr
+++ b/src/test/ui/parser/byte-literals.stderr
@@ -1,22 +1,22 @@
 error: unknown byte escape: f
   --> $DIR/byte-literals.rs:6:21
    |
-LL | static FOO: u8 = b'/f';
+LL | static FOO: u8 = b'\f';
    |                     ^ unknown byte escape
 
 error: unknown byte escape: f
   --> $DIR/byte-literals.rs:9:8
    |
-LL |     b'/f';
+LL |     b'\f';
    |        ^ unknown byte escape
 
 error: invalid character in numeric character escape: Z
   --> $DIR/byte-literals.rs:10:10
    |
-LL |     b'/x0Z';
+LL |     b'\x0Z';
    |          ^
 
-error: byte constant must be escaped: /t
+error: byte constant must be escaped: \t
   --> $DIR/byte-literals.rs:11:7
    |
 LL |     b'    ';
@@ -28,7 +28,7 @@ error: byte constant must be escaped: '
 LL |     b''';
    |       ^
 
-error: byte constant must be ASCII. Use a /xHH escape for a non-ASCII byte
+error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte
   --> $DIR/byte-literals.rs:13:7
    |
 LL |     b'é';
diff --git a/src/test/ui/parser/byte-string-literals.stderr b/src/test/ui/parser/byte-string-literals.stderr
index 45c1a94b519..6701cfd8e66 100644
--- a/src/test/ui/parser/byte-string-literals.stderr
+++ b/src/test/ui/parser/byte-string-literals.stderr
@@ -1,22 +1,22 @@
 error: unknown byte escape: f
   --> $DIR/byte-string-literals.rs:6:32
    |
-LL | static FOO: &'static [u8] = b"/f";
+LL | static FOO: &'static [u8] = b"\f";
    |                                ^ unknown byte escape
 
 error: unknown byte escape: f
   --> $DIR/byte-string-literals.rs:9:8
    |
-LL |     b"/f";
+LL |     b"\f";
    |        ^ unknown byte escape
 
 error: invalid character in numeric character escape: Z
   --> $DIR/byte-string-literals.rs:10:10
    |
-LL |     b"/x0Z";
+LL |     b"\x0Z";
    |          ^
 
-error: byte constant must be ASCII. Use a /xHH escape for a non-ASCII byte
+error: byte constant must be ASCII. Use a \xHH escape for a non-ASCII byte
   --> $DIR/byte-string-literals.rs:11:7
    |
 LL |     b"é";
diff --git a/src/test/ui/parser/issue-23620-invalid-escapes.stderr b/src/test/ui/parser/issue-23620-invalid-escapes.stderr
index 669a6d26905..295ba3b73e8 100644
--- a/src/test/ui/parser/issue-23620-invalid-escapes.stderr
+++ b/src/test/ui/parser/issue-23620-invalid-escapes.stderr
@@ -1,118 +1,118 @@
 error: unicode escape sequences cannot be used as a byte or in a byte string
   --> $DIR/issue-23620-invalid-escapes.rs:4:15
    |
-LL |     let _ = b"/u{a66e}";
+LL |     let _ = b"\u{a66e}";
    |               ^^^^^^^^
 
 error: unicode escape sequences cannot be used as a byte or in a byte string
   --> $DIR/issue-23620-invalid-escapes.rs:7:15
    |
-LL |     let _ = b'/u{a66e}';
+LL |     let _ = b'\u{a66e}';
    |               ^^^^^^^^
 
 error: incorrect unicode escape sequence
   --> $DIR/issue-23620-invalid-escapes.rs:10:15
    |
-LL |     let _ = b'/u';
+LL |     let _ = b'\u';
    |               ^^ incorrect unicode escape sequence
    |
-   = help: format of unicode escape sequences is `/u{...}`
+   = help: format of unicode escape sequences is `\u{...}`
 
 error: unicode escape sequences cannot be used as a byte or in a byte string
   --> $DIR/issue-23620-invalid-escapes.rs:10:15
    |
-LL |     let _ = b'/u';
+LL |     let _ = b'\u';
    |               ^^
 
 error: numeric character escape is too short
   --> $DIR/issue-23620-invalid-escapes.rs:14:17
    |
-LL |     let _ = b'/x5';
+LL |     let _ = b'\x5';
    |                 ^
 
 error: invalid character in numeric character escape: x
   --> $DIR/issue-23620-invalid-escapes.rs:17:17
    |
-LL |     let _ = b'/xxy';
+LL |     let _ = b'\xxy';
    |                 ^
 
 error: invalid character in numeric character escape: y
   --> $DIR/issue-23620-invalid-escapes.rs:17:18
    |
-LL |     let _ = b'/xxy';
+LL |     let _ = b'\xxy';
    |                  ^
 
 error: numeric character escape is too short
   --> $DIR/issue-23620-invalid-escapes.rs:21:16
    |
-LL |     let _ = '/x5';
+LL |     let _ = '\x5';
    |                ^
 
 error: invalid character in numeric character escape: x
   --> $DIR/issue-23620-invalid-escapes.rs:24:16
    |
-LL |     let _ = '/xxy';
+LL |     let _ = '\xxy';
    |                ^
 
 error: invalid character in numeric character escape: y
   --> $DIR/issue-23620-invalid-escapes.rs:24:17
    |
-LL |     let _ = '/xxy';
+LL |     let _ = '\xxy';
    |                 ^
 
 error: unicode escape sequences cannot be used as a byte or in a byte string
   --> $DIR/issue-23620-invalid-escapes.rs:28:15
    |
-LL |     let _ = b"/u{a4a4} /xf /u";
+LL |     let _ = b"\u{a4a4} \xf \u";
    |               ^^^^^^^^
 
 error: invalid character in numeric character escape:  
   --> $DIR/issue-23620-invalid-escapes.rs:28:27
    |
-LL |     let _ = b"/u{a4a4} /xf /u";
+LL |     let _ = b"\u{a4a4} \xf \u";
    |                           ^
 
 error: incorrect unicode escape sequence
   --> $DIR/issue-23620-invalid-escapes.rs:28:28
    |
-LL |     let _ = b"/u{a4a4} /xf /u";
+LL |     let _ = b"\u{a4a4} \xf \u";
    |                            ^^ incorrect unicode escape sequence
    |
-   = help: format of unicode escape sequences is `/u{...}`
+   = help: format of unicode escape sequences is `\u{...}`
 
 error: unicode escape sequences cannot be used as a byte or in a byte string
   --> $DIR/issue-23620-invalid-escapes.rs:28:28
    |
-LL |     let _ = b"/u{a4a4} /xf /u";
+LL |     let _ = b"\u{a4a4} \xf \u";
    |                            ^^
 
 error: invalid character in numeric character escape:  
   --> $DIR/issue-23620-invalid-escapes.rs:34:17
    |
-LL |     let _ = "/xf /u";
+LL |     let _ = "\xf \u";
    |                 ^
 
-error: this form of character escape may only be used with characters in the range [/x00-/x7f]
+error: this form of character escape may only be used with characters in the range [\x00-\x7f]
   --> $DIR/issue-23620-invalid-escapes.rs:34:16
    |
-LL |     let _ = "/xf /u";
+LL |     let _ = "\xf \u";
    |                ^^
 
 error: incorrect unicode escape sequence
   --> $DIR/issue-23620-invalid-escapes.rs:34:18
    |
-LL |     let _ = "/xf /u";
+LL |     let _ = "\xf \u";
    |                  ^^ incorrect unicode escape sequence
    |
-   = help: format of unicode escape sequences is `/u{...}`
+   = help: format of unicode escape sequences is `\u{...}`
 
 error: incorrect unicode escape sequence
   --> $DIR/issue-23620-invalid-escapes.rs:39:14
    |
-LL |     let _ = "/u8f";
+LL |     let _ = "\u8f";
    |              ^^--
    |              |
-   |              help: format of unicode escape sequences uses braces: `/u{8f}`
+   |              help: format of unicode escape sequences uses braces: `\u{8f}`
 
 error: aborting due to 18 previous errors
 
diff --git a/src/test/ui/parser/issue-43692.stderr b/src/test/ui/parser/issue-43692.stderr
index 9408182f952..69a54af3d82 100644
--- a/src/test/ui/parser/issue-43692.stderr
+++ b/src/test/ui/parser/issue-43692.stderr
@@ -1,7 +1,7 @@
 error: invalid start of unicode escape
   --> $DIR/issue-43692.rs:2:9
    |
-LL |     '/u{_10FFFF}';
+LL |     '\u{_10FFFF}';
    |         ^
 
 error: aborting due to previous error
diff --git a/src/test/ui/parser/lex-bad-char-literals-1.stderr b/src/test/ui/parser/lex-bad-char-literals-1.stderr
index e6b71108086..414ad81512a 100644
--- a/src/test/ui/parser/lex-bad-char-literals-1.stderr
+++ b/src/test/ui/parser/lex-bad-char-literals-1.stderr
@@ -1,25 +1,25 @@
 error: numeric character escape is too short
   --> $DIR/lex-bad-char-literals-1.rs:3:8
    |
-LL |     '/x1'
+LL |     '\x1'
    |        ^
 
 error: numeric character escape is too short
   --> $DIR/lex-bad-char-literals-1.rs:7:8
    |
-LL |     "/x1"
+LL |     "\x1"
    |        ^
 
-error: unknown character escape: /u{25cf}
+error: unknown character escape: \u{25cf}
   --> $DIR/lex-bad-char-literals-1.rs:11:7
    |
-LL |     '/●'
+LL |     '\●'
    |       ^ unknown character escape
 
-error: unknown character escape: /u{25cf}
+error: unknown character escape: \u{25cf}
   --> $DIR/lex-bad-char-literals-1.rs:15:7
    |
-LL |     "/●"
+LL |     "\●"
    |       ^ unknown character escape
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/parser/lex-bad-char-literals-5.stderr b/src/test/ui/parser/lex-bad-char-literals-5.stderr
index ef029733101..97c6338820d 100644
--- a/src/test/ui/parser/lex-bad-char-literals-5.stderr
+++ b/src/test/ui/parser/lex-bad-char-literals-5.stderr
@@ -1,21 +1,21 @@
 error: character literal may only contain one codepoint
   --> $DIR/lex-bad-char-literals-5.rs:1:18
    |
-LL | static c: char = '/x10/x10';
+LL | static c: char = '\x10\x10';
    |                  ^^^^^^^^^^
 help: if you meant to write a `str` literal, use double quotes
    |
-LL | static c: char = "/x10/x10";
+LL | static c: char = "\x10\x10";
    |                  ^^^^^^^^^^
 
 error: character literal may only contain one codepoint
   --> $DIR/lex-bad-char-literals-5.rs:5:20
    |
-LL |     let ch: &str = '/x10/x10';
+LL |     let ch: &str = '\x10\x10';
    |                    ^^^^^^^^^^
 help: if you meant to write a `str` literal, use double quotes
    |
-LL |     let ch: &str = "/x10/x10";
+LL |     let ch: &str = "\x10\x10";
    |                    ^^^^^^^^^^
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/parser/lex-bad-token.stderr b/src/test/ui/parser/lex-bad-token.stderr
index c0c2e542058..43c43721b19 100644
--- a/src/test/ui/parser/lex-bad-token.stderr
+++ b/src/test/ui/parser/lex-bad-token.stderr
@@ -1,4 +1,4 @@
-error: unknown start of token: /u{25cf}
+error: unknown start of token: \u{25cf}
   --> $DIR/lex-bad-token.rs:1:1
    |
 LL | ●
diff --git a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr
index b4d538bf613..7d944569ca9 100644
--- a/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr
+++ b/src/test/ui/parser/lex-bare-cr-string-literal-doc-comment.stderr
@@ -22,22 +22,22 @@ error: bare CR not allowed in block doc-comment
 LL |     /*! block doc comment with bare CR: '
' */
    |                                          ^
 
-error: bare CR not allowed in string, use /r instead
+error: bare CR not allowed in string, use \r instead
   --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:21:18
    |
 LL |     let _s = "foo
bar";
    |                  ^
 
-error: bare CR not allowed in raw string, use /r instead
+error: bare CR not allowed in raw string, use \r instead
   --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:24:14
    |
 LL |     let _s = r"bar
foo";
    |              ^^^^^
 
-error: unknown character escape: /r
+error: unknown character escape: \r
   --> $DIR/lex-bare-cr-string-literal-doc-comment.rs:27:19
    |
-LL |     let _s = "foo/
bar";
+LL |     let _s = "foo\
bar";
    |                   ^ unknown character escape
    |
    = help: this is an isolated carriage return; consider checking your editor and version control settings
diff --git a/src/test/ui/parser/lex-stray-backslash.stderr b/src/test/ui/parser/lex-stray-backslash.stderr
index 7ce061b8be0..06dc0f2b537 100644
--- a/src/test/ui/parser/lex-stray-backslash.stderr
+++ b/src/test/ui/parser/lex-stray-backslash.stderr
@@ -1,7 +1,7 @@
-error: unknown start of token: /
+error: unknown start of token: \
   --> $DIR/lex-stray-backslash.rs:1:1
    |
-LL | /
+LL | \
    | ^
 
 error: aborting due to previous error
diff --git a/src/test/ui/parser/new-unicode-escapes-1.stderr b/src/test/ui/parser/new-unicode-escapes-1.stderr
index 5a191735307..a8da50951dd 100644
--- a/src/test/ui/parser/new-unicode-escapes-1.stderr
+++ b/src/test/ui/parser/new-unicode-escapes-1.stderr
@@ -1,7 +1,7 @@
 error: unterminated unicode escape (needed a `}`)
   --> $DIR/new-unicode-escapes-1.rs:2:21
    |
-LL |     let s = "/u{2603";
+LL |     let s = "\u{2603";
    |                     ^
 
 error: aborting due to previous error
diff --git a/src/test/ui/parser/new-unicode-escapes-2.stderr b/src/test/ui/parser/new-unicode-escapes-2.stderr
index 0fb8befa45b..ede49cdf7e1 100644
--- a/src/test/ui/parser/new-unicode-escapes-2.stderr
+++ b/src/test/ui/parser/new-unicode-escapes-2.stderr
@@ -1,7 +1,7 @@
 error: overlong unicode escape (must have at most 6 hex digits)
   --> $DIR/new-unicode-escapes-2.rs:2:17
    |
-LL |     let s = "/u{260311111111}";
+LL |     let s = "\u{260311111111}";
    |                 ^^^^^^^^^^^^
 
 error: aborting due to previous error
diff --git a/src/test/ui/parser/new-unicode-escapes-3.stderr b/src/test/ui/parser/new-unicode-escapes-3.stderr
index 427426788f6..59cfb988f28 100644
--- a/src/test/ui/parser/new-unicode-escapes-3.stderr
+++ b/src/test/ui/parser/new-unicode-escapes-3.stderr
@@ -1,7 +1,7 @@
 error: invalid unicode character escape
   --> $DIR/new-unicode-escapes-3.rs:2:14
    |
-LL |     let s1 = "/u{d805}";
+LL |     let s1 = "\u{d805}";
    |              ^^^^^^^^^^
    |
    = help: unicode escape must not be a surrogate
@@ -9,7 +9,7 @@ LL |     let s1 = "/u{d805}";
 error: invalid unicode character escape
   --> $DIR/new-unicode-escapes-3.rs:3:14
    |
-LL |     let s2 = "/u{ffffff}";
+LL |     let s2 = "\u{ffffff}";
    |              ^^^^^^^^^^^^
    |
    = help: unicode escape must be at most 10FFFF
diff --git a/src/test/ui/parser/new-unicode-escapes-4.stderr b/src/test/ui/parser/new-unicode-escapes-4.stderr
index c8dbe027184..ca96b00aa7b 100644
--- a/src/test/ui/parser/new-unicode-escapes-4.stderr
+++ b/src/test/ui/parser/new-unicode-escapes-4.stderr
@@ -1,7 +1,7 @@
 error: invalid character in unicode escape: l
   --> $DIR/new-unicode-escapes-4.rs:4:17
    |
-LL |     let s = "/u{lol}";
+LL |     let s = "\u{lol}";
    |                 ^
 
 error: aborting due to previous error
diff --git a/src/test/ui/parser/raw-byte-string-literals.stderr b/src/test/ui/parser/raw-byte-string-literals.stderr
index 5670ed6590a..a7f1af0a347 100644
--- a/src/test/ui/parser/raw-byte-string-literals.stderr
+++ b/src/test/ui/parser/raw-byte-string-literals.stderr
@@ -1,4 +1,4 @@
-error: raw byte string must be ASCII: /u{e9}
+error: raw byte string must be ASCII: \u{e9}
   --> $DIR/raw-byte-string-literals.rs:5:8
    |
 LL |     br"é";
diff --git a/src/test/ui/parser/trailing-carriage-return-in-string.stderr b/src/test/ui/parser/trailing-carriage-return-in-string.stderr
index f70f8ac8d77..3687b9dd282 100644
--- a/src/test/ui/parser/trailing-carriage-return-in-string.stderr
+++ b/src/test/ui/parser/trailing-carriage-return-in-string.stderr
@@ -1,7 +1,7 @@
-error: unknown character escape: /r
+error: unknown character escape: \r
   --> $DIR/trailing-carriage-return-in-string.rs:10:25
    |
-LL |     let bad = "This is /
 a test";
+LL |     let bad = "This is \
 a test";
    |                         ^ unknown character escape
    |
    = help: this is an isolated carriage return; consider checking your editor and version control settings
diff --git a/src/test/ui/parser/unicode-chars.stderr b/src/test/ui/parser/unicode-chars.stderr
index 3a360d8f468..76bf6627a4b 100644
--- a/src/test/ui/parser/unicode-chars.stderr
+++ b/src/test/ui/parser/unicode-chars.stderr
@@ -1,4 +1,4 @@
-error: unknown start of token: /u{37e}
+error: unknown start of token: \u{37e}
   --> $DIR/unicode-chars.rs:2:14
    |
 LL |     let y = 0;
diff --git a/src/test/ui/parser/unicode-quote-chars.stderr b/src/test/ui/parser/unicode-quote-chars.stderr
index 315e20cf854..4a09ed75605 100644
--- a/src/test/ui/parser/unicode-quote-chars.stderr
+++ b/src/test/ui/parser/unicode-quote-chars.stderr
@@ -1,4 +1,4 @@
-error: unknown start of token: /u{201c}
+error: unknown start of token: \u{201c}
   --> $DIR/unicode-quote-chars.rs:4:14
    |
 LL |     println!(“hello world”);
diff --git a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr
index 346eba04c65..1406b795ba8 100644
--- a/src/test/ui/parser/wrong-escape-of-curly-braces.stderr
+++ b/src/test/ui/parser/wrong-escape-of-curly-braces.stderr
@@ -1,7 +1,7 @@
 error: unknown character escape: {
   --> $DIR/wrong-escape-of-curly-braces.rs:3:17
    |
-LL |     let bad = "/{it is wrong/}";
+LL |     let bad = "\{it is wrong\}";
    |                 ^ unknown character escape
    |
    = help: if used in a formatting string, curly braces are escaped with `{{` and `}}`
@@ -9,7 +9,7 @@ LL |     let bad = "/{it is wrong/}";
 error: unknown character escape: }
   --> $DIR/wrong-escape-of-curly-braces.rs:3:30
    |
-LL |     let bad = "/{it is wrong/}";
+LL |     let bad = "\{it is wrong\}";
    |                              ^ unknown character escape
    |
    = help: if used in a formatting string, curly braces are escaped with `{{` and `}}`
diff --git a/src/test/ui/regions/region-bound-on-closure-outlives-call.nll.stderr b/src/test/ui/regions/region-bound-on-closure-outlives-call.nll.stderr
index bce310bafaa..d455902ee8c 100644
--- a/src/test/ui/regions/region-bound-on-closure-outlives-call.nll.stderr
+++ b/src/test/ui/regions/region-bound-on-closure-outlives-call.nll.stderr
@@ -14,11 +14,10 @@ error[E0505]: cannot move out of `f` because it is borrowed
   --> $DIR/region-bound-on-closure-outlives-call.rs:3:25
    |
 LL |     (|x| f(x))(call_rec(f))
-   |     ----------          ^ move out of `f` occurs here
-   |     ||   |
-   |     ||   borrow occurs due to use in closure
-   |     |borrow of `f` occurs here
-   |     borrow later used by call
+   |      --- -              ^ move out of `f` occurs here
+   |      |   |
+   |      |   borrow occurs due to use in closure
+   |      borrow of `f` occurs here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr
index 80dc3ef2f80..1a5ab7a7d56 100644
--- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr
+++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr
@@ -42,7 +42,6 @@ LL |     f(Box::new(|a| {
    |     -          ^^^ move out of `f` occurs here
    |     |
    |     borrow of `f` occurs here
-   |     borrow later used by call
 LL |         foo(f);
    |             - move occurs due to use in closure
 
diff --git a/src/test/ui/suggestions/borrow-for-loop-head.nll.stderr b/src/test/ui/suggestions/borrow-for-loop-head.nll.stderr
index 6450f7f52a4..96dbdec7074 100644
--- a/src/test/ui/suggestions/borrow-for-loop-head.nll.stderr
+++ b/src/test/ui/suggestions/borrow-for-loop-head.nll.stderr
@@ -2,10 +2,7 @@ error[E0505]: cannot move out of `a` because it is borrowed
   --> $DIR/borrow-for-loop-head.rs:4:18
    |
 LL |     for i in &a {
-   |              --
-   |              |
-   |              borrow of `a` occurs here
-   |              borrow later used here
+   |              -- borrow of `a` occurs here
 LL |         for j in a {
    |                  ^ move out of `a` occurs here
 
@@ -17,6 +14,10 @@ LL |     let a = vec![1, 2, 3];
 LL |     for i in &a {
 LL |         for j in a {
    |                  ^ value moved here, in previous iteration of loop
+help: consider borrowing this to avoid moving it into the for loop
+   |
+LL |         for j in &a {
+   |                  ^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index c1920dde5b1..089cbc7b78a 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -246,6 +246,11 @@ pub struct Config {
     /// mode describing what file the actual ui output will be compared to
     pub compare_mode: Option<CompareMode>,
 
+    /// If true, this will generate a coverage file with UI test files that run `MachineApplicable`
+    /// diagnostics but are missing `run-rustfix` annotations. The generated coverage file is
+    /// created in `/<build_base>/rustfix_missing_coverage.txt`
+    pub rustfix_coverage: bool,
+
     // Configuration for various run-make tests frobbing things like C compilers
     // or querying about various LLVM component information.
     pub cc: String,
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index d91710dda52..dfc023da973 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -233,6 +233,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
             "mode describing what file the actual ui output will be compared to",
             "COMPARE MODE",
         )
+        .optflag(
+            "",
+            "rustfix-coverage",
+            "enable this to generate a Rustfix coverage file, which is saved in \
+                `./<build_base>/rustfix_missing_coverage.txt`",
+        )
         .optflag("h", "help", "show this message");
 
     let (argv0, args_) = args.split_first().unwrap();
@@ -336,6 +342,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         color,
         remote_test_client: matches.opt_str("remote-test-client").map(PathBuf::from),
         compare_mode: matches.opt_str("compare-mode").map(CompareMode::parse),
+        rustfix_coverage: matches.opt_present("rustfix-coverage"),
 
         cc: matches.opt_str("cc").unwrap(),
         cxx: matches.opt_str("cxx").unwrap(),
@@ -475,6 +482,19 @@ pub fn run_tests(config: &Config) {
         let _ = fs::remove_dir_all("tmp/partitioning-tests");
     }
 
+    // If we want to collect rustfix coverage information,
+    // we first make sure that the coverage file does not exist.
+    // It will be created later on.
+    if config.rustfix_coverage {
+        let mut coverage_file_path = config.build_base.clone();
+        coverage_file_path.push("rustfix_missing_coverage.txt");
+        if coverage_file_path.exists() {
+            if let Err(e) = fs::remove_file(&coverage_file_path) {
+                panic!("Could not delete {} due to {}", coverage_file_path.display(), e)
+            }
+        }
+    }
+
     let opts = test_opts(config);
     let tests = make_tests(config);
     // sadly osx needs some file descriptor limits raised for running tests in
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 3e3499edf60..35f8dca79b5 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -10,7 +10,7 @@ use crate::errors::{self, Error, ErrorKind};
 use filetime::FileTime;
 use crate::header::TestProps;
 use crate::json;
-use regex::Regex;
+use regex::{Captures, Regex};
 use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
 use crate::util::{logv, PathBufExt};
 
@@ -19,7 +19,7 @@ use std::collections::{HashMap, HashSet, VecDeque};
 use std::env;
 use std::ffi::{OsStr, OsString};
 use std::fmt;
-use std::fs::{self, create_dir_all, File};
+use std::fs::{self, create_dir_all, File, OpenOptions};
 use std::hash::{Hash, Hasher};
 use std::io::prelude::*;
 use std::io::{self, BufReader};
@@ -2818,6 +2818,31 @@ impl<'test> TestCx<'test> {
 
         if self.config.compare_mode.is_some() {
             // don't test rustfix with nll right now
+        } else if self.config.rustfix_coverage {
+            // Find out which tests have `MachineApplicable` suggestions but are missing
+            // `run-rustfix` or `run-rustfix-only-machine-applicable` headers
+            let suggestions = get_suggestions_from_json(
+                &proc_res.stderr,
+                &HashSet::new(),
+                Filter::MachineApplicableOnly
+            ).unwrap();
+            if suggestions.len() > 0
+                && !self.props.run_rustfix
+                && !self.props.rustfix_only_machine_applicable {
+                    let mut coverage_file_path = self.config.build_base.clone();
+                    coverage_file_path.push("rustfix_missing_coverage.txt");
+                    debug!("coverage_file_path: {}", coverage_file_path.display());
+
+                    let mut file = OpenOptions::new()
+                        .create(true)
+                        .append(true)
+                        .open(coverage_file_path.as_path())
+                        .expect("could not create or open file");
+
+                    if let Err(_) = writeln!(file, "{}", self.testpaths.file.display()) {
+                        panic!("couldn't write to {}", coverage_file_path.display());
+                    }
+            }
         } else if self.props.run_rustfix {
             // Apply suggestions from rustc to the code itself
             let unfixed_code = self
@@ -3147,10 +3172,8 @@ impl<'test> TestCx<'test> {
         normalized = Regex::new("SRC_DIR(.+):\\d+:\\d+").unwrap()
             .replace_all(&normalized, "SRC_DIR$1:LL:COL").into_owned();
 
-        normalized = normalized.replace("\\\\", "\\") // denormalize for paths on windows
-              .replace("\\", "/") // normalize for paths on windows
-              .replace("\r\n", "\n") // normalize for linebreaks on windows
-              .replace("\t", "\\t"); // makes tabs visible
+        normalized = Self::normalize_platform_differences(&normalized);
+        normalized = normalized.replace("\t", "\\t"); // makes tabs visible
 
         // Remove test annotations like `//~ ERROR text` from the output,
         // since they duplicate actual errors and make the output hard to read.
@@ -3164,6 +3187,36 @@ impl<'test> TestCx<'test> {
         normalized
     }
 
+    /// Normalize output differences across platforms. Generally changes Windows output to be more
+    /// Unix-like.
+    ///
+    /// Replaces backslashes in paths with forward slashes, and replaces CRLF line endings
+    /// with LF.
+    fn normalize_platform_differences(output: &str) -> String {
+        lazy_static! {
+            /// Used to find Windows paths.
+            ///
+            /// It's not possible to detect paths in the error messages generally, but this is a
+            /// decent enough heuristic.
+            static ref PATH_BACKSLASH_RE: Regex = Regex::new(r#"(?x)
+                (?:
+                  # Match paths that don't include spaces.
+                  (?:\\[\pL\pN\.\-_']+)+\.\pL+
+                |
+                  # If the path starts with a well-known root, then allow spaces.
+                  \$(?:DIR|SRC_DIR|TEST_BUILD_DIR|BUILD_DIR|LIB_DIR)(?:\\[\pL\pN\.\-_' ]+)+
+                )"#
+            ).unwrap();
+        }
+
+        let output = output.replace(r"\\", r"\");
+
+        PATH_BACKSLASH_RE.replace_all(&output, |caps: &Captures<'_>| {
+            println!("{}", &caps[0]);
+            caps[0].replace(r"\", "/")
+        }).replace("\r\n", "\n")
+    }
+
     fn expected_output_path(&self, kind: &str) -> PathBuf {
         let mut path = expected_output_path(
             &self.testpaths,
@@ -3495,3 +3548,68 @@ fn read2_abbreviated(mut child: Child) -> io::Result<Output> {
         stderr: stderr.into_bytes(),
     })
 }
+
+#[cfg(test)]
+mod tests {
+    use super::TestCx;
+
+    #[test]
+    fn normalize_platform_differences() {
+        assert_eq!(
+            TestCx::normalize_platform_differences(r"$DIR\foo.rs"),
+            "$DIR/foo.rs"
+        );
+        assert_eq!(
+            TestCx::normalize_platform_differences(r"$BUILD_DIR\..\parser.rs"),
+            "$BUILD_DIR/../parser.rs"
+        );
+        assert_eq!(
+            TestCx::normalize_platform_differences(r"$DIR\bar.rs hello\nworld"),
+            r"$DIR/bar.rs hello\nworld"
+        );
+        assert_eq!(
+            TestCx::normalize_platform_differences(r"either bar\baz.rs or bar\baz\mod.rs"),
+            r"either bar/baz.rs or bar/baz/mod.rs",
+        );
+        assert_eq!(
+            TestCx::normalize_platform_differences(r"`.\some\path.rs`"),
+            r"`./some/path.rs`",
+        );
+        assert_eq!(
+            TestCx::normalize_platform_differences(r"`some\path.rs`"),
+            r"`some/path.rs`",
+        );
+        assert_eq!(
+            TestCx::normalize_platform_differences(r"$DIR\path-with-dashes.rs"),
+            r"$DIR/path-with-dashes.rs"
+        );
+        assert_eq!(
+            TestCx::normalize_platform_differences(r"$DIR\path_with_underscores.rs"),
+            r"$DIR/path_with_underscores.rs",
+        );
+        assert_eq!(
+            TestCx::normalize_platform_differences(r"$DIR\foo.rs:12:11"), "$DIR/foo.rs:12:11",
+        );
+        assert_eq!(
+            TestCx::normalize_platform_differences(r"$DIR\path with spaces 'n' quotes"),
+            "$DIR/path with spaces 'n' quotes",
+        );
+        assert_eq!(
+            TestCx::normalize_platform_differences(r"$DIR\file_with\no_extension"),
+            "$DIR/file_with/no_extension",
+        );
+
+        assert_eq!(TestCx::normalize_platform_differences(r"\n"), r"\n");
+        assert_eq!(TestCx::normalize_platform_differences(r"{ \n"), r"{ \n");
+        assert_eq!(TestCx::normalize_platform_differences(r"`\]`"), r"`\]`");
+        assert_eq!(TestCx::normalize_platform_differences(r#""\{""#), r#""\{""#);
+        assert_eq!(
+            TestCx::normalize_platform_differences(r#"write!(&mut v, "Hello\n")"#),
+            r#"write!(&mut v, "Hello\n")"#
+        );
+        assert_eq!(
+            TestCx::normalize_platform_differences(r#"println!("test\ntest")"#),
+            r#"println!("test\ntest")"#,
+        );
+    }
+}