about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-03-24 06:14:41 +0000
committerbors <bors@rust-lang.org>2020-03-24 06:14:41 +0000
commit9d0ae58d30523198dec60a9cd840c30c2bd9c4c0 (patch)
tree0ec28589d74b37976a4d11ffce40912d4c490270
parent342c5f33d097b2dc07a2dbc0ca45a37379d2ff60 (diff)
parent170112cd1503aa6c220ba108441ee1d384beb9bc (diff)
downloadrust-9d0ae58d30523198dec60a9cd840c30c2bd9c4c0.tar.gz
rust-9d0ae58d30523198dec60a9cd840c30c2bd9c4c0.zip
Auto merge of #70351 - Centril:rollup-tveoq3w, r=Centril
Rollup of 8 pull requests

Successful merges:

 - #68884 (Make the `type_of` return a generic type for generators)
 - #69788 (Fix sequence of Type and Trait in optin-builtin-traits in Unstable Book)
 - #70074 (Expand: nix all fatal errors)
 - #70077 (Store idents for `DefPathData` into crate metadata)
 - #70213 (traits/fulfill: allow `stalled_on` to track `ty::Const::Infer(_)` (unused yet).)
 - #70259 (Use Reveal::All in MIR optimizations)
 - #70284 (correctly handle const params in type_of)
 - #70289 (Refactor `codegen`)

Failed merges:

r? @ghost
-rw-r--r--src/doc/unstable-book/src/language-features/optin-builtin-traits.md2
-rw-r--r--src/librustc_builtin_macros/cmdline_attrs.rs9
-rw-r--r--src/librustc_builtin_macros/source_util.rs24
-rw-r--r--src/librustc_builtin_macros/test.rs16
-rw-r--r--src/librustc_builtin_macros/test_harness.rs20
-rw-r--r--src/librustc_codegen_llvm/back/write.rs174
-rw-r--r--src/librustc_codegen_ssa/back/write.rs39
-rw-r--r--src/librustc_expand/base.rs69
-rw-r--r--src/librustc_expand/expand.rs16
-rw-r--r--src/librustc_expand/lib.rs19
-rw-r--r--src/librustc_expand/mbe/macro_parser.rs29
-rw-r--r--src/librustc_expand/mbe/macro_rules.rs144
-rw-r--r--src/librustc_expand/mbe/transcribe.rs27
-rw-r--r--src/librustc_expand/proc_macro.rs67
-rw-r--r--src/librustc_hir/def.rs1
-rw-r--r--src/librustc_infer/infer/mod.rs134
-rw-r--r--src/librustc_metadata/rmeta/decoder.rs56
-rw-r--r--src/librustc_metadata/rmeta/decoder/cstore_impl.rs6
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs23
-rw-r--r--src/librustc_metadata/rmeta/mod.rs1
-rw-r--r--src/librustc_mir/transform/const_prop.rs9
-rw-r--r--src/librustc_mir/transform/inline.rs13
-rw-r--r--src/librustc_mir_build/build/mod.rs3
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs5
-rw-r--r--src/librustc_trait_selection/traits/fulfill.rs54
-rw-r--r--src/librustc_typeck/collect/type_of.rs42
-rw-r--r--src/librustc_typeck/lib.rs1
-rw-r--r--src/test/mir-opt/const_prop/control-flow-simplification.rs64
-rw-r--r--src/test/ui/async-await/async-block-control-flow-static-semantics.stderr32
-rw-r--r--src/test/ui/async-await/async-error-span.rs1
-rw-r--r--src/test/ui/async-await/async-error-span.stderr20
-rw-r--r--src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs1
-rw-r--r--src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr49
-rw-r--r--src/test/ui/async-await/issue-67651.rs20
-rw-r--r--src/test/ui/async-await/issue-67651.stderr12
-rw-r--r--src/test/ui/async-await/issues/issue-63388-2.nll.stderr13
-rw-r--r--src/test/ui/async-await/issues/issue-63388-2.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-63388-2.stderr17
-rw-r--r--src/test/ui/async-await/issues/issue-65159.rs1
-rw-r--r--src/test/ui/async-await/issues/issue-65159.stderr11
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs3
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr39
-rw-r--r--src/test/ui/const-generics/issues/issue70273-assoc-fn.rs17
-rw-r--r--src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr8
-rw-r--r--src/test/ui/const-generics/type_of_anon_const.rs21
-rw-r--r--src/test/ui/const-generics/type_of_anon_const.stderr8
-rw-r--r--src/test/ui/copy-a-resource.rs5
-rw-r--r--src/test/ui/copy-a-resource.stderr10
-rw-r--r--src/test/ui/derives/derive-assoc-type-not-impl.rs5
-rw-r--r--src/test/ui/derives/derive-assoc-type-not-impl.stderr10
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2015-parsing.rs10
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr21
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2018-parsing.rs10
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr21
-rw-r--r--src/test/ui/error-codes/E0004-2.rs5
-rw-r--r--src/test/ui/error-codes/E0004-2.stderr10
-rw-r--r--src/test/ui/error-codes/E0005.rs5
-rw-r--r--src/test/ui/error-codes/E0005.stderr7
-rw-r--r--src/test/ui/error-codes/E0297.rs5
-rw-r--r--src/test/ui/error-codes/E0297.stderr7
-rw-r--r--src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs5
-rw-r--r--src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr7
-rw-r--r--src/test/ui/generic-associated-types/iterable.rs5
-rw-r--r--src/test/ui/generic-associated-types/iterable.stderr18
-rw-r--r--src/test/ui/impl-trait/no-method-suggested-traits.stderr10
-rw-r--r--src/test/ui/issues/issue-2823.rs5
-rw-r--r--src/test/ui/issues/issue-2823.stderr10
-rw-r--r--src/test/ui/issues/issue-69725.rs5
-rw-r--r--src/test/ui/issues/issue-69725.stderr10
-rw-r--r--src/test/ui/macros/issue-61033-1.rs3
-rw-r--r--src/test/ui/macros/issue-61033-1.stderr11
-rw-r--r--src/test/ui/macros/issue-61033-2.rs8
-rw-r--r--src/test/ui/macros/issue-61033-2.stderr15
-rw-r--r--src/test/ui/macros/local-ambiguity-multiple-parsing-options.rs8
-rw-r--r--src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr14
-rw-r--r--src/test/ui/macros/macro-context.rs2
-rw-r--r--src/test/ui/macros/macro-context.stderr26
-rw-r--r--src/test/ui/macros/macro-match-nonterminal.rs9
-rw-r--r--src/test/ui/macros/macro-match-nonterminal.stderr18
-rw-r--r--src/test/ui/macros/trace_faulty_macros.rs12
-rw-r--r--src/test/ui/macros/trace_faulty_macros.stderr23
-rw-r--r--src/test/ui/non-copyable-void.rs5
-rw-r--r--src/test/ui/non-copyable-void.stderr10
-rw-r--r--src/test/ui/noncopyable-class.rs5
-rw-r--r--src/test/ui/noncopyable-class.stderr10
-rw-r--r--src/test/ui/parser/issue-62894.rs5
-rw-r--r--src/test/ui/parser/issue-62894.stderr13
-rw-r--r--src/test/ui/parser/macro/issue-33569.rs2
-rw-r--r--src/test/ui/parser/macro/macro-repeat.rs9
-rw-r--r--src/test/ui/parser/macro/macro-repeat.stderr8
-rw-r--r--src/test/ui/parser/nt-parsing-has-recovery.rs10
-rw-r--r--src/test/ui/parser/nt-parsing-has-recovery.stderr29
-rw-r--r--src/test/ui/pattern/usefulness/match-arm-statics-2.rs5
-rw-r--r--src/test/ui/pattern/usefulness/match-arm-statics-2.stderr14
-rw-r--r--src/test/ui/pattern/usefulness/match-privately-empty.rs5
-rw-r--r--src/test/ui/pattern/usefulness/match-privately-empty.stderr7
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match.rs5
-rw-r--r--src/test/ui/pattern/usefulness/non-exhaustive-match.stderr21
-rw-r--r--src/test/ui/proc-macro/derive-bad.rs8
-rw-r--r--src/test/ui/proc-macro/derive-bad.stderr26
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-1.rs2
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-2.rs2
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-3.rs2
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-4.rs9
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-4.stderr11
-rw-r--r--src/test/ui/proc-macro/issue-36935.rs1
-rw-r--r--src/test/ui/proc-macro/issue-36935.stderr14
-rw-r--r--src/test/ui/recursion/recursive-types-are-not-uninhabited.rs5
-rw-r--r--src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr7
-rw-r--r--src/test/ui/resolve/issue-3907-2.stderr5
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr7
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr7
-rw-r--r--src/test/ui/self/elision/ref-self-async.nll.stderr77
-rw-r--r--src/test/ui/self/elision/ref-self-async.rs1
-rw-r--r--src/test/ui/self/elision/ref-self-async.stderr14
-rw-r--r--src/test/ui/span/transitive-dep-span.rs2
-rw-r--r--src/test/ui/test-attrs/test-attr-non-associated-functions.rs8
-rw-r--r--src/test/ui/test-attrs/test-attr-non-associated-functions.stderr12
-rw-r--r--src/test/ui/type/ascription/issue-47666.rs2
-rw-r--r--src/test/ui/type/ascription/issue-47666.stderr32
-rw-r--r--src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs5
-rw-r--r--src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr29
-rw-r--r--src/test/ui/union/union-derive-clone.rs5
-rw-r--r--src/test/ui/union/union-derive-clone.stderr12
-rw-r--r--src/test/ui/unique-object-noncopyable.stderr8
-rw-r--r--src/test/ui/unique-pinned-nocopy.stderr8
126 files changed, 1527 insertions, 654 deletions
diff --git a/src/doc/unstable-book/src/language-features/optin-builtin-traits.md b/src/doc/unstable-book/src/language-features/optin-builtin-traits.md
index 5c8124c9c6b..1ec8b8bf8dd 100644
--- a/src/doc/unstable-book/src/language-features/optin-builtin-traits.md
+++ b/src/doc/unstable-book/src/language-features/optin-builtin-traits.md
@@ -16,7 +16,7 @@ has explicitly opted out via a negative impl.
 [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
 
 ```rust,ignore
-impl !Type for Trait
+impl !Trait for Type
 ```
 
 Example:
diff --git a/src/librustc_builtin_macros/cmdline_attrs.rs b/src/librustc_builtin_macros/cmdline_attrs.rs
index 7ddbf08306b..093815dbbcd 100644
--- a/src/librustc_builtin_macros/cmdline_attrs.rs
+++ b/src/librustc_builtin_macros/cmdline_attrs.rs
@@ -3,7 +3,6 @@
 use rustc_ast::ast::{self, AttrItem, AttrStyle};
 use rustc_ast::attr::mk_attr;
 use rustc_ast::token;
-use rustc_expand::panictry;
 use rustc_session::parse::ParseSess;
 use rustc_span::FileName;
 
@@ -16,7 +15,13 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -
         );
 
         let start_span = parser.token.span;
-        let AttrItem { path, args } = panictry!(parser.parse_attr_item());
+        let AttrItem { path, args } = match parser.parse_attr_item() {
+            Ok(ai) => ai,
+            Err(mut err) => {
+                err.emit();
+                continue;
+            }
+        };
         let end_span = parser.token.span;
         if parser.token != token::Eof {
             parse_sess.span_diagnostic.span_err(start_span.to(end_span), "invalid crate attribute");
diff --git a/src/librustc_builtin_macros/source_util.rs b/src/librustc_builtin_macros/source_util.rs
index 51a15f9df1b..67145c6bf43 100644
--- a/src/librustc_builtin_macros/source_util.rs
+++ b/src/librustc_builtin_macros/source_util.rs
@@ -5,7 +5,6 @@ use rustc_ast::tokenstream::TokenStream;
 use rustc_ast_pretty::pprust;
 use rustc_expand::base::{self, *};
 use rustc_expand::module::DirectoryOwnership;
-use rustc_expand::panictry;
 use rustc_parse::{self, new_parser_from_file, parser::Parser};
 use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
 use rustc_span::symbol::Symbol;
@@ -126,7 +125,7 @@ pub fn expand_include<'cx>(
     }
     impl<'a> base::MacResult for ExpandResult<'a> {
         fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
-            let r = panictry!(self.p.parse_expr());
+            let r = base::parse_expr(&mut self.p)?;
             if self.p.token != token::Eof {
                 self.p.sess.buffer_lint(
                     &INCOMPLETE_INCLUDE,
@@ -141,18 +140,17 @@ pub fn expand_include<'cx>(
         fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
             let mut ret = SmallVec::new();
             while self.p.token != token::Eof {
-                match panictry!(self.p.parse_item()) {
-                    Some(item) => ret.push(item),
-                    None => {
+                match self.p.parse_item() {
+                    Err(mut err) => {
+                        err.emit();
+                        break;
+                    }
+                    Ok(Some(item)) => ret.push(item),
+                    Ok(None) => {
                         let token = pprust::token_to_string(&self.p.token);
-                        self.p
-                            .sess
-                            .span_diagnostic
-                            .span_fatal(
-                                self.p.token.span,
-                                &format!("expected item, found `{}`", token),
-                            )
-                            .raise();
+                        let msg = format!("expected item, found `{}`", token);
+                        self.p.struct_span_err(self.p.token.span, &msg).emit();
+                        break;
                     }
                 }
             }
diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs
index 39009ca27f1..bdc4ae2fe27 100644
--- a/src/librustc_builtin_macros/test.rs
+++ b/src/librustc_builtin_macros/test.rs
@@ -74,16 +74,16 @@ pub fn expand_test_or_bench(
         return vec![];
     }
 
-    let item = if let Annotatable::Item(i) = item {
-        i
-    } else {
-        cx.parse_sess
-            .span_diagnostic
-            .span_fatal(
-                item.span(),
+    let item = match item {
+        Annotatable::Item(i) => i,
+        other => {
+            cx.struct_span_err(
+                other.span(),
                 "`#[test]` attribute is only allowed on non associated functions",
             )
-            .raise();
+            .emit();
+            return vec![other];
+        }
     };
 
     if let ast::ItemKind::MacCall(_) = item.kind {
diff --git a/src/librustc_builtin_macros/test_harness.rs b/src/librustc_builtin_macros/test_harness.rs
index b87767f4a41..160a5204eaf 100644
--- a/src/librustc_builtin_macros/test_harness.rs
+++ b/src/librustc_builtin_macros/test_harness.rs
@@ -345,14 +345,14 @@ fn is_test_case(i: &ast::Item) -> bool {
 
 fn get_test_runner(sd: &rustc_errors::Handler, krate: &ast::Crate) -> Option<ast::Path> {
     let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?;
-    test_attr.meta_item_list().map(|meta_list| {
-        if meta_list.len() != 1 {
-            sd.span_fatal(test_attr.span, "`#![test_runner(..)]` accepts exactly 1 argument")
-                .raise()
-        }
-        match meta_list[0].meta_item() {
-            Some(meta_item) if meta_item.is_word() => meta_item.path.clone(),
-            _ => sd.span_fatal(test_attr.span, "`test_runner` argument must be a path").raise(),
-        }
-    })
+    let meta_list = test_attr.meta_item_list()?;
+    let span = test_attr.span;
+    match &*meta_list {
+        [single] => match single.meta_item() {
+            Some(meta_item) if meta_item.is_word() => return Some(meta_item.path.clone()),
+            _ => sd.struct_span_err(span, "`test_runner` argument must be a path").emit(),
+        },
+        _ => sd.struct_span_err(span, "`#![test_runner(..)]` accepts exactly 1 argument").emit(),
+    }
+    None
 }
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 2327b96e26c..5759eb2991a 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -16,7 +16,7 @@ use crate::ModuleLlvm;
 use log::debug;
 use rustc::bug;
 use rustc::ty::TyCtxt;
-use rustc_codegen_ssa::back::write::{run_assembler, CodegenContext, ModuleConfig};
+use rustc_codegen_ssa::back::write::{run_assembler, CodegenContext, EmbedBitcode, ModuleConfig};
 use rustc_codegen_ssa::traits::*;
 use rustc_codegen_ssa::{CompiledModule, ModuleCodegen, RLIB_BYTECODE_EXTENSION};
 use rustc_data_structures::small_c_str::SmallCStr;
@@ -634,30 +634,24 @@ pub(crate) unsafe fn codegen(
             f(cpm)
         }
 
-        // If we don't have the integrated assembler, then we need to emit asm
-        // from LLVM and use `gcc` to create the object file.
-        let asm_to_obj = config.emit_obj && config.no_integrated_as;
-
-        // Change what we write and cleanup based on whether obj files are
-        // just llvm bitcode. In that case write bitcode, and possibly
-        // delete the bitcode if it wasn't requested. Don't generate the
-        // machine code, instead copy the .o file from the .bc
-        let write_bc = config.emit_bc || config.obj_is_bitcode;
-        let rm_bc = !config.emit_bc && config.obj_is_bitcode;
-        let write_obj = config.emit_obj && !config.obj_is_bitcode && !asm_to_obj;
-        let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode;
+        // Two things to note:
+        // - If object files are just LLVM bitcode we write bitcode, copy it to
+        //   the .o file, and delete the bitcode if it wasn't otherwise
+        //   requested.
+        // - If we don't have the integrated assembler then we need to emit
+        //   asm from LLVM and use `gcc` to create the object file.
 
         let bc_out = cgcx.output_filenames.temp_path(OutputType::Bitcode, module_name);
         let obj_out = cgcx.output_filenames.temp_path(OutputType::Object, module_name);
 
-        if write_bc || config.emit_bc_compressed || config.embed_bitcode {
+        if config.bitcode_needed() {
             let _timer = cgcx
                 .prof
                 .generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &module.name[..]);
             let thin = ThinBuffer::new(llmod);
             let data = thin.data();
 
-            if write_bc {
+            if config.emit_bc || config.obj_is_bitcode {
                 let _timer = cgcx.prof.generic_activity_with_arg(
                     "LLVM_module_codegen_emit_bitcode",
                     &module.name[..],
@@ -668,7 +662,7 @@ pub(crate) unsafe fn codegen(
                 }
             }
 
-            if config.embed_bitcode {
+            if config.embed_bitcode == EmbedBitcode::Full {
                 let _timer = cgcx.prof.generic_activity_with_arg(
                     "LLVM_module_codegen_embed_bitcode",
                     &module.name[..],
@@ -688,81 +682,75 @@ pub(crate) unsafe fn codegen(
                     diag_handler.err(&msg);
                 }
             }
-        } else if config.embed_bitcode_marker {
+        } else if config.embed_bitcode == EmbedBitcode::Marker {
             embed_bitcode(cgcx, llcx, llmod, None);
         }
 
-        {
-            if config.emit_ir {
-                let _timer = cgcx
-                    .prof
-                    .generic_activity_with_arg("LLVM_module_codegen_emit_ir", &module.name[..]);
-                let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
-                let out_c = path_to_c_string(&out);
-
-                extern "C" fn demangle_callback(
-                    input_ptr: *const c_char,
-                    input_len: size_t,
-                    output_ptr: *mut c_char,
-                    output_len: size_t,
-                ) -> size_t {
-                    let input = unsafe {
-                        slice::from_raw_parts(input_ptr as *const u8, input_len as usize)
-                    };
-
-                    let input = match str::from_utf8(input) {
-                        Ok(s) => s,
-                        Err(_) => return 0,
-                    };
-
-                    let output = unsafe {
-                        slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize)
-                    };
-                    let mut cursor = io::Cursor::new(output);
-
-                    let demangled = match rustc_demangle::try_demangle(input) {
-                        Ok(d) => d,
-                        Err(_) => return 0,
-                    };
-
-                    if write!(cursor, "{:#}", demangled).is_err() {
-                        // Possible only if provided buffer is not big enough
-                        return 0;
-                    }
-
-                    cursor.position() as size_t
+        if config.emit_ir {
+            let _timer = cgcx
+                .prof
+                .generic_activity_with_arg("LLVM_module_codegen_emit_ir", &module.name[..]);
+            let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name);
+            let out_c = path_to_c_string(&out);
+
+            extern "C" fn demangle_callback(
+                input_ptr: *const c_char,
+                input_len: size_t,
+                output_ptr: *mut c_char,
+                output_len: size_t,
+            ) -> size_t {
+                let input =
+                    unsafe { slice::from_raw_parts(input_ptr as *const u8, input_len as usize) };
+
+                let input = match str::from_utf8(input) {
+                    Ok(s) => s,
+                    Err(_) => return 0,
+                };
+
+                let output = unsafe {
+                    slice::from_raw_parts_mut(output_ptr as *mut u8, output_len as usize)
+                };
+                let mut cursor = io::Cursor::new(output);
+
+                let demangled = match rustc_demangle::try_demangle(input) {
+                    Ok(d) => d,
+                    Err(_) => return 0,
+                };
+
+                if write!(cursor, "{:#}", demangled).is_err() {
+                    // Possible only if provided buffer is not big enough
+                    return 0;
                 }
 
-                let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback);
-                result.into_result().map_err(|()| {
-                    let msg = format!("failed to write LLVM IR to {}", out.display());
-                    llvm_err(diag_handler, &msg)
-                })?;
+                cursor.position() as size_t
             }
 
-            if config.emit_asm || asm_to_obj {
-                let _timer = cgcx
-                    .prof
-                    .generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]);
-                let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
+            let result = llvm::LLVMRustPrintModule(llmod, out_c.as_ptr(), demangle_callback);
+            result.into_result().map_err(|()| {
+                let msg = format!("failed to write LLVM IR to {}", out.display());
+                llvm_err(diag_handler, &msg)
+            })?;
+        }
 
-                // We can't use the same module for asm and binary output, because that triggers
-                // various errors like invalid IR or broken binaries, so we might have to clone the
-                // module to produce the asm output
-                let llmod = if config.emit_obj { llvm::LLVMCloneModule(llmod) } else { llmod };
-                with_codegen(tm, llmod, config.no_builtins, |cpm| {
-                    write_output_file(
-                        diag_handler,
-                        tm,
-                        cpm,
-                        llmod,
-                        &path,
-                        llvm::FileType::AssemblyFile,
-                    )
-                })?;
-            }
+        let config_emit_normal_obj = config.emit_obj && !config.obj_is_bitcode;
 
-            if write_obj {
+        if config.emit_asm || (config_emit_normal_obj && config.no_integrated_as) {
+            let _timer = cgcx
+                .prof
+                .generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]);
+            let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name);
+
+            // We can't use the same module for asm and binary output, because that triggers
+            // various errors like invalid IR or broken binaries, so we might have to clone the
+            // module to produce the asm output
+            let llmod = if config.emit_obj { llvm::LLVMCloneModule(llmod) } else { llmod };
+            with_codegen(tm, llmod, config.no_builtins, |cpm| {
+                write_output_file(diag_handler, tm, cpm, llmod, &path, llvm::FileType::AssemblyFile)
+            })?;
+        }
+
+        if config_emit_normal_obj {
+            if !config.no_integrated_as {
                 let _timer = cgcx
                     .prof
                     .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]);
@@ -776,7 +764,7 @@ pub(crate) unsafe fn codegen(
                         llvm::FileType::ObjectFile,
                     )
                 })?;
-            } else if asm_to_obj {
+            } else {
                 let _timer = cgcx
                     .prof
                     .generic_activity_with_arg("LLVM_module_codegen_asm_to_obj", &module.name[..]);
@@ -789,17 +777,19 @@ pub(crate) unsafe fn codegen(
             }
         }
 
-        if copy_bc_to_obj {
-            debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
-            if let Err(e) = link_or_copy(&bc_out, &obj_out) {
-                diag_handler.err(&format!("failed to copy bitcode to object file: {}", e));
+        if config.obj_is_bitcode {
+            if config.emit_obj {
+                debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
+                if let Err(e) = link_or_copy(&bc_out, &obj_out) {
+                    diag_handler.err(&format!("failed to copy bitcode to object file: {}", e));
+                }
             }
-        }
 
-        if rm_bc {
-            debug!("removing_bitcode {:?}", bc_out);
-            if let Err(e) = fs::remove_file(&bc_out) {
-                diag_handler.err(&format!("failed to remove bitcode: {}", e));
+            if !config.emit_bc {
+                debug!("removing_bitcode {:?}", bc_out);
+                if let Err(e) = fs::remove_file(&bc_out) {
+                    diag_handler.err(&format!("failed to remove bitcode: {}", e));
+                }
             }
         }
 
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 746ab34d284..a4b5acdcd18 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -51,6 +51,14 @@ use std::thread;
 
 const PRE_LTO_BC_EXT: &str = "pre-lto.bc";
 
+/// The kind of bitcode to embed in object files.
+#[derive(PartialEq)]
+pub enum EmbedBitcode {
+    None,
+    Marker,
+    Full,
+}
+
 /// Module-specific configuration for `optimize_and_codegen`.
 pub struct ModuleConfig {
     /// Names of additional optimization passes to run.
@@ -74,7 +82,6 @@ pub struct ModuleConfig {
     pub emit_no_opt_bc: bool,
     pub emit_bc: bool,
     pub emit_bc_compressed: bool,
-    pub emit_lto_bc: bool,
     pub emit_ir: bool,
     pub emit_asm: bool,
     pub emit_obj: bool,
@@ -94,8 +101,7 @@ pub struct ModuleConfig {
     // emscripten's ecc compiler, when used as the linker.
     pub obj_is_bitcode: bool,
     pub no_integrated_as: bool,
-    pub embed_bitcode: bool,
-    pub embed_bitcode_marker: bool,
+    pub embed_bitcode: EmbedBitcode,
 }
 
 impl ModuleConfig {
@@ -116,13 +122,11 @@ impl ModuleConfig {
             emit_pre_lto_bc: false,
             emit_bc: false,
             emit_bc_compressed: false,
-            emit_lto_bc: false,
             emit_ir: false,
             emit_asm: false,
             emit_obj: false,
             obj_is_bitcode: false,
-            embed_bitcode: false,
-            embed_bitcode_marker: false,
+            embed_bitcode: EmbedBitcode::None,
             no_integrated_as: false,
 
             verify_llvm_ir: false,
@@ -145,16 +149,15 @@ impl ModuleConfig {
         self.new_llvm_pass_manager = sess.opts.debugging_opts.new_llvm_pass_manager;
         self.obj_is_bitcode =
             sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled();
-        let embed_bitcode =
-            sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode;
-        if embed_bitcode {
-            match sess.opts.optimize {
-                config::OptLevel::No | config::OptLevel::Less => {
-                    self.embed_bitcode_marker = embed_bitcode;
+        self.embed_bitcode =
+            if sess.target.target.options.embed_bitcode || sess.opts.debugging_opts.embed_bitcode {
+                match sess.opts.optimize {
+                    config::OptLevel::No | config::OptLevel::Less => EmbedBitcode::Marker,
+                    _ => EmbedBitcode::Full,
                 }
-                _ => self.embed_bitcode = embed_bitcode,
-            }
-        }
+            } else {
+                EmbedBitcode::None
+            };
 
         // Copy what clang does by turning on loop vectorization at O2 and
         // slp vectorization at O3. Otherwise configure other optimization aspects
@@ -190,7 +193,10 @@ impl ModuleConfig {
     }
 
     pub fn bitcode_needed(&self) -> bool {
-        self.emit_bc || self.obj_is_bitcode || self.emit_bc_compressed || self.embed_bitcode
+        self.emit_bc
+            || self.obj_is_bitcode
+            || self.emit_bc_compressed
+            || self.embed_bitcode == EmbedBitcode::Full
     }
 }
 
@@ -379,7 +385,6 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
         modules_config.emit_no_opt_bc = true;
         modules_config.emit_pre_lto_bc = true;
         modules_config.emit_bc = true;
-        modules_config.emit_lto_bc = true;
         metadata_config.emit_bc = true;
         allocator_config.emit_bc = true;
     }
diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs
index 0fc477bbd0b..59c1a5468f1 100644
--- a/src/librustc_expand/base.rs
+++ b/src/librustc_expand/base.rs
@@ -10,7 +10,7 @@ use rustc_ast::visit::{AssocCtxt, Visitor};
 use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{self, Lrc};
-use rustc_errors::{DiagnosticBuilder, DiagnosticId};
+use rustc_errors::{DiagnosticBuilder, ErrorReported};
 use rustc_parse::{self, parser, MACRO_ARGUMENTS};
 use rustc_session::parse::ParseSess;
 use rustc_span::edition::Edition;
@@ -296,16 +296,26 @@ where
 }
 
 pub trait ProcMacro {
-    fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt<'_>, span: Span, ts: TokenStream) -> TokenStream;
+    fn expand<'cx>(
+        &self,
+        ecx: &'cx mut ExtCtxt<'_>,
+        span: Span,
+        ts: TokenStream,
+    ) -> Result<TokenStream, ErrorReported>;
 }
 
 impl<F> ProcMacro for F
 where
     F: Fn(TokenStream) -> TokenStream,
 {
-    fn expand<'cx>(&self, _ecx: &'cx mut ExtCtxt<'_>, _span: Span, ts: TokenStream) -> TokenStream {
+    fn expand<'cx>(
+        &self,
+        _ecx: &'cx mut ExtCtxt<'_>,
+        _span: Span,
+        ts: TokenStream,
+    ) -> Result<TokenStream, ErrorReported> {
         // FIXME setup implicit context in TLS before calling self.
-        (*self)(ts)
+        Ok((*self)(ts))
     }
 }
 
@@ -316,7 +326,7 @@ pub trait AttrProcMacro {
         span: Span,
         annotation: TokenStream,
         annotated: TokenStream,
-    ) -> TokenStream;
+    ) -> Result<TokenStream, ErrorReported>;
 }
 
 impl<F> AttrProcMacro for F
@@ -329,9 +339,9 @@ where
         _span: Span,
         annotation: TokenStream,
         annotated: TokenStream,
-    ) -> TokenStream {
+    ) -> Result<TokenStream, ErrorReported> {
         // FIXME setup implicit context in TLS before calling self.
-        (*self)(annotation, annotated)
+        Ok((*self)(annotation, annotated))
     }
 }
 
@@ -1004,31 +1014,9 @@ impl<'a> ExtCtxt<'a> {
         self.current_expansion.id.expansion_cause()
     }
 
-    pub fn struct_span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> {
-        self.parse_sess.span_diagnostic.struct_span_warn(sp, msg)
-    }
     pub fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> {
         self.parse_sess.span_diagnostic.struct_span_err(sp, msg)
     }
-    pub fn struct_span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> {
-        self.parse_sess.span_diagnostic.struct_span_fatal(sp, msg)
-    }
-
-    /// Emit `msg` attached to `sp`, and stop compilation immediately.
-    ///
-    /// `span_err` should be strongly preferred where-ever possible:
-    /// this should *only* be used when:
-    ///
-    /// - continuing has a high risk of flow-on errors (e.g., errors in
-    ///   declaring a macro would cause all uses of that macro to
-    ///   complain about "undefined macro"), or
-    /// - there is literally nothing else that can be done (however,
-    ///   in most cases one can construct a dummy expression/item to
-    ///   substitute; we never hit resolve/type-checking so the dummy
-    ///   value doesn't have to match anything)
-    pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
-        self.parse_sess.span_diagnostic.span_fatal(sp, msg).raise();
-    }
 
     /// Emit `msg` attached to `sp`, without immediately stopping
     /// compilation.
@@ -1038,9 +1026,6 @@ impl<'a> ExtCtxt<'a> {
     pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.parse_sess.span_diagnostic.span_err(sp, msg);
     }
-    pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
-        self.parse_sess.span_diagnostic.span_err_with_code(sp, msg, code);
-    }
     pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.parse_sess.span_diagnostic.span_warn(sp, msg);
     }
@@ -1168,6 +1153,18 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>, sp: Span, tts: TokenStream, name: &str)
     }
 }
 
+/// Parse an expression. On error, emit it, advancing to `Eof`, and return `None`.
+pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option<P<ast::Expr>> {
+    match p.parse_expr() {
+        Ok(e) => return Some(e),
+        Err(mut err) => err.emit(),
+    }
+    while p.token != token::Eof {
+        p.bump();
+    }
+    None
+}
+
 /// Interpreting `tts` as a comma-separated sequence of expressions,
 /// expect exactly one string literal, or emit an error and return `None`.
 pub fn get_single_str_from_tts(
@@ -1181,7 +1178,7 @@ pub fn get_single_str_from_tts(
         cx.span_err(sp, &format!("{} takes 1 argument", name));
         return None;
     }
-    let ret = panictry!(p.parse_expr());
+    let ret = parse_expr(&mut p)?;
     let _ = p.eat(&token::Comma);
 
     if p.token != token::Eof {
@@ -1190,8 +1187,8 @@ pub fn get_single_str_from_tts(
     expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| s.to_string())
 }
 
-/// Extracts comma-separated expressions from `tts`. If there is a
-/// parsing error, emit a non-fatal error and return `None`.
+/// Extracts comma-separated expressions from `tts`.
+/// On error, emit it, and return `None`.
 pub fn get_exprs_from_tts(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
@@ -1200,7 +1197,7 @@ pub fn get_exprs_from_tts(
     let mut p = cx.new_parser_from_tts(tts);
     let mut es = Vec::new();
     while p.token != token::Eof {
-        let expr = panictry!(p.parse_expr());
+        let expr = parse_expr(&mut p)?;
 
         // Perform eager expansion on the expression.
         // We want to be able to handle e.g., `concat!("foo", "bar")`.
diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs
index 4f568e5456c..51208906c2f 100644
--- a/src/librustc_expand/expand.rs
+++ b/src/librustc_expand/expand.rs
@@ -204,7 +204,7 @@ ast_fragments! {
 }
 
 impl AstFragmentKind {
-    fn dummy(self, span: Span) -> AstFragment {
+    crate fn dummy(self, span: Span) -> AstFragment {
         self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment")
     }
 
@@ -682,7 +682,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             InvocationKind::Bang { mac, .. } => match ext {
                 SyntaxExtensionKind::Bang(expander) => {
                     self.gate_proc_macro_expansion_kind(span, fragment_kind);
-                    let tok_result = expander.expand(self.cx, span, mac.args.inner_tokens());
+                    let tok_result = match expander.expand(self.cx, span, mac.args.inner_tokens()) {
+                        Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)),
+                        Ok(ts) => ts,
+                    };
                     self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
                 }
                 SyntaxExtensionKind::LegacyBang(expander) => {
@@ -709,8 +712,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     if let MacArgs::Eq(..) = attr_item.args {
                         self.cx.span_err(span, "key-value macro attributes are not supported");
                     }
-                    let tok_result =
-                        expander.expand(self.cx, span, attr_item.args.inner_tokens(), tokens);
+                    let inner_tokens = attr_item.args.inner_tokens();
+                    let tok_result = match expander.expand(self.cx, span, inner_tokens, tokens) {
+                        Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)),
+                        Ok(ts) => ts,
+                    };
                     self.parse_ast_fragment(tok_result, fragment_kind, &attr_item.path, span)
                 }
                 SyntaxExtensionKind::LegacyAttr(expander) => {
@@ -1139,6 +1145,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
             // macros are expanded before any lint passes so this warning has to be hardcoded
             if attr.has_name(sym::derive) {
                 self.cx
+                    .parse_sess()
+                    .span_diagnostic
                     .struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations")
                     .note("this may become a hard error in a future release")
                     .emit();
diff --git a/src/librustc_expand/lib.rs b/src/librustc_expand/lib.rs
index 0320a275e5d..876a26de3fb 100644
--- a/src/librustc_expand/lib.rs
+++ b/src/librustc_expand/lib.rs
@@ -9,25 +9,6 @@
 
 extern crate proc_macro as pm;
 
-// A variant of 'try!' that panics on an Err. This is used as a crutch on the
-// way towards a non-panic!-prone parser. It should be used for fatal parsing
-// errors; eventually we plan to convert all code using panictry to just use
-// normal try.
-#[macro_export]
-macro_rules! panictry {
-    ($e:expr) => {{
-        use rustc_errors::FatalError;
-        use std::result::Result::{Err, Ok};
-        match $e {
-            Ok(e) => e,
-            Err(mut e) => {
-                e.emit();
-                FatalError.raise()
-            }
-        }
-    }};
-}
-
 mod placeholders;
 mod proc_macro_server;
 
diff --git a/src/librustc_expand/mbe/macro_parser.rs b/src/librustc_expand/mbe/macro_parser.rs
index 0d777d88cad..e868b7e36aa 100644
--- a/src/librustc_expand/mbe/macro_parser.rs
+++ b/src/librustc_expand/mbe/macro_parser.rs
@@ -84,7 +84,7 @@ use rustc_parse::parser::{FollowedByType, Parser, PathStyle};
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent, Symbol};
 
-use rustc_errors::{FatalError, PResult};
+use rustc_errors::PResult;
 use rustc_span::Span;
 use smallvec::{smallvec, SmallVec};
 
@@ -271,6 +271,7 @@ crate enum ParseResult<T> {
     Failure(Token, &'static str),
     /// Fatal error (malformed macro?). Abort compilation.
     Error(rustc_span::Span, String),
+    ErrorReported,
 }
 
 /// A `ParseResult` where the `Success` variant contains a mapping of
@@ -652,6 +653,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
             Success(_) => {}
             Failure(token, msg) => return Failure(token, msg),
             Error(sp, msg) => return Error(sp, msg),
+            ErrorReported => return ErrorReported,
         }
 
         // inner parse loop handled all cur_items, so it's empty
@@ -735,10 +737,11 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
             let mut item = bb_items.pop().unwrap();
             if let TokenTree::MetaVarDecl(span, _, ident) = item.top_elts.get_tt(item.idx) {
                 let match_cur = item.match_cur;
-                item.push_match(
-                    match_cur,
-                    MatchedNonterminal(Lrc::new(parse_nt(parser.to_mut(), span, ident.name))),
-                );
+                let nt = match parse_nt(parser.to_mut(), span, ident.name) {
+                    Err(()) => return ErrorReported,
+                    Ok(nt) => nt,
+                };
+                item.push_match(match_cur, MatchedNonterminal(Lrc::new(nt)));
                 item.idx += 1;
                 item.match_cur += 1;
             } else {
@@ -849,20 +852,16 @@ fn may_begin_with(token: &Token, name: Name) -> bool {
 /// # Returns
 ///
 /// The parsed non-terminal.
-fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Nonterminal {
+fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Result<Nonterminal, ()> {
     // FIXME(Centril): Consider moving this to `parser.rs` to make
     // the visibilities of the methods used below `pub(super)` at most.
-
     if name == sym::tt {
-        return token::NtTT(p.parse_token_tree());
-    }
-    match parse_nt_inner(p, sp, name) {
-        Ok(nt) => nt,
-        Err(mut err) => {
-            err.emit();
-            FatalError.raise();
-        }
+        return Ok(token::NtTT(p.parse_token_tree()));
     }
+    parse_nt_inner(p, sp, name).map_err(|mut err| {
+        err.span_label(sp, format!("while parsing argument for this `{}` macro fragment", name))
+            .emit()
+    })
 }
 
 fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, Nonterminal> {
diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs
index b6b69400bad..859362b5e29 100644
--- a/src/librustc_expand/mbe/macro_rules.rs
+++ b/src/librustc_expand/mbe/macro_rules.rs
@@ -4,7 +4,7 @@ use crate::expand::{ensure_complete_parse, parse_ast_fragment, AstFragment, AstF
 use crate::mbe;
 use crate::mbe::macro_check;
 use crate::mbe::macro_parser::parse_tt;
-use crate::mbe::macro_parser::{Error, Failure, Success};
+use crate::mbe::macro_parser::{Error, ErrorReported, Failure, Success};
 use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq};
 use crate::mbe::transcribe::transcribe;
 
@@ -15,7 +15,7 @@ use rustc_ast_pretty::pprust;
 use rustc_attr::{self as attr, TransparencyError};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{Applicability, DiagnosticBuilder, FatalError};
+use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_feature::Features;
 use rustc_parse::parser::Parser;
 use rustc_session::parse::ParseSess;
@@ -83,41 +83,56 @@ fn suggest_slice_pat(e: &mut DiagnosticBuilder<'_>, site_span: Span, parser: &Pa
     );
 }
 
+fn emit_frag_parse_err(
+    mut e: DiagnosticBuilder<'_>,
+    parser: &Parser<'_>,
+    site_span: Span,
+    macro_ident: ast::Ident,
+    arm_span: Span,
+    kind: AstFragmentKind,
+) {
+    if parser.token == token::Eof && e.message().ends_with(", found `<eof>`") {
+        if !e.span.is_dummy() {
+            // early end of macro arm (#52866)
+            e.replace_span_with(parser.sess.source_map().next_point(parser.token.span));
+        }
+        let msg = &e.message[0];
+        e.message[0] = (
+            format!(
+                "macro expansion ends with an incomplete expression: {}",
+                msg.0.replace(", found `<eof>`", ""),
+            ),
+            msg.1,
+        );
+    }
+    if e.span.is_dummy() {
+        // Get around lack of span in error (#30128)
+        e.replace_span_with(site_span);
+        if !parser.sess.source_map().is_imported(arm_span) {
+            e.span_label(arm_span, "in this macro arm");
+        }
+    } else if parser.sess.source_map().is_imported(parser.token.span) {
+        e.span_label(site_span, "in this macro invocation");
+    }
+    match kind {
+        AstFragmentKind::Pat if macro_ident.name == sym::vec => {
+            suggest_slice_pat(&mut e, site_span, parser);
+        }
+        _ => annotate_err_with_kind(&mut e, kind, site_span),
+    };
+    e.emit();
+}
+
 impl<'a> ParserAnyMacro<'a> {
     crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
         let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
-        let fragment = panictry!(parse_ast_fragment(parser, kind).map_err(|mut e| {
-            if parser.token == token::Eof && e.message().ends_with(", found `<eof>`") {
-                if !e.span.is_dummy() {
-                    // early end of macro arm (#52866)
-                    e.replace_span_with(parser.sess.source_map().next_point(parser.token.span));
-                }
-                let msg = &e.message[0];
-                e.message[0] = (
-                    format!(
-                        "macro expansion ends with an incomplete expression: {}",
-                        msg.0.replace(", found `<eof>`", ""),
-                    ),
-                    msg.1,
-                );
+        let fragment = match parse_ast_fragment(parser, kind) {
+            Ok(f) => f,
+            Err(err) => {
+                emit_frag_parse_err(err, parser, site_span, macro_ident, arm_span, kind);
+                return kind.dummy(site_span);
             }
-            if e.span.is_dummy() {
-                // Get around lack of span in error (#30128)
-                e.replace_span_with(site_span);
-                if !parser.sess.source_map().is_imported(arm_span) {
-                    e.span_label(arm_span, "in this macro arm");
-                }
-            } else if parser.sess.source_map().is_imported(parser.token.span) {
-                e.span_label(site_span, "in this macro invocation");
-            }
-            match kind {
-                AstFragmentKind::Pat if macro_ident.name == sym::vec => {
-                    suggest_slice_pat(&mut e, site_span, parser);
-                }
-                _ => annotate_err_with_kind(&mut e, kind, site_span),
-            };
-            e
-        }));
+        };
 
         // We allow semicolons at the end of expressions -- e.g., the semicolon in
         // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
@@ -165,6 +180,14 @@ impl TTMacroExpander for MacroRulesMacroExpander {
     }
 }
 
+fn macro_rules_dummy_expander<'cx>(
+    _: &'cx mut ExtCtxt<'_>,
+    span: Span,
+    _: TokenStream,
+) -> Box<dyn MacResult + 'cx> {
+    DummyResult::any(span)
+}
+
 fn trace_macros_note(cx_expansions: &mut FxHashMap<Span, Vec<String>>, sp: Span, message: String) {
     let sp = sp.macro_backtrace().last().map(|trace| trace.call_site).unwrap_or(sp);
     cx_expansions.entry(sp).or_default().push(message);
@@ -240,7 +263,13 @@ fn generic_extension<'cx>(
 
                 let rhs_spans = rhs.iter().map(|t| t.span()).collect::<Vec<_>>();
                 // rhs has holes ( `$id` and `$(...)` that need filled)
-                let mut tts = transcribe(cx, &named_matches, rhs, transparency);
+                let mut tts = match transcribe(cx, &named_matches, rhs, transparency) {
+                    Ok(tts) => tts,
+                    Err(mut err) => {
+                        err.emit();
+                        return DummyResult::any(arm_span);
+                    }
+                };
 
                 // Replace all the tokens for the corresponding positions in the macro, to maintain
                 // proper positions in error reporting, while maintaining the macro_backtrace.
@@ -278,7 +307,12 @@ fn generic_extension<'cx>(
                 Some((ref best_token, _)) if best_token.span.lo() >= token.span.lo() => {}
                 _ => best_failure = Some((token, msg)),
             },
-            Error(err_sp, ref msg) => cx.span_fatal(err_sp.substitute_dummy(sp), &msg[..]),
+            Error(err_sp, ref msg) => {
+                let span = err_sp.substitute_dummy(sp);
+                cx.struct_span_err(span, &msg).emit();
+                return DummyResult::any(span);
+            }
+            ErrorReported => return DummyResult::any(sp),
         }
 
         // The matcher was not `Success(..)`ful.
@@ -337,6 +371,18 @@ pub fn compile_declarative_macro(
     def: &ast::Item,
     edition: Edition,
 ) -> SyntaxExtension {
+    let mk_syn_ext = |expander| {
+        SyntaxExtension::new(
+            sess,
+            SyntaxExtensionKind::LegacyBang(expander),
+            def.span,
+            Vec::new(),
+            edition,
+            def.ident.name,
+            &def.attrs,
+        )
+    };
+
     let diag = &sess.span_diagnostic;
     let lhs_nm = ast::Ident::new(sym::lhs, def.span);
     let rhs_nm = ast::Ident::new(sym::rhs, def.span);
@@ -391,13 +437,15 @@ pub fn compile_declarative_macro(
         Failure(token, msg) => {
             let s = parse_failure_msg(&token);
             let sp = token.span.substitute_dummy(def.span);
-            let mut err = sess.span_diagnostic.struct_span_fatal(sp, &s);
-            err.span_label(sp, msg);
-            err.emit();
-            FatalError.raise();
+            sess.span_diagnostic.struct_span_err(sp, &s).span_label(sp, msg).emit();
+            return mk_syn_ext(Box::new(macro_rules_dummy_expander));
+        }
+        Error(sp, msg) => {
+            sess.span_diagnostic.struct_span_err(sp.substitute_dummy(def.span), &msg).emit();
+            return mk_syn_ext(Box::new(macro_rules_dummy_expander));
         }
-        Error(sp, s) => {
-            sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &s).raise();
+        ErrorReported => {
+            return mk_syn_ext(Box::new(macro_rules_dummy_expander));
         }
     };
 
@@ -460,24 +508,14 @@ pub fn compile_declarative_macro(
         None => {}
     }
 
-    let expander: Box<_> = Box::new(MacroRulesMacroExpander {
+    mk_syn_ext(Box::new(MacroRulesMacroExpander {
         name: def.ident,
         span: def.span,
         transparency,
         lhses,
         rhses,
         valid,
-    });
-
-    SyntaxExtension::new(
-        sess,
-        SyntaxExtensionKind::LegacyBang(expander),
-        def.span,
-        Vec::new(),
-        edition,
-        def.ident.name,
-        &def.attrs,
-    )
+    }))
 }
 
 fn check_lhs_nt_follows(
diff --git a/src/librustc_expand/mbe/transcribe.rs b/src/librustc_expand/mbe/transcribe.rs
index 1b1093c9529..e2d3d5c4d64 100644
--- a/src/librustc_expand/mbe/transcribe.rs
+++ b/src/librustc_expand/mbe/transcribe.rs
@@ -8,7 +8,7 @@ use rustc_ast::token::{self, NtTT, Token};
 use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::pluralize;
+use rustc_errors::{pluralize, PResult};
 use rustc_span::hygiene::{ExpnId, Transparency};
 use rustc_span::symbol::MacroRulesNormalizedIdent;
 use rustc_span::Span;
@@ -80,15 +80,15 @@ impl Iterator for Frame {
 /// `transcribe` would return a `TokenStream` containing `println!("{}", stringify!(bar));`.
 ///
 /// Along the way, we do some additional error checking.
-pub(super) fn transcribe(
-    cx: &ExtCtxt<'_>,
+pub(super) fn transcribe<'a>(
+    cx: &ExtCtxt<'a>,
     interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
     src: Vec<mbe::TokenTree>,
     transparency: Transparency,
-) -> TokenStream {
+) -> PResult<'a, TokenStream> {
     // Nothing for us to transcribe...
     if src.is_empty() {
-        return TokenStream::default();
+        return Ok(TokenStream::default());
     }
 
     // We descend into the RHS (`src`), expanding things as we go. This stack contains the things
@@ -152,7 +152,7 @@ pub(super) fn transcribe(
                 Frame::Delimited { forest, span, .. } => {
                     if result_stack.is_empty() {
                         // No results left to compute! We are back at the top-level.
-                        return TokenStream::new(result);
+                        return Ok(TokenStream::new(result));
                     }
 
                     // Step back into the parent Delimited.
@@ -173,11 +173,11 @@ pub(super) fn transcribe(
             seq @ mbe::TokenTree::Sequence(..) => {
                 match lockstep_iter_size(&seq, interp, &repeats) {
                     LockstepIterSize::Unconstrained => {
-                        cx.span_fatal(
+                        return Err(cx.struct_span_err(
                             seq.span(), /* blame macro writer */
                             "attempted to repeat an expression containing no syntax variables \
                              matched as repeating at this depth",
-                        );
+                        ));
                     }
 
                     LockstepIterSize::Contradiction(ref msg) => {
@@ -185,7 +185,7 @@ pub(super) fn transcribe(
                         // happens when two meta-variables are used in the same repetition in a
                         // sequence, but they come from different sequence matchers and repeat
                         // different amounts.
-                        cx.span_fatal(seq.span(), &msg[..]);
+                        return Err(cx.struct_span_err(seq.span(), &msg[..]));
                     }
 
                     LockstepIterSize::Constraint(len, _) => {
@@ -203,7 +203,10 @@ pub(super) fn transcribe(
                                 // FIXME: this really ought to be caught at macro definition
                                 // time... It happens when the Kleene operator in the matcher and
                                 // the body for the same meta-variable do not match.
-                                cx.span_fatal(sp.entire(), "this must repeat at least once");
+                                return Err(cx.struct_span_err(
+                                    sp.entire(),
+                                    "this must repeat at least once",
+                                ));
                             }
                         } else {
                             // 0 is the initial counter (we have done 0 repretitions so far). `len`
@@ -242,10 +245,10 @@ pub(super) fn transcribe(
                         }
                     } else {
                         // We were unable to descend far enough. This is an error.
-                        cx.span_fatal(
+                        return Err(cx.struct_span_err(
                             sp, /* blame the macro writer */
                             &format!("variable '{}' is still repeating at this depth", ident),
-                        );
+                        ));
                     }
                 } else {
                     // If we aren't able to match the meta-var, we push it back into the result but
diff --git a/src/librustc_expand/proc_macro.rs b/src/librustc_expand/proc_macro.rs
index cb9afa4cd4f..df7bf9438c3 100644
--- a/src/librustc_expand/proc_macro.rs
+++ b/src/librustc_expand/proc_macro.rs
@@ -5,7 +5,7 @@ use rustc_ast::ast::{self, ItemKind, MetaItemKind, NestedMetaItem};
 use rustc_ast::token;
 use rustc_ast::tokenstream::{self, TokenStream};
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{Applicability, FatalError};
+use rustc_errors::{Applicability, ErrorReported};
 use rustc_span::symbol::sym;
 use rustc_span::{Span, DUMMY_SP};
 
@@ -21,21 +21,16 @@ impl base::ProcMacro for BangProcMacro {
         ecx: &'cx mut ExtCtxt<'_>,
         span: Span,
         input: TokenStream,
-    ) -> TokenStream {
+    ) -> Result<TokenStream, ErrorReported> {
         let server = proc_macro_server::Rustc::new(ecx);
-        match self.client.run(&EXEC_STRATEGY, server, input) {
-            Ok(stream) => stream,
-            Err(e) => {
-                let msg = "proc macro panicked";
-                let mut err = ecx.struct_span_fatal(span, msg);
-                if let Some(s) = e.as_str() {
-                    err.help(&format!("message: {}", s));
-                }
-
-                err.emit();
-                FatalError.raise();
+        self.client.run(&EXEC_STRATEGY, server, input).map_err(|e| {
+            let mut err = ecx.struct_span_err(span, "proc macro panicked");
+            if let Some(s) = e.as_str() {
+                err.help(&format!("message: {}", s));
             }
-        }
+            err.emit();
+            ErrorReported
+        })
     }
 }
 
@@ -50,21 +45,16 @@ impl base::AttrProcMacro for AttrProcMacro {
         span: Span,
         annotation: TokenStream,
         annotated: TokenStream,
-    ) -> TokenStream {
+    ) -> Result<TokenStream, ErrorReported> {
         let server = proc_macro_server::Rustc::new(ecx);
-        match self.client.run(&EXEC_STRATEGY, server, annotation, annotated) {
-            Ok(stream) => stream,
-            Err(e) => {
-                let msg = "custom attribute panicked";
-                let mut err = ecx.struct_span_fatal(span, msg);
-                if let Some(s) = e.as_str() {
-                    err.help(&format!("message: {}", s));
-                }
-
-                err.emit();
-                FatalError.raise();
+        self.client.run(&EXEC_STRATEGY, server, annotation, annotated).map_err(|e| {
+            let mut err = ecx.struct_span_err(span, "custom attribute panicked");
+            if let Some(s) = e.as_str() {
+                err.help(&format!("message: {}", s));
             }
-        }
+            err.emit();
+            ErrorReported
+        })
     }
 }
 
@@ -96,8 +86,7 @@ impl MultiItemModifier for ProcMacroDerive {
             | Annotatable::Expr(_) => {
                 ecx.span_err(
                     span,
-                    "proc-macro derives may only be \
-                                    applied to a struct, enum, or union",
+                    "proc-macro derives may only be applied to a struct, enum, or union",
                 );
                 return ExpandResult::Ready(Vec::new());
             }
@@ -107,8 +96,7 @@ impl MultiItemModifier for ProcMacroDerive {
             _ => {
                 ecx.span_err(
                     span,
-                    "proc-macro derives may only be \
-                                    applied to a struct, enum, or union",
+                    "proc-macro derives may only be applied to a struct, enum, or union",
                 );
                 return ExpandResult::Ready(Vec::new());
             }
@@ -121,20 +109,16 @@ impl MultiItemModifier for ProcMacroDerive {
         let stream = match self.client.run(&EXEC_STRATEGY, server, input) {
             Ok(stream) => stream,
             Err(e) => {
-                let msg = "proc-macro derive panicked";
-                let mut err = ecx.struct_span_fatal(span, msg);
+                let mut err = ecx.struct_span_err(span, "proc-macro derive panicked");
                 if let Some(s) = e.as_str() {
                     err.help(&format!("message: {}", s));
                 }
-
                 err.emit();
-                FatalError.raise();
+                return ExpandResult::Ready(vec![]);
             }
         };
 
         let error_count_before = ecx.parse_sess.span_diagnostic.err_count();
-        let msg = "proc-macro derive produced unparseable tokens";
-
         let mut parser =
             rustc_parse::stream_to_parser(ecx.parse_sess, stream, Some("proc-macro derive"));
         let mut items = vec![];
@@ -144,18 +128,15 @@ impl MultiItemModifier for ProcMacroDerive {
                 Ok(None) => break,
                 Ok(Some(item)) => items.push(Annotatable::Item(item)),
                 Err(mut err) => {
-                    // FIXME: handle this better
-                    err.cancel();
-                    ecx.struct_span_fatal(span, msg).emit();
-                    FatalError.raise();
+                    err.emit();
+                    break;
                 }
             }
         }
 
         // fail if there have been errors emitted
         if ecx.parse_sess.span_diagnostic.err_count() > error_count_before {
-            ecx.struct_span_fatal(span, msg).emit();
-            FatalError.raise();
+            ecx.struct_span_err(span, "proc-macro derive produced unparseable tokens").emit();
         }
 
         ExpandResult::Ready(items)
diff --git a/src/librustc_hir/def.rs b/src/librustc_hir/def.rs
index 696aa5c6f7d..3334cc32a52 100644
--- a/src/librustc_hir/def.rs
+++ b/src/librustc_hir/def.rs
@@ -159,6 +159,7 @@ impl DefKind {
     }
 }
 
+/// The resolution of a path or export.
 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 #[derive(HashStable_Generic)]
 pub enum Res<Id = hir::HirId> {
diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs
index fb00fbe2826..dc494b8e413 100644
--- a/src/librustc_infer/infer/mod.rs
+++ b/src/librustc_infer/infer/mod.rs
@@ -19,7 +19,7 @@ use rustc::traits::select;
 use rustc::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
 use rustc::ty::fold::{TypeFoldable, TypeFolder};
 use rustc::ty::relate::RelateResult;
-use rustc::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
+use rustc::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef};
 pub use rustc::ty::IntVarValue;
 use rustc::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
 use rustc::ty::{ConstVid, FloatVid, IntVid, TyVid};
@@ -501,6 +501,7 @@ impl NLLRegionVariableOrigin {
     }
 }
 
+// FIXME(eddyb) investigate overlap between this and `TyOrConstInferVar`.
 #[derive(Copy, Clone, Debug)]
 pub enum FixupError<'tcx> {
     UnresolvedIntTy(IntVid),
@@ -1347,8 +1348,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     where
         T: TypeFoldable<'tcx>,
     {
-        let mut r = ShallowResolver::new(self);
-        value.fold_with(&mut r)
+        value.fold_with(&mut ShallowResolver { infcx: self })
     }
 
     pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
@@ -1551,22 +1551,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         // variables, thus we don't need to substitute back the original values.
         self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, span)
     }
-}
-
-pub struct ShallowResolver<'a, 'tcx> {
-    infcx: &'a InferCtxt<'a, 'tcx>,
-}
-
-impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
-    #[inline(always)]
-    pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
-        ShallowResolver { infcx }
-    }
 
     /// If `typ` is a type variable of some kind, resolve it one level
     /// (but do not resolve types found in the result). If `typ` is
     /// not a type variable, just return it unmodified.
-    pub fn shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> {
+    // FIXME(eddyb) inline into `ShallowResolver::visit_ty`.
+    fn shallow_resolve_ty(&self, typ: Ty<'tcx>) -> Ty<'tcx> {
         match typ.kind {
             ty::Infer(ty::TyVar(v)) => {
                 // Not entirely obvious: if `typ` is a type variable,
@@ -1580,69 +1570,133 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
                 // depth.
                 //
                 // Note: if these two lines are combined into one we get
-                // dynamic borrow errors on `self.infcx.inner`.
-                let known = self.infcx.inner.borrow_mut().type_variables.probe(v).known();
-                known.map(|t| self.fold_ty(t)).unwrap_or(typ)
+                // dynamic borrow errors on `self.inner`.
+                let known = self.inner.borrow_mut().type_variables.probe(v).known();
+                known.map(|t| self.shallow_resolve_ty(t)).unwrap_or(typ)
             }
 
             ty::Infer(ty::IntVar(v)) => self
-                .infcx
                 .inner
                 .borrow_mut()
                 .int_unification_table
                 .probe_value(v)
-                .map(|v| v.to_type(self.infcx.tcx))
+                .map(|v| v.to_type(self.tcx))
                 .unwrap_or(typ),
 
             ty::Infer(ty::FloatVar(v)) => self
-                .infcx
                 .inner
                 .borrow_mut()
                 .float_unification_table
                 .probe_value(v)
-                .map(|v| v.to_type(self.infcx.tcx))
+                .map(|v| v.to_type(self.tcx))
                 .unwrap_or(typ),
 
             _ => typ,
         }
     }
 
-    // `resolver.shallow_resolve_changed(ty)` is equivalent to
-    // `resolver.shallow_resolve(ty) != ty`, but more efficient. It's always
-    // inlined, despite being large, because it has only two call sites that
-    // are extremely hot.
+    /// `ty_or_const_infer_var_changed` is equivalent to one of these two:
+    ///   * `shallow_resolve(ty) != ty` (where `ty.kind = ty::Infer(_)`)
+    ///   * `shallow_resolve(ct) != ct` (where `ct.kind = ty::ConstKind::Infer(_)`)
+    ///
+    /// However, `ty_or_const_infer_var_changed` is more efficient. It's always
+    /// inlined, despite being large, because it has only two call sites that
+    /// are extremely hot (both in `traits::fulfill`'s checking of `stalled_on`
+    /// inference variables), and it handles both `Ty` and `ty::Const` without
+    /// having to resort to storing full `GenericArg`s in `stalled_on`.
     #[inline(always)]
-    pub fn shallow_resolve_changed(&self, infer: ty::InferTy) -> bool {
-        match infer {
-            ty::TyVar(v) => {
+    pub fn ty_or_const_infer_var_changed(&self, infer_var: TyOrConstInferVar<'tcx>) -> bool {
+        match infer_var {
+            TyOrConstInferVar::Ty(v) => {
                 use self::type_variable::TypeVariableValue;
 
-                // If `inlined_probe` returns a `Known` value its `kind` never
-                // matches `infer`.
-                match self.infcx.inner.borrow_mut().type_variables.inlined_probe(v) {
+                // If `inlined_probe` returns a `Known` value, it never equals
+                // `ty::Infer(ty::TyVar(v))`.
+                match self.inner.borrow_mut().type_variables.inlined_probe(v) {
                     TypeVariableValue::Unknown { .. } => false,
                     TypeVariableValue::Known { .. } => true,
                 }
             }
 
-            ty::IntVar(v) => {
-                // If inlined_probe_value returns a value it's always a
+            TyOrConstInferVar::TyInt(v) => {
+                // If `inlined_probe_value` returns a value it's always a
                 // `ty::Int(_)` or `ty::UInt(_)`, which never matches a
                 // `ty::Infer(_)`.
-                self.infcx.inner.borrow_mut().int_unification_table.inlined_probe_value(v).is_some()
+                self.inner.borrow_mut().int_unification_table.inlined_probe_value(v).is_some()
             }
 
-            ty::FloatVar(v) => {
-                // If inlined_probe_value returns a value it's always a
+            TyOrConstInferVar::TyFloat(v) => {
+                // If `probe_value` returns a value it's always a
                 // `ty::Float(_)`, which never matches a `ty::Infer(_)`.
                 //
                 // Not `inlined_probe_value(v)` because this call site is colder.
-                self.infcx.inner.borrow_mut().float_unification_table.probe_value(v).is_some()
+                self.inner.borrow_mut().float_unification_table.probe_value(v).is_some()
             }
 
-            _ => unreachable!(),
+            TyOrConstInferVar::Const(v) => {
+                // If `probe_value` returns a `Known` value, it never equals
+                // `ty::ConstKind::Infer(ty::InferConst::Var(v))`.
+                //
+                // Not `inlined_probe_value(v)` because this call site is colder.
+                match self.inner.borrow_mut().const_unification_table.probe_value(v).val {
+                    ConstVariableValue::Unknown { .. } => false,
+                    ConstVariableValue::Known { .. } => true,
+                }
+            }
+        }
+    }
+}
+
+/// Helper for `ty_or_const_infer_var_changed` (see comment on that), currently
+/// used only for `traits::fulfill`'s list of `stalled_on` inference variables.
+#[derive(Copy, Clone, Debug)]
+pub enum TyOrConstInferVar<'tcx> {
+    /// Equivalent to `ty::Infer(ty::TyVar(_))`.
+    Ty(TyVid),
+    /// Equivalent to `ty::Infer(ty::IntVar(_))`.
+    TyInt(IntVid),
+    /// Equivalent to `ty::Infer(ty::FloatVar(_))`.
+    TyFloat(FloatVid),
+
+    /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`.
+    Const(ConstVid<'tcx>),
+}
+
+impl TyOrConstInferVar<'tcx> {
+    /// Tries to extract an inference variable from a type or a constant, returns `None`
+    /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`) and
+    /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
+    pub fn maybe_from_generic_arg(arg: GenericArg<'tcx>) -> Option<Self> {
+        match arg.unpack() {
+            GenericArgKind::Type(ty) => Self::maybe_from_ty(ty),
+            GenericArgKind::Const(ct) => Self::maybe_from_const(ct),
+            GenericArgKind::Lifetime(_) => None,
         }
     }
+
+    /// Tries to extract an inference variable from a type, returns `None`
+    /// for types other than `ty::Infer(_)` (or `InferTy::Fresh*`).
+    pub fn maybe_from_ty(ty: Ty<'tcx>) -> Option<Self> {
+        match ty.kind {
+            ty::Infer(ty::TyVar(v)) => Some(TyOrConstInferVar::Ty(v)),
+            ty::Infer(ty::IntVar(v)) => Some(TyOrConstInferVar::TyInt(v)),
+            ty::Infer(ty::FloatVar(v)) => Some(TyOrConstInferVar::TyFloat(v)),
+            _ => None,
+        }
+    }
+
+    /// Tries to extract an inference variable from a constant, returns `None`
+    /// for constants other than `ty::ConstKind::Infer(_)` (or `InferConst::Fresh`).
+    pub fn maybe_from_const(ct: &'tcx ty::Const<'tcx>) -> Option<Self> {
+        match ct.val {
+            ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)),
+            _ => None,
+        }
+    }
+}
+
+struct ShallowResolver<'a, 'tcx> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
 }
 
 impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
@@ -1651,7 +1705,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
     }
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.shallow_resolve(ty)
+        self.infcx.shallow_resolve_ty(ty)
     }
 
     fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs
index 4e086bcbb2d..4520df58899 100644
--- a/src/librustc_metadata/rmeta/decoder.rs
+++ b/src/librustc_metadata/rmeta/decoder.rs
@@ -509,14 +509,6 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
     }
 }
 
-impl SpecializedDecoder<Ident> for DecodeContext<'_, '_> {
-    fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
-        // FIXME(jseyfried): intercrate hygiene
-
-        Ok(Ident::with_dummy_span(Symbol::decode(self)?))
-    }
-}
-
 impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for DecodeContext<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
         Fingerprint::decode_opaque(&mut self.opaque)
@@ -663,15 +655,27 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         &self.raw_proc_macros.unwrap()[pos]
     }
 
-    fn item_name(&self, item_index: DefIndex) -> Symbol {
+    fn item_ident(&self, item_index: DefIndex, sess: &Session) -> Ident {
         if !self.is_proc_macro(item_index) {
-            self.def_key(item_index)
+            let name = self
+                .def_key(item_index)
                 .disambiguated_data
                 .data
                 .get_opt_name()
-                .expect("no name in item_name")
+                .expect("no name in item_ident");
+            let span = self
+                .root
+                .per_def
+                .ident_span
+                .get(self, item_index)
+                .map(|data| data.decode((self, sess)))
+                .unwrap_or_else(|| panic!("Missing ident span for {:?} ({:?})", name, item_index));
+            Ident::new(name, span)
         } else {
-            Symbol::intern(self.raw_proc_macro(item_index).name())
+            Ident::new(
+                Symbol::intern(self.raw_proc_macro(item_index).name()),
+                self.get_span(item_index, sess),
+            )
         }
     }
 
@@ -750,6 +754,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         kind: &EntryKind,
         index: DefIndex,
         parent_did: DefId,
+        sess: &Session,
     ) -> ty::VariantDef {
         let data = match kind {
             EntryKind::Variant(data) | EntryKind::Struct(data, _) | EntryKind::Union(data, _) => {
@@ -771,7 +776,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
         ty::VariantDef::new(
             tcx,
-            Ident::with_dummy_span(self.item_name(index)),
+            self.item_ident(index, sess),
             variant_did,
             ctor_did,
             data.discr,
@@ -783,7 +788,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                 .decode(self)
                 .map(|index| ty::FieldDef {
                     did: self.local_def_id(index),
-                    ident: Ident::with_dummy_span(self.item_name(index)),
+                    ident: self.item_ident(index, sess),
                     vis: self.get_visibility(index),
                 })
                 .collect(),
@@ -812,10 +817,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                 .get(self, item_id)
                 .unwrap_or(Lazy::empty())
                 .decode(self)
-                .map(|index| self.get_variant(tcx, &self.kind(index), index, did))
+                .map(|index| self.get_variant(tcx, &self.kind(index), index, did, tcx.sess))
                 .collect()
         } else {
-            std::iter::once(self.get_variant(tcx, &kind, item_id, did)).collect()
+            std::iter::once(self.get_variant(tcx, &kind, item_id, did, tcx.sess)).collect()
         };
 
         tcx.alloc_adt_def(did, adt_kind, variants, repr)
@@ -1007,7 +1012,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                             if let Some(kind) = self.def_kind(child_index) {
                                 callback(Export {
                                     res: Res::Def(kind, self.local_def_id(child_index)),
-                                    ident: Ident::with_dummy_span(self.item_name(child_index)),
+                                    ident: self.item_ident(child_index, sess),
                                     vis: self.get_visibility(child_index),
                                     span: self
                                         .root
@@ -1028,10 +1033,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
 
                 let def_key = self.def_key(child_index);
                 let span = self.get_span(child_index, sess);
-                if let (Some(kind), Some(name)) =
-                    (self.def_kind(child_index), def_key.disambiguated_data.data.get_opt_name())
-                {
-                    let ident = Ident::with_dummy_span(name);
+                if let (Some(kind), true) = (
+                    self.def_kind(child_index),
+                    def_key.disambiguated_data.data.get_opt_name().is_some(),
+                ) {
+                    let ident = self.item_ident(child_index, sess);
                     let vis = self.get_visibility(child_index);
                     let def_id = self.local_def_id(child_index);
                     let res = Res::Def(kind, def_id);
@@ -1138,10 +1144,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         }
     }
 
-    fn get_associated_item(&self, id: DefIndex) -> ty::AssocItem {
+    fn get_associated_item(&self, id: DefIndex, sess: &Session) -> ty::AssocItem {
         let def_key = self.def_key(id);
         let parent = self.local_def_id(def_key.parent.unwrap());
-        let name = def_key.disambiguated_data.data.get_opt_name().unwrap();
+        let ident = self.item_ident(id, sess);
 
         let (kind, container, has_self) = match self.kind(id) {
             EntryKind::AssocConst(container, _, _) => (ty::AssocKind::Const, container, false),
@@ -1155,7 +1161,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
         };
 
         ty::AssocItem {
-            ident: Ident::with_dummy_span(name),
+            ident,
             kind,
             vis: self.get_visibility(id),
             defaultness: container.defaultness(),
@@ -1219,7 +1225,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .get(self, id)
             .unwrap_or(Lazy::empty())
             .decode(self)
-            .map(|index| respan(self.get_span(index, sess), self.item_name(index)))
+            .map(|index| respan(self.get_span(index, sess), self.item_ident(index, sess).name))
             .collect()
     }
 
diff --git a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
index 1ac5caf138c..b9f1dd1663e 100644
--- a/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
+++ b/src/librustc_metadata/rmeta/decoder/cstore_impl.rs
@@ -110,7 +110,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
           |child| result.push(child.res.def_id()), tcx.sess);
         tcx.arena.alloc_slice(&result)
     }
-    associated_item => { cdata.get_associated_item(def_id.index) }
+    associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) }
     impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) }
     impl_polarity => { cdata.get_impl_polarity(def_id.index) }
     coerce_unsized_info => {
@@ -442,8 +442,8 @@ impl CStore {
         )
     }
 
-    pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssocItem {
-        self.get_crate_data(def.krate).get_associated_item(def.index)
+    pub fn associated_item_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::AssocItem {
+        self.get_crate_data(def.krate).get_associated_item(def.index, sess)
     }
 
     pub fn crate_source_untracked(&self, cnum: CrateNum) -> CrateSource {
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 52124fd3abb..9718d192816 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -12,7 +12,7 @@ use rustc::traits::specialization_graph;
 use rustc::ty::codec::{self as ty_codec, TyEncoder};
 use rustc::ty::layout::VariantIdx;
 use rustc::ty::{self, SymbolName, Ty, TyCtxt};
-use rustc_ast::ast;
+use rustc_ast::ast::{self, Ident};
 use rustc_ast::attr;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
@@ -30,7 +30,7 @@ use rustc_index::vec::Idx;
 use rustc_serialize::{opaque, Encodable, Encoder, SpecializedEncoder};
 use rustc_session::config::{self, CrateType};
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{kw, sym, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_span::{self, ExternalSource, FileName, SourceFile, Span};
 use std::hash::Hash;
 use std::num::NonZeroUsize;
@@ -220,13 +220,6 @@ impl<'tcx> SpecializedEncoder<Span> for EncodeContext<'tcx> {
     }
 }
 
-impl SpecializedEncoder<Ident> for EncodeContext<'tcx> {
-    fn specialized_encode(&mut self, ident: &Ident) -> Result<(), Self::Error> {
-        // FIXME(jseyfried): intercrate hygiene
-        ident.name.encode(self)
-    }
-}
-
 impl<'tcx> SpecializedEncoder<LocalDefId> for EncodeContext<'tcx> {
     #[inline]
     fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> {
@@ -633,6 +626,7 @@ impl EncodeContext<'tcx> {
             assert!(f.did.is_local());
             f.did.index
         }));
+        self.encode_ident_span(def_id, variant.ident);
         self.encode_stability(def_id);
         self.encode_deprecation(def_id);
         self.encode_item_type(def_id);
@@ -735,6 +729,7 @@ impl EncodeContext<'tcx> {
         record!(self.per_def.visibility[def_id] <- field.vis);
         record!(self.per_def.span[def_id] <- self.tcx.def_span(def_id));
         record!(self.per_def.attributes[def_id] <- variant_data.fields()[field_index].attrs);
+        self.encode_ident_span(def_id, field.ident);
         self.encode_stability(def_id);
         self.encode_deprecation(def_id);
         self.encode_item_type(def_id);
@@ -869,6 +864,7 @@ impl EncodeContext<'tcx> {
         record!(self.per_def.visibility[def_id] <- trait_item.vis);
         record!(self.per_def.span[def_id] <- ast_item.span);
         record!(self.per_def.attributes[def_id] <- ast_item.attrs);
+        self.encode_ident_span(def_id, ast_item.ident);
         self.encode_stability(def_id);
         self.encode_const_stability(def_id);
         self.encode_deprecation(def_id);
@@ -952,6 +948,7 @@ impl EncodeContext<'tcx> {
         record!(self.per_def.visibility[def_id] <- impl_item.vis);
         record!(self.per_def.span[def_id] <- ast_item.span);
         record!(self.per_def.attributes[def_id] <- ast_item.attrs);
+        self.encode_ident_span(def_id, impl_item.ident);
         self.encode_stability(def_id);
         self.encode_const_stability(def_id);
         self.encode_deprecation(def_id);
@@ -1058,6 +1055,8 @@ impl EncodeContext<'tcx> {
 
         debug!("EncodeContext::encode_info_for_item({:?})", def_id);
 
+        self.encode_ident_span(def_id, item.ident);
+
         record!(self.per_def.kind[def_id] <- match item.kind {
             hir::ItemKind::Static(_, hir::Mutability::Mut, _) => EntryKind::MutStatic,
             hir::ItemKind::Static(_, hir::Mutability::Not, _) => EntryKind::ImmStatic,
@@ -1284,6 +1283,7 @@ impl EncodeContext<'tcx> {
         record!(self.per_def.visibility[def_id] <- ty::Visibility::Public);
         record!(self.per_def.span[def_id] <- macro_def.span);
         record!(self.per_def.attributes[def_id] <- macro_def.attrs);
+        self.encode_ident_span(def_id, macro_def.ident);
         self.encode_stability(def_id);
         self.encode_deprecation(def_id);
     }
@@ -1528,6 +1528,7 @@ impl EncodeContext<'tcx> {
             ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, self.tcx));
         record!(self.per_def.span[def_id] <- nitem.span);
         record!(self.per_def.attributes[def_id] <- nitem.attrs);
+        self.encode_ident_span(def_id, nitem.ident);
         self.encode_stability(def_id);
         self.encode_const_stability(def_id);
         self.encode_deprecation(def_id);
@@ -1622,6 +1623,10 @@ impl EncodeContext<'tcx> {
         }
     }
 
+    fn encode_ident_span(&mut self, def_id: DefId, ident: Ident) {
+        record!(self.per_def.ident_span[def_id] <- ident.span);
+    }
+
     /// In some cases, along with the item itself, we also
     /// encode some sub-items. Usually we want some info from the item
     /// so it's easier to do that here then to wait until we would encounter
diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs
index 448c1610c13..3a4214e916a 100644
--- a/src/librustc_metadata/rmeta/mod.rs
+++ b/src/librustc_metadata/rmeta/mod.rs
@@ -256,6 +256,7 @@ define_per_def_tables! {
     kind: Table<DefIndex, Lazy<EntryKind>>,
     visibility: Table<DefIndex, Lazy<ty::Visibility>>,
     span: Table<DefIndex, Lazy<Span>>,
+    ident_span: Table<DefIndex, Lazy<Span>>,
     attributes: Table<DefIndex, Lazy<[ast::Attribute]>>,
     children: Table<DefIndex, Lazy<[DefIndex]>>,
     stability: Table<DefIndex, Lazy<attr::Stability>>,
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 8899f12b153..548c637efb2 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -337,14 +337,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
     ) -> ConstPropagator<'mir, 'tcx> {
         let def_id = source.def_id();
         let substs = &InternalSubsts::identity_for_item(tcx, def_id);
-        let mut param_env = tcx.param_env(def_id);
-
-        // If we're evaluating inside a monomorphic function, then use `Reveal::All` because
-        // we want to see the same instances that codegen will see. This allows us to `resolve()`
-        // specializations.
-        if !substs.needs_subst() {
-            param_env = param_env.with_reveal_all();
-        }
+        let param_env = tcx.param_env(def_id).with_reveal_all();
 
         let span = tcx.def_span(def_id);
         let mut ecx = InterpCx::new(tcx.at(span), param_env, ConstPropMachine, ());
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 52c7225a850..16c32e138fd 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -3,8 +3,8 @@
 use rustc::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc::mir::visit::*;
 use rustc::mir::*;
-use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef};
-use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable};
+use rustc::ty::subst::{Subst, SubstsRef};
+use rustc::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
 use rustc_attr as attr;
 use rustc_hir::def_id::DefId;
 use rustc_index::bit_set::BitSet;
@@ -66,14 +66,7 @@ impl Inliner<'tcx> {
 
         let mut callsites = VecDeque::new();
 
-        let mut param_env = self.tcx.param_env(self.source.def_id());
-
-        let substs = &InternalSubsts::identity_for_item(self.tcx, self.source.def_id());
-
-        // For monomorphic functions, we can use `Reveal::All` to resolve specialized instances.
-        if !substs.needs_subst() {
-            param_env = param_env.with_reveal_all();
-        }
+        let param_env = self.tcx.param_env(self.source.def_id()).with_reveal_all();
 
         // Only do inlining into fn bodies.
         let id = self.tcx.hir().as_local_hir_id(self.source.def_id()).unwrap();
diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs
index d5daf465bb7..a7ec4f501ae 100644
--- a/src/librustc_mir_build/build/mod.rs
+++ b/src/librustc_mir_build/build/mod.rs
@@ -139,7 +139,8 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
             let arguments = implicit_argument.into_iter().chain(explicit_arguments);
 
             let (yield_ty, return_ty) = if body.generator_kind.is_some() {
-                let gen_sig = match ty.kind {
+                let gen_ty = tcx.body_tables(body_id).node_type(id);
+                let gen_sig = match gen_ty.kind {
                     ty::Generator(_, gen_substs, ..) => gen_substs.as_generator().sig(),
                     _ => span_bug!(tcx.hir().span(id), "generator w/o generator type: {:?}", ty),
                 };
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index db500a8b1fd..5408c85a4d0 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -904,7 +904,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 self.insert_field_names(def_id, field_names);
             }
             Res::Def(DefKind::AssocFn, def_id) => {
-                if cstore.associated_item_cloned_untracked(def_id).method_has_self_argument {
+                if cstore
+                    .associated_item_cloned_untracked(def_id, self.r.session)
+                    .method_has_self_argument
+                {
                     self.r.has_self.insert(def_id);
                 }
             }
diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs
index 865a4ba866e..0578c00fefb 100644
--- a/src/librustc_trait_selection/traits/fulfill.rs
+++ b/src/librustc_trait_selection/traits/fulfill.rs
@@ -1,4 +1,4 @@
-use crate::infer::{InferCtxt, ShallowResolver};
+use crate::infer::{InferCtxt, TyOrConstInferVar};
 use rustc::ty::error::ExpectedFound;
 use rustc::ty::{self, ToPolyTraitRef, Ty, TypeFoldable};
 use rustc_data_structures::obligation_forest::ProcessResult;
@@ -73,7 +73,10 @@ pub struct FulfillmentContext<'tcx> {
 #[derive(Clone, Debug)]
 pub struct PendingPredicateObligation<'tcx> {
     pub obligation: PredicateObligation<'tcx>,
-    pub stalled_on: Vec<ty::InferTy>,
+    // FIXME(eddyb) look into whether this could be a `SmallVec`.
+    // Judging by the comment in `process_obligation`, the 1-element case
+    // is common so this could be a `SmallVec<[TyOrConstInferVar<'tcx>; 1]>`.
+    pub stalled_on: Vec<TyOrConstInferVar<'tcx>>,
 }
 
 // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -266,8 +269,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
             // Match arms are in order of frequency, which matters because this
             // code is so hot. 1 and 0 dominate; 2+ is fairly rare.
             1 => {
-                let infer = pending_obligation.stalled_on[0];
-                ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer)
+                let infer_var = pending_obligation.stalled_on[0];
+                self.selcx.infcx().ty_or_const_infer_var_changed(infer_var)
             }
             0 => {
                 // In this case we haven't changed, but wish to make a change.
@@ -277,8 +280,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
                 // This `for` loop was once a call to `all()`, but this lower-level
                 // form was a perf win. See #64545 for details.
                 (|| {
-                    for &infer in &pending_obligation.stalled_on {
-                        if ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(infer) {
+                    for &infer_var in &pending_obligation.stalled_on {
+                        if self.selcx.infcx().ty_or_const_infer_var_changed(infer_var) {
                             return true;
                         }
                     }
@@ -309,13 +312,6 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
 
         debug!("process_obligation: obligation = {:?} cause = {:?}", obligation, obligation.cause);
 
-        fn infer_ty(ty: Ty<'tcx>) -> ty::InferTy {
-            match ty.kind {
-                ty::Infer(infer) => infer,
-                _ => panic!(),
-            }
-        }
-
         match obligation.predicate {
             ty::Predicate::Trait(ref data, _) => {
                 let trait_obligation = obligation.with(data.clone());
@@ -467,7 +463,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
                     obligation.cause.span,
                 ) {
                     None => {
-                        pending_obligation.stalled_on = vec![infer_ty(ty)];
+                        pending_obligation.stalled_on =
+                            vec![TyOrConstInferVar::maybe_from_ty(ty).unwrap()];
                         ProcessResult::Unchanged
                     }
                     Some(os) => ProcessResult::Changed(mk_pending(os)),
@@ -483,8 +480,8 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
                     None => {
                         // None means that both are unresolved.
                         pending_obligation.stalled_on = vec![
-                            infer_ty(subtype.skip_binder().a),
-                            infer_ty(subtype.skip_binder().b),
+                            TyOrConstInferVar::maybe_from_ty(subtype.skip_binder().a).unwrap(),
+                            TyOrConstInferVar::maybe_from_ty(subtype.skip_binder().b).unwrap(),
                         ];
                         ProcessResult::Unchanged
                     }
@@ -534,20 +531,23 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
     }
 }
 
-/// Returns the set of type variables contained in a trait ref
+/// Returns the set of type inference variables contained in a trait ref.
 fn trait_ref_type_vars<'a, 'tcx>(
     selcx: &mut SelectionContext<'a, 'tcx>,
-    t: ty::PolyTraitRef<'tcx>,
-) -> Vec<ty::InferTy> {
-    t.skip_binder() // ok b/c this check doesn't care about regions
+    trait_ref: ty::PolyTraitRef<'tcx>,
+) -> Vec<TyOrConstInferVar<'tcx>> {
+    trait_ref
+        .skip_binder() // ok b/c this check doesn't care about regions
+        // FIXME(eddyb) walk over `GenericArg` to support const infer vars.
         .input_types()
-        .map(|t| selcx.infcx().resolve_vars_if_possible(&t))
-        .filter(|t| t.has_infer_types())
-        .flat_map(|t| t.walk())
-        .filter_map(|t| match t.kind {
-            ty::Infer(infer) => Some(infer),
-            _ => None,
-        })
+        .map(|ty| selcx.infcx().resolve_vars_if_possible(&ty))
+        // FIXME(eddyb) try using `maybe_walk` to skip *all* subtrees that
+        // don't contain inference variables, not just the outermost level.
+        // FIXME(eddyb) use `has_infer_types_or_const`.
+        .filter(|ty| ty.has_infer_types())
+        .flat_map(|ty| ty.walk())
+        // FIXME(eddyb) use `TyOrConstInferVar::maybe_from_generic_arg`.
+        .filter_map(TyOrConstInferVar::maybe_from_ty)
         .collect()
 }
 
diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs
index 55642dfb455..30741ed53b5 100644
--- a/src/librustc_typeck/collect/type_of.rs
+++ b/src/librustc_typeck/collect/type_of.rs
@@ -188,12 +188,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
         Node::Field(field) => icx.to_ty(&field.ty),
 
         Node::Expr(&Expr { kind: ExprKind::Closure(.., gen), .. }) => {
-            if gen.is_some() {
-                return tcx.typeck_tables_of(def_id).node_type(hir_id);
-            }
-
             let substs = InternalSubsts::identity_for_item(tcx, def_id);
-            tcx.mk_closure(def_id, substs)
+            if let Some(movability) = gen {
+                tcx.mk_generator(def_id, substs, movability)
+            } else {
+                tcx.mk_closure(def_id, substs)
+            }
         }
 
         Node::AnonConst(_) => {
@@ -235,29 +235,31 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     };
 
                     if let Some(path) = path {
-                        let arg_index = path
+                        // We've encountered an `AnonConst` in some path, so we need to
+                        // figure out which generic parameter it corresponds to and return
+                        // the relevant type.
+
+                        let (arg_index, segment) = path
                             .segments
                             .iter()
-                            .filter_map(|seg| seg.args.as_ref())
-                            .map(|generic_args| generic_args.args)
-                            .find_map(|args| {
+                            .filter_map(|seg| seg.args.as_ref().map(|args| (args.args, seg)))
+                            .find_map(|(args, seg)| {
                                 args.iter()
                                     .filter(|arg| arg.is_const())
                                     .enumerate()
                                     .filter(|(_, arg)| arg.id() == hir_id)
-                                    .map(|(index, _)| index)
+                                    .map(|(index, _)| (index, seg))
                                     .next()
                             })
                             .unwrap_or_else(|| {
                                 bug!("no arg matching AnonConst in path");
                             });
 
-                        // We've encountered an `AnonConst` in some path, so we need to
-                        // figure out which generic parameter it corresponds to and return
-                        // the relevant type.
-                        let generics = match path.res {
-                            Res::Def(DefKind::Ctor(..), def_id)
-                            | Res::Def(DefKind::AssocTy, def_id) => {
+                        // Try to use the segment resolution if it is valid, otherwise we
+                        // default to the path resolution.
+                        let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
+                        let generics = match res {
+                            Res::Def(DefKind::Ctor(..), def_id) => {
                                 tcx.generics_of(tcx.parent(def_id).unwrap())
                             }
                             Res::Def(_, def_id) => tcx.generics_of(def_id),
@@ -265,8 +267,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                                 tcx.sess.delay_span_bug(
                                     DUMMY_SP,
                                     &format!(
-                                        "unexpected const parent path def, parent: {:?}, def: {:?}",
-                                        parent_node, res
+                                        "unexpected anon const res {:?} in path: {:?}",
+                                        res, path,
                                     ),
                                 );
                                 return tcx.types.err;
@@ -291,8 +293,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                                 tcx.sess.delay_span_bug(
                                     DUMMY_SP,
                                     &format!(
-                                        "missing generic parameter for `AnonConst`, parent {:?}",
-                                        parent_node
+                                        "missing generic parameter for `AnonConst`, parent: {:?}, res: {:?}",
+                                        parent_node, res
                                     ),
                                 );
                                 tcx.types.err
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index e487e0d265c..fd854c75018 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -62,6 +62,7 @@ This API is completely unstable and subject to change.
 #![feature(crate_visibility_modifier)]
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
+#![feature(or_patterns)]
 #![feature(try_blocks)]
 #![feature(never_type)]
 #![feature(slice_partition_dedup)]
diff --git a/src/test/mir-opt/const_prop/control-flow-simplification.rs b/src/test/mir-opt/const_prop/control-flow-simplification.rs
new file mode 100644
index 00000000000..0e9f33b15e2
--- /dev/null
+++ b/src/test/mir-opt/const_prop/control-flow-simplification.rs
@@ -0,0 +1,64 @@
+// compile-flags: -Zmir-opt-level=1
+
+trait NeedsDrop:Sized{
+    const NEEDS:bool=std::mem::needs_drop::<Self>();
+}
+
+impl<This> NeedsDrop for This{}
+
+fn hello<T>(){
+    if <bool>::NEEDS {
+        panic!()
+    }
+}
+
+pub fn main() {
+    hello::<()>();
+    hello::<Vec<()>>();
+}
+
+// END RUST SOURCE
+// START rustc.hello.ConstProp.before.mir
+// let mut _0: ();
+// let mut _1: bool;
+// let mut _2: !;
+// bb0: {
+//   StorageLive(_1);
+//   _1 = const <bool as NeedsDrop>::NEEDS;
+//   switchInt(_1) -> [false: bb1, otherwise: bb2];
+// }
+// bb1: {
+//   _0 = ();
+//   StorageDead(_1);
+//   return;
+// }
+// bb2: {
+//   StorageLive(_2);
+//   const std::rt::begin_panic::<&str>(const "explicit panic");
+// }
+// END rustc.hello.ConstProp.before.mir
+// START rustc.hello.ConstProp.after.mir
+// let mut _0: ();
+// let mut _1: bool;
+// let mut _2: !;
+// bb0: {
+//   StorageLive(_1);
+//   _1 = const false;
+//   switchInt(const false) -> [false: bb1, otherwise: bb2];
+// }
+// bb1: {
+//   _0 = ();
+//   StorageDead(_1);
+//   return;
+// }
+// bb2: {
+//   StorageLive(_2);
+//   const std::rt::begin_panic::<&str>(const "explicit panic");
+// }
+// END rustc.hello.ConstProp.after.mir
+// START rustc.hello.PreCodegen.before.mir
+// let mut _0: ();
+// bb0: {
+//   return;
+// }
+// END rustc.hello.PreCodegen.before.mir
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
index afb8f146192..46a132da309 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -19,22 +19,6 @@ LL | |         };
    | |_________- enclosing `async` block
 
 error[E0308]: mismatched types
-  --> $DIR/async-block-control-flow-static-semantics.rs:13:43
-   |
-LL | fn return_targets_async_block_not_fn() -> u8 {
-   |    ---------------------------------      ^^ expected `u8`, found `()`
-   |    |
-   |    implicitly returns `()` as its body has no tail or `return` expression
-
-error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
-  --> $DIR/async-block-control-flow-static-semantics.rs:18:39
-   |
-LL |     let _: &dyn Future<Output = ()> = &block;
-   |                                       ^^^^^^ expected `()`, found `u8`
-   |
-   = note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
-
-error[E0308]: mismatched types
   --> $DIR/async-block-control-flow-static-semantics.rs:22:58
    |
 LL |   async fn return_targets_async_block_not_async_fn() -> u8 {
@@ -56,6 +40,22 @@ LL |     let _: &dyn Future<Output = ()> = &block;
    = note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
 
 error[E0308]: mismatched types
+  --> $DIR/async-block-control-flow-static-semantics.rs:13:43
+   |
+LL | fn return_targets_async_block_not_fn() -> u8 {
+   |    ---------------------------------      ^^ expected `u8`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+
+error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()`
+  --> $DIR/async-block-control-flow-static-semantics.rs:18:39
+   |
+LL |     let _: &dyn Future<Output = ()> = &block;
+   |                                       ^^^^^^ expected `()`, found `u8`
+   |
+   = note: required for the cast to the object type `dyn std::future::Future<Output = ()>`
+
+error[E0308]: mismatched types
   --> $DIR/async-block-control-flow-static-semantics.rs:48:44
    |
 LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> {
diff --git a/src/test/ui/async-await/async-error-span.rs b/src/test/ui/async-await/async-error-span.rs
index 28132c9789c..cf10ebfeca9 100644
--- a/src/test/ui/async-await/async-error-span.rs
+++ b/src/test/ui/async-await/async-error-span.rs
@@ -5,6 +5,7 @@
 use std::future::Future;
 
 fn get_future() -> impl Future<Output = ()> {
+//~^ ERROR the trait bound `(): std::future::Future` is not satisfied
     panic!()
 }
 
diff --git a/src/test/ui/async-await/async-error-span.stderr b/src/test/ui/async-await/async-error-span.stderr
index b551b99587d..4054e739c48 100644
--- a/src/test/ui/async-await/async-error-span.stderr
+++ b/src/test/ui/async-await/async-error-span.stderr
@@ -1,15 +1,27 @@
+error[E0277]: the trait bound `(): std::future::Future` is not satisfied
+  --> $DIR/async-error-span.rs:7:20
+   |
+LL | fn get_future() -> impl Future<Output = ()> {
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `()`
+LL |
+LL |     panic!()
+   |     -------- this returned value is of type `!`
+   |
+   = note: the return type of a function must have a statically known size
+
 error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/async-error-span.rs:12:9
+  --> $DIR/async-error-span.rs:13:9
    |
 LL |     let a;
    |         ^ cannot infer type
    |
 note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/async-error-span.rs:13:5
+  --> $DIR/async-error-span.rs:14:5
    |
 LL |     get_future().await;
    |     ^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0698`.
+Some errors have detailed explanations: E0277, E0698.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
index 22bcbb1064d..cebff3be6b0 100644
--- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
+++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
@@ -62,6 +62,7 @@ fn foo10() -> Result<(), ()> {
 fn foo11() -> Result<(), ()> {
     let _ = await bar()?; //~ ERROR `await` is only allowed inside `async` functions and blocks
     //~^ ERROR incorrect use of `await`
+    //~| ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
     Ok(())
 }
 fn foo12() -> Result<(), ()> {
diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
index 92cef80c193..61f2570b2ff 100644
--- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
+++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
@@ -71,49 +71,49 @@ LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:68:14
+  --> $DIR/incorrect-syntax-suggestions.rs:69:14
    |
 LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:73:24
+  --> $DIR/incorrect-syntax-suggestions.rs:74:24
    |
 LL |     let _ = bar().await();
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:78:24
+  --> $DIR/incorrect-syntax-suggestions.rs:79:24
    |
 LL |     let _ = bar().await()?;
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:106:13
+  --> $DIR/incorrect-syntax-suggestions.rs:107:13
    |
 LL |     let _ = await!(bar());
    |             ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:110:13
+  --> $DIR/incorrect-syntax-suggestions.rs:111:13
    |
 LL |     let _ = await!(bar())?;
    |             ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:115:17
+  --> $DIR/incorrect-syntax-suggestions.rs:116:17
    |
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:123:17
+  --> $DIR/incorrect-syntax-suggestions.rs:124:17
    |
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: expected expression, found `=>`
-  --> $DIR/incorrect-syntax-suggestions.rs:131:25
+  --> $DIR/incorrect-syntax-suggestions.rs:132:25
    |
 LL |     match await { await => () }
    |                   ----- ^^ expected expression
@@ -121,13 +121,13 @@ LL |     match await { await => () }
    |                   while parsing this incorrect await expression
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:131:11
+  --> $DIR/incorrect-syntax-suggestions.rs:132:11
    |
 LL |     match await { await => () }
    |           ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
 
 error: expected one of `.`, `?`, `{`, or an operator, found `}`
-  --> $DIR/incorrect-syntax-suggestions.rs:134:1
+  --> $DIR/incorrect-syntax-suggestions.rs:135:1
    |
 LL |     match await { await => () }
    |     -----                      - expected one of `.`, `?`, `{`, or an operator
@@ -162,7 +162,7 @@ LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:68:14
+  --> $DIR/incorrect-syntax-suggestions.rs:69:14
    |
 LL | fn foo12() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -170,7 +170,7 @@ LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:73:13
+  --> $DIR/incorrect-syntax-suggestions.rs:74:13
    |
 LL | fn foo13() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -178,7 +178,7 @@ LL |     let _ = bar().await();
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:78:13
+  --> $DIR/incorrect-syntax-suggestions.rs:79:13
    |
 LL | fn foo14() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -186,7 +186,7 @@ LL |     let _ = bar().await()?;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:83:13
+  --> $DIR/incorrect-syntax-suggestions.rs:84:13
    |
 LL | fn foo15() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -194,7 +194,7 @@ LL |     let _ = bar().await;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:87:13
+  --> $DIR/incorrect-syntax-suggestions.rs:88:13
    |
 LL | fn foo16() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -202,7 +202,7 @@ LL |     let _ = bar().await?;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:92:17
+  --> $DIR/incorrect-syntax-suggestions.rs:93:17
    |
 LL |     fn foo() -> Result<(), ()> {
    |        --- this is not `async`
@@ -210,7 +210,7 @@ LL |         let _ = bar().await?;
    |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:99:17
+  --> $DIR/incorrect-syntax-suggestions.rs:100:17
    |
 LL |     let foo = || {
    |               -- this is not `async`
@@ -218,7 +218,7 @@ LL |         let _ = bar().await?;
    |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:115:17
+  --> $DIR/incorrect-syntax-suggestions.rs:116:17
    |
 LL |     fn foo() -> Result<(), ()> {
    |        --- this is not `async`
@@ -226,7 +226,7 @@ LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:123:17
+  --> $DIR/incorrect-syntax-suggestions.rs:124:17
    |
 LL |     let foo = || {
    |               -- this is not `async`
@@ -242,7 +242,16 @@ LL |     let _ = await bar()?;
    = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
    = note: required by `std::ops::Try::into_result`
 
-error: aborting due to 35 previous errors
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+  --> $DIR/incorrect-syntax-suggestions.rs:63:19
+   |
+LL |     let _ = await bar()?;
+   |                   ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future`
+   |
+   = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
+   = note: required by `std::ops::Try::into_result`
+
+error: aborting due to 36 previous errors
 
 Some errors have detailed explanations: E0277, E0728.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/async-await/issue-67651.rs b/src/test/ui/async-await/issue-67651.rs
new file mode 100644
index 00000000000..bd96a3b709b
--- /dev/null
+++ b/src/test/ui/async-await/issue-67651.rs
@@ -0,0 +1,20 @@
+// edition:2018
+
+trait From {
+    fn from();
+}
+
+impl From for () {
+    fn from() {}
+}
+
+impl From for () {
+//~^ ERROR conflicting implementations of trait
+    fn from() {}
+}
+
+fn bar() -> impl core::future::Future<Output = ()> {
+    async move { From::from() }
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/issue-67651.stderr b/src/test/ui/async-await/issue-67651.stderr
new file mode 100644
index 00000000000..99857c215eb
--- /dev/null
+++ b/src/test/ui/async-await/issue-67651.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `From` for type `()`:
+  --> $DIR/issue-67651.rs:11:1
+   |
+LL | impl From for () {
+   | ---------------- first implementation here
+...
+LL | impl From for () {
+   | ^^^^^^^^^^^^^^^^ conflicting implementation for `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/src/test/ui/async-await/issues/issue-63388-2.nll.stderr b/src/test/ui/async-await/issues/issue-63388-2.nll.stderr
deleted file mode 100644
index 6edb9e63d48..00000000000
--- a/src/test/ui/async-await/issues/issue-63388-2.nll.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0106]: missing lifetime specifier
-  --> $DIR/issue-63388-2.rs:12:10
-   |
-LL |         foo: &dyn Foo, bar: &'a dyn Foo
-   |              --------       -----------
-LL |     ) -> &dyn Foo
-   |          ^ help: consider using the named lifetime: `&'a`
-   |
-   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/async-await/issues/issue-63388-2.rs b/src/test/ui/async-await/issues/issue-63388-2.rs
index 73e7f25f97d..458bc9faeaf 100644
--- a/src/test/ui/async-await/issues/issue-63388-2.rs
+++ b/src/test/ui/async-await/issues/issue-63388-2.rs
@@ -8,7 +8,7 @@ trait Foo {}
 
 impl Xyz {
     async fn do_sth<'a>(
-        foo: &dyn Foo, bar: &'a dyn Foo //~ ERROR cannot infer
+        foo: &dyn Foo, bar: &'a dyn Foo
     ) -> &dyn Foo //~ ERROR missing lifetime specifier
     {
         foo
diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr
index 9f51ced9c3f..6edb9e63d48 100644
--- a/src/test/ui/async-await/issues/issue-63388-2.stderr
+++ b/src/test/ui/async-await/issues/issue-63388-2.stderr
@@ -8,21 +8,6 @@ LL |     ) -> &dyn Foo
    |
    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
 
-error: cannot infer an appropriate lifetime
-  --> $DIR/issue-63388-2.rs:11:9
-   |
-LL |         foo: &dyn Foo, bar: &'a dyn Foo
-   |         ^^^ ...but this borrow...
-...
-LL |         foo
-   |         --- this return type evaluates to the `'static` lifetime...
-   |
-note: ...can't outlive the lifetime `'_` as defined on the method body at 11:14
-  --> $DIR/issue-63388-2.rs:11:14
-   |
-LL |         foo: &dyn Foo, bar: &'a dyn Foo
-   |              ^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0106`.
diff --git a/src/test/ui/async-await/issues/issue-65159.rs b/src/test/ui/async-await/issues/issue-65159.rs
index b5fee061f27..2f80435046b 100644
--- a/src/test/ui/async-await/issues/issue-65159.rs
+++ b/src/test/ui/async-await/issues/issue-65159.rs
@@ -5,6 +5,7 @@
 async fn copy() -> Result<()> //~ ERROR wrong number of type arguments
 {
     Ok(())
+    //~^ type annotations needed
 }
 
 fn main() { }
diff --git a/src/test/ui/async-await/issues/issue-65159.stderr b/src/test/ui/async-await/issues/issue-65159.stderr
index 56d2c38b302..04cfa524998 100644
--- a/src/test/ui/async-await/issues/issue-65159.stderr
+++ b/src/test/ui/async-await/issues/issue-65159.stderr
@@ -4,6 +4,13 @@ error[E0107]: wrong number of type arguments: expected 2, found 1
 LL | async fn copy() -> Result<()>
    |                    ^^^^^^^^^^ expected 2 type arguments
 
-error: aborting due to previous error
+error[E0282]: type annotations needed
+  --> $DIR/issue-65159.rs:7:5
+   |
+LL |     Ok(())
+   |     ^^ cannot infer type for type parameter `E` declared on the enum `Result`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0107, E0282.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs
index b12d7bccece..05960c0c7f6 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs
@@ -9,6 +9,9 @@ impl<T> Trait<'_, '_> for T { }
 async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
     //~^ ERROR ambiguous lifetime bound
     //~| ERROR ambiguous lifetime bound
+    //~| ERROR ambiguous lifetime bound
+    //~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
+    //~| ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds
     (a, b)
 }
 
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
index f9a1b4b3394..c69595a3f4d 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr
@@ -14,5 +14,42 @@ LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'
    |
    = help: add #![feature(member_constraints)] to the crate attributes to enable
 
-error: aborting due to 2 previous errors
+error: ambiguous lifetime bound in `impl Trait`
+  --> $DIR/ret-impl-trait-no-fg.rs:9:64
+   |
+LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
+   |                                                                ^^^^^^^^^^^^^^^^^^ the elided lifetimes here do not outlive one another
+   |
+   = help: add #![feature(member_constraints)] to the crate attributes to enable
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ret-impl-trait-no-fg.rs:9:1
+   |
+LL | / async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     (a, b)
+LL | | }
+   | |_^
+   |
+   = note: hidden type `(&u8, &u8)` captures lifetime '_#4r
+
+error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
+  --> $DIR/ret-impl-trait-no-fg.rs:9:1
+   |
+LL | / async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     (a, b)
+LL | | }
+   | |_^
+   |
+   = note: hidden type `(&u8, &u8)` captures lifetime '_#5r
+
+error: aborting due to 5 previous errors
 
+For more information about this error, try `rustc --explain E0700`.
diff --git a/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs b/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
new file mode 100644
index 00000000000..a192ddea9c6
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue70273-assoc-fn.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+trait T<const A: usize> {
+    fn f();
+}
+struct S;
+
+impl T<0usize> for S {
+    fn f() {}
+}
+
+fn main() {
+    let _err = <S as T<0usize>>::f();
+}
diff --git a/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr b/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr
new file mode 100644
index 00000000000..64007ade0f2
--- /dev/null
+++ b/src/test/ui/const-generics/issues/issue70273-assoc-fn.stderr
@@ -0,0 +1,8 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/issue70273-assoc-fn.rs:3:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
diff --git a/src/test/ui/const-generics/type_of_anon_const.rs b/src/test/ui/const-generics/type_of_anon_const.rs
new file mode 100644
index 00000000000..776084b77a5
--- /dev/null
+++ b/src/test/ui/const-generics/type_of_anon_const.rs
@@ -0,0 +1,21 @@
+// run-pass
+
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+trait T<const A: usize> {
+    fn l<const N: bool>() -> usize;
+    fn r<const N: bool>() -> bool;
+}
+
+struct S;
+
+impl<const N: usize> T<N> for S {
+    fn l<const M: bool>() -> usize { N }
+    fn r<const M: bool>() -> bool { M }
+}
+
+fn main() {
+   assert_eq!(<S as T<123>>::l::<true>(), 123);
+   assert!(<S as T<123>>::r::<true>());
+}
diff --git a/src/test/ui/const-generics/type_of_anon_const.stderr b/src/test/ui/const-generics/type_of_anon_const.stderr
new file mode 100644
index 00000000000..495d34ce09b
--- /dev/null
+++ b/src/test/ui/const-generics/type_of_anon_const.stderr
@@ -0,0 +1,8 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/type_of_anon_const.rs:3:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
diff --git a/src/test/ui/copy-a-resource.rs b/src/test/ui/copy-a-resource.rs
index 55f2dd4ee6d..1a647692018 100644
--- a/src/test/ui/copy-a-resource.rs
+++ b/src/test/ui/copy-a-resource.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 #[derive(Debug)]
 struct Foo {
   i: isize,
diff --git a/src/test/ui/copy-a-resource.stderr b/src/test/ui/copy-a-resource.stderr
index c95e8d239d2..71d2eead355 100644
--- a/src/test/ui/copy-a-resource.stderr
+++ b/src/test/ui/copy-a-resource.stderr
@@ -1,11 +1,19 @@
 error[E0599]: no method named `clone` found for struct `Foo` in the current scope
-  --> $DIR/copy-a-resource.rs:18:16
+  --> $DIR/copy-a-resource.rs:23:16
    |
 LL | struct Foo {
    | ---------- method `clone` not found for this
 ...
 LL |     let _y = x.clone();
    |                ^^^^^ method not found in `Foo`
+   | 
+  ::: $SRC_DIR/libcore/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |        -----
+   |        |
+   |        the method is available for `std::sync::Arc<Foo>` here
+   |        the method is available for `std::rc::Rc<Foo>` here
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `clone`, perhaps you need to implement it:
diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.rs b/src/test/ui/derives/derive-assoc-type-not-impl.rs
index 0f642d63a1d..fa5afd24192 100644
--- a/src/test/ui/derives/derive-assoc-type-not-impl.rs
+++ b/src/test/ui/derives/derive-assoc-type-not-impl.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 trait Foo {
     type X;
     fn method(&self) {}
diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.stderr b/src/test/ui/derives/derive-assoc-type-not-impl.stderr
index c4c85773fbc..f15aba97ded 100644
--- a/src/test/ui/derives/derive-assoc-type-not-impl.stderr
+++ b/src/test/ui/derives/derive-assoc-type-not-impl.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `clone` found for struct `Bar<NotClone>` in the current scope
-  --> $DIR/derive-assoc-type-not-impl.rs:18:30
+  --> $DIR/derive-assoc-type-not-impl.rs:23:30
    |
 LL | struct Bar<T: Foo> {
    | ------------------
@@ -12,6 +12,14 @@ LL | struct NotClone;
 ...
 LL |     Bar::<NotClone> { x: 1 }.clone();
    |                              ^^^^^ method not found in `Bar<NotClone>`
+   | 
+  ::: $SRC_DIR/libcore/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |        -----
+   |        |
+   |        the method is available for `std::sync::Arc<Bar<NotClone>>` here
+   |        the method is available for `std::rc::Rc<Bar<NotClone>>` here
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `NotClone: std::clone::Clone`
diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs b/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs
index dbc0465b08e..d5ed9fb9a28 100644
--- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs
+++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs
@@ -1,9 +1,17 @@
 // edition:2018
 // aux-build:edition-kw-macro-2015.rs
 
+#![feature(async_closure)]
+
+fn main() {}
+
 #[macro_use]
 extern crate edition_kw_macro_2015;
 
+mod module {
+    pub fn r#async() {}
+}
+
 pub fn check_async() {
     let mut async = 1; //~ ERROR expected identifier, found keyword `async`
     let mut r#async = 1; // OK
@@ -17,4 +25,6 @@ pub fn check_async() {
     if passes_ident!(r#async) == 1 {} // OK
     module::async(); //~ ERROR expected identifier, found keyword `async`
     module::r#async(); // OK
+
+    let _recovery_witness: () = 0; //~ ERROR mismatched types
 }
diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
index e12d1a48463..28663563c6c 100644
--- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
+++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
@@ -1,5 +1,5 @@
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:8:13
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:16:13
    |
 LL |     let mut async = 1;
    |             ^^^^^ expected identifier, found keyword
@@ -10,7 +10,7 @@ LL |     let mut r#async = 1;
    |             ^^^^^^^
 
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:18:13
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:26:13
    |
 LL |     module::async();
    |             ^^^^^ expected identifier, found keyword
@@ -21,13 +21,13 @@ LL |     module::r#async();
    |             ^^^^^^^
 
 error: no rules expected the token `r#async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:12:31
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:20:31
    |
 LL |     r#async = consumes_async!(r#async);
    |                               ^^^^^^^ no rules expected this token in macro call
 
 error: no rules expected the token `async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:13:35
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:21:35
    |
 LL |     r#async = consumes_async_raw!(async);
    |                                   ^^^^^ no rules expected this token in macro call
@@ -38,10 +38,19 @@ error: macro expansion ends with an incomplete expression: expected one of `move
 LL |     ($i: ident) => ($i)
    |                       ^ expected one of `move`, `|`, or `||`
    | 
-  ::: $DIR/edition-keywords-2018-2015-parsing.rs:16:8
+  ::: $DIR/edition-keywords-2018-2015-parsing.rs:24:8
    |
 LL |     if passes_ident!(async) == 1 {}
    |        -------------------- in this macro invocation
 
-error: aborting due to 5 previous errors
+error[E0308]: mismatched types
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:29:33
+   |
+LL |     let _recovery_witness: () = 0;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 6 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs b/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs
index 5aca0839f0f..044ab249f2c 100644
--- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs
+++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs
@@ -1,9 +1,17 @@
 // edition:2018
 // aux-build:edition-kw-macro-2018.rs
 
+#![feature(async_closure)]
+
+fn main() {}
+
 #[macro_use]
 extern crate edition_kw_macro_2018;
 
+mod module {
+    pub fn r#async() {}
+}
+
 pub fn check_async() {
     let mut async = 1; //~ ERROR expected identifier, found keyword `async`
     let mut r#async = 1; // OK
@@ -17,4 +25,6 @@ pub fn check_async() {
     if passes_ident!(r#async) == 1 {} // OK
     module::async(); //~ ERROR expected identifier, found keyword `async`
     module::r#async(); // OK
+
+    let _recovery_witness: () = 0; //~ ERROR mismatched types
 }
diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
index 110165fc077..cda7e65e437 100644
--- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
+++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
@@ -1,5 +1,5 @@
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:8:13
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:16:13
    |
 LL |     let mut async = 1;
    |             ^^^^^ expected identifier, found keyword
@@ -10,7 +10,7 @@ LL |     let mut r#async = 1;
    |             ^^^^^^^
 
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:18:13
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:26:13
    |
 LL |     module::async();
    |             ^^^^^ expected identifier, found keyword
@@ -21,13 +21,13 @@ LL |     module::r#async();
    |             ^^^^^^^
 
 error: no rules expected the token `r#async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:12:31
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:20:31
    |
 LL |     r#async = consumes_async!(r#async);
    |                               ^^^^^^^ no rules expected this token in macro call
 
 error: no rules expected the token `async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:13:35
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:21:35
    |
 LL |     r#async = consumes_async_raw!(async);
    |                                   ^^^^^ no rules expected this token in macro call
@@ -38,10 +38,19 @@ error: macro expansion ends with an incomplete expression: expected one of `move
 LL |     ($i: ident) => ($i)
    |                       ^ expected one of `move`, `|`, or `||`
    | 
-  ::: $DIR/edition-keywords-2018-2018-parsing.rs:16:8
+  ::: $DIR/edition-keywords-2018-2018-parsing.rs:24:8
    |
 LL |     if passes_ident!(async) == 1 {}
    |        -------------------- in this macro invocation
 
-error: aborting due to 5 previous errors
+error[E0308]: mismatched types
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:29:33
+   |
+LL |     let _recovery_witness: () = 0;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 6 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/error-codes/E0004-2.rs b/src/test/ui/error-codes/E0004-2.rs
index c7612fd50a7..7f1d064cf3f 100644
--- a/src/test/ui/error-codes/E0004-2.rs
+++ b/src/test/ui/error-codes/E0004-2.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 fn main() {
     let x = Some(1);
 
diff --git a/src/test/ui/error-codes/E0004-2.stderr b/src/test/ui/error-codes/E0004-2.stderr
index f5b41cd1cc0..e47a4fa755c 100644
--- a/src/test/ui/error-codes/E0004-2.stderr
+++ b/src/test/ui/error-codes/E0004-2.stderr
@@ -1,8 +1,16 @@
 error[E0004]: non-exhaustive patterns: `None` and `Some(_)` not covered
-  --> $DIR/E0004-2.rs:4:11
+  --> $DIR/E0004-2.rs:9:11
    |
 LL |     match x { }
    |           ^ patterns `None` and `Some(_)` not covered
+   | 
+  ::: $SRC_DIR/libcore/option.rs:LL:COL
+   |
+LL |     None,
+   |     ---- not covered
+...
+LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+   |     ---- not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
diff --git a/src/test/ui/error-codes/E0005.rs b/src/test/ui/error-codes/E0005.rs
index f4730697e18..75faad80579 100644
--- a/src/test/ui/error-codes/E0005.rs
+++ b/src/test/ui/error-codes/E0005.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 fn main() {
     let x = Some(1);
     let Some(y) = x; //~ ERROR E0005
diff --git a/src/test/ui/error-codes/E0005.stderr b/src/test/ui/error-codes/E0005.stderr
index 577c6e886d5..192b9944031 100644
--- a/src/test/ui/error-codes/E0005.stderr
+++ b/src/test/ui/error-codes/E0005.stderr
@@ -1,8 +1,13 @@
 error[E0005]: refutable pattern in local binding: `None` not covered
-  --> $DIR/E0005.rs:3:9
+  --> $DIR/E0005.rs:8:9
    |
 LL |     let Some(y) = x;
    |         ^^^^^^^ pattern `None` not covered
+   | 
+  ::: $SRC_DIR/libcore/option.rs:LL:COL
+   |
+LL |     None,
+   |     ---- not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
diff --git a/src/test/ui/error-codes/E0297.rs b/src/test/ui/error-codes/E0297.rs
index 27c7960d977..b26ede9c8e2 100644
--- a/src/test/ui/error-codes/E0297.rs
+++ b/src/test/ui/error-codes/E0297.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 fn main() {
     let xs : Vec<Option<i32>> = vec![Some(1), None];
 
diff --git a/src/test/ui/error-codes/E0297.stderr b/src/test/ui/error-codes/E0297.stderr
index f356a5b954d..4a75e9d1771 100644
--- a/src/test/ui/error-codes/E0297.stderr
+++ b/src/test/ui/error-codes/E0297.stderr
@@ -1,8 +1,13 @@
 error[E0005]: refutable pattern in `for` loop binding: `None` not covered
-  --> $DIR/E0297.rs:4:9
+  --> $DIR/E0297.rs:9:9
    |
 LL |     for Some(x) in xs {}
    |         ^^^^^^^ pattern `None` not covered
+   | 
+  ::: $SRC_DIR/libcore/option.rs:LL:COL
+   |
+LL |     None,
+   |     ---- not covered
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs
index f0cc9ea7055..d2e52299c0d 100644
--- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs
+++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 #![feature(never_type)]
 
 fn foo() -> Result<u32, !> {
diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
index 08c36cece4c..c2dd90b91e7 100644
--- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
+++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr
@@ -1,8 +1,13 @@
 error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/feature-gate-exhaustive-patterns.rs:8:9
+  --> $DIR/feature-gate-exhaustive-patterns.rs:13:9
    |
 LL |     let Ok(_x) = foo();
    |         ^^^^^^ pattern `Err(_)` not covered
+   | 
+  ::: $SRC_DIR/libcore/result.rs:LL:COL
+   |
+LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
+   |     --- not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
diff --git a/src/test/ui/generic-associated-types/iterable.rs b/src/test/ui/generic-associated-types/iterable.rs
index 105ab4a8adc..616421112db 100644
--- a/src/test/ui/generic-associated-types/iterable.rs
+++ b/src/test/ui/generic-associated-types/iterable.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 #![allow(incomplete_features)]
 #![feature(generic_associated_types)]
 
diff --git a/src/test/ui/generic-associated-types/iterable.stderr b/src/test/ui/generic-associated-types/iterable.stderr
index ccb1c9bcc7f..e18c6cec64e 100644
--- a/src/test/ui/generic-associated-types/iterable.stderr
+++ b/src/test/ui/generic-associated-types/iterable.stderr
@@ -1,10 +1,15 @@
 error[E0271]: type mismatch resolving `for<'a> <<std::vec::Vec<T> as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <std::vec::Vec<T> as Iterable>::Item<'a>`
-  --> $DIR/iterable.rs:15:5
+  --> $DIR/iterable.rs:20:5
    |
 LL | impl<T> Iterable for Vec<T> {
    | --------------------------- in this `impl` item
 LL |     type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type
+   | 
+  ::: $SRC_DIR/libcore/iter/traits/iterator.rs:LL:COL
+   |
+LL |     type Item;
+   |          ---- associated type defined here
    |
    = note:    expected reference `&T`
            found associated type `<std::vec::Vec<T> as Iterable>::Item<'_>`
@@ -12,12 +17,17 @@ LL |     type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item
    = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>`
-  --> $DIR/iterable.rs:27:5
+  --> $DIR/iterable.rs:32:5
    |
 LL | impl<T> Iterable for [T] {
    | ------------------------ in this `impl` item
 LL |     type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found associated type
+   | 
+  ::: $SRC_DIR/libcore/iter/traits/iterator.rs:LL:COL
+   |
+LL |     type Item;
+   |          ---- associated type defined here
    |
    = note:    expected reference `&T`
            found associated type `<[T] as Iterable>::Item<'_>`
@@ -25,7 +35,7 @@ LL |     type Item<'a> where T: 'a = <std::slice::Iter<'a, T> as Iterator>::Item
    = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `for<'a> <<std::vec::Vec<T> as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <std::vec::Vec<T> as Iterable>::Item<'a>`
-  --> $DIR/iterable.rs:19:30
+  --> $DIR/iterable.rs:24:30
    |
 LL | trait Iterable {
    | -------------- required by `Iterable`
@@ -39,7 +49,7 @@ LL |     fn iter<'a>(&'a self) -> Self::Iter<'a> {
    = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `for<'a> <<[T] as Iterable>::Iter<'a> as std::iter::Iterator>::Item == <[T] as Iterable>::Item<'a>`
-  --> $DIR/iterable.rs:31:30
+  --> $DIR/iterable.rs:36:30
    |
 LL | trait Iterable {
    | -------------- required by `Iterable`
diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
index c0ca341385d..b5135b53e18 100644
--- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr
+++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
@@ -83,6 +83,16 @@ error[E0599]: no method named `method` found for struct `std::rc::Rc<&mut std::b
    |
 LL |     std::rc::Rc::new(&mut Box::new(&1i32)).method();
    |                                            ^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&i32>>`
+   | 
+  ::: $DIR/auxiliary/no_method_suggested_traits.rs:8:12
+   |
+LL |         fn method(&self) {}
+   |            ------
+   |            |
+   |            the method is available for `std::boxed::Box<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
+   |            the method is available for `std::pin::Pin<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
+   |            the method is available for `std::sync::Arc<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
+   |            the method is available for `std::rc::Rc<std::rc::Rc<&mut std::boxed::Box<&i32>>>` here
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope; perhaps add a `use` for it:
diff --git a/src/test/ui/issues/issue-2823.rs b/src/test/ui/issues/issue-2823.rs
index 7b443b41526..f00c2304733 100644
--- a/src/test/ui/issues/issue-2823.rs
+++ b/src/test/ui/issues/issue-2823.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 struct C {
     x: isize,
 }
diff --git a/src/test/ui/issues/issue-2823.stderr b/src/test/ui/issues/issue-2823.stderr
index aa720fd4589..6e11dd40288 100644
--- a/src/test/ui/issues/issue-2823.stderr
+++ b/src/test/ui/issues/issue-2823.stderr
@@ -1,11 +1,19 @@
 error[E0599]: no method named `clone` found for struct `C` in the current scope
-  --> $DIR/issue-2823.rs:13:16
+  --> $DIR/issue-2823.rs:18:16
    |
 LL | struct C {
    | -------- method `clone` not found for this
 ...
 LL |     let _d = c.clone();
    |                ^^^^^ method not found in `C`
+   | 
+  ::: $SRC_DIR/libcore/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |        -----
+   |        |
+   |        the method is available for `std::sync::Arc<C>` here
+   |        the method is available for `std::rc::Rc<C>` here
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `clone`, perhaps you need to implement it:
diff --git a/src/test/ui/issues/issue-69725.rs b/src/test/ui/issues/issue-69725.rs
index b8130b41f21..a8e72e9459e 100644
--- a/src/test/ui/issues/issue-69725.rs
+++ b/src/test/ui/issues/issue-69725.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 // aux-build:issue-69725.rs
 
 extern crate issue_69725;
diff --git a/src/test/ui/issues/issue-69725.stderr b/src/test/ui/issues/issue-69725.stderr
index 667383e072a..439fae95111 100644
--- a/src/test/ui/issues/issue-69725.stderr
+++ b/src/test/ui/issues/issue-69725.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `clone` found for struct `issue_69725::Struct<A>` in the current scope
-  --> $DIR/issue-69725.rs:7:32
+  --> $DIR/issue-69725.rs:12:32
    |
 LL |     let _ = Struct::<A>::new().clone();
    |                                ^^^^^ method not found in `issue_69725::Struct<A>`
@@ -8,6 +8,14 @@ LL |     let _ = Struct::<A>::new().clone();
    |
 LL | pub struct Struct<A>(A);
    | ------------------------ doesn't satisfy `issue_69725::Struct<A>: std::clone::Clone`
+   | 
+  ::: $SRC_DIR/libcore/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |        -----
+   |        |
+   |        the method is available for `std::sync::Arc<issue_69725::Struct<A>>` here
+   |        the method is available for `std::rc::Rc<issue_69725::Struct<A>>` here
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `A: std::clone::Clone`
diff --git a/src/test/ui/macros/issue-61033-1.rs b/src/test/ui/macros/issue-61033-1.rs
index 8f85dec017f..18df3f6ee94 100644
--- a/src/test/ui/macros/issue-61033-1.rs
+++ b/src/test/ui/macros/issue-61033-1.rs
@@ -1,9 +1,10 @@
 // Regression test for issue #61033.
 
 macro_rules! test1 {
-    ($x:ident, $($tt:tt)*) => { $($tt)+ } //~ERROR this must repeat at least once
+    ($x:ident, $($tt:tt)*) => { $($tt)+ } //~ ERROR this must repeat at least once
 }
 
 fn main() {
     test1!(x,);
+    let _recovery_witness: () = 0; //~ ERROR mismatched types
 }
diff --git a/src/test/ui/macros/issue-61033-1.stderr b/src/test/ui/macros/issue-61033-1.stderr
index f3c68f4928d..18205c3436b 100644
--- a/src/test/ui/macros/issue-61033-1.stderr
+++ b/src/test/ui/macros/issue-61033-1.stderr
@@ -4,5 +4,14 @@ error: this must repeat at least once
 LL |     ($x:ident, $($tt:tt)*) => { $($tt)+ }
    |                                  ^^^^^
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/issue-61033-1.rs:9:33
+   |
+LL |     let _recovery_witness: () = 0;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/macros/issue-61033-2.rs b/src/test/ui/macros/issue-61033-2.rs
index 0799be10b96..1760ba1584d 100644
--- a/src/test/ui/macros/issue-61033-2.rs
+++ b/src/test/ui/macros/issue-61033-2.rs
@@ -5,7 +5,9 @@ macro_rules! test2 {
         $(* $id1:ident)*
         $(+ $id2:ident)*
     ) => {
-        $( //~ERROR meta-variable `id1` repeats 2 times
+        $(
+        //~^ ERROR meta-variable `id1` repeats 2 times
+        //~| ERROR meta-variable `id1` repeats 2 times
             $id1 + $id2 // $id1 and $id2 may repeat different numbers of times
         )*
     }
@@ -16,4 +18,8 @@ fn main() {
         * a * b
         + a + b + c
     }
+    test2! {
+        * a * b
+        + a + b + c + d
+    }
 }
diff --git a/src/test/ui/macros/issue-61033-2.stderr b/src/test/ui/macros/issue-61033-2.stderr
index bf502919cf7..cdfe7934a0c 100644
--- a/src/test/ui/macros/issue-61033-2.stderr
+++ b/src/test/ui/macros/issue-61033-2.stderr
@@ -3,9 +3,22 @@ error: meta-variable `id1` repeats 2 times, but `id2` repeats 3 times
    |
 LL |           $(
    |  __________^
+LL | |
+LL | |
 LL | |             $id1 + $id2 // $id1 and $id2 may repeat different numbers of times
 LL | |         )*
    | |_________^
 
-error: aborting due to previous error
+error: meta-variable `id1` repeats 2 times, but `id2` repeats 4 times
+  --> $DIR/issue-61033-2.rs:8:10
+   |
+LL |           $(
+   |  __________^
+LL | |
+LL | |
+LL | |             $id1 + $id2 // $id1 and $id2 may repeat different numbers of times
+LL | |         )*
+   | |_________^
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/macros/local-ambiguity-multiple-parsing-options.rs b/src/test/ui/macros/local-ambiguity-multiple-parsing-options.rs
new file mode 100644
index 00000000000..3967481098c
--- /dev/null
+++ b/src/test/ui/macros/local-ambiguity-multiple-parsing-options.rs
@@ -0,0 +1,8 @@
+fn main() {}
+
+macro_rules! ambiguity {
+    ($($i:ident)* $j:ident) => {};
+}
+
+ambiguity!(error); //~ ERROR local ambiguity
+ambiguity!(error); //~ ERROR local ambiguity
diff --git a/src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr b/src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr
new file mode 100644
index 00000000000..0ae56c42221
--- /dev/null
+++ b/src/test/ui/macros/local-ambiguity-multiple-parsing-options.stderr
@@ -0,0 +1,14 @@
+error: local ambiguity: multiple parsing options: built-in NTs ident ('i') or ident ('j').
+  --> $DIR/local-ambiguity-multiple-parsing-options.rs:7:12
+   |
+LL | ambiguity!(error);
+   |            ^^^^^
+
+error: local ambiguity: multiple parsing options: built-in NTs ident ('i') or ident ('j').
+  --> $DIR/local-ambiguity-multiple-parsing-options.rs:8:12
+   |
+LL | ambiguity!(error);
+   |            ^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/macros/macro-context.rs b/src/test/ui/macros/macro-context.rs
index 9130c3d921c..13e179578ad 100644
--- a/src/test/ui/macros/macro-context.rs
+++ b/src/test/ui/macros/macro-context.rs
@@ -4,6 +4,8 @@ macro_rules! m {
                             //~| ERROR macro expansion ignores token `typeof`
                             //~| ERROR macro expansion ignores token `;`
                             //~| ERROR macro expansion ignores token `;`
+                            //~| ERROR cannot find type `i` in this scope
+                            //~| ERROR cannot find value `i` in this scope
 }
 
 fn main() {
diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr
index 2e712110689..17c73898124 100644
--- a/src/test/ui/macros/macro-context.stderr
+++ b/src/test/ui/macros/macro-context.stderr
@@ -42,5 +42,29 @@ LL |     m!();
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 4 previous errors
+error[E0412]: cannot find type `i` in this scope
+  --> $DIR/macro-context.rs:3:13
+   |
+LL |     () => ( i ; typeof );
+   |             ^ help: a builtin type with a similar name exists: `i8`
+...
+LL |     let a: m!();
+   |            ---- in this macro invocation
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0425]: cannot find value `i` in this scope
+  --> $DIR/macro-context.rs:3:13
+   |
+LL |     () => ( i ; typeof );
+   |             ^ help: a local variable with a similar name exists: `a`
+...
+LL |     let i = m!();
+   |             ---- in this macro invocation
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors
 
+Some errors have detailed explanations: E0412, E0425.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/macros/macro-match-nonterminal.rs b/src/test/ui/macros/macro-match-nonterminal.rs
index 6d4b32c9bc9..b23e5c71c03 100644
--- a/src/test/ui/macros/macro-match-nonterminal.rs
+++ b/src/test/ui/macros/macro-match-nonterminal.rs
@@ -1,4 +1,11 @@
-macro_rules! test { ($a, $b) => (()); } //~ ERROR missing fragment
+macro_rules! test {
+    ($a, $b) => {
+        //~^ ERROR missing fragment
+        //~| ERROR missing fragment
+        //~| WARN this was previously accepted
+        ()
+    };
+}
 
 fn main() {
     test!()
diff --git a/src/test/ui/macros/macro-match-nonterminal.stderr b/src/test/ui/macros/macro-match-nonterminal.stderr
index 1de8c5bd4b4..674ce3434aa 100644
--- a/src/test/ui/macros/macro-match-nonterminal.stderr
+++ b/src/test/ui/macros/macro-match-nonterminal.stderr
@@ -1,8 +1,18 @@
 error: missing fragment specifier
-  --> $DIR/macro-match-nonterminal.rs:1:24
+  --> $DIR/macro-match-nonterminal.rs:2:8
    |
-LL | macro_rules! test { ($a, $b) => (()); }
-   |                        ^
+LL |     ($a, $b) => {
+   |        ^
 
-error: aborting due to previous error
+error: missing fragment specifier
+  --> $DIR/macro-match-nonterminal.rs:2:10
+   |
+LL |     ($a, $b) => {
+   |          ^^
+   |
+   = note: `#[deny(missing_fragment_specifier)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/macros/trace_faulty_macros.rs b/src/test/ui/macros/trace_faulty_macros.rs
index a55f05414b2..5a8e2f50ce3 100644
--- a/src/test/ui/macros/trace_faulty_macros.rs
+++ b/src/test/ui/macros/trace_faulty_macros.rs
@@ -1,6 +1,6 @@
 // compile-flags: -Z trace-macros
 
-#![recursion_limit="4"]
+#![recursion_limit = "4"]
 
 macro_rules! my_faulty_macro {
     () => {
@@ -24,9 +24,7 @@ macro_rules! my_recursive_macro {
 }
 
 macro_rules! my_macro {
-    () => {
-
-    };
+    () => {};
 }
 
 fn main() {
@@ -39,7 +37,7 @@ fn main() {
 }
 
 #[my_macro]
-fn use_bang_macro_as_attr(){}
+fn use_bang_macro_as_attr() {}
 
-#[derive(Debug)]
-fn use_derive_macro_as_attr(){}
+#[derive(Debug)] //~ ERROR `derive` may only be applied to structs
+fn use_derive_macro_as_attr() {}
diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr
index 109b493b437..aec9d1ab191 100644
--- a/src/test/ui/macros/trace_faulty_macros.stderr
+++ b/src/test/ui/macros/trace_faulty_macros.stderr
@@ -13,7 +13,7 @@ LL |     my_faulty_macro!();
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 note: trace_macro
-  --> $DIR/trace_faulty_macros.rs:33:5
+  --> $DIR/trace_faulty_macros.rs:31:5
    |
 LL |     my_faulty_macro!();
    |     ^^^^^^^^^^^^^^^^^^^
@@ -35,7 +35,7 @@ LL |     my_recursive_macro!();
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 note: trace_macro
-  --> $DIR/trace_faulty_macros.rs:34:5
+  --> $DIR/trace_faulty_macros.rs:32:5
    |
 LL |     my_recursive_macro!();
    |     ^^^^^^^^^^^^^^^^^^^^^^
@@ -60,5 +60,22 @@ LL |     let a = pat_macro!();
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 3 previous errors
+error: `derive` may only be applied to structs, enums and unions
+  --> $DIR/trace_faulty_macros.rs:42:1
+   |
+LL | #[derive(Debug)]
+   | ^^^^^^^^^^^^^^^^
+
+note: trace_macro
+  --> $DIR/trace_faulty_macros.rs:36:13
+   |
+LL |     let a = pat_macro!();
+   |             ^^^^^^^^^^^^
+   |
+   = note: expanding `pat_macro! {  }`
+   = note: to `pat_macro ! (A { a : a, b : 0, c : _, .. }) ;`
+   = note: expanding `pat_macro! { A { a : a, b : 0, c : _, .. } }`
+   = note: to `A { a: a, b: 0, c: _, .. }`
+
+error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/non-copyable-void.rs b/src/test/ui/non-copyable-void.rs
index ddaaee436ae..186731f2e72 100644
--- a/src/test/ui/non-copyable-void.rs
+++ b/src/test/ui/non-copyable-void.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 // ignore-wasm32-bare no libc to test ffi with
 
 #![feature(rustc_private)]
diff --git a/src/test/ui/non-copyable-void.stderr b/src/test/ui/non-copyable-void.stderr
index 074ed66a261..dd67a110d22 100644
--- a/src/test/ui/non-copyable-void.stderr
+++ b/src/test/ui/non-copyable-void.stderr
@@ -1,8 +1,16 @@
 error[E0599]: no method named `clone` found for enum `libc::c_void` in the current scope
-  --> $DIR/non-copyable-void.rs:11:23
+  --> $DIR/non-copyable-void.rs:16:23
    |
 LL |         let _z = (*y).clone();
    |                       ^^^^^ method not found in `libc::c_void`
+   | 
+  ::: $SRC_DIR/libcore/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |        -----
+   |        |
+   |        the method is available for `std::sync::Arc<libc::c_void>` here
+   |        the method is available for `std::rc::Rc<libc::c_void>` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/noncopyable-class.rs b/src/test/ui/noncopyable-class.rs
index 11b6eb736e9..731f4ab9c78 100644
--- a/src/test/ui/noncopyable-class.rs
+++ b/src/test/ui/noncopyable-class.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 // Test that a class with a non-copyable field can't be
 // copied
 
diff --git a/src/test/ui/noncopyable-class.stderr b/src/test/ui/noncopyable-class.stderr
index 6c3c4a6ac98..472ce34870a 100644
--- a/src/test/ui/noncopyable-class.stderr
+++ b/src/test/ui/noncopyable-class.stderr
@@ -1,11 +1,19 @@
 error[E0599]: no method named `clone` found for struct `Foo` in the current scope
-  --> $DIR/noncopyable-class.rs:34:16
+  --> $DIR/noncopyable-class.rs:39:16
    |
 LL | struct Foo {
    | ---------- method `clone` not found for this
 ...
 LL |     let _y = x.clone();
    |                ^^^^^ method not found in `Foo`
+   | 
+  ::: $SRC_DIR/libcore/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |        -----
+   |        |
+   |        the method is available for `std::sync::Arc<Foo>` here
+   |        the method is available for `std::rc::Rc<Foo>` here
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `clone`, perhaps you need to implement it:
diff --git a/src/test/ui/parser/issue-62894.rs b/src/test/ui/parser/issue-62894.rs
index b9c0bf834dd..e38b7b65089 100644
--- a/src/test/ui/parser/issue-62894.rs
+++ b/src/test/ui/parser/issue-62894.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 // Regression test for #62894, shouldn't crash.
 // error-pattern: this file contains an unclosed delimiter
 // error-pattern: expected one of `(`, `[`, or `{`, found keyword `fn`
diff --git a/src/test/ui/parser/issue-62894.stderr b/src/test/ui/parser/issue-62894.stderr
index 6db380f7a7f..4a1d7e275be 100644
--- a/src/test/ui/parser/issue-62894.stderr
+++ b/src/test/ui/parser/issue-62894.stderr
@@ -1,5 +1,5 @@
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-62894.rs:7:14
+  --> $DIR/issue-62894.rs:12:14
    |
 LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
    |        -           -                   - unclosed delimiter
@@ -11,7 +11,7 @@ LL | fn main() {}
    |              ^
 
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-62894.rs:7:14
+  --> $DIR/issue-62894.rs:12:14
    |
 LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
    |        -           -                   - unclosed delimiter
@@ -23,7 +23,7 @@ LL | fn main() {}
    |              ^
 
 error: this file contains an unclosed delimiter
-  --> $DIR/issue-62894.rs:7:14
+  --> $DIR/issue-62894.rs:12:14
    |
 LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
    |        -           -                   - unclosed delimiter
@@ -35,13 +35,18 @@ LL | fn main() {}
    |              ^
 
 error: expected one of `(`, `[`, or `{`, found keyword `fn`
-  --> $DIR/issue-62894.rs:7:1
+  --> $DIR/issue-62894.rs:12:1
    |
 LL | fn f() { assert_eq!(f(), (), assert_eq!(assert_eq!
    |                                                   - expected one of `(`, `[`, or `{`
 LL | 
 LL | fn main() {}
    | ^^ unexpected token
+   | 
+  ::: $SRC_DIR/libcore/macros/mod.rs:LL:COL
+   |
+LL |     ($left:expr, $right:expr) => ({
+   |      ---------- while parsing argument for this `expr` macro fragment
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/parser/macro/issue-33569.rs b/src/test/ui/parser/macro/issue-33569.rs
index 9ed53519ceb..80e2d7c6545 100644
--- a/src/test/ui/parser/macro/issue-33569.rs
+++ b/src/test/ui/parser/macro/issue-33569.rs
@@ -6,3 +6,5 @@ macro_rules! foo {
 }
 
 foo!();
+
+fn main() {}
diff --git a/src/test/ui/parser/macro/macro-repeat.rs b/src/test/ui/parser/macro/macro-repeat.rs
index 580a1daacbf..3ffbea217e7 100644
--- a/src/test/ui/parser/macro/macro-repeat.rs
+++ b/src/test/ui/parser/macro/macro-repeat.rs
@@ -1,9 +1,12 @@
 macro_rules! mac {
-    ( $($v:tt)* ) => (
-        $v  //~ ERROR still repeating at this depth
-    )
+    ( $($v:tt)* ) => {
+        $v
+        //~^ ERROR still repeating at this depth
+        //~| ERROR still repeating at this depth
+    };
 }
 
 fn main() {
     mac!(0);
+    mac!(1);
 }
diff --git a/src/test/ui/parser/macro/macro-repeat.stderr b/src/test/ui/parser/macro/macro-repeat.stderr
index c86684de744..63554b197b9 100644
--- a/src/test/ui/parser/macro/macro-repeat.stderr
+++ b/src/test/ui/parser/macro/macro-repeat.stderr
@@ -4,5 +4,11 @@ error: variable 'v' is still repeating at this depth
 LL |         $v
    |         ^^
 
-error: aborting due to previous error
+error: variable 'v' is still repeating at this depth
+  --> $DIR/macro-repeat.rs:3:9
+   |
+LL |         $v
+   |         ^^
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/nt-parsing-has-recovery.rs b/src/test/ui/parser/nt-parsing-has-recovery.rs
new file mode 100644
index 00000000000..ccbeb398af5
--- /dev/null
+++ b/src/test/ui/parser/nt-parsing-has-recovery.rs
@@ -0,0 +1,10 @@
+macro_rules! foo {
+    ($e:expr) => {}
+}
+
+foo!(1 + @); //~ ERROR expected expression, found `@`
+foo!(1 + @); //~ ERROR expected expression, found `@`
+
+fn main() {
+    let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/parser/nt-parsing-has-recovery.stderr b/src/test/ui/parser/nt-parsing-has-recovery.stderr
new file mode 100644
index 00000000000..263c4ad5361
--- /dev/null
+++ b/src/test/ui/parser/nt-parsing-has-recovery.stderr
@@ -0,0 +1,29 @@
+error: expected expression, found `@`
+  --> $DIR/nt-parsing-has-recovery.rs:5:10
+   |
+LL |     ($e:expr) => {}
+   |      ------- while parsing argument for this `expr` macro fragment
+...
+LL | foo!(1 + @);
+   |          ^ expected expression
+
+error: expected expression, found `@`
+  --> $DIR/nt-parsing-has-recovery.rs:6:10
+   |
+LL |     ($e:expr) => {}
+   |      ------- while parsing argument for this `expr` macro fragment
+...
+LL | foo!(1 + @);
+   |          ^ expected expression
+
+error[E0308]: mismatched types
+  --> $DIR/nt-parsing-has-recovery.rs:9:33
+   |
+LL |     let _recovery_witness: () = 0;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.rs b/src/test/ui/pattern/usefulness/match-arm-statics-2.rs
index 4c5f2d35649..728d4a64495 100644
--- a/src/test/ui/pattern/usefulness/match-arm-statics-2.rs
+++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 use self::Direction::{North, East, South, West};
 
 #[derive(PartialEq, Eq)]
diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
index 8521e37d3fd..7bb6a700a37 100644
--- a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
+++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `(true, false)` not covered
-  --> $DIR/match-arm-statics-2.rs:17:11
+  --> $DIR/match-arm-statics-2.rs:22:11
    |
 LL |     match (true, false) {
    |           ^^^^^^^^^^^^^ pattern `(true, false)` not covered
@@ -7,15 +7,23 @@ LL |     match (true, false) {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered
-  --> $DIR/match-arm-statics-2.rs:29:11
+  --> $DIR/match-arm-statics-2.rs:34:11
    |
 LL |     match Some(Some(North)) {
    |           ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered
+   | 
+  ::: $SRC_DIR/libcore/option.rs:LL:COL
+   |
+LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+   |     ----
+   |     |
+   |     not covered
+   |     not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` not covered
-  --> $DIR/match-arm-statics-2.rs:48:11
+  --> $DIR/match-arm-statics-2.rs:53:11
    |
 LL | / struct Foo {
 LL | |     bar: Option<Direction>,
diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.rs b/src/test/ui/pattern/usefulness/match-privately-empty.rs
index 315eb03d165..c7cde468bb9 100644
--- a/src/test/ui/pattern/usefulness/match-privately-empty.rs
+++ b/src/test/ui/pattern/usefulness/match-privately-empty.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 #![feature(never_type)]
 #![feature(exhaustive_patterns)]
 
diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.stderr b/src/test/ui/pattern/usefulness/match-privately-empty.stderr
index f79d180a1b8..4dcbf05ecce 100644
--- a/src/test/ui/pattern/usefulness/match-privately-empty.stderr
+++ b/src/test/ui/pattern/usefulness/match-privately-empty.stderr
@@ -1,8 +1,13 @@
 error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
-  --> $DIR/match-privately-empty.rs:13:11
+  --> $DIR/match-privately-empty.rs:18:11
    |
 LL |     match private::DATA {
    |           ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered
+   | 
+  ::: $SRC_DIR/libcore/option.rs:LL:COL
+   |
+LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+   |     ---- not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
index 9947989dc12..59f7bb892c6 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 #![allow(illegal_floating_point_literal_pattern)]
 
 enum T { A, B }
diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
index a06ad578851..dff2c8d9424 100644
--- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
+++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `A` not covered
-  --> $DIR/non-exhaustive-match.rs:7:11
+  --> $DIR/non-exhaustive-match.rs:12:11
    |
 LL | enum T { A, B }
    | ---------------
@@ -13,7 +13,7 @@ LL |     match x { T::B => { } }
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `false` not covered
-  --> $DIR/non-exhaustive-match.rs:8:11
+  --> $DIR/non-exhaustive-match.rs:13:11
    |
 LL |     match true {
    |           ^^^^ pattern `false` not covered
@@ -21,15 +21,20 @@ LL |     match true {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Some(_)` not covered
-  --> $DIR/non-exhaustive-match.rs:11:11
+  --> $DIR/non-exhaustive-match.rs:16:11
    |
 LL |     match Some(10) {
    |           ^^^^^^^^ pattern `Some(_)` not covered
+   | 
+  ::: $SRC_DIR/libcore/option.rs:LL:COL
+   |
+LL |     Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+   |     ---- not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered
-  --> $DIR/non-exhaustive-match.rs:14:11
+  --> $DIR/non-exhaustive-match.rs:19:11
    |
 LL |     match (2, 3, 4) {
    |           ^^^^^^^^^ patterns `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered
@@ -37,7 +42,7 @@ LL |     match (2, 3, 4) {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `(A, A)` not covered
-  --> $DIR/non-exhaustive-match.rs:18:11
+  --> $DIR/non-exhaustive-match.rs:23:11
    |
 LL |     match (T::A, T::A) {
    |           ^^^^^^^^^^^^ pattern `(A, A)` not covered
@@ -45,7 +50,7 @@ LL |     match (T::A, T::A) {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `B` not covered
-  --> $DIR/non-exhaustive-match.rs:22:11
+  --> $DIR/non-exhaustive-match.rs:27:11
    |
 LL | enum T { A, B }
    | ---------------
@@ -59,7 +64,7 @@ LL |     match T::A {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `[]` not covered
-  --> $DIR/non-exhaustive-match.rs:33:11
+  --> $DIR/non-exhaustive-match.rs:38:11
    |
 LL |     match *vec {
    |           ^^^^ pattern `[]` not covered
@@ -67,7 +72,7 @@ LL |     match *vec {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered
-  --> $DIR/non-exhaustive-match.rs:46:11
+  --> $DIR/non-exhaustive-match.rs:51:11
    |
 LL |     match *vec {
    |           ^^^^ pattern `[_, _, _, _, ..]` not covered
diff --git a/src/test/ui/proc-macro/derive-bad.rs b/src/test/ui/proc-macro/derive-bad.rs
index 62c0741b669..cb5188b5fb4 100644
--- a/src/test/ui/proc-macro/derive-bad.rs
+++ b/src/test/ui/proc-macro/derive-bad.rs
@@ -3,11 +3,9 @@
 #[macro_use]
 extern crate derive_bad;
 
-#[derive(
-    A
-)]
-//~^^ ERROR proc-macro derive produced unparseable tokens
+#[derive(A)]
+//~^ ERROR proc-macro derive produced unparseable tokens
 //~| ERROR expected `:`, found `}`
-struct A;
+struct A; //~ ERROR the name `A` is defined multiple times
 
 fn main() {}
diff --git a/src/test/ui/proc-macro/derive-bad.stderr b/src/test/ui/proc-macro/derive-bad.stderr
index 8667396c989..bc5ed981523 100644
--- a/src/test/ui/proc-macro/derive-bad.stderr
+++ b/src/test/ui/proc-macro/derive-bad.stderr
@@ -1,16 +1,28 @@
 error: expected `:`, found `}`
-  --> $DIR/derive-bad.rs:7:5
+  --> $DIR/derive-bad.rs:6:10
    |
-LL |     A
-   |     ^ expected `:`
+LL | #[derive(A)]
+   |          ^ expected `:`
    |
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: proc-macro derive produced unparseable tokens
-  --> $DIR/derive-bad.rs:7:5
+  --> $DIR/derive-bad.rs:6:10
    |
-LL |     A
-   |     ^
+LL | #[derive(A)]
+   |          ^
 
-error: aborting due to 2 previous errors
+error[E0428]: the name `A` is defined multiple times
+  --> $DIR/derive-bad.rs:9:1
+   |
+LL | #[derive(A)]
+   |          - previous definition of the type `A` here
+...
+LL | struct A;
+   | ^^^^^^^^^ `A` redefined here
+   |
+   = note: `A` must be defined only once in the type namespace of this module
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0428`.
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.rs b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
index 9de57da5af4..3f78dea917b 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-1.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
@@ -14,3 +14,5 @@
 extern crate invalid_punct_ident;
 
 invalid_punct!(); //~ ERROR proc macro panicked
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-2.rs b/src/test/ui/proc-macro/invalid-punct-ident-2.rs
index 79f72324b1d..4e89e80ae7c 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-2.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-2.rs
@@ -14,3 +14,5 @@
 extern crate invalid_punct_ident;
 
 invalid_ident!(); //~ ERROR proc macro panicked
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.rs b/src/test/ui/proc-macro/invalid-punct-ident-3.rs
index d01e9b699ca..8d8ce8f932e 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-3.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-3.rs
@@ -14,3 +14,5 @@
 extern crate invalid_punct_ident;
 
 invalid_raw_ident!(); //~ ERROR proc macro panicked
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.rs b/src/test/ui/proc-macro/invalid-punct-ident-4.rs
index e50f24deae3..59b347dac67 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-4.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-4.rs
@@ -3,5 +3,10 @@
 #[macro_use]
 extern crate invalid_punct_ident;
 
-lexer_failure!(); //~ ERROR proc macro panicked
-                  //~| ERROR unexpected closing delimiter: `)`
+lexer_failure!();
+//~^ ERROR proc macro panicked
+//~| ERROR unexpected closing delimiter: `)`
+
+fn main() {
+    let _recovery_witness: () = 0; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
index fe3e55b31be..3b357aecea8 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
+++ b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
@@ -12,5 +12,14 @@ error: proc macro panicked
 LL | lexer_failure!();
    | ^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/invalid-punct-ident-4.rs:11:33
+   |
+LL |     let _recovery_witness: () = 0;
+   |                            --   ^ expected `()`, found integer
+   |                            |
+   |                            expected due to this
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/proc-macro/issue-36935.rs b/src/test/ui/proc-macro/issue-36935.rs
index f809592d5f4..5c43a564c00 100644
--- a/src/test/ui/proc-macro/issue-36935.rs
+++ b/src/test/ui/proc-macro/issue-36935.rs
@@ -5,6 +5,7 @@ extern crate test_macros;
 
 #[derive(Identity, Panic)] //~ ERROR proc-macro derive panicked
 struct Baz {
+    //~^ ERROR the name `Baz` is defined multiple times
     a: i32,
     b: i32,
 }
diff --git a/src/test/ui/proc-macro/issue-36935.stderr b/src/test/ui/proc-macro/issue-36935.stderr
index da4366eb668..2b2e28fdb2f 100644
--- a/src/test/ui/proc-macro/issue-36935.stderr
+++ b/src/test/ui/proc-macro/issue-36935.stderr
@@ -6,5 +6,17 @@ LL | #[derive(Identity, Panic)]
    |
    = help: message: panic-derive
 
-error: aborting due to previous error
+error[E0428]: the name `Baz` is defined multiple times
+  --> $DIR/issue-36935.rs:7:1
+   |
+LL | struct Baz {
+   | ^^^^^^^^^^
+   | |
+   | `Baz` redefined here
+   | previous definition of the type `Baz` here
+   |
+   = note: `Baz` must be defined only once in the type namespace of this module
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0428`.
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
index 44893036383..5be426eb382 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 struct R<'a> {
     r: &'a R<'a>,
 }
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
index aa23aed4b42..f371d460cf7 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
@@ -1,8 +1,13 @@
 error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/recursive-types-are-not-uninhabited.rs:6:9
+  --> $DIR/recursive-types-are-not-uninhabited.rs:11:9
    |
 LL |     let Ok(x) = res;
    |         ^^^^^ pattern `Err(_)` not covered
+   | 
+  ::: $SRC_DIR/libcore/result.rs:LL:COL
+   |
+LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
+   |     --- not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr
index d0c278d12d7..bd6e9d59502 100644
--- a/src/test/ui/resolve/issue-3907-2.stderr
+++ b/src/test/ui/resolve/issue-3907-2.stderr
@@ -3,8 +3,11 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
    |
 LL | fn bar(_x: Foo) {}
    |            ^^^ the trait `issue_3907::Foo` cannot be made into an object
+   | 
+  ::: $DIR/auxiliary/issue-3907.rs:2:8
    |
-   = note: the trait cannot be made into an object because associated function `bar` has no `self` parameter
+LL |     fn bar();
+   |        --- the trait cannot be made into an object because associated function `bar` has no `self` parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
index ccc25a184e9..a214a652a38 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
@@ -27,6 +27,13 @@ error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covere
    |
 LL |     match x {}
    |           ^ patterns `Tuple(_)` and `Struct { .. }` not covered
+   | 
+  ::: $DIR/auxiliary/uninhabited.rs:17:23
+   |
+LL |     #[non_exhaustive] Tuple(!),
+   |                       ----- not covered
+LL |     #[non_exhaustive] Struct { x: ! }
+   |                       ------ not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
index a54885c96e5..63564e9c3cc 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
@@ -27,6 +27,13 @@ error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covere
    |
 LL |     match x {}
    |           ^ patterns `Tuple(_)` and `Struct { .. }` not covered
+   | 
+  ::: $DIR/auxiliary/uninhabited.rs:17:23
+   |
+LL |     #[non_exhaustive] Tuple(!),
+   |                       ----- not covered
+LL |     #[non_exhaustive] Struct { x: ! }
+   |                       ------ not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
diff --git a/src/test/ui/self/elision/ref-self-async.nll.stderr b/src/test/ui/self/elision/ref-self-async.nll.stderr
index 541e4954322..bd1f80811b5 100644
--- a/src/test/ui/self/elision/ref-self-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-self-async.nll.stderr
@@ -1,13 +1,72 @@
-error[E0658]: `Wrap<&Struct, Struct>` cannot be used as the type of `self` without the `arbitrary_self_types` feature
-  --> $DIR/ref-self-async.rs:47:39
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:23:9
    |
-LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
-   |                                       ^^^^^^^^^^^^^^^^^
+LL |     async fn ref_self(&self, f: &u32) -> &u32 {
+   |                       -         - let's call the lifetime of this reference `'1`
+   |                       |
+   |                       let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:29:9
+   |
+LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
+   |                             -         - let's call the lifetime of this reference `'1`
+   |                             |
+   |                             let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:33:9
    |
-   = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
-   = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
-   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
+   |                                     -          - let's call the lifetime of this reference `'1`
+   |                                     |
+   |                                     let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:37:9
+   |
+LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
+   |                                     -          - let's call the lifetime of this reference `'1`
+   |                                     |
+   |                                     let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:41:9
+   |
+LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
+   |                                             -           - let's call the lifetime of this reference `'1`
+   |                                             |
+   |                                             let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:45:9
+   |
+LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
+   |                                             -           - let's call the lifetime of this reference `'1`
+   |                                             |
+   |                                             let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+
+error: lifetime may not live long enough
+  --> $DIR/ref-self-async.rs:49:9
+   |
+LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
+   |                                            -                - let's call the lifetime of this reference `'1`
+   |                                            |
+   |                                            let's call the lifetime of this reference `'2`
+LL |         f
+   |         ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
 
-error: aborting due to previous error
+error: aborting due to 7 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/self/elision/ref-self-async.rs b/src/test/ui/self/elision/ref-self-async.rs
index 6a98b79cb3b..0fbbd95c975 100644
--- a/src/test/ui/self/elision/ref-self-async.rs
+++ b/src/test/ui/self/elision/ref-self-async.rs
@@ -1,6 +1,7 @@
 // edition:2018
 
 #![allow(non_snake_case)]
+#![feature(arbitrary_self_types)]
 
 use std::marker::PhantomData;
 use std::ops::Deref;
diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr
index b73290b024f..bda958241b6 100644
--- a/src/test/ui/self/elision/ref-self-async.stderr
+++ b/src/test/ui/self/elision/ref-self-async.stderr
@@ -1,5 +1,5 @@
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:22:9
+  --> $DIR/ref-self-async.rs:23:9
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
    |                       -----              ----
@@ -9,7 +9,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:28:9
+  --> $DIR/ref-self-async.rs:29:9
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
    |                             -----              ----
@@ -19,7 +19,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:32:9
+  --> $DIR/ref-self-async.rs:33:9
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
    |                                     -----               ----
@@ -29,7 +29,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:36:9
+  --> $DIR/ref-self-async.rs:37:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
    |                                     -----               ----
@@ -39,7 +39,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:40:9
+  --> $DIR/ref-self-async.rs:41:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
    |                                             -----                ----
@@ -49,7 +49,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:44:9
+  --> $DIR/ref-self-async.rs:45:9
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
    |                                             -----                ----
@@ -59,7 +59,7 @@ LL |         f
    |         ^ ...but data from `f` is returned here
 
 error[E0623]: lifetime mismatch
-  --> $DIR/ref-self-async.rs:48:9
+  --> $DIR/ref-self-async.rs:49:9
    |
 LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
    |                                            -----                    ---
diff --git a/src/test/ui/span/transitive-dep-span.rs b/src/test/ui/span/transitive-dep-span.rs
index b445d389c56..2d46f74ad9b 100644
--- a/src/test/ui/span/transitive-dep-span.rs
+++ b/src/test/ui/span/transitive-dep-span.rs
@@ -11,3 +11,5 @@
 extern crate transitive_dep_two;
 
 transitive_dep_two::parse_error!(); //~ ERROR expected one of
+
+fn main() {}
diff --git a/src/test/ui/test-attrs/test-attr-non-associated-functions.rs b/src/test/ui/test-attrs/test-attr-non-associated-functions.rs
index e475f5b4a75..31e567c3960 100644
--- a/src/test/ui/test-attrs/test-attr-non-associated-functions.rs
+++ b/src/test/ui/test-attrs/test-attr-non-associated-functions.rs
@@ -6,7 +6,13 @@ struct A {}
 
 impl A {
     #[test]
-    fn new() -> A { //~ ERROR `#[test]` attribute is only allowed on non associated functions
+    fn new() -> A {
+        //~^ ERROR `#[test]` attribute is only allowed on non associated functions
+        A {}
+    }
+    #[test]
+    fn recovery_witness() -> A {
+        //~^ ERROR `#[test]` attribute is only allowed on non associated functions
         A {}
     }
 }
diff --git a/src/test/ui/test-attrs/test-attr-non-associated-functions.stderr b/src/test/ui/test-attrs/test-attr-non-associated-functions.stderr
index cb3ae51823e..a81b8f3980c 100644
--- a/src/test/ui/test-attrs/test-attr-non-associated-functions.stderr
+++ b/src/test/ui/test-attrs/test-attr-non-associated-functions.stderr
@@ -2,9 +2,19 @@ error: `#[test]` attribute is only allowed on non associated functions
   --> $DIR/test-attr-non-associated-functions.rs:9:5
    |
 LL | /     fn new() -> A {
+LL | |
 LL | |         A {}
 LL | |     }
    | |_____^
 
-error: aborting due to previous error
+error: `#[test]` attribute is only allowed on non associated functions
+  --> $DIR/test-attr-non-associated-functions.rs:14:5
+   |
+LL | /     fn recovery_witness() -> A {
+LL | |
+LL | |         A {}
+LL | |     }
+   | |_____^
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/type/ascription/issue-47666.rs b/src/test/ui/type/ascription/issue-47666.rs
index ceb1dd89dae..8035de4a48a 100644
--- a/src/test/ui/type/ascription/issue-47666.rs
+++ b/src/test/ui/type/ascription/issue-47666.rs
@@ -1,5 +1,7 @@
 fn main() {
     let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found
+    //~^ ERROR expected value, found enum `Option`
+    //~| ERROR expected type, found variant `Some`
 }
 
 // This case isn't currently being handled gracefully due to the macro invocation.
diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr
index f4c9240ab53..3cd3be70aa7 100644
--- a/src/test/ui/type/ascription/issue-47666.stderr
+++ b/src/test/ui/type/ascription/issue-47666.stderr
@@ -13,5 +13,35 @@ LL |     let _ = Option:Some(vec![0, 1]);
    = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to previous error
+error[E0423]: expected value, found enum `Option`
+  --> $DIR/issue-47666.rs:2:13
+   |
+LL |     let _ = Option:Some(vec![0, 1]);
+   |             ^^^^^^
+   |
+help: try using one of the enum's variants
+   |
+LL |     let _ = std::option::Option::None:Some(vec![0, 1]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _ = std::option::Option::Some:Some(vec![0, 1]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0573]: expected type, found variant `Some`
+  --> $DIR/issue-47666.rs:2:20
+   |
+LL |     let _ = Option:Some(vec![0, 1]);
+   |                    ^^^^^^^^^^^^^^^^ not a type
+   |
+help: try using the variant's enum
+   |
+LL |     let _ = Option:std::option::Option;
+   |                    ^^^^^^^^^^^^^^^^^^^
+help: maybe you meant to write a path separator here
+   |
+LL |     let _ = Option::Some(vec![0, 1]);
+   |                   ^^
+
+error: aborting due to 3 previous errors
 
+Some errors have detailed explanations: E0423, E0573.
+For more information about an error, try `rustc --explain E0423`.
diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs
index e804afcf9ed..a959aaae055 100644
--- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs
+++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 use std::mem::zeroed;
 enum Void {}
 
diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
index a667e1fe2da..9245e293caa 100644
--- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
+++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr
@@ -1,13 +1,18 @@
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:6:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:11:19
    |
 LL |     let _ = match x {
    |                   ^ pattern `Err(_)` not covered
+   | 
+  ::: $SRC_DIR/libcore/result.rs:LL:COL
+   |
+LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
+   |     --- not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: type `&Void` is non-empty
-  --> $DIR/uninhabited-matches-feature-gated.rs:15:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:20:19
    |
 LL | enum Void {}
    | ------------ `Void` defined here
@@ -18,7 +23,7 @@ LL |     let _ = match x {};
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty
-  --> $DIR/uninhabited-matches-feature-gated.rs:18:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:23:19
    |
 LL |     let _ = match x {};
    |                   ^
@@ -26,7 +31,7 @@ LL |     let _ = match x {};
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
-  --> $DIR/uninhabited-matches-feature-gated.rs:21:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:26:19
    |
 LL |     let _ = match x {};
    |                   ^
@@ -34,7 +39,7 @@ LL |     let _ = match x {};
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:24:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:29:19
    |
 LL |     let _ = match x {
    |                   ^ pattern `&[_, ..]` not covered
@@ -42,18 +47,28 @@ LL |     let _ = match x {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0004]: non-exhaustive patterns: `Err(_)` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:32:19
+  --> $DIR/uninhabited-matches-feature-gated.rs:37:19
    |
 LL |     let _ = match x {
    |                   ^ pattern `Err(_)` not covered
+   | 
+  ::: $SRC_DIR/libcore/result.rs:LL:COL
+   |
+LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
+   |     --- not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/uninhabited-matches-feature-gated.rs:37:9
+  --> $DIR/uninhabited-matches-feature-gated.rs:42:9
    |
 LL |     let Ok(x) = x;
    |         ^^^^^ pattern `Err(_)` not covered
+   | 
+  ::: $SRC_DIR/libcore/result.rs:LL:COL
+   |
+LL |     Err(#[stable(feature = "rust1", since = "1.0.0")] E),
+   |     --- not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
diff --git a/src/test/ui/union/union-derive-clone.rs b/src/test/ui/union/union-derive-clone.rs
index 4a106cc940a..4b92475f1e4 100644
--- a/src/test/ui/union/union-derive-clone.rs
+++ b/src/test/ui/union/union-derive-clone.rs
@@ -1,3 +1,8 @@
+// FIXME: missing sysroot spans (#53081)
+// ignore-i586-unknown-linux-gnu
+// ignore-i586-unknown-linux-musl
+// ignore-i686-unknown-linux-musl
+
 #![feature(untagged_unions)]
 
 use std::mem::ManuallyDrop;
diff --git a/src/test/ui/union/union-derive-clone.stderr b/src/test/ui/union/union-derive-clone.stderr
index 01c8e8471aa..d0a82a96c16 100644
--- a/src/test/ui/union/union-derive-clone.stderr
+++ b/src/test/ui/union/union-derive-clone.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `U1: std::marker::Copy` is not satisfied
-  --> $DIR/union-derive-clone.rs:5:10
+  --> $DIR/union-derive-clone.rs:10:10
    |
 LL | #[derive(Clone)]
    |          ^^^^^ the trait `std::marker::Copy` is not implemented for `U1`
@@ -8,7 +8,7 @@ LL | #[derive(Clone)]
    = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0599]: no method named `clone` found for union `U5<CloneNoCopy>` in the current scope
-  --> $DIR/union-derive-clone.rs:37:15
+  --> $DIR/union-derive-clone.rs:42:15
    |
 LL | union U5<T> {
    | -----------
@@ -21,6 +21,14 @@ LL | struct CloneNoCopy;
 ...
 LL |     let w = u.clone();
    |               ^^^^^ method not found in `U5<CloneNoCopy>`
+   | 
+  ::: $SRC_DIR/libcore/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |        -----
+   |        |
+   |        the method is available for `std::sync::Arc<U5<CloneNoCopy>>` here
+   |        the method is available for `std::rc::Rc<U5<CloneNoCopy>>` here
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `CloneNoCopy: std::marker::Copy`
diff --git a/src/test/ui/unique-object-noncopyable.stderr b/src/test/ui/unique-object-noncopyable.stderr
index fb78095224b..2e81e7cf832 100644
--- a/src/test/ui/unique-object-noncopyable.stderr
+++ b/src/test/ui/unique-object-noncopyable.stderr
@@ -14,6 +14,14 @@ LL |     let _z = y.clone();
    |
 LL | pub struct Box<T: ?Sized>(Unique<T>);
    | ------------------------------------- doesn't satisfy `std::boxed::Box<dyn Foo>: std::clone::Clone`
+   | 
+  ::: $SRC_DIR/libcore/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |        -----
+   |        |
+   |        the method is available for `std::sync::Arc<std::boxed::Box<dyn Foo>>` here
+   |        the method is available for `std::rc::Rc<std::boxed::Box<dyn Foo>>` here
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `dyn Foo: std::marker::Sized`
diff --git a/src/test/ui/unique-pinned-nocopy.stderr b/src/test/ui/unique-pinned-nocopy.stderr
index ea6575d1d85..06c4b95baef 100644
--- a/src/test/ui/unique-pinned-nocopy.stderr
+++ b/src/test/ui/unique-pinned-nocopy.stderr
@@ -11,6 +11,14 @@ LL |     let _j = i.clone();
    |
 LL | pub struct Box<T: ?Sized>(Unique<T>);
    | ------------------------------------- doesn't satisfy `std::boxed::Box<R>: std::clone::Clone`
+   | 
+  ::: $SRC_DIR/libcore/clone.rs:LL:COL
+   |
+LL |     fn clone(&self) -> Self;
+   |        -----
+   |        |
+   |        the method is available for `std::sync::Arc<std::boxed::Box<R>>` here
+   |        the method is available for `std::rc::Rc<std::boxed::Box<R>>` here
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `R: std::clone::Clone`