about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl25
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs12
-rw-r--r--compiler/rustc_builtin_macros/src/cmdline_attrs.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs88
-rw-r--r--compiler/rustc_builtin_macros/src/global_allocator.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/proc_macro_harness.rs14
-rw-r--r--compiler/rustc_builtin_macros/src/test.rs7
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs5
-rw-r--r--compiler/rustc_builtin_macros/src/trace_macros.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs27
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs78
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/type_.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs26
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs1
-rw-r--r--compiler/rustc_infer/src/traits/util.rs82
-rw-r--r--compiler/rustc_privacy/messages.ftl2
-rw-r--r--compiler/rustc_privacy/src/errors.rs2
-rw-r--r--compiler/rustc_privacy/src/lib.rs3
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs5
-rw-r--r--compiler/rustc_resolve/src/ident.rs23
-rw-r--r--compiler/rustc_resolve/src/imports.rs23
-rw-r--r--compiler/rustc_resolve/src/lib.rs6
-rw-r--r--compiler/rustc_resolve/src/macros.rs2
-rw-r--r--src/bootstrap/builder.rs2
-rw-r--r--src/bootstrap/doc.rs50
-rw-r--r--src/bootstrap/test.rs20
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header.rs48
-rw-r--r--src/tools/compiletest/src/header/needs.rs4
-rw-r--r--src/tools/compiletest/src/runtest.rs347
-rw-r--r--tests/run-coverage-rustdoc/auxiliary/doctest_crate.rs (renamed from tests/run-make/coverage/lib/doctest_crate.rs)0
-rw-r--r--tests/run-coverage-rustdoc/doctest.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.doctest.txt)26
-rw-r--r--tests/run-coverage-rustdoc/doctest.rs (renamed from tests/run-make/coverage/doctest.rs)2
-rw-r--r--tests/run-coverage/abort.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.abort.txt)0
-rw-r--r--tests/run-coverage/abort.rs (renamed from tests/run-make/coverage/abort.rs)0
-rw-r--r--tests/run-coverage/assert.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.assert.txt)2
-rw-r--r--tests/run-coverage/assert.rs (renamed from tests/run-make/coverage/assert.rs)2
-rw-r--r--tests/run-coverage/async.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.async.txt)0
-rw-r--r--tests/run-coverage/async.rs (renamed from tests/run-make/coverage/async.rs)0
-rw-r--r--tests/run-coverage/async2.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.async2.txt)0
-rw-r--r--tests/run-coverage/async2.rs (renamed from tests/run-make/coverage/async2.rs)0
-rw-r--r--tests/run-coverage/auxiliary/inline_always_with_dead_code.rs (renamed from tests/run-make/coverage/lib/inline_always_with_dead_code.rs)0
-rw-r--r--tests/run-coverage/auxiliary/unused_mod_helper.rs (renamed from tests/run-make/coverage/lib/unused_mod_helper.rs)0
-rw-r--r--tests/run-coverage/auxiliary/used_crate.rs (renamed from tests/run-make/coverage/lib/used_crate.rs)4
-rw-r--r--tests/run-coverage/auxiliary/used_inline_crate.rs (renamed from tests/run-make/coverage/lib/used_inline_crate.rs)4
-rw-r--r--tests/run-coverage/closure.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.closure.txt)4
-rw-r--r--tests/run-coverage/closure.rs (renamed from tests/run-make/coverage/closure.rs)4
-rw-r--r--tests/run-coverage/closure_macro.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.closure_macro.txt)0
-rw-r--r--tests/run-coverage/closure_macro.rs (renamed from tests/run-make/coverage/closure_macro.rs)0
-rw-r--r--tests/run-coverage/closure_macro_async.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.closure_macro_async.txt)0
-rw-r--r--tests/run-coverage/closure_macro_async.rs (renamed from tests/run-make/coverage/closure_macro_async.rs)0
-rw-r--r--tests/run-coverage/conditions.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.conditions.txt)0
-rw-r--r--tests/run-coverage/conditions.rs (renamed from tests/run-make/coverage/conditions.rs)0
-rw-r--r--tests/run-coverage/continue.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.continue.txt)0
-rw-r--r--tests/run-coverage/continue.rs (renamed from tests/run-make/coverage/continue.rs)0
-rw-r--r--tests/run-coverage/dead_code.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.dead_code.txt)0
-rw-r--r--tests/run-coverage/dead_code.rs (renamed from tests/run-make/coverage/dead_code.rs)0
-rw-r--r--tests/run-coverage/drop_trait.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.drop_trait.txt)2
-rw-r--r--tests/run-coverage/drop_trait.rs (renamed from tests/run-make/coverage/drop_trait.rs)2
-rw-r--r--tests/run-coverage/generator.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.generator.txt)0
-rw-r--r--tests/run-coverage/generator.rs (renamed from tests/run-make/coverage/generator.rs)0
-rw-r--r--tests/run-coverage/generics.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.generics.txt)2
-rw-r--r--tests/run-coverage/generics.rs (renamed from tests/run-make/coverage/generics.rs)2
-rw-r--r--tests/run-coverage/if.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.if.txt)0
-rw-r--r--tests/run-coverage/if.rs (renamed from tests/run-make/coverage/if.rs)0
-rw-r--r--tests/run-coverage/if_else.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.if_else.txt)0
-rw-r--r--tests/run-coverage/if_else.rs (renamed from tests/run-make/coverage/if_else.rs)0
-rw-r--r--tests/run-coverage/inline-dead.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.inline-dead.txt)0
-rw-r--r--tests/run-coverage/inline-dead.rs (renamed from tests/run-make/coverage/inline-dead.rs)0
-rw-r--r--tests/run-coverage/inline.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.inline.txt)0
-rw-r--r--tests/run-coverage/inline.rs (renamed from tests/run-make/coverage/inline.rs)0
-rw-r--r--tests/run-coverage/inner_items.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.inner_items.txt)0
-rw-r--r--tests/run-coverage/inner_items.rs (renamed from tests/run-make/coverage/inner_items.rs)0
-rw-r--r--tests/run-coverage/issue-83601.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.issue-83601.txt)0
-rw-r--r--tests/run-coverage/issue-83601.rs (renamed from tests/run-make/coverage/issue-83601.rs)0
-rw-r--r--tests/run-coverage/issue-84561.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.issue-84561.txt)2
-rw-r--r--tests/run-coverage/issue-84561.rs (renamed from tests/run-make/coverage/issue-84561.rs)2
-rw-r--r--tests/run-coverage/issue-85461.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.issue-85461.txt)26
-rw-r--r--tests/run-coverage/issue-85461.rs (renamed from tests/run-make/coverage/issue-85461.rs)2
-rw-r--r--tests/run-coverage/issue-93054.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.issue-93054.txt)0
-rw-r--r--tests/run-coverage/issue-93054.rs (renamed from tests/run-make/coverage/issue-93054.rs)0
-rw-r--r--tests/run-coverage/lazy_boolean.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.lazy_boolean.txt)0
-rw-r--r--tests/run-coverage/lazy_boolean.rs (renamed from tests/run-make/coverage/lazy_boolean.rs)0
-rw-r--r--tests/run-coverage/loop_break_value.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.loop_break_value.txt)0
-rw-r--r--tests/run-coverage/loop_break_value.rs (renamed from tests/run-make/coverage/loop_break_value.rs)0
-rw-r--r--tests/run-coverage/loops_branches.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.loops_branches.txt)0
-rw-r--r--tests/run-coverage/loops_branches.rs (renamed from tests/run-make/coverage/loops_branches.rs)0
-rw-r--r--tests/run-coverage/match_or_pattern.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.match_or_pattern.txt)0
-rw-r--r--tests/run-coverage/match_or_pattern.rs (renamed from tests/run-make/coverage/match_or_pattern.rs)0
-rw-r--r--tests/run-coverage/nested_loops.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.nested_loops.txt)0
-rw-r--r--tests/run-coverage/nested_loops.rs (renamed from tests/run-make/coverage/nested_loops.rs)0
-rw-r--r--tests/run-coverage/no_cov_crate.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.no_cov_crate.txt)0
-rw-r--r--tests/run-coverage/no_cov_crate.rs (renamed from tests/run-make/coverage/no_cov_crate.rs)0
-rw-r--r--tests/run-coverage/overflow.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.overflow.txt)2
-rw-r--r--tests/run-coverage/overflow.rs (renamed from tests/run-make/coverage/overflow.rs)2
-rw-r--r--tests/run-coverage/panic_unwind.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.panic_unwind.txt)2
-rw-r--r--tests/run-coverage/panic_unwind.rs (renamed from tests/run-make/coverage/panic_unwind.rs)2
-rw-r--r--tests/run-coverage/partial_eq.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.partial_eq.txt)0
-rw-r--r--tests/run-coverage/partial_eq.rs (renamed from tests/run-make/coverage/partial_eq.rs)0
-rw-r--r--tests/run-coverage/simple_loop.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.simple_loop.txt)0
-rw-r--r--tests/run-coverage/simple_loop.rs (renamed from tests/run-make/coverage/simple_loop.rs)0
-rw-r--r--tests/run-coverage/simple_match.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.simple_match.txt)0
-rw-r--r--tests/run-coverage/simple_match.rs (renamed from tests/run-make/coverage/simple_match.rs)0
-rw-r--r--tests/run-coverage/sort_groups.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.sort_groups.txt)0
-rw-r--r--tests/run-coverage/sort_groups.rs (renamed from tests/run-make/coverage/sort_groups.rs)0
-rw-r--r--tests/run-coverage/test_harness.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.test_harness.txt)0
-rw-r--r--tests/run-coverage/test_harness.rs (renamed from tests/run-make/coverage/test_harness.rs)0
-rw-r--r--tests/run-coverage/tight_inf_loop.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.tight_inf_loop.txt)0
-rw-r--r--tests/run-coverage/tight_inf_loop.rs (renamed from tests/run-make/coverage/tight_inf_loop.rs)0
-rw-r--r--tests/run-coverage/try_error_result.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.try_error_result.txt)2
-rw-r--r--tests/run-coverage/try_error_result.rs (renamed from tests/run-make/coverage/try_error_result.rs)2
-rw-r--r--tests/run-coverage/unused.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.unused.txt)0
-rw-r--r--tests/run-coverage/unused.rs (renamed from tests/run-make/coverage/unused.rs)0
-rw-r--r--tests/run-coverage/unused_mod.coverage13
-rw-r--r--tests/run-coverage/unused_mod.rs (renamed from tests/run-make/coverage/unused_mod.rs)2
-rw-r--r--tests/run-coverage/uses_crate.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt)26
-rw-r--r--tests/run-coverage/uses_crate.rs (renamed from tests/run-make/coverage/uses_crate.rs)8
-rw-r--r--tests/run-coverage/uses_inline_crate.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt)29
-rw-r--r--tests/run-coverage/uses_inline_crate.rs (renamed from tests/run-make/coverage/uses_inline_crate.rs)8
-rw-r--r--tests/run-coverage/while.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.while.txt)0
-rw-r--r--tests/run-coverage/while.rs (renamed from tests/run-make/coverage/while.rs)0
-rw-r--r--tests/run-coverage/while_early_ret.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.while_early_ret.txt)2
-rw-r--r--tests/run-coverage/while_early_ret.rs (renamed from tests/run-make/coverage/while_early_ret.rs)2
-rw-r--r--tests/run-coverage/yield.coverage (renamed from tests/run-make/coverage-reports/expected_show_coverage.yield.txt)0
-rw-r--r--tests/run-coverage/yield.rs (renamed from tests/run-make/coverage/yield.rs)0
-rw-r--r--tests/run-make/coverage-llvmir/Makefile2
-rw-r--r--tests/run-make/coverage-reports/Makefile178
-rw-r--r--tests/run-make/coverage-reports/expected_show_coverage.unused_mod.txt4
-rwxr-xr-xtests/run-make/coverage-reports/normalize_paths.py12
-rwxr-xr-xtests/run-make/coverage-reports/sort_subviews.py50
-rw-r--r--tests/run-make/coverage/WARNING_KEEP_NAMES_SHORT.txt10
-rw-r--r--tests/run-make/coverage/compiletest-ignore-dir3
-rw-r--r--tests/run-make/coverage/coverage_tools.mk6
-rw-r--r--tests/ui/associated-inherent-types/private-in-public.rs3
-rw-r--r--tests/ui/associated-inherent-types/private-in-public.stderr29
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-privacy.rs1
-rw-r--r--tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr7
-rw-r--r--tests/ui/error-codes/E0445.rs3
-rw-r--r--tests/ui/error-codes/E0445.stderr23
-rw-r--r--tests/ui/imports/issue-56125.stderr15
-rw-r--r--tests/ui/imports/issue-57539.stderr5
-rw-r--r--tests/ui/issues/issue-18389.rs1
-rw-r--r--tests/ui/issues/issue-18389.stderr7
-rw-r--r--tests/ui/privacy/private-in-public-non-principal.rs1
-rw-r--r--tests/ui/privacy/private-in-public-non-principal.stderr9
-rw-r--r--tests/ui/privacy/where-priv-type.rs6
-rw-r--r--tests/ui/privacy/where-priv-type.stderr56
-rw-r--r--tests/ui/privacy/where-pub-type-impls-priv-trait.rs5
-rw-r--r--tests/ui/privacy/where-pub-type-impls-priv-trait.stderr45
-rw-r--r--tests/ui/proc-macro/derive-helper-shadowing.rs2
-rw-r--r--tests/ui/proc-macro/derive-helper-shadowing.stderr21
-rw-r--r--tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs3
-rw-r--r--tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr23
-rw-r--r--tests/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr2
-rw-r--r--tests/ui/rust-2018/uniform-paths/ambiguity-macros.stderr2
-rw-r--r--tests/ui/rust-2018/uniform-paths/ambiguity-nested.rs4
-rw-r--r--tests/ui/rust-2018/uniform-paths/ambiguity-nested.stderr21
-rw-r--r--tests/ui/rust-2018/uniform-paths/ambiguity.rs4
-rw-r--r--tests/ui/rust-2018/uniform-paths/ambiguity.stderr21
-rw-r--r--tests/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs3
-rw-r--r--tests/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr24
-rw-r--r--tests/ui/rust-2018/uniform-paths/block-scoped-shadow.rs8
-rw-r--r--tests/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr60
-rw-r--r--tests/ui/rust-2018/uniform-paths/issue-56596.stderr5
-rw-r--r--tests/ui/rust-2018/uniform-paths/macro-rules.rs3
-rw-r--r--tests/ui/rust-2018/uniform-paths/macro-rules.stderr24
171 files changed, 1053 insertions, 790 deletions
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index f00cd39cbc8..322222ae330 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -1,4 +1,5 @@
 builtin_macros_alloc_error_must_be_fn = alloc_error_handler must be a function
+builtin_macros_alloc_must_statics = allocators must be statics
 
 builtin_macros_asm_clobber_abi = clobber_abi
 builtin_macros_asm_clobber_no_reg = asm with `clobber_abi` must specify explicit registers for outputs
@@ -56,6 +57,9 @@ builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `e
     .label = not applicable here
     .label2 = not a `struct`, `enum` or `union`
 
+builtin_macros_bench_sig = functions used as benches must have signature `fn(&mut Bencher) -> impl Termination`
+
+
 builtin_macros_cannot_derive_union = this trait cannot be derived for unions
 
 builtin_macros_cfg_accessible_has_args = `cfg_accessible` path cannot accept arguments
@@ -84,6 +88,7 @@ builtin_macros_concat_bytes_non_u8 = numeric literal is not a `u8`
 builtin_macros_concat_bytes_oob = numeric literal is out of bounds
 
 builtin_macros_concat_bytestr = cannot concatenate a byte string literal
+builtin_macros_concat_c_str_lit = cannot concatenate a C string literal
 
 builtin_macros_concat_idents_ident_args = `concat_idents!()` requires ident args
 
@@ -111,6 +116,10 @@ builtin_macros_env_takes_args = `env!()` takes 1 or 2 arguments
 
 builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
 
+builtin_macros_expected_register_class_or_explicit_register = expected register class or explicit register
+
+builtin_macros_export_macro_rules = cannot export macro_rules! macros from a `proc-macro` crate type currently
+
 builtin_macros_format_duplicate_arg = duplicate argument named `{$ident}`
     .label1 = previously here
     .label2 = duplicate argument
@@ -158,6 +167,8 @@ builtin_macros_format_unused_args = multiple unused formatting arguments
 
 builtin_macros_global_asm_clobber_abi = `clobber_abi` cannot be used with `global_asm!`
 
+builtin_macros_invalid_crate_attribute = invalid crate attribute
+
 builtin_macros_multiple_default_attrs = multiple `#[default]` attributes
     .note = only one `#[default]` attribute is needed
     .label = `#[default]` used here
@@ -177,6 +188,8 @@ builtin_macros_no_default_variant = no default declared
     .help = make a unit variant default by placing `#[default]` above it
     .suggestion = make `{$ident}` default
 
+builtin_macros_non_abi = at least one abi must be provided as an argument to `clobber_abi`
+
 builtin_macros_non_exhaustive_default = default variant must be exhaustive
     .label = declared `#[non_exhaustive]` here
     .help = consider a manual implementation of `Default`
@@ -184,12 +197,20 @@ builtin_macros_non_exhaustive_default = default variant must be exhaustive
 builtin_macros_non_unit_default = the `#[default]` attribute may only be used on unit enum variants
     .help = consider a manual implementation of `Default`
 
+builtin_macros_proc_macro = `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
+
 builtin_macros_requires_cfg_pattern =
     macro requires a cfg-pattern as an argument
     .label = cfg-pattern required
 
+builtin_macros_should_panic = functions using `#[should_panic]` must return `()`
+
 builtin_macros_sugg = consider using a positional formatting argument instead
 
+builtin_macros_test_arg_non_lifetime = functions used as tests can not have any non-lifetime generic parameters
+
+builtin_macros_test_args = functions used as tests can not have any arguments
+
 builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests
     .label = `{$kind}` because of this
 
@@ -198,6 +219,10 @@ builtin_macros_test_case_non_item = `#[test_case]` attribute is only allowed on
 builtin_macros_test_runner_invalid = `test_runner` argument must be a path
 builtin_macros_test_runner_nargs = `#![test_runner(..)]` accepts exactly 1 argument
 
+builtin_macros_tests_not_support = building tests with panic=abort is not supported without `-Zpanic_abort_tests`
+
+builtin_macros_trace_macros = trace_macros! accepts only `true` or `false`
+
 builtin_macros_unexpected_lit = expected path to a trait, found literal
     .label = not a trait
     .str_lit = try using `#[derive({$sym})]`
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 9734fc2b36d..6187e4f513b 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -371,11 +371,7 @@ fn parse_clobber_abi<'a>(p: &mut Parser<'a>, args: &mut AsmArgs) -> PResult<'a,
     p.expect(&token::OpenDelim(Delimiter::Parenthesis))?;
 
     if p.eat(&token::CloseDelim(Delimiter::Parenthesis)) {
-        let err = p.sess.span_diagnostic.struct_span_err(
-            p.token.span,
-            "at least one abi must be provided as an argument to `clobber_abi`",
-        );
-        return Err(err);
+        return Err(p.sess.span_diagnostic.create_err(errors::NonABI { span: p.token.span }));
     }
 
     let mut new_abis = Vec::new();
@@ -428,9 +424,9 @@ fn parse_reg<'a>(
             ast::InlineAsmRegOrRegClass::Reg(symbol)
         }
         _ => {
-            return Err(
-                p.struct_span_err(p.token.span, "expected register class or explicit register")
-            );
+            return Err(p.sess.create_err(errors::ExpectedRegisterClassOrExplicitRegister {
+                span: p.token.span,
+            }));
         }
     };
     p.bump();
diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
index 2b6fcc169be..7b75d7d84e4 100644
--- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
+++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs
@@ -1,5 +1,6 @@
 //! Attributes injected into the crate root from command line using `-Z crate-attr`.
 
+use crate::errors;
 use rustc_ast::attr::mk_attr;
 use rustc_ast::token;
 use rustc_ast::{self as ast, AttrItem, AttrStyle};
@@ -24,7 +25,9 @@ pub fn inject(krate: &mut ast::Crate, parse_sess: &ParseSess, attrs: &[String])
         };
         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");
+            parse_sess
+                .span_diagnostic
+                .emit_err(errors::InvalidCrateAttr { span: start_span.to(end_span) });
             continue;
         }
 
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index 50e88ae2eee..9695fb4fee1 100644
--- a/compiler/rustc_builtin_macros/src/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -33,7 +33,7 @@ pub fn expand_concat(
                     accumulator.push_str(&b.to_string());
                 }
                 Ok(ast::LitKind::CStr(..)) => {
-                    cx.span_err(e.span, "cannot concatenate a C string literal");
+                    cx.emit_err(errors::ConcatCStrLit{ span: e.span});
                     has_errors = true;
                 }
                 Ok(ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..)) => {
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index 5ef35af0a05..6a1586f071c 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -21,7 +21,7 @@ fn invalid_type_err(
         Ok(ast::LitKind::CStr(_, _)) => {
             // FIXME(c_str_literals): should concatenation of C string literals
             // include the null bytes in the end?
-            cx.span_err(span, "cannot concatenate C string literals");
+            cx.emit_err(errors::ConcatCStrLit { span: span });
         }
         Ok(ast::LitKind::Char(_)) => {
             let sugg =
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index f1ab279daba..7b2a375a822 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -88,6 +88,83 @@ pub(crate) struct ConcatBytestr {
 }
 
 #[derive(Diagnostic)]
+#[diag(builtin_macros_concat_c_str_lit)]
+pub(crate) struct ConcatCStrLit {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_export_macro_rules)]
+pub(crate) struct ExportMacroRules {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_proc_macro)]
+pub(crate) struct ProcMacro {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_invalid_crate_attribute)]
+pub(crate) struct InvalidCrateAttr {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_non_abi)]
+pub(crate) struct NonABI {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_trace_macros)]
+pub(crate) struct TraceMacros {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_bench_sig)]
+pub(crate) struct BenchSig {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_test_arg_non_lifetime)]
+pub(crate) struct TestArgNonLifetime {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_should_panic)]
+pub(crate) struct ShouldPanic {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_test_args)]
+pub(crate) struct TestArgs {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_alloc_must_statics)]
+pub(crate) struct AllocMustStatics {
+    #[primary_span]
+    pub(crate) span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(builtin_macros_concat_bytes_invalid)]
 pub(crate) struct ConcatBytesInvalid {
     #[primary_span]
@@ -202,6 +279,10 @@ pub(crate) struct BadDeriveTarget {
 }
 
 #[derive(Diagnostic)]
+#[diag(builtin_macros_tests_not_support)]
+pub(crate) struct TestsNotSupport {}
+
+#[derive(Diagnostic)]
 #[diag(builtin_macros_unexpected_lit, code = "E0777")]
 pub(crate) struct BadDeriveLit {
     #[primary_span]
@@ -732,3 +813,10 @@ pub(crate) struct TestRunnerNargs {
     #[primary_span]
     pub(crate) span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_expected_register_class_or_explicit_register)]
+pub(crate) struct ExpectedRegisterClassOrExplicitRegister {
+    #[primary_span]
+    pub(crate) span: Span,
+}
diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs
index f0d378d12f7..5772471931f 100644
--- a/compiler/rustc_builtin_macros/src/global_allocator.rs
+++ b/compiler/rustc_builtin_macros/src/global_allocator.rs
@@ -1,5 +1,6 @@
 use crate::util::check_builtin_macro_attribute;
 
+use crate::errors;
 use rustc_ast::expand::allocator::{
     global_fn_name, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS,
 };
@@ -34,7 +35,7 @@ pub fn expand(
         {
             (item, true, ecx.with_def_site_ctxt(ty.span))
         } else {
-            ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "allocators must be statics");
+            ecx.sess.parse_sess.span_diagnostic.emit_err(errors::AllocMustStatics{span: item.span()});
             return vec![orig_item];
         };
 
diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
index 52b5601bb11..b35a2e2a292 100644
--- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
+++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs
@@ -1,3 +1,4 @@
+use crate::errors;
 use rustc_ast::ptr::P;
 use rustc_ast::visit::{self, Visitor};
 use rustc_ast::{self as ast, attr, NodeId};
@@ -83,12 +84,7 @@ pub fn inject(
 impl<'a> CollectProcMacros<'a> {
     fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) {
         if self.is_proc_macro_crate && self.in_root && vis.kind.is_pub() {
-            self.handler.span_err(
-                sp,
-                "`proc-macro` crate types currently cannot export any items other \
-                    than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, \
-                    or `#[proc_macro_attribute]`",
-            );
+            self.handler.emit_err(errors::ProcMacro { span: sp });
         }
     }
 
@@ -157,9 +153,9 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
     fn visit_item(&mut self, item: &'a ast::Item) {
         if let ast::ItemKind::MacroDef(..) = item.kind {
             if self.is_proc_macro_crate && attr::contains_name(&item.attrs, sym::macro_export) {
-                let msg =
-                    "cannot export macro_rules! macros from a `proc-macro` crate type currently";
-                self.handler.span_err(self.source_map.guess_head_span(item.span), msg);
+                self.handler.emit_err(errors::ExportMacroRules {
+                    span: self.source_map.guess_head_span(item.span),
+                });
             }
         }
 
diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs
index d7a92dac50f..6bc4f6fc1fc 100644
--- a/compiler/rustc_builtin_macros/src/test.rs
+++ b/compiler/rustc_builtin_macros/src/test.rs
@@ -576,12 +576,7 @@ fn check_bench_signature(
     // N.B., inadequate check, but we're running
     // well before resolve, can't get too deep.
     if f.sig.decl.inputs.len() != 1 {
-        return Err(cx.sess.parse_sess.span_diagnostic.span_err(
-            i.span,
-            "functions used as benches must have \
-            signature `fn(&mut Bencher) -> impl Termination`",
-        ));
+        return Err(cx.sess.parse_sess.span_diagnostic.emit_err(errors::BenchSig { span: i.span }));
     }
-
     Ok(())
 }
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index 9bc1e27b4ec..81b618548da 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -63,10 +63,7 @@ pub fn inject(krate: &mut ast::Crate, sess: &Session, resolver: &mut dyn Resolve
                     // Silently allow compiling with panic=abort on these platforms,
                     // but with old behavior (abort if a test fails).
                 } else {
-                    span_diagnostic.err(
-                        "building tests with panic=abort is not supported \
-                                         without `-Zpanic_abort_tests`",
-                    );
+                    span_diagnostic.emit_err(errors::TestsNotSupport {});
                 }
                 PanicStrategy::Unwind
             }
diff --git a/compiler/rustc_builtin_macros/src/trace_macros.rs b/compiler/rustc_builtin_macros/src/trace_macros.rs
index 9c98723e1f4..af1a392acc5 100644
--- a/compiler/rustc_builtin_macros/src/trace_macros.rs
+++ b/compiler/rustc_builtin_macros/src/trace_macros.rs
@@ -1,3 +1,4 @@
+use crate::errors;
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_expand::base::{self, ExtCtxt};
 use rustc_span::symbol::kw;
@@ -20,7 +21,7 @@ pub fn expand_trace_macros(
     };
     err |= cursor.next().is_some();
     if err {
-        cx.span_err(sp, "trace_macros! accepts only `true` or `false`")
+        cx.emit_err(errors::TraceMacros { span: sp });
     } else {
         cx.set_trace_macros(value);
     }
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index e8a7afcc632..287a22bc9a6 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -8,7 +8,7 @@ use crate::llvm_util;
 use crate::type_::Type;
 use crate::value::Value;
 
-use rustc_codegen_ssa::base::wants_msvc_seh;
+use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh};
 use rustc_codegen_ssa::traits::*;
 use rustc_data_structures::base_n;
 use rustc_data_structures::fx::FxHashMap;
@@ -532,19 +532,28 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         if let Some(llpersonality) = self.eh_personality.get() {
             return llpersonality;
         }
+
+        let name = if wants_msvc_seh(self.sess()) {
+            Some("__CxxFrameHandler3")
+        } else if wants_wasm_eh(self.sess()) {
+            // LLVM specifically tests for the name of the personality function
+            // There is no need for this function to exist anywhere, it will
+            // not be called. However, its name has to be "__gxx_wasm_personality_v0"
+            // for native wasm exceptions.
+            Some("__gxx_wasm_personality_v0")
+        } else {
+            None
+        };
+
         let tcx = self.tcx;
         let llfn = match tcx.lang_items().eh_personality() {
-            Some(def_id) if !wants_msvc_seh(self.sess()) => self.get_fn_addr(
+            Some(def_id) if name.is_none() => self.get_fn_addr(
                 ty::Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, ty::List::empty())
                     .unwrap()
                     .unwrap(),
             ),
             _ => {
-                let name = if wants_msvc_seh(self.sess()) {
-                    "__CxxFrameHandler3"
-                } else {
-                    "rust_eh_personality"
-                };
+                let name = name.unwrap_or("rust_eh_personality");
                 if let Some(llfn) = self.get_declared_value(name) {
                     llfn
                 } else {
@@ -662,6 +671,10 @@ impl<'ll> CodegenCx<'ll, '_> {
         let t_f32 = self.type_f32();
         let t_f64 = self.type_f64();
         let t_metadata = self.type_metadata();
+        let t_token = self.type_token();
+
+        ifn!("llvm.wasm.get.exception", fn(t_token) -> i8p);
+        ifn!("llvm.wasm.get.ehselector", fn(t_token) -> t_i32);
 
         ifn!("llvm.wasm.trunc.unsigned.i32.f32", fn(t_f32) -> t_i32);
         ifn!("llvm.wasm.trunc.unsigned.i32.f64", fn(t_f64) -> t_i32);
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 4e28034a850..31bafa87814 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -7,7 +7,7 @@ use crate::type_of::LayoutLlvmExt;
 use crate::va_arg::emit_va_arg;
 use crate::value::Value;
 
-use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh};
+use rustc_codegen_ssa::base::{compare_simd_types, wants_msvc_seh, wants_wasm_eh};
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
 use rustc_codegen_ssa::errors::{ExpectedPointerMutability, InvalidMonomorphization};
 use rustc_codegen_ssa::mir::operand::OperandRef;
@@ -452,6 +452,8 @@ fn try_intrinsic<'ll>(
         bx.store(bx.const_i32(0), dest, ret_align);
     } else if wants_msvc_seh(bx.sess()) {
         codegen_msvc_try(bx, try_func, data, catch_func, dest);
+    } else if wants_wasm_eh(bx.sess()) {
+        codegen_wasm_try(bx, try_func, data, catch_func, dest);
     } else if bx.sess().target.os == "emscripten" {
         codegen_emcc_try(bx, try_func, data, catch_func, dest);
     } else {
@@ -610,6 +612,80 @@ fn codegen_msvc_try<'ll>(
     bx.store(ret, dest, i32_align);
 }
 
+// WASM's definition of the `rust_try` function.
+fn codegen_wasm_try<'ll>(
+    bx: &mut Builder<'_, 'll, '_>,
+    try_func: &'ll Value,
+    data: &'ll Value,
+    catch_func: &'ll Value,
+    dest: &'ll Value,
+) {
+    let (llty, llfn) = get_rust_try_fn(bx, &mut |mut bx| {
+        bx.set_personality_fn(bx.eh_personality());
+
+        let normal = bx.append_sibling_block("normal");
+        let catchswitch = bx.append_sibling_block("catchswitch");
+        let catchpad = bx.append_sibling_block("catchpad");
+        let caught = bx.append_sibling_block("caught");
+
+        let try_func = llvm::get_param(bx.llfn(), 0);
+        let data = llvm::get_param(bx.llfn(), 1);
+        let catch_func = llvm::get_param(bx.llfn(), 2);
+
+        // We're generating an IR snippet that looks like:
+        //
+        //   declare i32 @rust_try(%try_func, %data, %catch_func) {
+        //      %slot = alloca i8*
+        //      invoke %try_func(%data) to label %normal unwind label %catchswitch
+        //
+        //   normal:
+        //      ret i32 0
+        //
+        //   catchswitch:
+        //      %cs = catchswitch within none [%catchpad] unwind to caller
+        //
+        //   catchpad:
+        //      %tok = catchpad within %cs [null]
+        //      %ptr = call @llvm.wasm.get.exception(token %tok)
+        //      %sel = call @llvm.wasm.get.ehselector(token %tok)
+        //      call %catch_func(%data, %ptr)
+        //      catchret from %tok to label %caught
+        //
+        //   caught:
+        //      ret i32 1
+        //   }
+        //
+        let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void());
+        bx.invoke(try_func_ty, None, None, try_func, &[data], normal, catchswitch, None);
+
+        bx.switch_to_block(normal);
+        bx.ret(bx.const_i32(0));
+
+        bx.switch_to_block(catchswitch);
+        let cs = bx.catch_switch(None, None, &[catchpad]);
+
+        bx.switch_to_block(catchpad);
+        let null = bx.const_null(bx.type_i8p());
+        let funclet = bx.catch_pad(cs, &[null]);
+
+        let ptr = bx.call_intrinsic("llvm.wasm.get.exception", &[funclet.cleanuppad()]);
+        let _sel = bx.call_intrinsic("llvm.wasm.get.ehselector", &[funclet.cleanuppad()]);
+
+        let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void());
+        bx.call(catch_ty, None, None, catch_func, &[data, ptr], Some(&funclet));
+        bx.catch_ret(&funclet, caught);
+
+        bx.switch_to_block(caught);
+        bx.ret(bx.const_i32(1));
+    });
+
+    // Note that no invoke is used here because by definition this function
+    // can't panic (that's what it's catching).
+    let ret = bx.call(llty, None, None, llfn, &[try_func, data, catch_func], None);
+    let i32_align = bx.tcx().data_layout.i32_align.abi;
+    bx.store(ret, dest, i32_align);
+}
+
 // Definition of the standard `try` function for Rust using the GNU-like model
 // of exceptions (e.g., the normal semantics of LLVM's `landingpad` and `invoke`
 // instructions).
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index fdc5f3b193e..08f47adcc04 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1071,6 +1071,7 @@ extern "C" {
 
     // Operations on other types
     pub fn LLVMVoidTypeInContext(C: &Context) -> &Type;
+    pub fn LLVMTokenTypeInContext(C: &Context) -> &Type;
     pub fn LLVMMetadataTypeInContext(C: &Context) -> &Type;
 
     // Operations on all values
diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs
index 4ffa2b9c6a3..7e672a8dc33 100644
--- a/compiler/rustc_codegen_llvm/src/type_.rs
+++ b/compiler/rustc_codegen_llvm/src/type_.rs
@@ -52,6 +52,10 @@ impl<'ll> CodegenCx<'ll, '_> {
         unsafe { llvm::LLVMVoidTypeInContext(self.llcx) }
     }
 
+    pub(crate) fn type_token(&self) -> &'ll Type {
+        unsafe { llvm::LLVMTokenTypeInContext(self.llcx) }
+    }
+
     pub(crate) fn type_metadata(&self) -> &'ll Type {
         unsafe { llvm::LLVMMetadataTypeInContext(self.llcx) }
     }
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 28f3c23364c..f8ced6949d5 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -357,6 +357,13 @@ pub fn cast_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     }
 }
 
+// Returns `true` if this session's target will use native wasm
+// exceptions. This means that the VM does the unwinding for
+// us
+pub fn wants_wasm_eh(sess: &Session) -> bool {
+    sess.target.is_like_wasm && sess.target.os != "emscripten"
+}
+
 /// Returns `true` if this session's target will use SEH-based unwinding.
 ///
 /// This is only true for MSVC targets, and even then the 64-bit MSVC target
@@ -366,6 +373,13 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
     sess.target.is_like_msvc
 }
 
+/// Returns `true` if this session's target requires the new exception
+/// handling LLVM IR instructions (catchpad / cleanuppad / ... instead
+/// of landingpad)
+pub fn wants_new_eh_instructions(sess: &Session) -> bool {
+    wants_wasm_eh(sess) || wants_msvc_seh(sess)
+}
+
 pub fn memcpy_ty<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     dst: Bx::Value,
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 5e40b672866..ac566c49ed4 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -79,8 +79,8 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
             lltarget = fx.landing_pad_for(target);
         }
         if is_cleanupret {
-            // MSVC cross-funclet jump - need a trampoline
-            debug_assert!(base::wants_msvc_seh(fx.cx.tcx().sess));
+            // Cross-funclet jump - need a trampoline
+            debug_assert!(base::wants_new_eh_instructions(fx.cx.tcx().sess));
             debug!("llbb_with_cleanup: creating cleanup trampoline for {:?}", target);
             let name = &format!("{:?}_cleanup_trampoline_{:?}", self.bb, target);
             let trampoline_llbb = Bx::append_block(fx.cx, fx.llfn, name);
@@ -177,9 +177,16 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
             mir::UnwindAction::Continue => None,
             mir::UnwindAction::Unreachable => None,
             mir::UnwindAction::Terminate => {
-                if fx.mir[self.bb].is_cleanup && base::wants_msvc_seh(fx.cx.tcx().sess) {
-                    // SEH will abort automatically if an exception tries to
+                if fx.mir[self.bb].is_cleanup && base::wants_new_eh_instructions(fx.cx.tcx().sess) {
+                    // MSVC SEH will abort automatically if an exception tries to
                     // propagate out from cleanup.
+
+                    // FIXME(@mirkootter): For wasm, we currently do not support terminate during
+                    // cleanup, because this requires a few more changes: The current code
+                    // caches the `terminate_block` for each function; funclet based code - however -
+                    // requires a different terminate_block for each funclet
+                    // Until this is implemented, we just do not unwind inside cleanup blocks
+
                     None
                 } else {
                     Some(fx.terminate_block())
@@ -1528,7 +1535,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     // FIXME(eddyb) rename this to `eh_pad_for_uncached`.
     fn landing_pad_for_uncached(&mut self, bb: mir::BasicBlock) -> Bx::BasicBlock {
         let llbb = self.llbb(bb);
-        if base::wants_msvc_seh(self.cx.sess()) {
+        if base::wants_new_eh_instructions(self.cx.sess()) {
             let cleanup_bb = Bx::append_block(self.cx, self.llfn, &format!("funclet_{:?}", bb));
             let mut cleanup_bx = Bx::build(self.cx, cleanup_bb);
             let funclet = cleanup_bx.cleanup_pad(None, &[]);
@@ -1587,6 +1594,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 //      } catch (...) {
                 //          bar();
                 //      }
+                //
+                // which creates an IR snippet like
+                //
+                //      cs_terminate:
+                //         %cs = catchswitch within none [%cp_terminate] unwind to caller
+                //      cp_terminate:
+                //         %cp = catchpad within %cs [null, i32 64, null]
+                //         ...
+
                 llbb = Bx::append_block(self.cx, self.llfn, "cs_terminate");
                 let cp_llbb = Bx::append_block(self.cx, self.llfn, "cp_terminate");
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 15b0e34b8e4..9ff6a249748 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -179,7 +179,8 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         start_bx.set_personality_fn(cx.eh_personality());
     }
 
-    let cleanup_kinds = base::wants_msvc_seh(cx.tcx().sess).then(|| analyze::cleanup_kinds(&mir));
+    let cleanup_kinds =
+        base::wants_new_eh_instructions(cx.tcx().sess).then(|| analyze::cleanup_kinds(&mir));
 
     let cached_llbbs: IndexVec<mir::BasicBlock, CachedLlbb<Bx::BasicBlock>> =
         mir.basic_blocks
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 6a3a31a0d60..9e06fec550d 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -284,6 +284,7 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
     // tidy-alphabetical-start
     ("atomics", Some(sym::wasm_target_feature)),
     ("bulk-memory", Some(sym::wasm_target_feature)),
+    ("exception-handling", Some(sym::wasm_target_feature)),
     ("multivalue", Some(sym::wasm_target_feature)),
     ("mutable-globals", Some(sym::wasm_target_feature)),
     ("nontrapping-fptoint", Some(sym::wasm_target_feature)),
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index 847b267b614..66389cf5995 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -80,14 +80,14 @@ pub struct Elaborator<'tcx, O> {
 pub trait Elaboratable<'tcx> {
     fn predicate(&self) -> ty::Predicate<'tcx>;
 
-    // Makes a new `Self` but with a different predicate.
-    fn child(&self, predicate: ty::Predicate<'tcx>) -> Self;
+    // Makes a new `Self` but with a different clause that comes from elaboration.
+    fn child(&self, clause: ty::Clause<'tcx>) -> Self;
 
-    // Makes a new `Self` but with a different predicate and a different cause
-    // code (if `Self` has one).
+    // Makes a new `Self` but with a different clause and a different cause
+    // code (if `Self` has one, such as [`PredicateObligation`]).
     fn child_with_derived_cause(
         &self,
-        predicate: ty::Predicate<'tcx>,
+        clause: ty::Clause<'tcx>,
         span: Span,
         parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
         index: usize,
@@ -99,18 +99,18 @@ impl<'tcx> Elaboratable<'tcx> for PredicateObligation<'tcx> {
         self.predicate
     }
 
-    fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
+    fn child(&self, clause: ty::Clause<'tcx>) -> Self {
         Obligation {
             cause: self.cause.clone(),
             param_env: self.param_env,
             recursion_depth: 0,
-            predicate,
+            predicate: clause.as_predicate(),
         }
     }
 
     fn child_with_derived_cause(
         &self,
-        predicate: ty::Predicate<'tcx>,
+        clause: ty::Clause<'tcx>,
         span: Span,
         parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
         index: usize,
@@ -123,7 +123,12 @@ impl<'tcx> Elaboratable<'tcx> for PredicateObligation<'tcx> {
                 span,
             }))
         });
-        Obligation { cause, param_env: self.param_env, recursion_depth: 0, predicate }
+        Obligation {
+            cause,
+            param_env: self.param_env,
+            recursion_depth: 0,
+            predicate: clause.as_predicate(),
+        }
     }
 }
 
@@ -132,18 +137,18 @@ impl<'tcx> Elaboratable<'tcx> for ty::Predicate<'tcx> {
         *self
     }
 
-    fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
-        predicate
+    fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+        clause.as_predicate()
     }
 
     fn child_with_derived_cause(
         &self,
-        predicate: ty::Predicate<'tcx>,
+        clause: ty::Clause<'tcx>,
         _span: Span,
         _parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
         _index: usize,
     ) -> Self {
-        predicate
+        clause.as_predicate()
     }
 }
 
@@ -152,18 +157,18 @@ impl<'tcx> Elaboratable<'tcx> for (ty::Predicate<'tcx>, Span) {
         self.0
     }
 
-    fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
-        (predicate, self.1)
+    fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+        (clause.as_predicate(), self.1)
     }
 
     fn child_with_derived_cause(
         &self,
-        predicate: ty::Predicate<'tcx>,
+        clause: ty::Clause<'tcx>,
         _span: Span,
         _parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
         _index: usize,
     ) -> Self {
-        (predicate, self.1)
+        (clause.as_predicate(), self.1)
     }
 }
 
@@ -172,18 +177,18 @@ impl<'tcx> Elaboratable<'tcx> for (ty::Clause<'tcx>, Span) {
         self.0.as_predicate()
     }
 
-    fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
-        (predicate.expect_clause(), self.1)
+    fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+        (clause, self.1)
     }
 
     fn child_with_derived_cause(
         &self,
-        predicate: ty::Predicate<'tcx>,
+        clause: ty::Clause<'tcx>,
         _span: Span,
         _parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
         _index: usize,
     ) -> Self {
-        (predicate.expect_clause(), self.1)
+        (clause, self.1)
     }
 }
 
@@ -192,18 +197,18 @@ impl<'tcx> Elaboratable<'tcx> for ty::Clause<'tcx> {
         self.as_predicate()
     }
 
-    fn child(&self, predicate: ty::Predicate<'tcx>) -> Self {
-        predicate.expect_clause()
+    fn child(&self, clause: ty::Clause<'tcx>) -> Self {
+        clause
     }
 
     fn child_with_derived_cause(
         &self,
-        predicate: ty::Predicate<'tcx>,
+        clause: ty::Clause<'tcx>,
         _span: Span,
         _parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
         _index: usize,
     ) -> Self {
-        predicate.expect_clause()
+        clause
     }
 }
 
@@ -252,14 +257,13 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
                 };
 
                 let obligations =
-                    predicates.predicates.iter().enumerate().map(|(index, &(mut pred, span))| {
+                    predicates.predicates.iter().enumerate().map(|(index, &(mut clause, span))| {
                         // when parent predicate is non-const, elaborate it to non-const predicates.
                         if data.constness == ty::BoundConstness::NotConst {
-                            pred = pred.without_const(tcx);
+                            clause = clause.without_const(tcx);
                         }
                         elaboratable.child_with_derived_cause(
-                            pred.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref))
-                                .as_predicate(),
+                            clause.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
                             span,
                             bound_predicate.rebind(data),
                             index,
@@ -333,17 +337,15 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
                                 if r.is_late_bound() {
                                     None
                                 } else {
-                                    Some(ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
-                                        ty::OutlivesPredicate(r, r_min),
+                                    Some(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
+                                        r, r_min,
                                     )))
                                 }
                             }
 
                             Component::Param(p) => {
                                 let ty = tcx.mk_ty_param(p.index, p.name);
-                                Some(ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
-                                    ty::OutlivesPredicate(ty, r_min),
-                                )))
+                                Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, r_min)))
                             }
 
                             Component::UnresolvedInferenceVariable(_) => None,
@@ -351,8 +353,9 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
                             Component::Alias(alias_ty) => {
                                 // We might end up here if we have `Foo<<Bar as Baz>::Assoc>: 'a`.
                                 // With this, we can deduce that `<Bar as Baz>::Assoc: 'a`.
-                                Some(ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
-                                    ty::OutlivesPredicate(alias_ty.to_ty(tcx), r_min),
+                                Some(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
+                                    alias_ty.to_ty(tcx),
+                                    r_min,
                                 )))
                             }
 
@@ -362,10 +365,9 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
                                 None
                             }
                         })
-                        .map(|predicate_kind| {
-                            bound_predicate.rebind(predicate_kind).to_predicate(tcx)
-                        })
-                        .map(|predicate| elaboratable.child(predicate)),
+                        .map(|clause| {
+                            elaboratable.child(bound_predicate.rebind(clause).to_predicate(tcx))
+                        }),
                 );
             }
             ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => {
diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl
index 6f51981cf09..b91e0d18a80 100644
--- a/compiler/rustc_privacy/messages.ftl
+++ b/compiler/rustc_privacy/messages.ftl
@@ -18,7 +18,7 @@ privacy_private_in_public_lint =
     })
 
 privacy_private_interface_or_bounds_lint = {$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}`
-    .item_note = {$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}`
+    .item_label = {$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}`
     .ty_note = but {$ty_kind} `{$ty_descr}` is only usable at visibility `{$ty_vis_descr}`
 
 privacy_report_effective_visibility = {$descr}
diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs
index 67689b5e713..da18f0c8268 100644
--- a/compiler/rustc_privacy/src/errors.rs
+++ b/compiler/rustc_privacy/src/errors.rs
@@ -116,7 +116,7 @@ pub struct UnnameableTypesLint<'a> {
 #[derive(LintDiagnostic)]
 #[diag(privacy_private_interface_or_bounds_lint)]
 pub struct PrivateInterfacesOrBoundsLint<'a> {
-    #[note(privacy_item_note)]
+    #[label(privacy_item_label)]
     pub item_span: Span,
     pub item_kind: &'a str,
     pub item_descr: DiagnosticArgFromDisplay<'a>,
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 3841beb733f..c3e8d45d201 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -1865,9 +1865,10 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
             } else {
                 lint::builtin::PRIVATE_BOUNDS
             };
-            self.tcx.emit_lint(
+            self.tcx.emit_spanned_lint(
                 lint,
                 hir_id,
+                span,
                 PrivateInterfacesOrBoundsLint {
                     item_span: span,
                     item_kind: self.tcx.def_descr(self.item_def_id.to_def_id()),
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index d77fb922e84..d9e4974626d 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1403,7 +1403,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         for ns in [Namespace::MacroNS, Namespace::TypeNS, Namespace::ValueNS] {
             if let Ok(binding) = self.early_resolve_ident_in_lexical_scope(
                 ident,
-                ScopeSet::All(ns, false),
+                ScopeSet::All(ns),
                 &parent_scope,
                 None,
                 false,
@@ -1841,10 +1841,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         _ => None,
                     }
                 } else {
-                    let scopes = ScopeSet::All(ns_to_try, opt_ns.is_none());
                     self.early_resolve_ident_in_lexical_scope(
                         ident,
-                        scopes,
+                        ScopeSet::All(ns_to_try),
                         parent_scope,
                         None,
                         false,
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index e5fa062967f..8e921f1ecb1 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -88,7 +88,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         let rust_2015 = ctxt.edition().is_rust_2015();
         let (ns, macro_kind, is_absolute_path) = match scope_set {
-            ScopeSet::All(ns, _) => (ns, None, false),
+            ScopeSet::All(ns) => (ns, None, false),
             ScopeSet::AbsolutePath(ns) => (ns, None, true),
             ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false),
             ScopeSet::Late(ns, ..) => (ns, None, false),
@@ -397,11 +397,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             return Err(Determinacy::Determined);
         }
 
-        let (ns, macro_kind, is_import) = match scope_set {
-            ScopeSet::All(ns, is_import) => (ns, None, is_import),
-            ScopeSet::AbsolutePath(ns) => (ns, None, false),
-            ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false),
-            ScopeSet::Late(ns, ..) => (ns, None, false),
+        let (ns, macro_kind) = match scope_set {
+            ScopeSet::All(ns) => (ns, None),
+            ScopeSet::AbsolutePath(ns) => (ns, None),
+            ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)),
+            ScopeSet::Late(ns, ..) => (ns, None),
         };
 
         // This is *the* result, resolution from the scope closest to the resolved identifier.
@@ -631,9 +631,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 let derive_helper_compat =
                                     Res::NonMacroAttr(NonMacroAttrKind::DeriveHelperCompat);
 
-                                let ambiguity_error_kind = if is_import {
-                                    Some(AmbiguityKind::Import)
-                                } else if is_builtin(innermost_res) || is_builtin(res) {
+                                let ambiguity_error_kind = if is_builtin(innermost_res)
+                                    || is_builtin(res)
+                                {
                                     Some(AmbiguityKind::BuiltinAttr)
                                 } else if innermost_res == derive_helper_compat
                                     || res == derive_helper_compat && innermost_res != derive_helper
@@ -853,10 +853,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     }
                 }
 
-                let scopes = ScopeSet::All(ns, true);
                 let binding = self.early_resolve_ident_in_lexical_scope(
                     ident,
-                    scopes,
+                    ScopeSet::All(ns),
                     parent_scope,
                     finalize,
                     finalize.is_some(),
@@ -1497,7 +1496,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             } else {
                 self.early_resolve_ident_in_lexical_scope(
                     ident,
-                    ScopeSet::All(ns, opt_ns.is_none()),
+                    ScopeSet::All(ns),
                     parent_scope,
                     finalize,
                     finalize.is_some(),
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 35491ebe10c..8bd08921fe6 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -10,10 +10,7 @@ use crate::errors::{
 use crate::Determinacy::{self, *};
 use crate::{fluent_generated as fluent, Namespace::*};
 use crate::{module_to_string, names_to_string, ImportSuggestion};
-use crate::{
-    AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, ModuleKind, ResolutionError,
-    Resolver, Segment,
-};
+use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
 use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
 use crate::{NameBinding, NameBindingKind, PathResult};
 
@@ -984,7 +981,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 match binding {
                     Ok(binding) => {
                         // Consistency checks, analogous to `finalize_macro_resolutions`.
-                        let initial_binding = source_bindings[ns].get().map(|initial_binding| {
+                        let initial_res = source_bindings[ns].get().map(|initial_binding| {
                             all_ns_err = false;
                             if let Some(target_binding) = target_bindings[ns].get() {
                                 if target.name == kw::Underscore
@@ -998,20 +995,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     );
                                 }
                             }
-                            initial_binding
+                            initial_binding.res()
                         });
                         let res = binding.res();
-                        if let Ok(initial_binding) = initial_binding {
-                            let initial_res = initial_binding.res();
+                        if let Ok(initial_res) = initial_res {
                             if res != initial_res && this.ambiguity_errors.is_empty() {
-                                this.ambiguity_errors.push(AmbiguityError {
-                                    kind: AmbiguityKind::Import,
-                                    ident,
-                                    b1: initial_binding,
-                                    b2: binding,
-                                    misc1: AmbiguityErrorMisc::None,
-                                    misc2: AmbiguityErrorMisc::None,
-                                });
+                                span_bug!(import.span, "inconsistent resolution for an import");
                             }
                         } else if res != Res::Err
                             && this.ambiguity_errors.is_empty()
@@ -1283,7 +1272,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
                 match this.early_resolve_ident_in_lexical_scope(
                     target,
-                    ScopeSet::All(ns, false),
+                    ScopeSet::All(ns),
                     &import.parent_scope,
                     None,
                     false,
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 8c1cd2f1557..ff698452ad5 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -131,7 +131,7 @@ enum Scope<'a> {
 #[derive(Clone, Copy)]
 enum ScopeSet<'a> {
     /// All scopes with the given namespace.
-    All(Namespace, /*is_import*/ bool),
+    All(Namespace),
     /// Crate root, then extern prelude (used for mixed 2015-2018 mode in macros).
     AbsolutePath(Namespace),
     /// All scopes with macro namespace and the given macro kind restriction.
@@ -718,7 +718,6 @@ struct UseError<'a> {
 
 #[derive(Clone, Copy, PartialEq, Debug)]
 enum AmbiguityKind {
-    Import,
     BuiltinAttr,
     DeriveHelper,
     MacroRulesVsModularized,
@@ -731,7 +730,6 @@ enum AmbiguityKind {
 impl AmbiguityKind {
     fn descr(self) -> &'static str {
         match self {
-            AmbiguityKind::Import => "multiple potential import sources",
             AmbiguityKind::BuiltinAttr => "a name conflict with a builtin attribute",
             AmbiguityKind::DeriveHelper => "a name conflict with a derive helper attribute",
             AmbiguityKind::MacroRulesVsModularized => {
@@ -1557,7 +1555,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
         }
 
-        self.visit_scopes(ScopeSet::All(TypeNS, false), parent_scope, ctxt, |this, scope, _, _| {
+        self.visit_scopes(ScopeSet::All(TypeNS), parent_scope, ctxt, |this, scope, _, _| {
             match scope {
                 Scope::Module(module, _) => {
                     this.traits_in_module(module, assoc_item, &mut found_traits);
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 4dcef8f6efd..d33e8d40b63 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -645,7 +645,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             self.prohibit_imported_non_macro_attrs(None, res.ok(), path_span);
             res
         } else {
-            let scope_set = kind.map_or(ScopeSet::All(MacroNS, false), ScopeSet::Macro);
+            let scope_set = kind.map_or(ScopeSet::All(MacroNS), ScopeSet::Macro);
             let binding = self.early_resolve_ident_in_lexical_scope(
                 path[0].ident,
                 scope_set,
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 7c8e3536df5..a1d3453377a 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -686,6 +686,7 @@ impl<'a> Builder<'a> {
                 test::Tidy,
                 test::Ui,
                 test::RunPassValgrind,
+                test::RunCoverage,
                 test::MirOpt,
                 test::Codegen,
                 test::CodegenUnits,
@@ -694,6 +695,7 @@ impl<'a> Builder<'a> {
                 test::Debuginfo,
                 test::UiFullDeps,
                 test::Rustdoc,
+                test::RunCoverageRustdoc,
                 test::Pretty,
                 test::Crate,
                 test::CrateLibrustc,
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 1ac52dffe58..5ebfe0995a8 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -751,7 +751,15 @@ impl Step for Rustc {
 }
 
 macro_rules! tool_doc {
-    ($tool: ident, $should_run: literal, $path: literal, $(rustc_tool = $rustc_tool:literal, )? $(in_tree = $in_tree:literal, )? [$($krate: literal),+ $(,)?] $(,)?) => {
+    (
+        $tool: ident,
+        $should_run: literal,
+        $path: literal,
+        $(rustc_tool = $rustc_tool:literal, )?
+        $(in_tree = $in_tree:literal, )?
+        [$($extra_arg: literal),+ $(,)?]
+        $(,)?
+    ) => {
         #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
         pub struct $tool {
             target: TargetSelection,
@@ -832,9 +840,9 @@ macro_rules! tool_doc {
                 cargo.arg("-Zskip-rustdoc-fingerprint");
                 // Only include compiler crates, no dependencies of those, such as `libc`.
                 cargo.arg("--no-deps");
-                cargo.arg("--lib");
+
                 $(
-                    cargo.arg("-p").arg($krate);
+                    cargo.arg($extra_arg);
                 )+
 
                 cargo.rustdocflag("--document-private-items");
@@ -850,15 +858,20 @@ macro_rules! tool_doc {
     }
 }
 
-tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", ["rustdoc", "rustdoc-json-types"],);
+tool_doc!(
+    Rustdoc,
+    "rustdoc-tool",
+    "src/tools/rustdoc",
+    ["-p", "rustdoc", "-p", "rustdoc-json-types"]
+);
 tool_doc!(
     Rustfmt,
     "rustfmt-nightly",
     "src/tools/rustfmt",
-    ["rustfmt-nightly", "rustfmt-config_proc_macro"],
+    ["-p", "rustfmt-nightly", "-p", "rustfmt-config_proc_macro"],
 );
-tool_doc!(Clippy, "clippy", "src/tools/clippy", ["clippy_utils"]);
-tool_doc!(Miri, "miri", "src/tools/miri", ["miri"]);
+tool_doc!(Clippy, "clippy", "src/tools/clippy", ["-p", "clippy_utils"]);
+tool_doc!(Miri, "miri", "src/tools/miri", ["-p", "miri"]);
 tool_doc!(
     Cargo,
     "cargo",
@@ -866,25 +879,44 @@ tool_doc!(
     rustc_tool = false,
     in_tree = false,
     [
+        "-p",
         "cargo",
+        "-p",
         "cargo-platform",
+        "-p",
         "cargo-util",
+        "-p",
         "crates-io",
+        "-p",
         "cargo-test-macro",
+        "-p",
         "cargo-test-support",
+        "-p",
         "cargo-credential",
+        "-p",
         "cargo-credential-1password",
+        "-p",
         "mdman",
         // FIXME: this trips a license check in tidy.
+        // "-p",
         // "resolver-tests",
         // FIXME: we should probably document these, but they're different per-platform so we can't use `tool_doc`.
+        // "-p",
         // "cargo-credential-gnome-secret",
+        // "-p",
         // "cargo-credential-macos-keychain",
+        // "-p",
         // "cargo-credential-wincred",
     ]
 );
-tool_doc!(Tidy, "tidy", "src/tools/tidy", rustc_tool = false, ["tidy"]);
-tool_doc!(Bootstrap, "bootstrap", "src/bootstrap", rustc_tool = false, ["bootstrap"]);
+tool_doc!(Tidy, "tidy", "src/tools/tidy", rustc_tool = false, ["-p", "tidy"]);
+tool_doc!(
+    Bootstrap,
+    "bootstrap",
+    "src/bootstrap",
+    rustc_tool = false,
+    ["--lib", "-p", "bootstrap"]
+);
 
 #[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct ErrorIndex {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index ec447a1cd73..2c1f612e39f 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1319,6 +1319,13 @@ host_test!(RunMakeFullDeps {
 
 default_test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly" });
 
+host_test!(RunCoverage { path: "tests/run-coverage", mode: "run-coverage", suite: "run-coverage" });
+host_test!(RunCoverageRustdoc {
+    path: "tests/run-coverage-rustdoc",
+    mode: "run-coverage",
+    suite: "run-coverage-rustdoc"
+});
+
 // For the mir-opt suite we do not use macros, as we need custom behavior when blessing.
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct MirOpt {
@@ -1503,6 +1510,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
             || (mode == "ui" && is_rustdoc)
             || mode == "js-doc-test"
             || mode == "rustdoc-json"
+            || suite == "run-coverage-rustdoc"
         {
             cmd.arg("--rustdoc-path").arg(builder.rustdoc(compiler));
         }
@@ -1516,7 +1524,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
                 .arg(builder.ensure(tool::JsonDocLint { compiler: json_compiler, target }));
         }
 
-        if mode == "run-make" {
+        if mode == "run-make" || mode == "run-coverage" {
             let rust_demangler = builder
                 .ensure(tool::RustDemangler {
                     compiler,
@@ -1703,17 +1711,21 @@ note: if you're sure you want to do this, please open an issue as to why. In the
                 add_link_lib_path(vec![llvm_libdir.trim().into()], &mut cmd);
             }
 
-            // Only pass correct values for these flags for the `run-make` suite as it
-            // requires that a C++ compiler was configured which isn't always the case.
-            if !builder.config.dry_run() && matches!(suite, "run-make" | "run-make-fulldeps") {
+            if !builder.config.dry_run()
+                && (matches!(suite, "run-make" | "run-make-fulldeps") || mode == "run-coverage")
+            {
                 // The llvm/bin directory contains many useful cross-platform
                 // tools. Pass the path to run-make tests so they can use them.
+                // (The run-coverage tests also need these tools to process
+                // coverage reports.)
                 let llvm_bin_path = llvm_config
                     .parent()
                     .expect("Expected llvm-config to be contained in directory");
                 assert!(llvm_bin_path.is_dir());
                 cmd.arg("--llvm-bin-dir").arg(llvm_bin_path);
+            }
 
+            if !builder.config.dry_run() && matches!(suite, "run-make" | "run-make-fulldeps") {
                 // If LLD is available, add it to the PATH
                 if builder.config.lld_enabled {
                     let lld_install_root =
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 85a8fbcffbe..81684c6f9f9 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -66,6 +66,7 @@ string_enum! {
         JsDocTest => "js-doc-test",
         MirOpt => "mir-opt",
         Assembly => "assembly",
+        RunCoverage => "run-coverage",
     }
 }
 
@@ -626,6 +627,7 @@ pub const UI_EXTENSIONS: &[&str] = &[
     UI_STDERR_64,
     UI_STDERR_32,
     UI_STDERR_16,
+    UI_COVERAGE,
 ];
 pub const UI_STDERR: &str = "stderr";
 pub const UI_STDOUT: &str = "stdout";
@@ -635,6 +637,7 @@ pub const UI_RUN_STDOUT: &str = "run.stdout";
 pub const UI_STDERR_64: &str = "64bit.stderr";
 pub const UI_STDERR_32: &str = "32bit.stderr";
 pub const UI_STDERR_16: &str = "16bit.stderr";
+pub const UI_COVERAGE: &str = "coverage";
 
 /// Absolute path to the directory where all output for all tests in the given
 /// `relative_dir` group should reside. Example:
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 8cc935e54d1..c835962ad12 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -161,7 +161,7 @@ pub struct TestProps {
     // customized normalization rules
     pub normalize_stdout: Vec<(String, String)>,
     pub normalize_stderr: Vec<(String, String)>,
-    pub failure_status: i32,
+    pub failure_status: Option<i32>,
     // For UI tests, allows compiler to exit with arbitrary failure status
     pub dont_check_failure_status: bool,
     // Whether or not `rustfix` should apply the `CodeSuggestion`s of this test and compile the
@@ -257,7 +257,7 @@ impl TestProps {
             check_test_line_numbers_match: false,
             normalize_stdout: vec![],
             normalize_stderr: vec![],
-            failure_status: -1,
+            failure_status: None,
             dont_check_failure_status: false,
             run_rustfix: false,
             rustfix_only_machine_applicable: false,
@@ -428,7 +428,7 @@ impl TestProps {
                     .parse_name_value_directive(ln, FAILURE_STATUS)
                     .and_then(|code| code.trim().parse::<i32>().ok())
                 {
-                    self.failure_status = code;
+                    self.failure_status = Some(code);
                 }
 
                 config.set_name_directive(
@@ -491,11 +491,8 @@ impl TestProps {
             });
         }
 
-        if self.failure_status == -1 {
-            self.failure_status = 1;
-        }
         if self.should_ice {
-            self.failure_status = 101;
+            self.failure_status = Some(101);
         }
 
         if config.mode == Mode::Incremental {
@@ -615,10 +612,25 @@ pub fn line_directive<'line>(
 }
 
 fn iter_header<R: Read>(testfile: &Path, rdr: R, it: &mut dyn FnMut(Option<&str>, &str, usize)) {
+    iter_header_extra(testfile, rdr, &[], it)
+}
+
+fn iter_header_extra(
+    testfile: &Path,
+    rdr: impl Read,
+    extra_directives: &[&str],
+    it: &mut dyn FnMut(Option<&str>, &str, usize),
+) {
     if testfile.is_dir() {
         return;
     }
 
+    // Process any extra directives supplied by the caller (e.g. because they
+    // are implied by the test mode), with a dummy line number of 0.
+    for directive in extra_directives {
+        it(None, directive, 0);
+    }
+
     let comment = if testfile.extension().map(|e| e == "rs") == Some(true) { "//" } else { "#" };
 
     let mut rdr = BufReader::new(rdr);
@@ -897,7 +909,27 @@ pub fn make_test_description<R: Read>(
     let mut ignore_message = None;
     let mut should_fail = false;
 
-    iter_header(path, src, &mut |revision, ln, line_number| {
+    let extra_directives: &[&str] = match config.mode {
+        // The run-coverage tests are treated as having these extra directives,
+        // without needing to specify them manually in every test file.
+        // (Some of the comments below have been copied over from
+        // `tests/run-make/coverage-reports/Makefile`, which no longer exists.)
+        Mode::RunCoverage => {
+            &[
+                "needs-profiler-support",
+                // FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
+                // properly. Since we only have GCC on the CI ignore the test for now.
+                "ignore-windows-gnu",
+                // FIXME(pietroalbini): this test currently does not work on cross-compiled
+                // targets because remote-test is not capable of sending back the *.profraw
+                // files generated by the LLVM instrumentation.
+                "ignore-cross-compile",
+            ]
+        }
+        _ => &[],
+    };
+
+    iter_header_extra(path, src, extra_directives, &mut |revision, ln, line_number| {
         if revision.is_some() && revision != cfg {
             return;
         }
diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index 0e306696a90..62364ede47b 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -87,7 +87,7 @@ pub(super) fn handle_needs(
         },
         Need {
             name: "needs-profiler-support",
-            condition: std::env::var_os("RUSTC_PROFILER_SUPPORT").is_some(),
+            condition: cache.profiler_support,
             ignore_reason: "ignored when profiler support is disabled",
         },
         Need {
@@ -195,6 +195,7 @@ pub(super) struct CachedNeedsConditions {
     sanitizer_memtag: bool,
     sanitizer_shadow_call_stack: bool,
     sanitizer_safestack: bool,
+    profiler_support: bool,
     xray: bool,
     rust_lld: bool,
     i686_dlltool: bool,
@@ -232,6 +233,7 @@ impl CachedNeedsConditions {
             sanitizer_memtag: util::MEMTAG_SUPPORTED_TARGETS.contains(target),
             sanitizer_shadow_call_stack: util::SHADOWCALLSTACK_SUPPORTED_TARGETS.contains(target),
             sanitizer_safestack: util::SAFESTACK_SUPPORTED_TARGETS.contains(target),
+            profiler_support: std::env::var_os("RUSTC_PROFILER_SUPPORT").is_some(),
             xray: util::XRAY_SUPPORTED_TARGETS.contains(target),
 
             // For tests using the `needs-rust-lld` directive (e.g. for `-Zgcc-ld=lld`), we need to find
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 5c8ee7895d3..8bdc2d65d27 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -6,8 +6,8 @@ use crate::common::{Assembly, Incremental, JsDocTest, MirOpt, RunMake, RustdocJs
 use crate::common::{Codegen, CodegenUnits, DebugInfo, Debugger, Rustdoc};
 use crate::common::{CompareMode, FailMode, PassMode};
 use crate::common::{Config, TestPaths};
-use crate::common::{Pretty, RunPassValgrind};
-use crate::common::{UI_RUN_STDERR, UI_RUN_STDOUT};
+use crate::common::{Pretty, RunCoverage, RunPassValgrind};
+use crate::common::{UI_COVERAGE, UI_RUN_STDERR, UI_RUN_STDOUT};
 use crate::compute_diff::{write_diff, write_filtered_diff};
 use crate::errors::{self, Error, ErrorKind};
 use crate::header::TestProps;
@@ -253,6 +253,7 @@ impl<'test> TestCx<'test> {
             MirOpt => self.run_mir_opt_test(),
             Assembly => self.run_assembly_test(),
             JsDocTest => self.run_js_doc_test(),
+            RunCoverage => self.run_coverage_test(),
         }
     }
 
@@ -384,7 +385,7 @@ impl<'test> TestCx<'test> {
     }
 
     fn check_correct_failure_status(&self, proc_res: &ProcRes) {
-        let expected_status = Some(self.props.failure_status);
+        let expected_status = Some(self.props.failure_status.unwrap_or(1));
         let received_status = proc_res.status.code();
 
         if expected_status != received_status {
@@ -465,6 +466,296 @@ impl<'test> TestCx<'test> {
         }
     }
 
+    fn run_coverage_test(&self) {
+        let should_run = self.run_if_enabled();
+        let proc_res = self.compile_test(should_run, Emit::None);
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+        drop(proc_res);
+
+        if let WillExecute::Disabled = should_run {
+            return;
+        }
+
+        let profraw_path = self.output_base_dir().join("default.profraw");
+        let profdata_path = self.output_base_dir().join("default.profdata");
+
+        // Delete any existing profraw/profdata files to rule out unintended
+        // interference between repeated test runs.
+        if profraw_path.exists() {
+            std::fs::remove_file(&profraw_path).unwrap();
+        }
+        if profdata_path.exists() {
+            std::fs::remove_file(&profdata_path).unwrap();
+        }
+
+        let proc_res = self.exec_compiled_test_general(
+            &[("LLVM_PROFILE_FILE", &profraw_path.to_str().unwrap())],
+            false,
+        );
+        if self.props.failure_status.is_some() {
+            self.check_correct_failure_status(&proc_res);
+        } else if !proc_res.status.success() {
+            self.fatal_proc_rec("test run failed!", &proc_res);
+        }
+        drop(proc_res);
+
+        let mut profraw_paths = vec![profraw_path];
+        let mut bin_paths = vec![self.make_exe_name()];
+
+        if self.config.suite == "run-coverage-rustdoc" {
+            self.run_doctests_for_coverage(&mut profraw_paths, &mut bin_paths);
+        }
+
+        // Run `llvm-profdata merge` to index the raw coverage output.
+        let proc_res = self.run_llvm_tool("llvm-profdata", |cmd| {
+            cmd.args(["merge", "--sparse", "--output"]);
+            cmd.arg(&profdata_path);
+            cmd.args(&profraw_paths);
+        });
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("llvm-profdata merge failed!", &proc_res);
+        }
+        drop(proc_res);
+
+        // Run `llvm-cov show` to produce a coverage report in text format.
+        let proc_res = self.run_llvm_tool("llvm-cov", |cmd| {
+            cmd.args(["show", "--format=text", "--show-line-counts-or-regions"]);
+
+            cmd.arg("--Xdemangler");
+            cmd.arg(self.config.rust_demangler_path.as_ref().unwrap());
+
+            cmd.arg("--instr-profile");
+            cmd.arg(&profdata_path);
+
+            for bin in &bin_paths {
+                cmd.arg("--object");
+                cmd.arg(bin);
+            }
+        });
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("llvm-cov show failed!", &proc_res);
+        }
+
+        let kind = UI_COVERAGE;
+
+        let expected_coverage = self.load_expected_output(kind);
+        let normalized_actual_coverage =
+            self.normalize_coverage_output(&proc_res.stdout).unwrap_or_else(|err| {
+                self.fatal_proc_rec(&err, &proc_res);
+            });
+
+        let coverage_errors = self.compare_output(
+            kind,
+            &normalized_actual_coverage,
+            &expected_coverage,
+            self.props.compare_output_lines_by_subset,
+        );
+
+        if coverage_errors > 0 {
+            self.fatal_proc_rec(
+                &format!("{} errors occurred comparing coverage output.", coverage_errors),
+                &proc_res,
+            );
+        }
+    }
+
+    /// Run any doctests embedded in this test file, and add any resulting
+    /// `.profraw` files and doctest executables to the given vectors.
+    fn run_doctests_for_coverage(
+        &self,
+        profraw_paths: &mut Vec<PathBuf>,
+        bin_paths: &mut Vec<PathBuf>,
+    ) {
+        // Put .profraw files and doctest executables in dedicated directories,
+        // to make it easier to glob them all later.
+        let profraws_dir = self.output_base_dir().join("doc_profraws");
+        let bins_dir = self.output_base_dir().join("doc_bins");
+
+        // Remove existing directories to prevent cross-run interference.
+        if profraws_dir.try_exists().unwrap() {
+            std::fs::remove_dir_all(&profraws_dir).unwrap();
+        }
+        if bins_dir.try_exists().unwrap() {
+            std::fs::remove_dir_all(&bins_dir).unwrap();
+        }
+
+        let mut rustdoc_cmd =
+            Command::new(self.config.rustdoc_path.as_ref().expect("--rustdoc-path not passed"));
+
+        // In general there will be multiple doctest binaries running, so we
+        // tell the profiler runtime to write their coverage data into separate
+        // profraw files.
+        rustdoc_cmd.env("LLVM_PROFILE_FILE", profraws_dir.join("%p-%m.profraw"));
+
+        rustdoc_cmd.args(["--test", "-Cinstrument-coverage"]);
+
+        // Without this, the doctests complain about not being able to find
+        // their enclosing file's crate for some reason.
+        rustdoc_cmd.args(["--crate-name", "workaround_for_79771"]);
+
+        // Persist the doctest binaries so that `llvm-cov show` can read their
+        // embedded coverage mappings later.
+        rustdoc_cmd.arg("-Zunstable-options");
+        rustdoc_cmd.arg("--persist-doctests");
+        rustdoc_cmd.arg(&bins_dir);
+
+        rustdoc_cmd.arg("-L");
+        rustdoc_cmd.arg(self.aux_output_dir_name());
+
+        rustdoc_cmd.arg(&self.testpaths.file);
+
+        let proc_res = self.compose_and_run_compiler(rustdoc_cmd, None);
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("rustdoc --test failed!", &proc_res)
+        }
+
+        fn glob_iter(path: impl AsRef<Path>) -> impl Iterator<Item = PathBuf> {
+            let path_str = path.as_ref().to_str().unwrap();
+            let iter = glob(path_str).unwrap();
+            iter.map(Result::unwrap)
+        }
+
+        // Find all profraw files in the profraw directory.
+        for p in glob_iter(profraws_dir.join("*.profraw")) {
+            profraw_paths.push(p);
+        }
+        // Find all executables in the `--persist-doctests` directory, while
+        // avoiding other file types (e.g. `.pdb` on Windows). This doesn't
+        // need to be perfect, as long as it can handle the files actually
+        // produced by `rustdoc --test`.
+        for p in glob_iter(bins_dir.join("**/*")) {
+            let is_bin = p.is_file()
+                && match p.extension() {
+                    None => true,
+                    Some(ext) => ext == OsStr::new("exe"),
+                };
+            if is_bin {
+                bin_paths.push(p);
+            }
+        }
+    }
+
+    fn run_llvm_tool(&self, name: &str, configure_cmd_fn: impl FnOnce(&mut Command)) -> ProcRes {
+        let tool_path = self
+            .config
+            .llvm_bin_dir
+            .as_ref()
+            .expect("this test expects the LLVM bin dir to be available")
+            .join(name);
+
+        let mut cmd = Command::new(tool_path);
+        configure_cmd_fn(&mut cmd);
+
+        let output = cmd.output().unwrap_or_else(|_| panic!("failed to exec `{cmd:?}`"));
+
+        let proc_res = ProcRes {
+            status: output.status,
+            stdout: String::from_utf8(output.stdout).unwrap(),
+            stderr: String::from_utf8(output.stderr).unwrap(),
+            cmdline: format!("{cmd:?}"),
+        };
+        self.dump_output(&proc_res.stdout, &proc_res.stderr);
+
+        proc_res
+    }
+
+    fn normalize_coverage_output(&self, coverage: &str) -> Result<String, String> {
+        let normalized = self.normalize_output(coverage, &[]);
+
+        let mut lines = normalized.lines().collect::<Vec<_>>();
+
+        Self::sort_coverage_file_sections(&mut lines)?;
+        Self::sort_coverage_subviews(&mut lines)?;
+
+        let joined_lines = lines.iter().flat_map(|line| [line, "\n"]).collect::<String>();
+        Ok(joined_lines)
+    }
+
+    /// Coverage reports can describe multiple source files, separated by
+    /// blank lines. The order of these files is unpredictable (since it
+    /// depends on implementation details), so we need to sort the file
+    /// sections into a consistent order before comparing against a snapshot.
+    fn sort_coverage_file_sections(coverage_lines: &mut Vec<&str>) -> Result<(), String> {
+        // Group the lines into file sections, separated by blank lines.
+        let mut sections = coverage_lines.split(|line| line.is_empty()).collect::<Vec<_>>();
+
+        // The last section should be empty, representing an extra trailing blank line.
+        if !sections.last().is_some_and(|last| last.is_empty()) {
+            return Err("coverage report should end with an extra blank line".to_owned());
+        }
+
+        // Sort the file sections (not including the final empty "section").
+        let except_last = sections.len() - 1;
+        (&mut sections[..except_last]).sort();
+
+        // Join the file sections back into a flat list of lines, with
+        // sections separated by blank lines.
+        let joined = sections.join(&[""] as &[_]);
+        assert_eq!(joined.len(), coverage_lines.len());
+        *coverage_lines = joined;
+
+        Ok(())
+    }
+
+    fn sort_coverage_subviews(coverage_lines: &mut Vec<&str>) -> Result<(), String> {
+        let mut output_lines = Vec::new();
+
+        // We accumulate a list of zero or more "subviews", where each
+        // subview is a list of one or more lines.
+        let mut subviews: Vec<Vec<&str>> = Vec::new();
+
+        fn flush<'a>(subviews: &mut Vec<Vec<&'a str>>, output_lines: &mut Vec<&'a str>) {
+            if subviews.is_empty() {
+                return;
+            }
+
+            // Take and clear the list of accumulated subviews.
+            let mut subviews = std::mem::take(subviews);
+
+            // The last "subview" should be just a boundary line on its own,
+            // so exclude it when sorting the other subviews.
+            let except_last = subviews.len() - 1;
+            (&mut subviews[..except_last]).sort();
+
+            for view in subviews {
+                for line in view {
+                    output_lines.push(line);
+                }
+            }
+        }
+
+        for (line, line_num) in coverage_lines.iter().zip(1..) {
+            if line.starts_with("  ------------------") {
+                // This is a subview boundary line, so start a new subview.
+                subviews.push(vec![line]);
+            } else if line.starts_with("  |") {
+                // Add this line to the current subview.
+                subviews
+                    .last_mut()
+                    .ok_or(format!(
+                        "unexpected subview line outside of a subview on line {line_num}"
+                    ))?
+                    .push(line);
+            } else {
+                // This line is not part of a subview, so sort and print any
+                // accumulated subviews, and then print the line as-is.
+                flush(&mut subviews, &mut output_lines);
+                output_lines.push(line);
+            }
+        }
+
+        flush(&mut subviews, &mut output_lines);
+        assert!(subviews.is_empty());
+
+        assert_eq!(output_lines.len(), coverage_lines.len());
+        *coverage_lines = output_lines;
+
+        Ok(())
+    }
+
     fn run_pretty_test(&self) {
         if self.props.pp_exact.is_some() {
             logv(self.config, "testing for exact pretty-printing".to_owned());
@@ -1598,7 +1889,26 @@ impl<'test> TestCx<'test> {
     }
 
     fn exec_compiled_test(&self) -> ProcRes {
-        let env = &self.props.exec_env;
+        self.exec_compiled_test_general(&[], true)
+    }
+
+    fn exec_compiled_test_general(
+        &self,
+        env_extra: &[(&str, &str)],
+        delete_after_success: bool,
+    ) -> ProcRes {
+        let prepare_env = |cmd: &mut Command| {
+            for key in &self.props.unset_exec_env {
+                cmd.env_remove(key);
+            }
+
+            for (key, val) in &self.props.exec_env {
+                cmd.env(key, val);
+            }
+            for (key, val) in env_extra {
+                cmd.env(key, val);
+            }
+        };
 
         let proc_res = match &*self.config.target {
             // This is pretty similar to below, we're transforming:
@@ -1635,10 +1945,7 @@ impl<'test> TestCx<'test> {
                     .args(support_libs)
                     .args(args);
 
-                for key in &self.props.unset_exec_env {
-                    test_client.env_remove(key);
-                }
-                test_client.envs(env.clone());
+                prepare_env(&mut test_client);
 
                 self.compose_and_run(
                     test_client,
@@ -1653,10 +1960,7 @@ impl<'test> TestCx<'test> {
                 let mut wr_run = Command::new("wr-run");
                 wr_run.args(&[&prog]).args(args);
 
-                for key in &self.props.unset_exec_env {
-                    wr_run.env_remove(key);
-                }
-                wr_run.envs(env.clone());
+                prepare_env(&mut wr_run);
 
                 self.compose_and_run(
                     wr_run,
@@ -1671,10 +1975,7 @@ impl<'test> TestCx<'test> {
                 let mut program = Command::new(&prog);
                 program.args(args).current_dir(&self.output_base_dir());
 
-                for key in &self.props.unset_exec_env {
-                    program.env_remove(key);
-                }
-                program.envs(env.clone());
+                prepare_env(&mut program);
 
                 self.compose_and_run(
                     program,
@@ -1685,7 +1986,7 @@ impl<'test> TestCx<'test> {
             }
         };
 
-        if proc_res.status.success() {
+        if delete_after_success && proc_res.status.success() {
             // delete the executable after running it to save space.
             // it is ok if the deletion failed.
             let _ = fs::remove_file(self.make_exe_name());
@@ -1812,6 +2113,7 @@ impl<'test> TestCx<'test> {
             || self.is_vxworks_pure_static()
             || self.config.target.contains("bpf")
             || !self.config.target_cfg().dynamic_linking
+            || self.config.mode == RunCoverage
         {
             // We primarily compile all auxiliary libraries as dynamic libraries
             // to avoid code size bloat and large binaries as much as possible
@@ -1822,6 +2124,10 @@ impl<'test> TestCx<'test> {
             // dynamic libraries so we just go back to building a normal library. Note,
             // however, that for MUSL if the library is built with `force_host` then
             // it's ok to be a dylib as the host should always support dylibs.
+            //
+            // Coverage tests want static linking by default so that coverage
+            // mappings in auxiliary libraries can be merged into the final
+            // executable.
             (false, Some("lib"))
         } else {
             (true, Some("dylib"))
@@ -1999,6 +2305,10 @@ impl<'test> TestCx<'test> {
                     }
                 }
                 DebugInfo => { /* debuginfo tests must be unoptimized */ }
+                RunCoverage => {
+                    // Coverage reports are affected by optimization level, and
+                    // the current snapshots assume no optimization by default.
+                }
                 _ => {
                     rustc.arg("-O");
                 }
@@ -2065,6 +2375,9 @@ impl<'test> TestCx<'test> {
 
                 rustc.arg(dir_opt);
             }
+            RunCoverage => {
+                rustc.arg("-Cinstrument-coverage");
+            }
             RunPassValgrind | Pretty | DebugInfo | Codegen | Rustdoc | RustdocJson | RunMake
             | CodegenUnits | JsDocTest | Assembly => {
                 // do not use JSON output
diff --git a/tests/run-make/coverage/lib/doctest_crate.rs b/tests/run-coverage-rustdoc/auxiliary/doctest_crate.rs
index c3210146d69..c3210146d69 100644
--- a/tests/run-make/coverage/lib/doctest_crate.rs
+++ b/tests/run-coverage-rustdoc/auxiliary/doctest_crate.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.doctest.txt b/tests/run-coverage-rustdoc/doctest.coverage
index 732de652627..0fce73a6048 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.doctest.txt
+++ b/tests/run-coverage-rustdoc/doctest.coverage
@@ -1,4 +1,15 @@
-../coverage/doctest.rs:
+$DIR/auxiliary/doctest_crate.rs:
+    1|       |/// A function run only from within doctests
+    2|      3|pub fn fn_run_in_doctests(conditional: usize) {
+    3|      3|    match conditional {
+    4|      1|        1 => assert_eq!(1, 1), // this is run,
+    5|      1|        2 => assert_eq!(1, 1), // this,
+    6|      1|        3 => assert_eq!(1, 1), // and this too
+    7|      0|        _ => assert_eq!(1, 2), // however this is not
+    8|       |    }
+    9|      3|}
+
+$DIR/doctest.rs:
     1|       |//! This test ensures that code from doctests is properly re-mapped.
     2|       |//! See <https://github.com/rust-lang/rust/issues/79417> for more info.
     3|       |//!
@@ -67,7 +78,7 @@
    63|       |//!     doctest_main()
    64|       |//! }
    65|       |//! ```
-   66|       |
+   66|       |// aux-build:doctest_crate.rs
    67|       |/// doctest attached to fn testing external code:
    68|       |/// ```
    69|      1|/// extern crate doctest_crate;
@@ -102,14 +113,3 @@
    98|       |// what affect it might have on diagnostic messages from the compiler, and whether anyone would care
    99|       |// if the indentation changed. I don't know if there is a more viable solution.
 
-../coverage/lib/doctest_crate.rs:
-    1|       |/// A function run only from within doctests
-    2|      3|pub fn fn_run_in_doctests(conditional: usize) {
-    3|      3|    match conditional {
-    4|      1|        1 => assert_eq!(1, 1), // this is run,
-    5|      1|        2 => assert_eq!(1, 1), // this,
-    6|      1|        3 => assert_eq!(1, 1), // and this too
-    7|      0|        _ => assert_eq!(1, 2), // however this is not
-    8|       |    }
-    9|      3|}
-
diff --git a/tests/run-make/coverage/doctest.rs b/tests/run-coverage-rustdoc/doctest.rs
index ec04ea57063..251b0c291e9 100644
--- a/tests/run-make/coverage/doctest.rs
+++ b/tests/run-coverage-rustdoc/doctest.rs
@@ -63,7 +63,7 @@
 //!     doctest_main()
 //! }
 //! ```
-
+// aux-build:doctest_crate.rs
 /// doctest attached to fn testing external code:
 /// ```
 /// extern crate doctest_crate;
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.abort.txt b/tests/run-coverage/abort.coverage
index a71c58d618d..a71c58d618d 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.abort.txt
+++ b/tests/run-coverage/abort.coverage
diff --git a/tests/run-make/coverage/abort.rs b/tests/run-coverage/abort.rs
index 98264bdc1af..98264bdc1af 100644
--- a/tests/run-make/coverage/abort.rs
+++ b/tests/run-coverage/abort.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.assert.txt b/tests/run-coverage/assert.coverage
index 405688806ea..a7134a149e2 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.assert.txt
+++ b/tests/run-coverage/assert.coverage
@@ -1,5 +1,5 @@
     1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-101
+    2|       |// failure-status: 101
     3|       |
     4|      4|fn might_fail_assert(one_plus_one: u32) {
     5|      4|    println!("does 1 + 1 = {}?", one_plus_one);
diff --git a/tests/run-make/coverage/assert.rs b/tests/run-coverage/assert.rs
index c85f2748eb9..d32a37e078e 100644
--- a/tests/run-make/coverage/assert.rs
+++ b/tests/run-coverage/assert.rs
@@ -1,5 +1,5 @@
 #![allow(unused_assignments)]
-// expect-exit-status-101
+// failure-status: 101
 
 fn might_fail_assert(one_plus_one: u32) {
     println!("does 1 + 1 = {}?", one_plus_one);
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.async.txt b/tests/run-coverage/async.coverage
index 93c1535b06b..93c1535b06b 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.async.txt
+++ b/tests/run-coverage/async.coverage
diff --git a/tests/run-make/coverage/async.rs b/tests/run-coverage/async.rs
index efd9e62d64e..efd9e62d64e 100644
--- a/tests/run-make/coverage/async.rs
+++ b/tests/run-coverage/async.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.async2.txt b/tests/run-coverage/async2.coverage
index 500dde1f269..500dde1f269 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.async2.txt
+++ b/tests/run-coverage/async2.coverage
diff --git a/tests/run-make/coverage/async2.rs b/tests/run-coverage/async2.rs
index 959d48ce9db..959d48ce9db 100644
--- a/tests/run-make/coverage/async2.rs
+++ b/tests/run-coverage/async2.rs
diff --git a/tests/run-make/coverage/lib/inline_always_with_dead_code.rs b/tests/run-coverage/auxiliary/inline_always_with_dead_code.rs
index 2b21dee6ccf..2b21dee6ccf 100644
--- a/tests/run-make/coverage/lib/inline_always_with_dead_code.rs
+++ b/tests/run-coverage/auxiliary/inline_always_with_dead_code.rs
diff --git a/tests/run-make/coverage/lib/unused_mod_helper.rs b/tests/run-coverage/auxiliary/unused_mod_helper.rs
index ae1cc1531ed..ae1cc1531ed 100644
--- a/tests/run-make/coverage/lib/unused_mod_helper.rs
+++ b/tests/run-coverage/auxiliary/unused_mod_helper.rs
diff --git a/tests/run-make/coverage/lib/used_crate.rs b/tests/run-coverage/auxiliary/used_crate.rs
index 8b8b1f7f351..16592d48dda 100644
--- a/tests/run-make/coverage/lib/used_crate.rs
+++ b/tests/run-coverage/auxiliary/used_crate.rs
@@ -1,6 +1,6 @@
 #![allow(unused_assignments, unused_variables)]
-// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
-use std::fmt::Debug;
+// compile-flags: -C opt-level=3
+use std::fmt::Debug; // ^^ validates coverage now works with optimizations
 
 pub fn used_function() {
     // Initialize test constants in a way that cannot be determined at compile time, to ensure
diff --git a/tests/run-make/coverage/lib/used_inline_crate.rs b/tests/run-coverage/auxiliary/used_inline_crate.rs
index 4a052756d4e..8b8e9d5483f 100644
--- a/tests/run-make/coverage/lib/used_inline_crate.rs
+++ b/tests/run-coverage/auxiliary/used_inline_crate.rs
@@ -1,7 +1,7 @@
 #![allow(unused_assignments, unused_variables)]
 
-// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
-
+// compile-flags: -C opt-level=3
+// ^^ validates coverage now works with optimizations
 use std::fmt::Debug;
 
 pub fn used_function() {
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.closure.txt b/tests/run-coverage/closure.coverage
index 002ecec3b91..45d36b72e3a 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.closure.txt
+++ b/tests/run-coverage/closure.coverage
@@ -1,6 +1,6 @@
     1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |// compile-flags: -C opt-level=2 # fix described in rustc_middle/mir/mono.rs
-    3|      1|fn main() {
+    2|       |// compile-flags: -C opt-level=2
+    3|      1|fn main() { // ^^ fix described in rustc_middle/mir/mono.rs
     4|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
     5|      1|    // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
     6|      1|    // dependent conditions.
diff --git a/tests/run-make/coverage/closure.rs b/tests/run-coverage/closure.rs
index 32ec0bcdf8c..eb3a1ebff88 100644
--- a/tests/run-make/coverage/closure.rs
+++ b/tests/run-coverage/closure.rs
@@ -1,6 +1,6 @@
 #![allow(unused_assignments, unused_variables)]
-// compile-flags: -C opt-level=2 # fix described in rustc_middle/mir/mono.rs
-fn main() {
+// compile-flags: -C opt-level=2
+fn main() { // ^^ fix described in rustc_middle/mir/mono.rs
     // Initialize test constants in a way that cannot be determined at compile time, to ensure
     // rustc and LLVM cannot optimize out statements (or coverage counters) downstream from
     // dependent conditions.
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.closure_macro.txt b/tests/run-coverage/closure_macro.coverage
index 87f7014760e..87f7014760e 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.closure_macro.txt
+++ b/tests/run-coverage/closure_macro.coverage
diff --git a/tests/run-make/coverage/closure_macro.rs b/tests/run-coverage/closure_macro.rs
index 5e3b00d1ef5..5e3b00d1ef5 100644
--- a/tests/run-make/coverage/closure_macro.rs
+++ b/tests/run-coverage/closure_macro.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.closure_macro_async.txt b/tests/run-coverage/closure_macro_async.coverage
index 2b5418132c3..2b5418132c3 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.closure_macro_async.txt
+++ b/tests/run-coverage/closure_macro_async.coverage
diff --git a/tests/run-make/coverage/closure_macro_async.rs b/tests/run-coverage/closure_macro_async.rs
index e3e89e9c8b3..e3e89e9c8b3 100644
--- a/tests/run-make/coverage/closure_macro_async.rs
+++ b/tests/run-coverage/closure_macro_async.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.conditions.txt b/tests/run-coverage/conditions.coverage
index 2d8a98a5d0c..2d8a98a5d0c 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.conditions.txt
+++ b/tests/run-coverage/conditions.coverage
diff --git a/tests/run-make/coverage/conditions.rs b/tests/run-coverage/conditions.rs
index 057599d1b47..057599d1b47 100644
--- a/tests/run-make/coverage/conditions.rs
+++ b/tests/run-coverage/conditions.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.continue.txt b/tests/run-coverage/continue.coverage
index bf42924b191..bf42924b191 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.continue.txt
+++ b/tests/run-coverage/continue.coverage
diff --git a/tests/run-make/coverage/continue.rs b/tests/run-coverage/continue.rs
index 624aa98341b..624aa98341b 100644
--- a/tests/run-make/coverage/continue.rs
+++ b/tests/run-coverage/continue.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.dead_code.txt b/tests/run-coverage/dead_code.coverage
index 09ff14c6f27..09ff14c6f27 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.dead_code.txt
+++ b/tests/run-coverage/dead_code.coverage
diff --git a/tests/run-make/coverage/dead_code.rs b/tests/run-coverage/dead_code.rs
index a1285df0ec6..a1285df0ec6 100644
--- a/tests/run-make/coverage/dead_code.rs
+++ b/tests/run-coverage/dead_code.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.drop_trait.txt b/tests/run-coverage/drop_trait.coverage
index fe6a9e93cbf..293001e9590 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.drop_trait.txt
+++ b/tests/run-coverage/drop_trait.coverage
@@ -1,5 +1,5 @@
     1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-1
+    2|       |// failure-status: 1
     3|       |
     4|       |struct Firework {
     5|       |    strength: i32,
diff --git a/tests/run-make/coverage/drop_trait.rs b/tests/run-coverage/drop_trait.rs
index d15bfc0f877..a9b5d1d1e7f 100644
--- a/tests/run-make/coverage/drop_trait.rs
+++ b/tests/run-coverage/drop_trait.rs
@@ -1,5 +1,5 @@
 #![allow(unused_assignments)]
-// expect-exit-status-1
+// failure-status: 1
 
 struct Firework {
     strength: i32,
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.generator.txt b/tests/run-coverage/generator.coverage
index 0fb3808ff2e..0fb3808ff2e 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.generator.txt
+++ b/tests/run-coverage/generator.coverage
diff --git a/tests/run-make/coverage/generator.rs b/tests/run-coverage/generator.rs
index 4319991021e..4319991021e 100644
--- a/tests/run-make/coverage/generator.rs
+++ b/tests/run-coverage/generator.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.generics.txt b/tests/run-coverage/generics.coverage
index 7eb33a29a92..7a7649674ca 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.generics.txt
+++ b/tests/run-coverage/generics.coverage
@@ -1,5 +1,5 @@
     1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-1
+    2|       |// failure-status: 1
     3|       |
     4|       |struct Firework<T> where T: Copy + std::fmt::Display {
     5|       |    strength: T,
diff --git a/tests/run-make/coverage/generics.rs b/tests/run-coverage/generics.rs
index 18b38868496..150ffb9db39 100644
--- a/tests/run-make/coverage/generics.rs
+++ b/tests/run-coverage/generics.rs
@@ -1,5 +1,5 @@
 #![allow(unused_assignments)]
-// expect-exit-status-1
+// failure-status: 1
 
 struct Firework<T> where T: Copy + std::fmt::Display {
     strength: T,
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.if.txt b/tests/run-coverage/if.coverage
index 0c9eff227ed..0c9eff227ed 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.if.txt
+++ b/tests/run-coverage/if.coverage
diff --git a/tests/run-make/coverage/if.rs b/tests/run-coverage/if.rs
index 8ad5042ff7b..8ad5042ff7b 100644
--- a/tests/run-make/coverage/if.rs
+++ b/tests/run-coverage/if.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.if_else.txt b/tests/run-coverage/if_else.coverage
index 4285d318686..4285d318686 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.if_else.txt
+++ b/tests/run-coverage/if_else.coverage
diff --git a/tests/run-make/coverage/if_else.rs b/tests/run-coverage/if_else.rs
index 3244e1e3afd..3244e1e3afd 100644
--- a/tests/run-make/coverage/if_else.rs
+++ b/tests/run-coverage/if_else.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.inline-dead.txt b/tests/run-coverage/inline-dead.coverage
index a59fe1146f4..a59fe1146f4 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.inline-dead.txt
+++ b/tests/run-coverage/inline-dead.coverage
diff --git a/tests/run-make/coverage/inline-dead.rs b/tests/run-coverage/inline-dead.rs
index 854fa062967..854fa062967 100644
--- a/tests/run-make/coverage/inline-dead.rs
+++ b/tests/run-coverage/inline-dead.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.inline.txt b/tests/run-coverage/inline.coverage
index 6f5d1544fa0..6f5d1544fa0 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.inline.txt
+++ b/tests/run-coverage/inline.coverage
diff --git a/tests/run-make/coverage/inline.rs b/tests/run-coverage/inline.rs
index 9cfab9ddbad..9cfab9ddbad 100644
--- a/tests/run-make/coverage/inline.rs
+++ b/tests/run-coverage/inline.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.inner_items.txt b/tests/run-coverage/inner_items.coverage
index 883254a09ba..883254a09ba 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.inner_items.txt
+++ b/tests/run-coverage/inner_items.coverage
diff --git a/tests/run-make/coverage/inner_items.rs b/tests/run-coverage/inner_items.rs
index bcb62b3031c..bcb62b3031c 100644
--- a/tests/run-make/coverage/inner_items.rs
+++ b/tests/run-coverage/inner_items.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.issue-83601.txt b/tests/run-coverage/issue-83601.coverage
index 25c74ab2e70..25c74ab2e70 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.issue-83601.txt
+++ b/tests/run-coverage/issue-83601.coverage
diff --git a/tests/run-make/coverage/issue-83601.rs b/tests/run-coverage/issue-83601.rs
index 0b72a81947c..0b72a81947c 100644
--- a/tests/run-make/coverage/issue-83601.rs
+++ b/tests/run-coverage/issue-83601.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.issue-84561.txt b/tests/run-coverage/issue-84561.coverage
index 4a60432c14c..7a97e353245 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.issue-84561.txt
+++ b/tests/run-coverage/issue-84561.coverage
@@ -1,6 +1,6 @@
     1|       |// This demonstrated Issue #84561: function-like macros produce unintuitive coverage results.
     2|       |
-    3|       |// expect-exit-status-101
+    3|       |// failure-status: 101
     4|     21|#[derive(PartialEq, Eq)]
     5|       |struct Foo(u32);
     6|      1|fn test3() {
diff --git a/tests/run-make/coverage/issue-84561.rs b/tests/run-coverage/issue-84561.rs
index b39a289c45e..facf5b5b4cf 100644
--- a/tests/run-make/coverage/issue-84561.rs
+++ b/tests/run-coverage/issue-84561.rs
@@ -1,6 +1,6 @@
 // This demonstrated Issue #84561: function-like macros produce unintuitive coverage results.
 
-// expect-exit-status-101
+// failure-status: 101
 #[derive(PartialEq, Eq)]
 struct Foo(u32);
 fn test3() {
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.issue-85461.txt b/tests/run-coverage/issue-85461.coverage
index 1aa4a22c33e..d78a4a1129c 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.issue-85461.txt
+++ b/tests/run-coverage/issue-85461.coverage
@@ -1,16 +1,4 @@
-../coverage/issue-85461.rs:
-    1|       |// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
-    2|       |
-    3|       |extern crate inline_always_with_dead_code;
-    4|       |
-    5|       |use inline_always_with_dead_code::{bar, baz};
-    6|       |
-    7|      1|fn main() {
-    8|      1|    bar::call_me();
-    9|      1|    baz::call_me();
-   10|      1|}
-
-../coverage/lib/inline_always_with_dead_code.rs:
+$DIR/auxiliary/inline_always_with_dead_code.rs:
     1|       |// compile-flags: -Cinstrument-coverage -Ccodegen-units=4 -Copt-level=0
     2|       |
     3|       |#![allow(dead_code)]
@@ -34,3 +22,15 @@
    21|      1|    }
    22|       |}
 
+$DIR/issue-85461.rs:
+    1|       |// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
+    2|       |// aux-build:inline_always_with_dead_code.rs
+    3|       |extern crate inline_always_with_dead_code;
+    4|       |
+    5|       |use inline_always_with_dead_code::{bar, baz};
+    6|       |
+    7|      1|fn main() {
+    8|      1|    bar::call_me();
+    9|      1|    baz::call_me();
+   10|      1|}
+
diff --git a/tests/run-make/coverage/issue-85461.rs b/tests/run-coverage/issue-85461.rs
index a1b9ebb1ed3..6f626b4a65b 100644
--- a/tests/run-make/coverage/issue-85461.rs
+++ b/tests/run-coverage/issue-85461.rs
@@ -1,5 +1,5 @@
 // Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)]
-
+// aux-build:inline_always_with_dead_code.rs
 extern crate inline_always_with_dead_code;
 
 use inline_always_with_dead_code::{bar, baz};
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.issue-93054.txt b/tests/run-coverage/issue-93054.coverage
index a1655adedd4..a1655adedd4 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.issue-93054.txt
+++ b/tests/run-coverage/issue-93054.coverage
diff --git a/tests/run-make/coverage/issue-93054.rs b/tests/run-coverage/issue-93054.rs
index c160b3db03f..c160b3db03f 100644
--- a/tests/run-make/coverage/issue-93054.rs
+++ b/tests/run-coverage/issue-93054.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.lazy_boolean.txt b/tests/run-coverage/lazy_boolean.coverage
index bd349df2fbc..bd349df2fbc 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.lazy_boolean.txt
+++ b/tests/run-coverage/lazy_boolean.coverage
diff --git a/tests/run-make/coverage/lazy_boolean.rs b/tests/run-coverage/lazy_boolean.rs
index bb6219e851c..bb6219e851c 100644
--- a/tests/run-make/coverage/lazy_boolean.rs
+++ b/tests/run-coverage/lazy_boolean.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.loop_break_value.txt b/tests/run-coverage/loop_break_value.coverage
index 022fe4c5962..022fe4c5962 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.loop_break_value.txt
+++ b/tests/run-coverage/loop_break_value.coverage
diff --git a/tests/run-make/coverage/loop_break_value.rs b/tests/run-coverage/loop_break_value.rs
index dbc4fad7a23..dbc4fad7a23 100644
--- a/tests/run-make/coverage/loop_break_value.rs
+++ b/tests/run-coverage/loop_break_value.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.loops_branches.txt b/tests/run-coverage/loops_branches.coverage
index b7ad79a2484..b7ad79a2484 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.loops_branches.txt
+++ b/tests/run-coverage/loops_branches.coverage
diff --git a/tests/run-make/coverage/loops_branches.rs b/tests/run-coverage/loops_branches.rs
index 7116ce47f4b..7116ce47f4b 100644
--- a/tests/run-make/coverage/loops_branches.rs
+++ b/tests/run-coverage/loops_branches.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.match_or_pattern.txt b/tests/run-coverage/match_or_pattern.coverage
index a0fccb24f99..a0fccb24f99 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.match_or_pattern.txt
+++ b/tests/run-coverage/match_or_pattern.coverage
diff --git a/tests/run-make/coverage/match_or_pattern.rs b/tests/run-coverage/match_or_pattern.rs
index 4c6a8a9b703..4c6a8a9b703 100644
--- a/tests/run-make/coverage/match_or_pattern.rs
+++ b/tests/run-coverage/match_or_pattern.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.nested_loops.txt b/tests/run-coverage/nested_loops.coverage
index 0dbd6bcf313..0dbd6bcf313 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.nested_loops.txt
+++ b/tests/run-coverage/nested_loops.coverage
diff --git a/tests/run-make/coverage/nested_loops.rs b/tests/run-coverage/nested_loops.rs
index 4c7c7842796..4c7c7842796 100644
--- a/tests/run-make/coverage/nested_loops.rs
+++ b/tests/run-coverage/nested_loops.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.no_cov_crate.txt b/tests/run-coverage/no_cov_crate.coverage
index 83a9204136f..83a9204136f 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.no_cov_crate.txt
+++ b/tests/run-coverage/no_cov_crate.coverage
diff --git a/tests/run-make/coverage/no_cov_crate.rs b/tests/run-coverage/no_cov_crate.rs
index 0bfbdda2cab..0bfbdda2cab 100644
--- a/tests/run-make/coverage/no_cov_crate.rs
+++ b/tests/run-coverage/no_cov_crate.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.overflow.txt b/tests/run-coverage/overflow.coverage
index 25e822bffd1..95043759166 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.overflow.txt
+++ b/tests/run-coverage/overflow.coverage
@@ -1,5 +1,5 @@
     1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-101
+    2|       |// failure-status: 101
     3|       |
     4|      4|fn might_overflow(to_add: u32) -> u32 {
     5|      4|    if to_add > 5 {
diff --git a/tests/run-make/coverage/overflow.rs b/tests/run-coverage/overflow.rs
index e537b0e95c3..7df8de6f3cd 100644
--- a/tests/run-make/coverage/overflow.rs
+++ b/tests/run-coverage/overflow.rs
@@ -1,5 +1,5 @@
 #![allow(unused_assignments)]
-// expect-exit-status-101
+// failure-status: 101
 
 fn might_overflow(to_add: u32) -> u32 {
     if to_add > 5 {
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.panic_unwind.txt b/tests/run-coverage/panic_unwind.coverage
index 114507dc9fd..58b9ba448ee 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.panic_unwind.txt
+++ b/tests/run-coverage/panic_unwind.coverage
@@ -1,5 +1,5 @@
     1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-101
+    2|       |// failure-status: 101
     3|       |
     4|      4|fn might_panic(should_panic: bool) {
     5|      4|    if should_panic {
diff --git a/tests/run-make/coverage/panic_unwind.rs b/tests/run-coverage/panic_unwind.rs
index 03128c2cce6..638d2eb6aaa 100644
--- a/tests/run-make/coverage/panic_unwind.rs
+++ b/tests/run-coverage/panic_unwind.rs
@@ -1,5 +1,5 @@
 #![allow(unused_assignments)]
-// expect-exit-status-101
+// failure-status: 101
 
 fn might_panic(should_panic: bool) {
     if should_panic {
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.partial_eq.txt b/tests/run-coverage/partial_eq.coverage
index a77175af663..a77175af663 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.partial_eq.txt
+++ b/tests/run-coverage/partial_eq.coverage
diff --git a/tests/run-make/coverage/partial_eq.rs b/tests/run-coverage/partial_eq.rs
index 4ceaba9b111..4ceaba9b111 100644
--- a/tests/run-make/coverage/partial_eq.rs
+++ b/tests/run-coverage/partial_eq.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.simple_loop.txt b/tests/run-coverage/simple_loop.coverage
index feb83bad674..feb83bad674 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.simple_loop.txt
+++ b/tests/run-coverage/simple_loop.coverage
diff --git a/tests/run-make/coverage/simple_loop.rs b/tests/run-coverage/simple_loop.rs
index 6f7f23475b8..6f7f23475b8 100644
--- a/tests/run-make/coverage/simple_loop.rs
+++ b/tests/run-coverage/simple_loop.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.simple_match.txt b/tests/run-coverage/simple_match.coverage
index b9298213111..b9298213111 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.simple_match.txt
+++ b/tests/run-coverage/simple_match.coverage
diff --git a/tests/run-make/coverage/simple_match.rs b/tests/run-coverage/simple_match.rs
index be99e59a826..be99e59a826 100644
--- a/tests/run-make/coverage/simple_match.rs
+++ b/tests/run-coverage/simple_match.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.sort_groups.txt b/tests/run-coverage/sort_groups.coverage
index 81468cb35da..81468cb35da 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.sort_groups.txt
+++ b/tests/run-coverage/sort_groups.coverage
diff --git a/tests/run-make/coverage/sort_groups.rs b/tests/run-coverage/sort_groups.rs
index f89f9f3ec61..f89f9f3ec61 100644
--- a/tests/run-make/coverage/sort_groups.rs
+++ b/tests/run-coverage/sort_groups.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.test_harness.txt b/tests/run-coverage/test_harness.coverage
index 93bd1cfcb48..93bd1cfcb48 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.test_harness.txt
+++ b/tests/run-coverage/test_harness.coverage
diff --git a/tests/run-make/coverage/test_harness.rs b/tests/run-coverage/test_harness.rs
index 12a755734c1..12a755734c1 100644
--- a/tests/run-make/coverage/test_harness.rs
+++ b/tests/run-coverage/test_harness.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.tight_inf_loop.txt b/tests/run-coverage/tight_inf_loop.coverage
index 2d4c57f451a..2d4c57f451a 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.tight_inf_loop.txt
+++ b/tests/run-coverage/tight_inf_loop.coverage
diff --git a/tests/run-make/coverage/tight_inf_loop.rs b/tests/run-coverage/tight_inf_loop.rs
index cef99027aaa..cef99027aaa 100644
--- a/tests/run-make/coverage/tight_inf_loop.rs
+++ b/tests/run-coverage/tight_inf_loop.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.try_error_result.txt b/tests/run-coverage/try_error_result.coverage
index 0ad0180b761..efe573a5607 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.try_error_result.txt
+++ b/tests/run-coverage/try_error_result.coverage
@@ -1,5 +1,5 @@
     1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-1
+    2|       |// failure-status: 1
     3|       |
     4|      6|fn call(return_error: bool) -> Result<(),()> {
     5|      6|    if return_error {
diff --git a/tests/run-make/coverage/try_error_result.rs b/tests/run-coverage/try_error_result.rs
index cd0acf72302..9eb1d2db218 100644
--- a/tests/run-make/coverage/try_error_result.rs
+++ b/tests/run-coverage/try_error_result.rs
@@ -1,5 +1,5 @@
 #![allow(unused_assignments)]
-// expect-exit-status-1
+// failure-status: 1
 
 fn call(return_error: bool) -> Result<(),()> {
     if return_error {
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.unused.txt b/tests/run-coverage/unused.coverage
index 15fcf21c0ef..15fcf21c0ef 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.unused.txt
+++ b/tests/run-coverage/unused.coverage
diff --git a/tests/run-make/coverage/unused.rs b/tests/run-coverage/unused.rs
index fb6113eb01c..fb6113eb01c 100644
--- a/tests/run-make/coverage/unused.rs
+++ b/tests/run-coverage/unused.rs
diff --git a/tests/run-coverage/unused_mod.coverage b/tests/run-coverage/unused_mod.coverage
new file mode 100644
index 00000000000..e1d82f66f75
--- /dev/null
+++ b/tests/run-coverage/unused_mod.coverage
@@ -0,0 +1,13 @@
+$DIR/auxiliary/unused_mod_helper.rs:
+    1|      0|pub fn never_called_function() {
+    2|      0|    println!("I am never called");
+    3|      0|}
+
+$DIR/unused_mod.rs:
+    1|       |#[path = "auxiliary/unused_mod_helper.rs"]
+    2|       |mod unused_module;
+    3|       |
+    4|      1|fn main() {
+    5|      1|    println!("hello world!");
+    6|      1|}
+
diff --git a/tests/run-make/coverage/unused_mod.rs b/tests/run-coverage/unused_mod.rs
index 679b4e53188..6e62839c998 100644
--- a/tests/run-make/coverage/unused_mod.rs
+++ b/tests/run-coverage/unused_mod.rs
@@ -1,4 +1,4 @@
-#[path = "lib/unused_mod_helper.rs"]
+#[path = "auxiliary/unused_mod_helper.rs"]
 mod unused_module;
 
 fn main() {
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt b/tests/run-coverage/uses_crate.coverage
index 412f4a93b9c..a3b78e21405 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.uses_crate.txt
+++ b/tests/run-coverage/uses_crate.coverage
@@ -1,6 +1,7 @@
+$DIR/auxiliary/used_crate.rs:
     1|       |#![allow(unused_assignments, unused_variables)]
-    2|       |// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
-    3|       |use std::fmt::Debug;
+    2|       |// compile-flags: -C opt-level=3
+    3|       |use std::fmt::Debug; // ^^ validates coverage now works with optimizations
     4|       |
     5|      1|pub fn used_function() {
     6|      1|    // Initialize test constants in a way that cannot be determined at compile time, to ensure
@@ -146,3 +147,24 @@
    99|       |// functions" list, which would then omit coverage results for
   100|       |// `unused_generic_function<T>()`, below.
 
+$DIR/uses_crate.rs:
+    1|       |// FIXME #110395
+    2|       |// ignore-linux
+    3|       |
+    4|       |// Validates coverage now works with optimizations
+    5|       |// compile-flags: -C opt-level=3
+    6|       |
+    7|       |#![allow(unused_assignments, unused_variables)]
+    8|       |
+    9|       |// aux-build:used_crate.rs
+   10|       |extern crate used_crate;
+   11|       |
+   12|      1|fn main() {
+   13|      1|    used_crate::used_function();
+   14|      1|    let some_vec = vec![1, 2, 3, 4];
+   15|      1|    used_crate::used_only_from_bin_crate_generic_function(&some_vec);
+   16|      1|    used_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
+   17|      1|    used_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
+   18|      1|    used_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function("interesting?");
+   19|      1|}
+
diff --git a/tests/run-make/coverage/uses_crate.rs b/tests/run-coverage/uses_crate.rs
index 1ee8037a1e7..ab466970f8e 100644
--- a/tests/run-make/coverage/uses_crate.rs
+++ b/tests/run-coverage/uses_crate.rs
@@ -1,8 +1,12 @@
 // FIXME #110395
-// ignore-llvm-cov-show-diffs
+// ignore-linux
+
+// Validates coverage now works with optimizations
+// compile-flags: -C opt-level=3
 
 #![allow(unused_assignments, unused_variables)]
-// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
+
+// aux-build:used_crate.rs
 extern crate used_crate;
 
 fn main() {
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt b/tests/run-coverage/uses_inline_crate.coverage
index 66ca9e80a32..f878d8107c5 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.uses_inline_crate.txt
+++ b/tests/run-coverage/uses_inline_crate.coverage
@@ -1,7 +1,8 @@
+$DIR/auxiliary/used_inline_crate.rs:
     1|       |#![allow(unused_assignments, unused_variables)]
     2|       |
-    3|       |// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
-    4|       |
+    3|       |// compile-flags: -C opt-level=3
+    4|       |// ^^ validates coverage now works with optimizations
     5|       |use std::fmt::Debug;
     6|       |
     7|      1|pub fn used_function() {
@@ -137,3 +138,27 @@
    89|      2|    used_only_from_this_lib_crate_generic_function("used ONLY from library used_crate.rs");
    90|      2|}
 
+$DIR/uses_inline_crate.rs:
+    1|       |// FIXME #110395
+    2|       |// ignore-linux
+    3|       |
+    4|       |// Validates coverage now works with optimizations
+    5|       |// compile-flags: -C opt-level=3
+    6|       |
+    7|       |#![allow(unused_assignments, unused_variables)]
+    8|       |
+    9|       |// aux-build:used_inline_crate.rs
+   10|       |extern crate used_inline_crate;
+   11|       |
+   12|      1|fn main() {
+   13|      1|    used_inline_crate::used_function();
+   14|      1|    used_inline_crate::used_inline_function();
+   15|      1|    let some_vec = vec![1, 2, 3, 4];
+   16|      1|    used_inline_crate::used_only_from_bin_crate_generic_function(&some_vec);
+   17|      1|    used_inline_crate::used_only_from_bin_crate_generic_function("used from bin uses_crate.rs");
+   18|      1|    used_inline_crate::used_from_bin_crate_and_lib_crate_generic_function(some_vec);
+   19|      1|    used_inline_crate::used_with_same_type_from_bin_crate_and_lib_crate_generic_function(
+   20|      1|        "interesting?",
+   21|      1|    );
+   22|      1|}
+
diff --git a/tests/run-make/coverage/uses_inline_crate.rs b/tests/run-coverage/uses_inline_crate.rs
index f7aff3c3f8a..4bd66d2f89c 100644
--- a/tests/run-make/coverage/uses_inline_crate.rs
+++ b/tests/run-coverage/uses_inline_crate.rs
@@ -1,10 +1,12 @@
 // FIXME #110395
-// ignore-llvm-cov-show-diffs
+// ignore-linux
 
-#![allow(unused_assignments, unused_variables)]
+// Validates coverage now works with optimizations
+// compile-flags: -C opt-level=3
 
-// compile-flags: -C opt-level=3 # validates coverage now works with optimizations
+#![allow(unused_assignments, unused_variables)]
 
+// aux-build:used_inline_crate.rs
 extern crate used_inline_crate;
 
 fn main() {
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.while.txt b/tests/run-coverage/while.coverage
index efa7d083f0c..efa7d083f0c 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.while.txt
+++ b/tests/run-coverage/while.coverage
diff --git a/tests/run-make/coverage/while.rs b/tests/run-coverage/while.rs
index 781b90b3566..781b90b3566 100644
--- a/tests/run-make/coverage/while.rs
+++ b/tests/run-coverage/while.rs
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.while_early_ret.txt b/tests/run-coverage/while_early_ret.coverage
index d19afc0de61..2ce94e0131d 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.while_early_ret.txt
+++ b/tests/run-coverage/while_early_ret.coverage
@@ -1,5 +1,5 @@
     1|       |#![allow(unused_assignments)]
-    2|       |// expect-exit-status-1
+    2|       |// failure-status: 1
     3|       |
     4|      1|fn main() -> Result<(),u8> {
     5|      1|    let mut countdown = 10;
diff --git a/tests/run-make/coverage/while_early_ret.rs b/tests/run-coverage/while_early_ret.rs
index 1fcea9c85c4..1c83c8fc7a8 100644
--- a/tests/run-make/coverage/while_early_ret.rs
+++ b/tests/run-coverage/while_early_ret.rs
@@ -1,5 +1,5 @@
 #![allow(unused_assignments)]
-// expect-exit-status-1
+// failure-status: 1
 
 fn main() -> Result<(),u8> {
     let mut countdown = 10;
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.yield.txt b/tests/run-coverage/yield.coverage
index 6e2f23ee77b..6e2f23ee77b 100644
--- a/tests/run-make/coverage-reports/expected_show_coverage.yield.txt
+++ b/tests/run-coverage/yield.coverage
diff --git a/tests/run-make/coverage/yield.rs b/tests/run-coverage/yield.rs
index ff7616656ff..ff7616656ff 100644
--- a/tests/run-make/coverage/yield.rs
+++ b/tests/run-coverage/yield.rs
diff --git a/tests/run-make/coverage-llvmir/Makefile b/tests/run-make/coverage-llvmir/Makefile
index 7be65505332..be92f8ac8fc 100644
--- a/tests/run-make/coverage-llvmir/Makefile
+++ b/tests/run-make/coverage-llvmir/Makefile
@@ -6,7 +6,7 @@
 # version during testing, with an additional directive at the top of this file
 # that sets, for example: `min-llvm-version: 12.0`
 
-include ../coverage/coverage_tools.mk
+include ../tools.mk
 
 BASEDIR=../coverage-llvmir
 
diff --git a/tests/run-make/coverage-reports/Makefile b/tests/run-make/coverage-reports/Makefile
deleted file mode 100644
index 0ae409c4119..00000000000
--- a/tests/run-make/coverage-reports/Makefile
+++ /dev/null
@@ -1,178 +0,0 @@
-# needs-profiler-support
-# ignore-windows-gnu
-
-# FIXME(pietroalbini): this test currently does not work on cross-compiled
-# targets because remote-test is not capable of sending back the *.profraw
-# files generated by the LLVM instrumentation.
-# ignore-cross-compile
-
-# Rust coverage maps support LLVM Coverage Mapping Format versions 5 and 6,
-# corresponding with LLVM versions 12 and 13, respectively.
-# When upgrading LLVM versions, consider whether to enforce a minimum LLVM
-# version during testing, with an additional directive at the top of this file
-# that sets, for example: `min-llvm-version: 12.0`
-
-# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
-# properly. Since we only have GCC on the CI ignore the test for now.
-
-include ../coverage/coverage_tools.mk
-
-BASEDIR=../coverage-reports
-SOURCEDIR=../coverage
-
-# The `llvm-cov show` flag `--debug`, used to generate the `counters` output files, is only
-# enabled if LLVM assertions are enabled. This requires Rust config `llvm/optimize` and not
-# `llvm/release_debuginfo`. Note that some CI builds disable debug assertions (by setting
-# `NO_LLVM_ASSERTIONS=1`), so the tests must still pass even if the `--debug` flag is
-# not supported. (Note that `counters` files are only produced in the `$(TMPDIR)`
-# directory, for inspection and debugging support. They are *not* copied to `expected_*`
-# files when `--bless`ed.)
-LLVM_COV_DEBUG := $(shell \
-		"$(LLVM_BIN_DIR)"/llvm-cov show --debug 2>&1 | \
-		grep -q "Unknown command line argument '--debug'"; \
-		echo $$?)
-ifeq ($(LLVM_COV_DEBUG), 1)
-DEBUG_FLAG=--debug
-endif
-
-# FIXME(richkadel): I'm adding `--ignore-filename-regex=` line(s) for specific test(s) that produce
-# `llvm-cov` results for multiple files (for example `uses_crate.rs` and `used_crate/mod.rs`) as a
-# workaround for two problems causing tests to fail on Windows:
-#
-# 1. When multiple files appear in the `llvm-cov show` results, each file's coverage results can
-#    appear in different a different order. Whether this is random or, somehow, platform-specific,
-#    the Windows output flips the order of the files, compared to Linux. In the `uses_crate.rs`
-#    test, the only test-unique (interesting) results we care about are the results for only one
-#    of the two files, `mod/uses_crate.rs`, so the workaround is to ignore all but this one file.
-#    In the future, we may want a more sophisticated solution that splits apart `llvm-cov show`
-#    results into separate results files for each result (taking care not to create new file
-#    paths that might be too long for Windows MAX_PATH limits when creating these new sub-results,
-#    as well).
-# 2. When multiple files appear in the `llvm-cov show` results, the results for each file are
-#    prefixed with their filename, including platform-specific path separators (`\` for Windows,
-#    and `/` everywhere else). This could be filtered or normalized of course, but by ignoring
-#    coverage results for all but one of the file, the filenames are no longer included anyway.
-#    If this changes (if/when we decide to support `llvm-cov show` results for multiple files),
-#    the file path separator differences may need to be addressed.
-#
-# Since this is only a workaround, I decided to implement the override by adding an option for
-# each file to be ignored, using a `--ignore-filename-regex=` entry for each one, rather than
-# implement some more sophisticated solution with a new custom test directive in the test file
-# itself (similar to `expect-exit-status`) because that would add a lot of complexity and still
-# be a workaround, with the same result, with no benefit.
-#
-# Yes these `--ignore-filename-regex=` options are included in all invocations of `llvm-cov show`
-# for now, but it is effectively ignored for all tests that don't include this file anyway.
-#
-# (Note that it's also possible the `_counters.<test>.txt` and `<test>.json` files (if generated)
-# may order results from multiple files inconsistently, which might also have to be accommodated
-# if and when we allow `llvm-cov` to produce results for multiple files. Note, the path separators
-# appear to be normalized to `/` in those files, thankfully.)
-LLVM_COV_IGNORE_FILES=\
-	--ignore-filename-regex='(uses_crate.rs|uses_inline_crate.rs|unused_mod.rs)'
-
-all: $(patsubst $(SOURCEDIR)/lib/%.rs,%,$(wildcard $(SOURCEDIR)/lib/*.rs)) $(patsubst $(SOURCEDIR)/%.rs,%,$(wildcard $(SOURCEDIR)/*.rs))
-
-# Ensure there are no `expected` results for tests that may have been removed or renamed
-.PHONY: clear_expected_if_blessed
-clear_expected_if_blessed:
-ifdef RUSTC_BLESS_TEST
-	rm -f expected_*
-endif
-
--include clear_expected_if_blessed
-
-%: $(SOURCEDIR)/lib/%.rs
-	# Compile the test library with coverage instrumentation
-	$(RUSTC) $(SOURCEDIR)/lib/$@.rs \
-			$$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/lib/$@.rs ) \
-			--crate-type rlib -Cinstrument-coverage --target $(TARGET)
-
-%: $(SOURCEDIR)/%.rs
-	# Compile the test program with coverage instrumentation
-	$(RUSTC) $(SOURCEDIR)/$@.rs \
-			$$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \
-			-L "$(TMPDIR)" -Cinstrument-coverage --target $(TARGET)
-
-	# Run it in order to generate some profiling data,
-	# with `LLVM_PROFILE_FILE=<profdata_file>` environment variable set to
-	# output the coverage stats for this run.
-	LLVM_PROFILE_FILE="$(TMPDIR)"/$@.profraw \
-			$(call RUN,$@) || \
-			( \
-				status=$$?; \
-				grep -q "^\/\/ expect-exit-status-$$status" $(SOURCEDIR)/$@.rs || \
-				( >&2 echo "program exited with an unexpected exit status: $$status"; \
-					false \
-				) \
-			)
-
-	# Run it through rustdoc as well to cover doctests.
-	# `%p` is the pid, and `%m` the binary signature. We suspect that the pid alone
-	# might result in overwritten files and failed tests, as rustdoc spawns each
-	# doctest as its own process, so make sure the filename is as unique as possible.
-	LLVM_PROFILE_FILE="$(TMPDIR)"/$@-%p-%m.profraw \
-			$(RUSTDOC) --crate-name workaround_for_79771 --test $(SOURCEDIR)/$@.rs \
-			$$( sed -n 's/^\/\/ compile-flags: \([^#]*\).*/\1/p' $(SOURCEDIR)/$@.rs ) \
-			-L "$(TMPDIR)" -Cinstrument-coverage \
-			-Z unstable-options --persist-doctests=$(TMPDIR)/rustdoc-$@
-
-	# Postprocess the profiling data so it can be used by the llvm-cov tool
-	"$(LLVM_BIN_DIR)"/llvm-profdata merge --sparse \
-			"$(TMPDIR)"/$@*.profraw \
-			-o "$(TMPDIR)"/$@.profdata
-
-	# Generate a coverage report using `llvm-cov show`.
-	"$(LLVM_BIN_DIR)"/llvm-cov show \
-			$(DEBUG_FLAG) \
-			$(LLVM_COV_IGNORE_FILES) \
-			--compilation-dir=. \
-			--Xdemangler="$(RUST_DEMANGLER)" \
-			--show-line-counts-or-regions \
-			--instr-profile="$(TMPDIR)"/$@.profdata \
-			$(call BIN,"$(TMPDIR)"/$@) \
-			$$( \
-				for file in $(TMPDIR)/rustdoc-$@/*/rust_out*; do \
-				[ -x "$$file" ] && printf "%s %s " -object $$file; \
-				done \
-			) \
-		2> "$(TMPDIR)"/show_coverage_stderr.$@.txt \
-		| "$(PYTHON)" $(BASEDIR)/normalize_paths.py \
-		| "$(PYTHON)" $(BASEDIR)/sort_subviews.py \
-		> "$(TMPDIR)"/actual_show_coverage.$@.txt || \
-	( status=$$? ; \
-		>&2 cat "$(TMPDIR)"/show_coverage_stderr.$@.txt ; \
-		exit $$status \
-	)
-
-ifdef DEBUG_FLAG
-	# The first line (beginning with "Args:" contains hard-coded, build-specific
-	# file paths. Strip that line and keep the remaining lines with counter debug
-	# data.
-	tail -n +2 "$(TMPDIR)"/show_coverage_stderr.$@.txt \
-		> "$(TMPDIR)"/actual_show_coverage_counters.$@.txt
-endif
-
-ifdef RUSTC_BLESS_TEST
-	cp "$(TMPDIR)"/actual_show_coverage.$@.txt \
-			expected_show_coverage.$@.txt
-else
-	# Compare the show coverage output (`--bless` refreshes `typical` files).
-	#
-	# `llvm-cov show` normally prints instantiation groups in an unpredictable
-	# order, but we have used `sort_subviews.py` to sort them, so we can still
-	# check the output directly with `diff`.
-	#
-	# Some of the test cases are currently not working (since #110393) and have
-	# been marked with `// ignore-llvm-cov-show-diffs` so that they don't fail
-	# the build.
-
-	$(DIFF) \
-		expected_show_coverage.$@.txt "$(TMPDIR)"/actual_show_coverage.$@.txt || \
-		( grep -q '^\/\/ ignore-llvm-cov-show-diffs' $(SOURCEDIR)/$@.rs && \
-			>&2 echo 'diff failed, but suppressed with `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs' \
-		) || \
-		( >&2 echo 'diff failed, and not suppressed without `// ignore-llvm-cov-show-diffs` in $(SOURCEDIR)/$@.rs'; \
-			false \
-		)
-endif
diff --git a/tests/run-make/coverage-reports/expected_show_coverage.unused_mod.txt b/tests/run-make/coverage-reports/expected_show_coverage.unused_mod.txt
deleted file mode 100644
index 82d6fccc271..00000000000
--- a/tests/run-make/coverage-reports/expected_show_coverage.unused_mod.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-    1|      0|pub fn never_called_function() {
-    2|      0|    println!("I am never called");
-    3|      0|}
-
diff --git a/tests/run-make/coverage-reports/normalize_paths.py b/tests/run-make/coverage-reports/normalize_paths.py
deleted file mode 100755
index e5777ad2512..00000000000
--- a/tests/run-make/coverage-reports/normalize_paths.py
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import print_function
-
-import sys
-
-# Normalize file paths in output
-for line in sys.stdin:
-    if line.startswith("..") and line.rstrip().endswith(".rs:"):
-        print(line.replace("\\", "/"), end='')
-    else:
-        print(line, end='')
diff --git a/tests/run-make/coverage-reports/sort_subviews.py b/tests/run-make/coverage-reports/sort_subviews.py
deleted file mode 100755
index 10cfc51d447..00000000000
--- a/tests/run-make/coverage-reports/sort_subviews.py
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/env python3
-
-# `llvm-cov show` prints grouped subviews (e.g. for generic functions) in an
-# unstable order, which is inconvenient when checking output snapshots with
-# `diff`. To work around that, this script detects consecutive subviews in its
-# piped input, and sorts them while preserving their contents.
-
-from __future__ import print_function
-
-import sys
-
-
-def main():
-    subviews = []
-
-    def flush_subviews():
-        if not subviews:
-            return
-
-        # The last "subview" should be just a boundary line on its own, so
-        # temporarily remove it before sorting the accumulated subviews.
-        terminator = subviews.pop()
-        subviews.sort()
-        subviews.append(terminator)
-
-        for view in subviews:
-            for line in view:
-                print(line, end="")
-
-        subviews.clear()
-
-    for line in sys.stdin:
-        if line.startswith("  ------------------"):
-            # This is a subview boundary line, so start a new subview.
-            subviews.append([line])
-        elif line.startswith("  |"):
-            # Add this line to the current subview.
-            subviews[-1].append(line)
-        else:
-            # This line is not part of a subview, so sort and print any
-            # accumulated subviews, and then print the line as-is.
-            flush_subviews()
-            print(line, end="")
-
-    flush_subviews()
-    assert not subviews
-
-
-if __name__ == "__main__":
-    main()
diff --git a/tests/run-make/coverage/WARNING_KEEP_NAMES_SHORT.txt b/tests/run-make/coverage/WARNING_KEEP_NAMES_SHORT.txt
deleted file mode 100644
index 6a1403b8a00..00000000000
--- a/tests/run-make/coverage/WARNING_KEEP_NAMES_SHORT.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-IMPORTANT: The Rust test programs in this directory generate various output
-files in the `../coverage*` directories (`expected` and `actual` files).
-
-Microsoft Windows has a relatively short limit on file paths (not individual
-path components, but the entire path). The files generated by these
-`../coverage*` tests typically have file paths that include the program
-source file name plus function and type names (depending on the program).
-
-Keep the test file names short, and keep function names and other symbols
-short as well, to avoid hitting the Windows limits.
diff --git a/tests/run-make/coverage/compiletest-ignore-dir b/tests/run-make/coverage/compiletest-ignore-dir
deleted file mode 100644
index 470ff996098..00000000000
--- a/tests/run-make/coverage/compiletest-ignore-dir
+++ /dev/null
@@ -1,3 +0,0 @@
-# Directory "coverage" supports the tests at prefix ../coverage-*
-
-# Use ./x.py [options] test tests/run-make/coverage to run all related tests.
diff --git a/tests/run-make/coverage/coverage_tools.mk b/tests/run-make/coverage/coverage_tools.mk
deleted file mode 100644
index 028c020a461..00000000000
--- a/tests/run-make/coverage/coverage_tools.mk
+++ /dev/null
@@ -1,6 +0,0 @@
-# Common Makefile include for Rust `run-make/coverage-* tests. Include this
-# file with the line:
-#
-# include ../coverage/coverage_tools.mk
-
-include ../tools.mk
diff --git a/tests/ui/associated-inherent-types/private-in-public.rs b/tests/ui/associated-inherent-types/private-in-public.rs
index 33b84fc9506..e9e189f95c9 100644
--- a/tests/ui/associated-inherent-types/private-in-public.rs
+++ b/tests/ui/associated-inherent-types/private-in-public.rs
@@ -12,12 +12,15 @@
 pub type PubAlias0 = PubTy::PrivAssocTy;
 //~^ ERROR private associated type `PubTy::PrivAssocTy` in public interface (error E0446)
 //~| WARNING this was previously accepted
+//~| WARNING associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0`
 pub type PubAlias1 = PrivTy::PubAssocTy;
 //~^ ERROR private type `PrivTy` in public interface (error E0446)
 //~| WARNING this was previously accepted
+//~| WARNING type `PrivTy` is more private than the item `PubAlias1`
 pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
 //~^ ERROR private type `PrivTy` in public interface (error E0446)
 //~| WARNING this was previously accepted
+//~| WARNING type `PrivTy` is more private than the item `PubAlias2`
 
 pub struct PubTy;
 impl PubTy {
diff --git a/tests/ui/associated-inherent-types/private-in-public.stderr b/tests/ui/associated-inherent-types/private-in-public.stderr
index d40db83707b..65d187c1bcd 100644
--- a/tests/ui/associated-inherent-types/private-in-public.stderr
+++ b/tests/ui/associated-inherent-types/private-in-public.stderr
@@ -13,14 +13,13 @@ LL | #![deny(private_in_public)]
    |         ^^^^^^^^^^^^^^^^^
 
 warning: associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0`
-   |
-note: type alias `PubAlias0` is reachable at visibility `pub`
   --> $DIR/private-in-public.rs:12:1
    |
 LL | pub type PubAlias0 = PubTy::PrivAssocTy;
-   | ^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^ type alias `PubAlias0` is reachable at visibility `pub`
+   |
 note: but associated type `PubTy::PrivAssocTy` is only usable at visibility `pub(crate)`
-  --> $DIR/private-in-public.rs:24:5
+  --> $DIR/private-in-public.rs:27:5
    |
 LL |     type PrivAssocTy = ();
    |     ^^^^^^^^^^^^^^^^
@@ -31,7 +30,7 @@ LL | #![warn(private_interfaces)]
    |         ^^^^^^^^^^^^^^^^^^
 
 error: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/private-in-public.rs:15:1
+  --> $DIR/private-in-public.rs:16:1
    |
 LL | pub type PubAlias1 = PrivTy::PubAssocTy;
    | ^^^^^^^^^^^^^^^^^^
@@ -40,20 +39,19 @@ LL | pub type PubAlias1 = PrivTy::PubAssocTy;
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 
 warning: type `PrivTy` is more private than the item `PubAlias1`
-   |
-note: type alias `PubAlias1` is reachable at visibility `pub`
-  --> $DIR/private-in-public.rs:15:1
+  --> $DIR/private-in-public.rs:16:1
    |
 LL | pub type PubAlias1 = PrivTy::PubAssocTy;
-   | ^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^ type alias `PubAlias1` is reachable at visibility `pub`
+   |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
-  --> $DIR/private-in-public.rs:28:1
+  --> $DIR/private-in-public.rs:31:1
    |
 LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
 error: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/private-in-public.rs:18:1
+  --> $DIR/private-in-public.rs:20:1
    |
 LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
    | ^^^^^^^^^^^^^^^^^^
@@ -62,14 +60,13 @@ LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 
 warning: type `PrivTy` is more private than the item `PubAlias2`
-   |
-note: type alias `PubAlias2` is reachable at visibility `pub`
-  --> $DIR/private-in-public.rs:18:1
+  --> $DIR/private-in-public.rs:20:1
    |
 LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
-   | ^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^ type alias `PubAlias2` is reachable at visibility `pub`
+   |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
-  --> $DIR/private-in-public.rs:28:1
+  --> $DIR/private-in-public.rs:31:1
    |
 LL | struct PrivTy;
    | ^^^^^^^^^^^^^
diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
index 5c43213e898..e5464a4253f 100644
--- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
+++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs
@@ -21,6 +21,7 @@ where
 {
     type AssocTy = Const<{ my_const_fn(U) }>;
     //~^ ERROR private type
+    //~| WARNING type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
     fn assoc_fn() -> Self::AssocTy {
         Const
     }
diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr
index 465621619b4..16fae6b5c63 100644
--- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr
@@ -8,14 +8,13 @@ LL | const fn my_const_fn(val: u8) -> u8 {
    | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
 
 warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
-   |
-note: associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub`
   --> $DIR/eval-privacy.rs:22:5
    |
 LL |     type AssocTy = Const<{ my_const_fn(U) }>;
-   |     ^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^ associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub`
+   |
 note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)`
-  --> $DIR/eval-privacy.rs:29:1
+  --> $DIR/eval-privacy.rs:30:1
    |
 LL | const fn my_const_fn(val: u8) -> u8 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/error-codes/E0445.rs b/tests/ui/error-codes/E0445.rs
index 30c222ae6f2..9f29c81673e 100644
--- a/tests/ui/error-codes/E0445.rs
+++ b/tests/ui/error-codes/E0445.rs
@@ -12,9 +12,12 @@ trait Foo {
 
 pub trait Bar : Foo {}
 //~^ ERROR private trait `Foo` in public interface [E0445]
+//~| WARNING trait `Foo` is more private than the item `Bar`
 pub struct Bar2<T: Foo>(pub T);
 //~^ ERROR private trait `Foo` in public interface [E0445]
+//~| WARNING trait `Foo` is more private than the item `Bar2`
 pub fn foo<T: Foo> (t: T) {}
 //~^ ERROR private trait `Foo` in public interface [E0445]
+//~| WARNING trait `Foo` is more private than the item `foo`
 
 fn main() {}
diff --git a/tests/ui/error-codes/E0445.stderr b/tests/ui/error-codes/E0445.stderr
index ba2c21485ef..4f940868ff9 100644
--- a/tests/ui/error-codes/E0445.stderr
+++ b/tests/ui/error-codes/E0445.stderr
@@ -8,12 +8,11 @@ LL | pub trait Bar : Foo {}
    | ^^^^^^^^^^^^^^^^^^^ can't leak private trait
 
 warning: trait `Foo` is more private than the item `Bar`
-   |
-note: trait `Bar` is reachable at visibility `pub`
   --> $DIR/E0445.rs:13:1
    |
 LL | pub trait Bar : Foo {}
-   | ^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^ trait `Bar` is reachable at visibility `pub`
+   |
 note: but trait `Foo` is only usable at visibility `pub(crate)`
   --> $DIR/E0445.rs:9:1
    |
@@ -26,7 +25,7 @@ LL | #[warn(private_bounds)]
    |        ^^^^^^^^^^^^^^
 
 error[E0445]: private trait `Foo` in public interface
-  --> $DIR/E0445.rs:15:1
+  --> $DIR/E0445.rs:16:1
    |
 LL | trait Foo {
    | --------- `Foo` declared as private
@@ -35,12 +34,11 @@ LL | pub struct Bar2<T: Foo>(pub T);
    | ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
 
 warning: trait `Foo` is more private than the item `Bar2`
-   |
-note: struct `Bar2` is reachable at visibility `pub`
-  --> $DIR/E0445.rs:15:1
+  --> $DIR/E0445.rs:16:1
    |
 LL | pub struct Bar2<T: Foo>(pub T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^ struct `Bar2` is reachable at visibility `pub`
+   |
 note: but trait `Foo` is only usable at visibility `pub(crate)`
   --> $DIR/E0445.rs:9:1
    |
@@ -48,7 +46,7 @@ LL | trait Foo {
    | ^^^^^^^^^
 
 error[E0445]: private trait `Foo` in public interface
-  --> $DIR/E0445.rs:17:1
+  --> $DIR/E0445.rs:19:1
    |
 LL | trait Foo {
    | --------- `Foo` declared as private
@@ -57,12 +55,11 @@ LL | pub fn foo<T: Foo> (t: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
 
 warning: trait `Foo` is more private than the item `foo`
-   |
-note: function `foo` is reachable at visibility `pub`
-  --> $DIR/E0445.rs:17:1
+  --> $DIR/E0445.rs:19:1
    |
 LL | pub fn foo<T: Foo> (t: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^ function `foo` is reachable at visibility `pub`
+   |
 note: but trait `Foo` is only usable at visibility `pub(crate)`
   --> $DIR/E0445.rs:9:1
    |
diff --git a/tests/ui/imports/issue-56125.stderr b/tests/ui/imports/issue-56125.stderr
index 3448f311977..15477fb6f10 100644
--- a/tests/ui/imports/issue-56125.stderr
+++ b/tests/ui/imports/issue-56125.stderr
@@ -22,7 +22,7 @@ error[E0659]: `issue_56125` is ambiguous
 LL |     use issue_56125::last_segment::*;
    |         ^^^^^^^^^^^ ambiguous name
    |
-   = note: ambiguous because of multiple potential import sources
+   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    = note: `issue_56125` could refer to a crate passed with `--extern`
    = help: use `::issue_56125` to refer to this crate unambiguously
 note: `issue_56125` could also refer to the module imported here
@@ -30,7 +30,8 @@ note: `issue_56125` could also refer to the module imported here
    |
 LL |     use issue_56125::last_segment::*;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: use `self::issue_56125` to refer to this module unambiguously
+   = help: consider adding an explicit import of `issue_56125` to disambiguate
+   = help: or use `self::issue_56125` to refer to this module unambiguously
 
 error[E0659]: `issue_56125` is ambiguous
   --> $DIR/issue-56125.rs:11:9
@@ -38,7 +39,7 @@ error[E0659]: `issue_56125` is ambiguous
 LL |     use issue_56125::non_last_segment::non_last_segment::*;
    |         ^^^^^^^^^^^ ambiguous name
    |
-   = note: ambiguous because of multiple potential import sources
+   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    = note: `issue_56125` could refer to a crate passed with `--extern`
    = help: use `::issue_56125` to refer to this crate unambiguously
 note: `issue_56125` could also refer to the module imported here
@@ -46,7 +47,8 @@ note: `issue_56125` could also refer to the module imported here
    |
 LL |     use issue_56125::non_last_segment::non_last_segment::*;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: use `self::issue_56125` to refer to this module unambiguously
+   = help: consider adding an explicit import of `issue_56125` to disambiguate
+   = help: or use `self::issue_56125` to refer to this module unambiguously
 
 error[E0659]: `issue_56125` is ambiguous
   --> $DIR/issue-56125.rs:18:9
@@ -54,7 +56,7 @@ error[E0659]: `issue_56125` is ambiguous
 LL |     use issue_56125::*;
    |         ^^^^^^^^^^^ ambiguous name
    |
-   = note: ambiguous because of multiple potential import sources
+   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    = note: `issue_56125` could refer to a crate passed with `--extern`
    = help: use `::issue_56125` to refer to this crate unambiguously
 note: `issue_56125` could also refer to the module imported here
@@ -62,7 +64,8 @@ note: `issue_56125` could also refer to the module imported here
    |
 LL |     use issue_56125::*;
    |         ^^^^^^^^^^^^^^
-   = help: use `self::issue_56125` to refer to this module unambiguously
+   = help: consider adding an explicit import of `issue_56125` to disambiguate
+   = help: or use `self::issue_56125` to refer to this module unambiguously
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/imports/issue-57539.stderr b/tests/ui/imports/issue-57539.stderr
index 1a3ca4edaca..88cc42ccf66 100644
--- a/tests/ui/imports/issue-57539.stderr
+++ b/tests/ui/imports/issue-57539.stderr
@@ -4,7 +4,7 @@ error[E0659]: `core` is ambiguous
 LL |     use core;
    |         ^^^^ ambiguous name
    |
-   = note: ambiguous because of multiple potential import sources
+   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    = note: `core` could refer to a built-in crate
    = help: use `::core` to refer to this crate unambiguously
 note: `core` could also refer to the module imported here
@@ -12,7 +12,8 @@ note: `core` could also refer to the module imported here
    |
 LL |     use crate::*;
    |         ^^^^^^^^
-   = help: use `self::core` to refer to this module unambiguously
+   = help: consider adding an explicit import of `core` to disambiguate
+   = help: or use `self::core` to refer to this module unambiguously
 
 error: aborting due to previous error
 
diff --git a/tests/ui/issues/issue-18389.rs b/tests/ui/issues/issue-18389.rs
index 0af693c4e0f..05a5decf462 100644
--- a/tests/ui/issues/issue-18389.rs
+++ b/tests/ui/issues/issue-18389.rs
@@ -13,6 +13,7 @@ trait Private<P, R> {
 }
 pub trait Public: Private<
 //~^ ERROR private trait `Private<<Self as Public>::P, <Self as Public>::R>` in public interface
+//~| WARNING trait `Private<<Self as Public>::P, <Self as Public>::R>` is more private than the item `Public`
     <Self as Public>::P,
     <Self as Public>::R
 > {
diff --git a/tests/ui/issues/issue-18389.stderr b/tests/ui/issues/issue-18389.stderr
index 6b78151c606..18ffc4177d7 100644
--- a/tests/ui/issues/issue-18389.stderr
+++ b/tests/ui/issues/issue-18389.stderr
@@ -6,22 +6,23 @@ LL |   trait Private<P, R> {
 ...
 LL | / pub trait Public: Private<
 LL | |
+LL | |
 LL | |     <Self as Public>::P,
 LL | |     <Self as Public>::R
 LL | | > {
    | |_^ can't leak private trait
 
 warning: trait `Private<<Self as Public>::P, <Self as Public>::R>` is more private than the item `Public`
-   |
-note: trait `Public` is reachable at visibility `pub`
   --> $DIR/issue-18389.rs:14:1
    |
 LL | / pub trait Public: Private<
 LL | |
+LL | |
 LL | |     <Self as Public>::P,
 LL | |     <Self as Public>::R
 LL | | > {
-   | |_^
+   | |_^ trait `Public` is reachable at visibility `pub`
+   |
 note: but trait `Private<<Self as Public>::P, <Self as Public>::R>` is only usable at visibility `pub(crate)`
   --> $DIR/issue-18389.rs:11:1
    |
diff --git a/tests/ui/privacy/private-in-public-non-principal.rs b/tests/ui/privacy/private-in-public-non-principal.rs
index 9ae7512c509..a2284c93027 100644
--- a/tests/ui/privacy/private-in-public-non-principal.rs
+++ b/tests/ui/privacy/private-in-public-non-principal.rs
@@ -13,6 +13,7 @@ auto trait PrivNonPrincipal {}
 pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
 //~^ WARN private trait `PrivNonPrincipal` in public interface
 //~| WARN this was previously accepted
+//~| ERROR trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal`
 
 #[deny(missing_docs)]
 fn container() {
diff --git a/tests/ui/privacy/private-in-public-non-principal.stderr b/tests/ui/privacy/private-in-public-non-principal.stderr
index 9fc12affe4b..1387f59cbde 100644
--- a/tests/ui/privacy/private-in-public-non-principal.stderr
+++ b/tests/ui/privacy/private-in-public-non-principal.stderr
@@ -9,12 +9,11 @@ LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal>
    = note: `#[warn(private_in_public)]` on by default
 
 error: trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal`
-   |
-note: function `leak_dyn_nonprincipal` is reachable at visibility `pub`
   --> $DIR/private-in-public-non-principal.rs:13:1
    |
 LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `leak_dyn_nonprincipal` is reachable at visibility `pub`
+   |
 note: but trait `PrivNonPrincipal` is only usable at visibility `pub(crate)`
   --> $DIR/private-in-public-non-principal.rs:11:1
    |
@@ -27,13 +26,13 @@ LL | #![deny(private_interfaces)]
    |         ^^^^^^^^^^^^^^^^^^
 
 error: missing documentation for an associated function
-  --> $DIR/private-in-public-non-principal.rs:20:9
+  --> $DIR/private-in-public-non-principal.rs:21:9
    |
 LL |         pub fn check_doc_lint() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/private-in-public-non-principal.rs:17:8
+  --> $DIR/private-in-public-non-principal.rs:18:8
    |
 LL | #[deny(missing_docs)]
    |        ^^^^^^^^^^^^
diff --git a/tests/ui/privacy/where-priv-type.rs b/tests/ui/privacy/where-priv-type.rs
index 468d6e98a74..2e0a6b3e72c 100644
--- a/tests/ui/privacy/where-priv-type.rs
+++ b/tests/ui/privacy/where-priv-type.rs
@@ -25,6 +25,7 @@ impl PubTrWithAssocTy for PrivTy { type AssocTy = PrivTy; }
 pub struct S
 //~^ WARNING private type `PrivTy` in public interface
 //~| WARNING hard error
+//~| WARNING type `PrivTy` is more private than the item `S`
 where
     PrivTy:
 {}
@@ -33,6 +34,7 @@ where
 pub enum E
 //~^ WARNING private type `PrivTy` in public interface
 //~| WARNING hard error
+//~| WARNING type `PrivTy` is more private than the item `E`
 where
     PrivTy:
 {}
@@ -41,6 +43,7 @@ where
 pub fn f()
 //~^ WARNING private type `PrivTy` in public interface
 //~| WARNING hard error
+//~| WARNING type `PrivTy` is more private than the item `f`
 where
     PrivTy:
 {}
@@ -48,12 +51,14 @@ where
 
 impl S
 //~^ ERROR private type `PrivTy` in public interface
+//~| WARNING type `PrivTy` is more private than the item `S`
 where
     PrivTy:
 {
     pub fn f()
     //~^ WARNING private type `PrivTy` in public interface
     //~| WARNING hard error
+    //~| WARNING type `PrivTy` is more private than the item `S::f`
     where
         PrivTy:
     {}
@@ -85,6 +90,7 @@ where
 {
     type AssocTy = Const<{ my_const_fn(U) }>;
     //~^ ERROR private type
+    //~| WARNING type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
     fn assoc_fn() -> Self::AssocTy {
         Const
     }
diff --git a/tests/ui/privacy/where-priv-type.stderr b/tests/ui/privacy/where-priv-type.stderr
index 2830fa6cd44..d6baf22b3fb 100644
--- a/tests/ui/privacy/where-priv-type.stderr
+++ b/tests/ui/privacy/where-priv-type.stderr
@@ -9,12 +9,11 @@ LL | pub struct S
    = note: `#[warn(private_in_public)]` on by default
 
 warning: type `PrivTy` is more private than the item `S`
-   |
-note: struct `S` is reachable at visibility `pub`
   --> $DIR/where-priv-type.rs:25:1
    |
 LL | pub struct S
-   | ^^^^^^^^^^^^
+   | ^^^^^^^^^^^^ struct `S` is reachable at visibility `pub`
+   |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
   --> $DIR/where-priv-type.rs:15:1
    |
@@ -27,7 +26,7 @@ LL | #![warn(private_bounds)]
    |         ^^^^^^^^^^^^^^
 
 warning: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/where-priv-type.rs:33:1
+  --> $DIR/where-priv-type.rs:34:1
    |
 LL | pub enum E
    | ^^^^^^^^^^
@@ -36,12 +35,11 @@ LL | pub enum E
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 
 warning: type `PrivTy` is more private than the item `E`
-   |
-note: enum `E` is reachable at visibility `pub`
-  --> $DIR/where-priv-type.rs:33:1
+  --> $DIR/where-priv-type.rs:34:1
    |
 LL | pub enum E
-   | ^^^^^^^^^^
+   | ^^^^^^^^^^ enum `E` is reachable at visibility `pub`
+   |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
   --> $DIR/where-priv-type.rs:15:1
    |
@@ -49,11 +47,12 @@ LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
 warning: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/where-priv-type.rs:41:1
+  --> $DIR/where-priv-type.rs:43:1
    |
 LL | / pub fn f()
 LL | |
 LL | |
+LL | |
 LL | | where
 LL | |     PrivTy:
    | |___________^
@@ -62,16 +61,16 @@ LL | |     PrivTy:
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 
 warning: type `PrivTy` is more private than the item `f`
-   |
-note: function `f` is reachable at visibility `pub`
-  --> $DIR/where-priv-type.rs:41:1
+  --> $DIR/where-priv-type.rs:43:1
    |
 LL | / pub fn f()
 LL | |
 LL | |
+LL | |
 LL | | where
 LL | |     PrivTy:
-   | |___________^
+   | |___________^ function `f` is reachable at visibility `pub`
+   |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
   --> $DIR/where-priv-type.rs:15:1
    |
@@ -79,7 +78,7 @@ LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
 error[E0446]: private type `PrivTy` in public interface
-  --> $DIR/where-priv-type.rs:49:1
+  --> $DIR/where-priv-type.rs:52:1
    |
 LL | struct PrivTy;
    | ------------- `PrivTy` declared as private
@@ -88,12 +87,11 @@ LL | impl S
    | ^^^^^^ can't leak private type
 
 warning: type `PrivTy` is more private than the item `S`
-   |
-note: implementation `S` is reachable at visibility `pub`
-  --> $DIR/where-priv-type.rs:49:1
+  --> $DIR/where-priv-type.rs:52:1
    |
 LL | impl S
-   | ^^^^^^
+   | ^^^^^^ implementation `S` is reachable at visibility `pub`
+   |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
   --> $DIR/where-priv-type.rs:15:1
    |
@@ -101,11 +99,12 @@ LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
 warning: private type `PrivTy` in public interface (error E0446)
-  --> $DIR/where-priv-type.rs:54:5
+  --> $DIR/where-priv-type.rs:58:5
    |
 LL | /     pub fn f()
 LL | |
 LL | |
+LL | |
 LL | |     where
 LL | |         PrivTy:
    | |_______________^
@@ -114,16 +113,16 @@ LL | |         PrivTy:
    = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
 
 warning: type `PrivTy` is more private than the item `S::f`
-   |
-note: associated function `S::f` is reachable at visibility `pub`
-  --> $DIR/where-priv-type.rs:54:5
+  --> $DIR/where-priv-type.rs:58:5
    |
 LL | /     pub fn f()
 LL | |
 LL | |
+LL | |
 LL | |     where
 LL | |         PrivTy:
-   | |_______________^
+   | |_______________^ associated function `S::f` is reachable at visibility `pub`
+   |
 note: but type `PrivTy` is only usable at visibility `pub(crate)`
   --> $DIR/where-priv-type.rs:15:1
    |
@@ -131,7 +130,7 @@ LL | struct PrivTy;
    | ^^^^^^^^^^^^^
 
 error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
-  --> $DIR/where-priv-type.rs:86:5
+  --> $DIR/where-priv-type.rs:91:5
    |
 LL |     type AssocTy = Const<{ my_const_fn(U) }>;
    |     ^^^^^^^^^^^^ can't leak private type
@@ -140,14 +139,13 @@ LL | const fn my_const_fn(val: u8) -> u8 {
    | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
 
 warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
-   |
-note: associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub`
-  --> $DIR/where-priv-type.rs:86:5
+  --> $DIR/where-priv-type.rs:91:5
    |
 LL |     type AssocTy = Const<{ my_const_fn(U) }>;
-   |     ^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^ associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub`
+   |
 note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)`
-  --> $DIR/where-priv-type.rs:93:1
+  --> $DIR/where-priv-type.rs:99:1
    |
 LL | const fn my_const_fn(val: u8) -> u8 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/privacy/where-pub-type-impls-priv-trait.rs b/tests/ui/privacy/where-pub-type-impls-priv-trait.rs
index 35e33bcb3b7..c59fdb7c7a9 100644
--- a/tests/ui/privacy/where-pub-type-impls-priv-trait.rs
+++ b/tests/ui/privacy/where-pub-type-impls-priv-trait.rs
@@ -23,6 +23,7 @@ impl PubTrWithAssocTy for PrivTy { type AssocTy = PrivTy; }
 
 pub struct S
 //~^ ERROR private trait `PrivTr` in public interface
+//~| WARNING trait `PrivTr` is more private than the item `S`
 where
     PubTy: PrivTr
 {}
@@ -30,6 +31,7 @@ where
 
 pub enum E
 //~^ ERROR private trait `PrivTr` in public interface
+//~| WARNING trait `PrivTr` is more private than the item `E`
 where
     PubTy: PrivTr
 {}
@@ -37,6 +39,7 @@ where
 
 pub fn f()
 //~^ ERROR private trait `PrivTr` in public interface
+//~| WARNING trait `PrivTr` is more private than the item `f`
 where
     PubTy: PrivTr
 {}
@@ -44,11 +47,13 @@ where
 
 impl S
 //~^ ERROR private trait `PrivTr` in public interface
+//~| WARNING trait `PrivTr` is more private than the item `S`
 where
     PubTy: PrivTr
 {
     pub fn f()
     //~^ ERROR private trait `PrivTr` in public interface
+    //~| WARNING trait `PrivTr` is more private than the item `S::f`
     where
         PubTy: PrivTr
     {}
diff --git a/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr b/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr
index 413f7f781cd..e2d7ce44692 100644
--- a/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr
+++ b/tests/ui/privacy/where-pub-type-impls-priv-trait.stderr
@@ -8,12 +8,11 @@ LL | pub struct S
    | ^^^^^^^^^^^^ can't leak private trait
 
 warning: trait `PrivTr` is more private than the item `S`
-   |
-note: struct `S` is reachable at visibility `pub`
   --> $DIR/where-pub-type-impls-priv-trait.rs:24:1
    |
 LL | pub struct S
-   | ^^^^^^^^^^^^
+   | ^^^^^^^^^^^^ struct `S` is reachable at visibility `pub`
+   |
 note: but trait `PrivTr` is only usable at visibility `pub(crate)`
   --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
    |
@@ -26,7 +25,7 @@ LL | #![warn(private_bounds)]
    |         ^^^^^^^^^^^^^^
 
 error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:31:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:32:1
    |
 LL | trait PrivTr {}
    | ------------ `PrivTr` declared as private
@@ -35,12 +34,11 @@ LL | pub enum E
    | ^^^^^^^^^^ can't leak private trait
 
 warning: trait `PrivTr` is more private than the item `E`
-   |
-note: enum `E` is reachable at visibility `pub`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:31:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:32:1
    |
 LL | pub enum E
-   | ^^^^^^^^^^
+   | ^^^^^^^^^^ enum `E` is reachable at visibility `pub`
+   |
 note: but trait `PrivTr` is only usable at visibility `pub(crate)`
   --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
    |
@@ -48,27 +46,28 @@ LL | trait PrivTr {}
    | ^^^^^^^^^^^^
 
 error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:38:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:40:1
    |
 LL |   trait PrivTr {}
    |   ------------ `PrivTr` declared as private
 ...
 LL | / pub fn f()
 LL | |
+LL | |
 LL | | where
 LL | |     PubTy: PrivTr
    | |_________________^ can't leak private trait
 
 warning: trait `PrivTr` is more private than the item `f`
-   |
-note: function `f` is reachable at visibility `pub`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:38:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:40:1
    |
 LL | / pub fn f()
 LL | |
+LL | |
 LL | | where
 LL | |     PubTy: PrivTr
-   | |_________________^
+   | |_________________^ function `f` is reachable at visibility `pub`
+   |
 note: but trait `PrivTr` is only usable at visibility `pub(crate)`
   --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
    |
@@ -76,7 +75,7 @@ LL | trait PrivTr {}
    | ^^^^^^^^^^^^
 
 error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:45:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:48:1
    |
 LL | trait PrivTr {}
    | ------------ `PrivTr` declared as private
@@ -85,12 +84,11 @@ LL | impl S
    | ^^^^^^ can't leak private trait
 
 warning: trait `PrivTr` is more private than the item `S`
-   |
-note: implementation `S` is reachable at visibility `pub`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:45:1
+  --> $DIR/where-pub-type-impls-priv-trait.rs:48:1
    |
 LL | impl S
-   | ^^^^^^
+   | ^^^^^^ implementation `S` is reachable at visibility `pub`
+   |
 note: but trait `PrivTr` is only usable at visibility `pub(crate)`
   --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
    |
@@ -98,27 +96,28 @@ LL | trait PrivTr {}
    | ^^^^^^^^^^^^
 
 error[E0445]: private trait `PrivTr` in public interface
-  --> $DIR/where-pub-type-impls-priv-trait.rs:50:5
+  --> $DIR/where-pub-type-impls-priv-trait.rs:54:5
    |
 LL |   trait PrivTr {}
    |   ------------ `PrivTr` declared as private
 ...
 LL | /     pub fn f()
 LL | |
+LL | |
 LL | |     where
 LL | |         PubTy: PrivTr
    | |_____________________^ can't leak private trait
 
 warning: trait `PrivTr` is more private than the item `S::f`
-   |
-note: associated function `S::f` is reachable at visibility `pub`
-  --> $DIR/where-pub-type-impls-priv-trait.rs:50:5
+  --> $DIR/where-pub-type-impls-priv-trait.rs:54:5
    |
 LL | /     pub fn f()
 LL | |
+LL | |
 LL | |     where
 LL | |         PubTy: PrivTr
-   | |_____________________^
+   | |_____________________^ associated function `S::f` is reachable at visibility `pub`
+   |
 note: but trait `PrivTr` is only usable at visibility `pub(crate)`
   --> $DIR/where-pub-type-impls-priv-trait.rs:14:1
    |
diff --git a/tests/ui/proc-macro/derive-helper-shadowing.rs b/tests/ui/proc-macro/derive-helper-shadowing.rs
index 80d982d2504..4f25b4b0dca 100644
--- a/tests/ui/proc-macro/derive-helper-shadowing.rs
+++ b/tests/ui/proc-macro/derive-helper-shadowing.rs
@@ -23,7 +23,7 @@ macro_rules! gen_helper_use {
 struct S {
     #[empty_helper] // OK, no ambiguity, derive helpers have highest priority
     field: [u8; {
-        use empty_helper; //~ ERROR `empty_helper` is ambiguous
+        use empty_helper; // OK, no ambiguity, derive helpers have highest priority
 
         #[empty_helper] // OK, no ambiguity, derive helpers have highest priority
         struct U;
diff --git a/tests/ui/proc-macro/derive-helper-shadowing.stderr b/tests/ui/proc-macro/derive-helper-shadowing.stderr
index 566c4130846..f284b1c54dd 100644
--- a/tests/ui/proc-macro/derive-helper-shadowing.stderr
+++ b/tests/ui/proc-macro/derive-helper-shadowing.stderr
@@ -38,25 +38,6 @@ LL +             use crate::empty_helper;
    |
 
 error[E0659]: `empty_helper` is ambiguous
-  --> $DIR/derive-helper-shadowing.rs:26:13
-   |
-LL |         use empty_helper;
-   |             ^^^^^^^^^^^^ ambiguous name
-   |
-   = note: ambiguous because of multiple potential import sources
-note: `empty_helper` could refer to the derive helper attribute defined here
-  --> $DIR/derive-helper-shadowing.rs:22:10
-   |
-LL | #[derive(Empty)]
-   |          ^^^^^
-note: `empty_helper` could also refer to the attribute macro imported here
-  --> $DIR/derive-helper-shadowing.rs:10:5
-   |
-LL | use test_macros::empty_attr as empty_helper;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = help: use `crate::empty_helper` to refer to this attribute macro unambiguously
-
-error[E0659]: `empty_helper` is ambiguous
   --> $DIR/derive-helper-shadowing.rs:19:3
    |
 LL | #[empty_helper]
@@ -88,6 +69,6 @@ LL | #[derive(Empty)]
    = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202>
    = note: `#[warn(legacy_derive_helpers)]` on by default
 
-error: aborting due to 5 previous errors; 1 warning emitted
+error: aborting due to 4 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0659`.
diff --git a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs
index bd8f6585f48..cdeea6224b2 100644
--- a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs
+++ b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.rs
@@ -27,14 +27,17 @@ pub struct Shell<T> {
 
 pub type Helix_pomatia = Shell<Snail>;
 //~^ ERROR private type `Snail` in public interface
+//~| WARNING type `Snail` is more private than the item `Helix_pomatia`
 //~| NOTE can't leak private type
 //~| NOTE type alias `Helix_pomatia` is reachable at visibility `pub`
 pub type Dermochelys_coriacea = Shell<sea::Turtle>;
 //~^ ERROR crate-private type `Turtle` in public interface
+//~| WARNING type `Turtle` is more private than the item `Dermochelys_coriacea`
 //~| NOTE can't leak crate-private type
 //~| NOTE type alias `Dermochelys_coriacea` is reachable at visibility `pub`
 pub type Testudo_graeca = Shell<Tortoise>;
 //~^ ERROR private type `Tortoise` in public interface
+//~| WARNING type `Tortoise` is more private than the item `Testudo_graeca`
 //~| NOTE can't leak private type
 //~| NOTE type alias `Testudo_graeca` is reachable at visibility `pub`
 
diff --git a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr
index 5ebda47558c..20e51e1901f 100644
--- a/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr
+++ b/tests/ui/pub/issue-33174-restricted-type-in-public-interface.stderr
@@ -8,12 +8,11 @@ LL | pub type Helix_pomatia = Shell<Snail>;
    | ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
 
 warning: type `Snail` is more private than the item `Helix_pomatia`
-   |
-note: type alias `Helix_pomatia` is reachable at visibility `pub`
   --> $DIR/issue-33174-restricted-type-in-public-interface.rs:28:1
    |
 LL | pub type Helix_pomatia = Shell<Snail>;
-   | ^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^ type alias `Helix_pomatia` is reachable at visibility `pub`
+   |
 note: but type `Snail` is only usable at visibility `pub(crate)`
   --> $DIR/issue-33174-restricted-type-in-public-interface.rs:10:1
    |
@@ -26,7 +25,7 @@ LL | #![warn(private_interfaces)]
    |         ^^^^^^^^^^^^^^^^^^
 
 error[E0446]: crate-private type `Turtle` in public interface
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:32:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:33:1
    |
 LL |     pub(super) struct Turtle;
    |     ------------------------ `Turtle` declared as crate-private
@@ -35,12 +34,11 @@ LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak crate-private type
 
 warning: type `Turtle` is more private than the item `Dermochelys_coriacea`
-   |
-note: type alias `Dermochelys_coriacea` is reachable at visibility `pub`
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:32:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:33:1
    |
 LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type alias `Dermochelys_coriacea` is reachable at visibility `pub`
+   |
 note: but type `Turtle` is only usable at visibility `pub(crate)`
   --> $DIR/issue-33174-restricted-type-in-public-interface.rs:15:5
    |
@@ -48,7 +46,7 @@ LL |     pub(super) struct Turtle;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0446]: private type `Tortoise` in public interface
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:36:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:38:1
    |
 LL | struct Tortoise;
    | --------------- `Tortoise` declared as private
@@ -57,12 +55,11 @@ LL | pub type Testudo_graeca = Shell<Tortoise>;
    | ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
 
 warning: type `Tortoise` is more private than the item `Testudo_graeca`
-   |
-note: type alias `Testudo_graeca` is reachable at visibility `pub`
-  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:36:1
+  --> $DIR/issue-33174-restricted-type-in-public-interface.rs:38:1
    |
 LL | pub type Testudo_graeca = Shell<Tortoise>;
-   | ^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^ type alias `Testudo_graeca` is reachable at visibility `pub`
+   |
 note: but type `Tortoise` is only usable at visibility `pub(crate)`
   --> $DIR/issue-33174-restricted-type-in-public-interface.rs:20:1
    |
diff --git a/tests/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr b/tests/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr
index 7e008d46574..a5c79366bf0 100644
--- a/tests/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr
+++ b/tests/ui/rust-2018/uniform-paths/ambiguity-macros-nested.stderr
@@ -4,7 +4,7 @@ error[E0659]: `std` is ambiguous
 LL |     pub use std::io;
    |             ^^^ ambiguous name
    |
-   = note: ambiguous because of multiple potential import sources
+   = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
    = note: `std` could refer to a built-in crate
    = help: use `::std` to refer to this crate unambiguously
 note: `std` could also refer to the module defined here
diff --git a/tests/ui/rust-2018/uniform-paths/ambiguity-macros.stderr b/tests/ui/rust-2018/uniform-paths/ambiguity-macros.stderr
index 771d2c10c1d..8045f3a45b6 100644
--- a/tests/ui/rust-2018/uniform-paths/ambiguity-macros.stderr
+++ b/tests/ui/rust-2018/uniform-paths/ambiguity-macros.stderr
@@ -4,7 +4,7 @@ error[E0659]: `std` is ambiguous
 LL | use std::io;
    |     ^^^ ambiguous name
    |
-   = note: ambiguous because of multiple potential import sources
+   = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution
    = note: `std` could refer to a built-in crate
    = help: use `::std` to refer to this crate unambiguously
 note: `std` could also refer to the module defined here
diff --git a/tests/ui/rust-2018/uniform-paths/ambiguity-nested.rs b/tests/ui/rust-2018/uniform-paths/ambiguity-nested.rs
index 50c8fc8229c..0ef580d7aa5 100644
--- a/tests/ui/rust-2018/uniform-paths/ambiguity-nested.rs
+++ b/tests/ui/rust-2018/uniform-paths/ambiguity-nested.rs
@@ -1,3 +1,4 @@
+// check-pass
 // edition:2018
 
 // This test is similar to `ambiguity.rs`, but nested in a module.
@@ -5,8 +6,7 @@
 #![allow(non_camel_case_types)]
 
 mod foo {
-    pub use std::io;
-    //~^ ERROR `std` is ambiguous
+    pub use std::io; // OK
 
     mod std {
         pub struct io;
diff --git a/tests/ui/rust-2018/uniform-paths/ambiguity-nested.stderr b/tests/ui/rust-2018/uniform-paths/ambiguity-nested.stderr
deleted file mode 100644
index defb16f7970..00000000000
--- a/tests/ui/rust-2018/uniform-paths/ambiguity-nested.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0659]: `std` is ambiguous
-  --> $DIR/ambiguity-nested.rs:8:13
-   |
-LL |     pub use std::io;
-   |             ^^^ ambiguous name
-   |
-   = note: ambiguous because of multiple potential import sources
-   = note: `std` could refer to a built-in crate
-   = help: use `::std` to refer to this crate unambiguously
-note: `std` could also refer to the module defined here
-  --> $DIR/ambiguity-nested.rs:11:5
-   |
-LL | /     mod std {
-LL | |         pub struct io;
-LL | |     }
-   | |_____^
-   = help: use `self::std` to refer to this module unambiguously
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0659`.
diff --git a/tests/ui/rust-2018/uniform-paths/ambiguity.rs b/tests/ui/rust-2018/uniform-paths/ambiguity.rs
index 60f77a1c663..890e8b7b3c0 100644
--- a/tests/ui/rust-2018/uniform-paths/ambiguity.rs
+++ b/tests/ui/rust-2018/uniform-paths/ambiguity.rs
@@ -1,9 +1,9 @@
+// check-pass
 // edition:2018
 
 #![allow(non_camel_case_types)]
 
-use std::io;
-//~^ ERROR `std` is ambiguous
+use std::io; // OK
 
 mod std {
     pub struct io;
diff --git a/tests/ui/rust-2018/uniform-paths/ambiguity.stderr b/tests/ui/rust-2018/uniform-paths/ambiguity.stderr
deleted file mode 100644
index 2d735c7e3fd..00000000000
--- a/tests/ui/rust-2018/uniform-paths/ambiguity.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0659]: `std` is ambiguous
-  --> $DIR/ambiguity.rs:5:5
-   |
-LL | use std::io;
-   |     ^^^ ambiguous name
-   |
-   = note: ambiguous because of multiple potential import sources
-   = note: `std` could refer to a built-in crate
-   = help: use `::std` to refer to this crate unambiguously
-note: `std` could also refer to the module defined here
-  --> $DIR/ambiguity.rs:8:1
-   |
-LL | / mod std {
-LL | |     pub struct io;
-LL | | }
-   | |_^
-   = help: use `crate::std` to refer to this module unambiguously
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0659`.
diff --git a/tests/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs b/tests/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs
index 3f5897901a0..4cba0949802 100644
--- a/tests/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs
+++ b/tests/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs
@@ -1,3 +1,4 @@
+// check-pass
 // edition:2018
 
 mod my {
@@ -13,7 +14,7 @@ mod sub {
 fn foo() {
     use my::sub;
     {
-        use sub::bar; //~ ERROR `sub` is ambiguous
+        use sub::bar; // OK
     }
 }
 
diff --git a/tests/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr b/tests/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr
deleted file mode 100644
index 3d45a814029..00000000000
--- a/tests/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr
+++ /dev/null
@@ -1,24 +0,0 @@
-error[E0659]: `sub` is ambiguous
-  --> $DIR/block-scoped-shadow-nested.rs:16:13
-   |
-LL |         use sub::bar;
-   |             ^^^ ambiguous name
-   |
-   = note: ambiguous because of multiple potential import sources
-note: `sub` could refer to the module imported here
-  --> $DIR/block-scoped-shadow-nested.rs:14:9
-   |
-LL |     use my::sub;
-   |         ^^^^^^^
-note: `sub` could also refer to the module defined here
-  --> $DIR/block-scoped-shadow-nested.rs:9:1
-   |
-LL | / mod sub {
-LL | |     pub fn bar() {}
-LL | | }
-   | |_^
-   = help: use `crate::sub` to refer to this module unambiguously
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0659`.
diff --git a/tests/ui/rust-2018/uniform-paths/block-scoped-shadow.rs b/tests/ui/rust-2018/uniform-paths/block-scoped-shadow.rs
index 828ee4fe474..c902d133e7c 100644
--- a/tests/ui/rust-2018/uniform-paths/block-scoped-shadow.rs
+++ b/tests/ui/rust-2018/uniform-paths/block-scoped-shadow.rs
@@ -1,3 +1,4 @@
+// check-pass
 // edition:2018
 
 #![allow(non_camel_case_types)]
@@ -8,14 +9,11 @@ struct std;
 
 fn main() {
     enum Foo { A, B }
-    use Foo::*;
-    //~^ ERROR `Foo` is ambiguous
+    use Foo::*; // OK
 
     let _ = (A, B);
 
     fn std() {}
     enum std {}
-    use std as foo;
-    //~^ ERROR `std` is ambiguous
-    //~| ERROR `std` is ambiguous
+    use std as foo; // OK
 }
diff --git a/tests/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr b/tests/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr
deleted file mode 100644
index b068312cedd..00000000000
--- a/tests/ui/rust-2018/uniform-paths/block-scoped-shadow.stderr
+++ /dev/null
@@ -1,60 +0,0 @@
-error[E0659]: `Foo` is ambiguous
-  --> $DIR/block-scoped-shadow.rs:11:9
-   |
-LL |     use Foo::*;
-   |         ^^^ ambiguous name
-   |
-   = note: ambiguous because of multiple potential import sources
-note: `Foo` could refer to the enum defined here
-  --> $DIR/block-scoped-shadow.rs:10:5
-   |
-LL |     enum Foo { A, B }
-   |     ^^^^^^^^^^^^^^^^^
-note: `Foo` could also refer to the enum defined here
-  --> $DIR/block-scoped-shadow.rs:5:1
-   |
-LL | enum Foo {}
-   | ^^^^^^^^^^^
-   = help: use `crate::Foo` to refer to this enum unambiguously
-
-error[E0659]: `std` is ambiguous
-  --> $DIR/block-scoped-shadow.rs:18:9
-   |
-LL |     use std as foo;
-   |         ^^^ ambiguous name
-   |
-   = note: ambiguous because of multiple potential import sources
-note: `std` could refer to the enum defined here
-  --> $DIR/block-scoped-shadow.rs:17:5
-   |
-LL |     enum std {}
-   |     ^^^^^^^^^^^
-note: `std` could also refer to the struct defined here
-  --> $DIR/block-scoped-shadow.rs:7:1
-   |
-LL | struct std;
-   | ^^^^^^^^^^^
-   = help: use `crate::std` to refer to this struct unambiguously
-
-error[E0659]: `std` is ambiguous
-  --> $DIR/block-scoped-shadow.rs:18:9
-   |
-LL |     use std as foo;
-   |         ^^^ ambiguous name
-   |
-   = note: ambiguous because of multiple potential import sources
-note: `std` could refer to the function defined here
-  --> $DIR/block-scoped-shadow.rs:16:5
-   |
-LL |     fn std() {}
-   |     ^^^^^^^^^^^
-note: `std` could also refer to the unit struct defined here
-  --> $DIR/block-scoped-shadow.rs:7:1
-   |
-LL | struct std;
-   | ^^^^^^^^^^^
-   = help: use `crate::std` to refer to this unit struct unambiguously
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0659`.
diff --git a/tests/ui/rust-2018/uniform-paths/issue-56596.stderr b/tests/ui/rust-2018/uniform-paths/issue-56596.stderr
index 8b8ab26dce2..849d6275eb8 100644
--- a/tests/ui/rust-2018/uniform-paths/issue-56596.stderr
+++ b/tests/ui/rust-2018/uniform-paths/issue-56596.stderr
@@ -4,7 +4,7 @@ error[E0659]: `issue_56596` is ambiguous
 LL | use issue_56596;
    |     ^^^^^^^^^^^ ambiguous name
    |
-   = note: ambiguous because of multiple potential import sources
+   = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution
    = note: `issue_56596` could refer to a crate passed with `--extern`
    = help: use `::issue_56596` to refer to this crate unambiguously
 note: `issue_56596` could also refer to the module imported here
@@ -12,7 +12,8 @@ note: `issue_56596` could also refer to the module imported here
    |
 LL | use m::*;
    |     ^^^^
-   = help: use `crate::issue_56596` to refer to this module unambiguously
+   = help: consider adding an explicit import of `issue_56596` to disambiguate
+   = help: or use `crate::issue_56596` to refer to this module unambiguously
 
 error: aborting due to previous error
 
diff --git a/tests/ui/rust-2018/uniform-paths/macro-rules.rs b/tests/ui/rust-2018/uniform-paths/macro-rules.rs
index 2d9a6a9a924..1084f5e8b34 100644
--- a/tests/ui/rust-2018/uniform-paths/macro-rules.rs
+++ b/tests/ui/rust-2018/uniform-paths/macro-rules.rs
@@ -27,8 +27,7 @@ mod m3 {
     fn f() {
         macro_rules! legacy_macro { () => () }
 
-        // Legacy macro imports create ambiguities with other names in the same namespace.
-        use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous
+        use legacy_macro as _; // OK
     }
 }
 
diff --git a/tests/ui/rust-2018/uniform-paths/macro-rules.stderr b/tests/ui/rust-2018/uniform-paths/macro-rules.stderr
index 9f8c928c32c..8a978c98a44 100644
--- a/tests/ui/rust-2018/uniform-paths/macro-rules.stderr
+++ b/tests/ui/rust-2018/uniform-paths/macro-rules.stderr
@@ -10,26 +10,6 @@ help: consider adding a `#[macro_export]` to the macro in the imported module
 LL |     macro_rules! legacy_macro { () => () }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0659]: `legacy_macro` is ambiguous
-  --> $DIR/macro-rules.rs:31:13
-   |
-LL |         use legacy_macro as _;
-   |             ^^^^^^^^^^^^ ambiguous name
-   |
-   = note: ambiguous because of multiple potential import sources
-note: `legacy_macro` could refer to the macro defined here
-  --> $DIR/macro-rules.rs:28:9
-   |
-LL |         macro_rules! legacy_macro { () => () }
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: `legacy_macro` could also refer to the macro defined here
-  --> $DIR/macro-rules.rs:25:5
-   |
-LL |     macro legacy_macro() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
-   = help: use `self::legacy_macro` to refer to this macro unambiguously
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0364, E0659.
-For more information about an error, try `rustc --explain E0364`.
+For more information about this error, try `rustc --explain E0364`.