about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig11
-rw-r--r--.github/workflows/ci.yml6
-rw-r--r--.github/workflows/dependencies.yml4
-rw-r--r--.github/workflows/ghcr.yml2
-rw-r--r--.github/workflows/post-merge.yml2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs21
-rw-r--r--compiler/rustc_expand/src/expand.rs1
-rw-r--r--compiler/rustc_lint/messages.ftl1
-rw-r--r--compiler/rustc_lint/src/early/diagnostics.rs10
-rw-r--r--compiler/rustc_lint/src/lints.rs3
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs7
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs2
-rw-r--r--compiler/rustc_mir_transform/src/cross_crate_inline.rs2
-rw-r--r--compiler/rustc_passes/messages.ftl1
-rw-r--r--compiler/rustc_passes/src/check_attr.rs38
-rw-r--r--compiler/rustc_passes/src/dead.rs2
-rw-r--r--compiler/rustc_passes/src/errors.rs2
-rw-r--r--compiler/rustc_passes/src/reachable.rs5
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs55
-rw-r--r--library/core/src/alloc/layout.rs8
-rw-r--r--library/core/src/ascii/ascii_char.rs612
-rw-r--r--library/core/src/ptr/mod.rs16
-rw-r--r--library/core/src/ptr/non_null.rs8
-rw-r--r--library/core/src/ptr/unique.rs8
-rw-r--r--library/std/src/lib.rs6
-rw-r--r--library/std/src/panic.rs2
-rw-r--r--library/std/src/path.rs3
-rw-r--r--library/std/src/sys/pal/hermit/time.rs32
-rw-r--r--library/std/src/sys/pal/sgx/time.rs15
-rw-r--r--library/std/src/sys/pal/solid/time.rs9
-rw-r--r--library/std/src/sys/pal/uefi/time.rs27
-rw-r--r--library/std/src/sys/pal/unix/time.rs30
-rw-r--r--library/std/src/sys/pal/unsupported/time.rs15
-rw-r--r--library/std/src/sys/pal/wasi/time.rs25
-rw-r--r--library/std/src/sys/pal/windows/time.rs30
-rw-r--r--library/std/src/sys/pal/xous/time.rs15
-rw-r--r--library/std/src/time.rs30
-rw-r--r--library/std/tests/path.rs8
-rw-r--r--library/test/src/cli.rs17
-rw-r--r--src/bootstrap/src/bin/rustc.rs2
-rw-r--r--src/bootstrap/src/bin/rustdoc.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs38
-rw-r--r--src/bootstrap/src/core/build_steps/clean.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/clippy.rs57
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs73
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs33
-rw-r--r--src/bootstrap/src/core/build_steps/install.rs8
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs91
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs40
-rw-r--r--src/bootstrap/src/core/builder/mod.rs2
-rw-r--r--src/bootstrap/src/lib.rs139
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/shared_helpers.rs5
-rw-r--r--src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile2
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh2
-rw-r--r--src/ci/github-actions/jobs.yml2
-rw-r--r--src/doc/rustc-dev-guide/src/building/optimized-build.md2
-rw-r--r--src/doc/rustc/src/tests/index.md8
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs2
-rw-r--r--src/tools/clippy/tests/missing-test-files.rs2
-rw-r--r--src/tools/miri/src/bin/miri.rs2
-rw-r--r--src/tools/miri/src/helpers.rs2
-rw-r--r--tests/run-make/wasm-panic-small/rmake.rs2
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs5
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr324
-rw-r--r--tests/ui/lint/unused/unused_attributes-must_use.fixed139
-rw-r--r--tests/ui/lint/unused/unused_attributes-must_use.rs3
-rw-r--r--tests/ui/lint/unused/unused_attributes-must_use.stderr64
70 files changed, 1515 insertions, 639 deletions
diff --git a/.editorconfig b/.editorconfig
index ef8ed24c52a..1b137cf4ebe 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -7,9 +7,18 @@ root = true
 [*]
 end_of_line = lf
 charset = utf-8
-trim_trailing_whitespace = true
 insert_final_newline = true
 
+# some tests need trailing whitespace in output snapshots
+[!tests/]
+trim_trailing_whitespace = true
+# for actual source code files of test, we still don't want trailing whitespace
+[tests/**.{rs,js}]
+trim_trailing_whitespace = true
+# these specific source files need to have trailing whitespace.
+[tests/ui/{frontmatter/frontmatter-whitespace-3.rs,parser/shebang/shebang-space.rs}]
+trim_trailing_whitespace = false
+
 [!src/llvm-project]
 indent_style = space
 indent_size = 4
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6ce543071d8..df5dda76eb7 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -52,7 +52,7 @@ jobs:
       run_type: ${{ steps.jobs.outputs.run_type }}
     steps:
       - name: Checkout the source code
-        uses: actions/checkout@v4
+        uses: actions/checkout@v5
       - name: Test citool
         # Only test citool on the auto branch, to reduce latency of the calculate matrix job
         # on PR/try builds.
@@ -113,7 +113,7 @@ jobs:
         run: git config --global core.autocrlf false
 
       - name: checkout the source code
-        uses: actions/checkout@v4
+        uses: actions/checkout@v5
         with:
           fetch-depth: 2
 
@@ -313,7 +313,7 @@ jobs:
     if: ${{ !cancelled() && contains(fromJSON('["auto", "try"]'), needs.calculate_matrix.outputs.run_type) }}
     steps:
       - name: checkout the source code
-        uses: actions/checkout@v4
+        uses: actions/checkout@v5
         with:
           fetch-depth: 2
       # Calculate the exit status of the whole CI workflow.
diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml
index 9d4b6192d6e..80ffd67e04e 100644
--- a/.github/workflows/dependencies.yml
+++ b/.github/workflows/dependencies.yml
@@ -51,7 +51,7 @@ jobs:
     runs-on: ubuntu-24.04
     steps:
       - name: checkout the source code
-        uses: actions/checkout@v4
+        uses: actions/checkout@v5
         with:
           submodules: recursive
       - name: install the bootstrap toolchain
@@ -101,7 +101,7 @@ jobs:
       pull-requests: write
     steps:
       - name: checkout the source code
-        uses: actions/checkout@v4
+        uses: actions/checkout@v5
 
       - name: download Cargo.lock from update job
         uses: actions/download-artifact@v4
diff --git a/.github/workflows/ghcr.yml b/.github/workflows/ghcr.yml
index 6d050d98cb2..a89867efe66 100644
--- a/.github/workflows/ghcr.yml
+++ b/.github/workflows/ghcr.yml
@@ -29,7 +29,7 @@ jobs:
       # Needed to write to the ghcr.io registry
       packages: write
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
         with:
           persist-credentials: false
 
diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml
index ca088ba31fd..12ff4be4f1e 100644
--- a/.github/workflows/post-merge.yml
+++ b/.github/workflows/post-merge.yml
@@ -15,7 +15,7 @@ jobs:
     permissions:
       pull-requests: write
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@v5
         with:
           # Make sure that we have enough commits to find the parent merge commit.
           # Since all merges should be through merge commits, fetching two commits
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 7e124f65324..0494666bda9 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -569,7 +569,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel
     // core/std/allocators/etc. For example symbols used to hook up allocation
     // are not considered for export
     let codegen_fn_attrs = tcx.codegen_fn_attrs(sym_def_id);
-    let is_extern = codegen_fn_attrs.contains_extern_indicator();
+    let is_extern = codegen_fn_attrs.contains_extern_indicator(tcx, sym_def_id);
     let std_internal =
         codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL);
 
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 7f54a47327a..287787eb3d1 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -443,6 +443,27 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
     if tcx.should_inherit_track_caller(did) {
         codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER;
     }
+
+    // Foreign items by default use no mangling for their symbol name.
+    if tcx.is_foreign_item(did) {
+        // There's a few exceptions to this rule though:
+        if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
+            // * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way
+            //   both for exports and imports through foreign items. This is handled further,
+            //   during symbol mangling logic.
+        } else if codegen_fn_attrs.link_name.is_some() {
+            // * This can be overridden with the `#[link_name]` attribute
+        } else {
+            // NOTE: there's one more exception that we cannot apply here. On wasm,
+            // some items cannot be `no_mangle`.
+            // However, we don't have enough information here to determine that.
+            // As such, no_mangle foreign items on wasm that have the same defid as some
+            // import will *still* be mangled despite this.
+            //
+            // if none of the exceptions apply; apply no_mangle
+            codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
+        }
+    }
 }
 
 fn check_result(
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index e7ae4416968..00533285fb4 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -2155,6 +2155,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
                             attr_name,
                             macro_name: pprust::path_to_string(&call.path),
                             invoc_span: call.path.span,
+                            attr_span: attr.span,
                         },
                     );
                 }
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 776d8d35e05..c485e6fc849 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -983,6 +983,7 @@ lint_unused_allocation_mut = unnecessary allocation, use `&mut` instead
 
 lint_unused_builtin_attribute = unused attribute `{$attr_name}`
     .note = the built-in attribute `{$attr_name}` will be ignored, since it's applied to the macro invocation `{$macro_name}`
+    .suggestion = remove the attribute
 
 lint_unused_closure =
     unused {$pre}{$count ->
diff --git a/compiler/rustc_lint/src/early/diagnostics.rs b/compiler/rustc_lint/src/early/diagnostics.rs
index 1e4bc79ce70..678d3d1f8ed 100644
--- a/compiler/rustc_lint/src/early/diagnostics.rs
+++ b/compiler/rustc_lint/src/early/diagnostics.rs
@@ -205,8 +205,14 @@ pub fn decorate_builtin_lint(
             }
             .decorate_lint(diag);
         }
-        BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, macro_name, invoc_span } => {
-            lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }.decorate_lint(diag);
+        BuiltinLintDiag::UnusedBuiltinAttribute {
+            attr_name,
+            macro_name,
+            invoc_span,
+            attr_span,
+        } => {
+            lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name, attr_span }
+                .decorate_lint(diag);
         }
         BuiltinLintDiag::TrailingMacro(is_trailing, name) => {
             lints::TrailingMacro { is_trailing, name }.decorate_lint(diag);
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index ba0112c8ac6..a6d59af6900 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2938,9 +2938,10 @@ pub(crate) struct RawPrefix {
 pub(crate) struct UnusedBuiltinAttribute {
     #[note]
     pub invoc_span: Span,
-
     pub attr_name: Symbol,
     pub macro_name: String,
+    #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
+    pub attr_span: Span,
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index dc5ea3922f1..3bb7bbce567 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -647,6 +647,7 @@ pub enum BuiltinLintDiag {
         attr_name: Symbol,
         macro_name: String,
         invoc_span: Span,
+        attr_span: Span,
     },
     PatternsInFnsWithoutBody {
         span: Span,
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index 94384e64afd..52341df0740 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -3,6 +3,7 @@ use std::borrow::Cow;
 use rustc_abi::Align;
 use rustc_ast::expand::autodiff_attrs::AutoDiffAttrs;
 use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr};
+use rustc_hir::def_id::DefId;
 use rustc_macros::{HashStable, TyDecodable, TyEncodable};
 use rustc_span::Symbol;
 use rustc_target::spec::SanitizerSet;
@@ -193,7 +194,11 @@ impl CodegenFnAttrs {
     /// * `#[linkage]` is present
     ///
     /// Keep this in sync with the logic for the unused_attributes for `#[inline]` lint.
-    pub fn contains_extern_indicator(&self) -> bool {
+    pub fn contains_extern_indicator(&self, tcx: TyCtxt<'_>, did: DefId) -> bool {
+        if tcx.is_foreign_item(did) {
+            return false;
+        }
+
         self.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
             || self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
             || self.export_name.is_some()
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index e5864660575..3afd946b30a 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -151,7 +151,7 @@ impl<'tcx> MonoItem<'tcx> {
         // instantiation:
         // We emit an unused_attributes lint for this case, which should be kept in sync if possible.
         let codegen_fn_attrs = tcx.codegen_instance_attrs(instance.def);
-        if codegen_fn_attrs.contains_extern_indicator()
+        if codegen_fn_attrs.contains_extern_indicator(tcx, instance.def.def_id())
             || codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED)
         {
             return InstantiationMode::GloballyShared { may_conflict: false };
diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
index b186c2bd775..03fdf9fbac5 100644
--- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs
+++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
@@ -18,7 +18,7 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
     let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id);
     // If this has an extern indicator, then this function is globally shared and thus will not
     // generate cgu-internal copies which would make it cross-crate inlinable.
-    if codegen_fn_attrs.contains_extern_indicator() {
+    if codegen_fn_attrs.contains_extern_indicator(tcx, def_id.into()) {
         return false;
     }
 
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index b5031f5d02e..eb03235de0c 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -510,6 +510,7 @@ passes_must_not_suspend =
 
 passes_must_use_no_effect =
     `#[must_use]` has no effect when applied to {$article} {$target}
+    .suggestion = remove the attribute
 
 passes_no_link =
     attribute should be applied to an `extern crate` item
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 93b94a8ba14..165f8fe1995 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -563,7 +563,24 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         match target {
             Target::Fn
             | Target::Closure
-            | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {}
+            | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
+                // `#[inline]` is ignored if the symbol must be codegened upstream because it's exported.
+                if let Some(did) = hir_id.as_owner()
+                    && self.tcx.def_kind(did).has_codegen_attrs()
+                    && kind != &InlineAttr::Never
+                {
+                    let attrs = self.tcx.codegen_fn_attrs(did);
+                    // Not checking naked as `#[inline]` is forbidden for naked functions anyways.
+                    if attrs.contains_extern_indicator(self.tcx, did.into()) {
+                        self.tcx.emit_node_span_lint(
+                            UNUSED_ATTRIBUTES,
+                            hir_id,
+                            attr_span,
+                            errors::InlineIgnoredForExported {},
+                        );
+                    }
+                }
+            }
             Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => {
                 self.tcx.emit_node_span_lint(
                     UNUSED_ATTRIBUTES,
@@ -590,23 +607,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 self.dcx().emit_err(errors::InlineNotFnOrClosure { attr_span, defn_span });
             }
         }
-
-        // `#[inline]` is ignored if the symbol must be codegened upstream because it's exported.
-        if let Some(did) = hir_id.as_owner()
-            && self.tcx.def_kind(did).has_codegen_attrs()
-            && kind != &InlineAttr::Never
-        {
-            let attrs = self.tcx.codegen_fn_attrs(did);
-            // Not checking naked as `#[inline]` is forbidden for naked functions anyways.
-            if attrs.contains_extern_indicator() {
-                self.tcx.emit_node_span_lint(
-                    UNUSED_ATTRIBUTES,
-                    hir_id,
-                    attr_span,
-                    errors::InlineIgnoredForExported {},
-                );
-            }
-        }
     }
 
     /// Checks that `#[coverage(..)]` is applied to a function/closure/method,
@@ -1622,7 +1622,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             UNUSED_ATTRIBUTES,
             hir_id,
             attr_span,
-            errors::MustUseNoEffect { article, target },
+            errors::MustUseNoEffect { article, target, attr_span },
         );
     }
 
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index d5d7cc5dc2e..de52973acbb 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -703,7 +703,7 @@ fn has_allow_dead_code_or_lang_attr(
 
             // #[used], #[no_mangle], #[export_name], etc also keeps the item alive
             // forcefully, e.g., for placing it in a specific section.
-            cg_attrs.contains_extern_indicator()
+            cg_attrs.contains_extern_indicator(tcx, def_id.into())
                 || cg_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER)
                 || cg_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
         }
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 10b30fbe8c9..37216656e57 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -469,6 +469,8 @@ pub(crate) struct FfiConstInvalidTarget {
 pub(crate) struct MustUseNoEffect {
     pub article: &'static str,
     pub target: rustc_hir::Target,
+    #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
+    pub attr_span: Span,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 2f78c22c748..6cd8a54ecf4 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -183,7 +183,7 @@ impl<'tcx> ReachableContext<'tcx> {
             } else {
                 CodegenFnAttrs::EMPTY
             };
-            let is_extern = codegen_attrs.contains_extern_indicator();
+            let is_extern = codegen_attrs.contains_extern_indicator(self.tcx, search_item.into());
             if is_extern {
                 self.reachable_symbols.insert(search_item);
             }
@@ -423,8 +423,9 @@ fn has_custom_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
     if !tcx.def_kind(def_id).has_codegen_attrs() {
         return false;
     }
+
     let codegen_attrs = tcx.codegen_fn_attrs(def_id);
-    codegen_attrs.contains_extern_indicator()
+    codegen_attrs.contains_extern_indicator(tcx, def_id.into())
         // FIXME(nbdd0121): `#[used]` are marked as reachable here so it's picked up by
         // `linked_symbols` in cg_ssa. They won't be exported in binary or cdylib due to their
         // `SymbolExportLevel::Rust` export level but may end up being exported in dylibs.
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index 6bcb7f6e093..f3c96f64190 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -218,32 +218,33 @@ fn compute_symbol_name<'tcx>(
         }
     }
 
-    // Foreign items by default use no mangling for their symbol name. There's a
-    // few exceptions to this rule though:
-    //
-    // * This can be overridden with the `#[link_name]` attribute
-    //
-    // * On the wasm32 targets there is a bug (or feature) in LLD [1] where the
-    //   same-named symbol when imported from different wasm modules will get
-    //   hooked up incorrectly. As a result foreign symbols, on the wasm target,
-    //   with a wasm import module, get mangled. Additionally our codegen will
-    //   deduplicate symbols based purely on the symbol name, but for wasm this
-    //   isn't quite right because the same-named symbol on wasm can come from
-    //   different modules. For these reasons if `#[link(wasm_import_module)]`
-    //   is present we mangle everything on wasm because the demangled form will
-    //   show up in the `wasm-import-name` custom attribute in LLVM IR.
-    //
-    // * `#[rustc_std_internal_symbol]` mangles the symbol name in a special way
-    //   both for exports and imports through foreign items. This is handled above.
-    // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316
-    if tcx.is_foreign_item(def_id)
-        && (!tcx.sess.target.is_like_wasm
-            || !tcx.wasm_import_module_map(def_id.krate).contains_key(&def_id))
+    let wasm_import_module_exception_force_mangling = {
+        // * On the wasm32 targets there is a bug (or feature) in LLD [1] where the
+        //   same-named symbol when imported from different wasm modules will get
+        //   hooked up incorrectly. As a result foreign symbols, on the wasm target,
+        //   with a wasm import module, get mangled. Additionally our codegen will
+        //   deduplicate symbols based purely on the symbol name, but for wasm this
+        //   isn't quite right because the same-named symbol on wasm can come from
+        //   different modules. For these reasons if `#[link(wasm_import_module)]`
+        //   is present we mangle everything on wasm because the demangled form will
+        //   show up in the `wasm-import-name` custom attribute in LLVM IR.
+        //
+        // [1]: https://bugs.llvm.org/show_bug.cgi?id=44316
+        //
+        // So, on wasm if a foreign item loses its `#[no_mangle]`, it might *still*
+        // be mangled if we're forced to. Note: I don't like this.
+        // These kinds of exceptions should be added during the `codegen_attrs` query.
+        // However, we don't have the wasm import module map there yet.
+        tcx.is_foreign_item(def_id)
+            && tcx.sess.target.is_like_wasm
+            && tcx.wasm_import_module_map(LOCAL_CRATE).contains_key(&def_id.into())
+    };
+
+    if let Some(name) = attrs.link_name
+        && !wasm_import_module_exception_force_mangling
     {
-        if let Some(name) = attrs.link_name {
-            return name.to_string();
-        }
-        return tcx.item_name(def_id).to_string();
+        // Use provided name
+        return name.to_string();
     }
 
     if let Some(name) = attrs.export_name {
@@ -251,7 +252,9 @@ fn compute_symbol_name<'tcx>(
         return name.to_string();
     }
 
-    if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) {
+    if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
+        && !wasm_import_module_exception_force_mangling
+    {
         // Don't mangle
         return tcx.item_name(def_id).to_string();
     }
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index 49275975f04..cd5fd77f865 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -226,10 +226,10 @@ impl Layout {
 
     /// Creates a `NonNull` that is dangling, but well-aligned for this Layout.
     ///
-    /// Note that the pointer value may potentially represent a valid pointer,
-    /// which means this must not be used as a "not yet initialized"
-    /// sentinel value. Types that lazily allocate must track initialization by
-    /// some other means.
+    /// Note that the address of the returned pointer may potentially
+    /// be that of a valid pointer, which means this must not be used
+    /// as a "not yet initialized" sentinel value.
+    /// Types that lazily allocate must track initialization by some other means.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
     #[must_use]
     #[inline]
diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs
index 054ddf84470..419e4694594 100644
--- a/library/core/src/ascii/ascii_char.rs
+++ b/library/core/src/ascii/ascii_char.rs
@@ -445,7 +445,15 @@ pub enum AsciiChar {
 }
 
 impl AsciiChar {
-    /// Creates an ascii character from the byte `b`,
+    /// The character with the lowest ASCII code.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    pub const MIN: Self = Self::Null;
+
+    /// The character with the highest ASCII code.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    pub const MAX: Self = Self::Delete;
+
+    /// Creates an ASCII character from the byte `b`,
     /// or returns `None` if it's too large.
     #[unstable(feature = "ascii_char", issue = "110998")]
     #[inline]
@@ -540,6 +548,608 @@ impl AsciiChar {
     pub const fn as_str(&self) -> &str {
         crate::slice::from_ref(self).as_str()
     }
+
+    /// Makes a copy of the value in its upper case equivalent.
+    ///
+    /// Letters 'a' to 'z' are mapped to 'A' to 'Z'.
+    ///
+    /// To uppercase the value in-place, use [`make_uppercase`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let lowercase_a = ascii::Char::SmallA;
+    ///
+    /// assert_eq!(
+    ///     ascii::Char::CapitalA,
+    ///     lowercase_a.to_uppercase(),
+    /// );
+    /// ```
+    ///
+    /// [`make_uppercase`]: Self::make_uppercase
+    #[must_use = "to uppercase the value in-place, use `make_uppercase()`"]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn to_uppercase(self) -> Self {
+        let uppercase_byte = self.to_u8().to_ascii_uppercase();
+        // SAFETY: Toggling the 6th bit won't convert ASCII to non-ASCII.
+        unsafe { Self::from_u8_unchecked(uppercase_byte) }
+    }
+
+    /// Makes a copy of the value in its lower case equivalent.
+    ///
+    /// Letters 'A' to 'Z' are mapped to 'a' to 'z'.
+    ///
+    /// To lowercase the value in-place, use [`make_lowercase`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    ///
+    /// assert_eq!(
+    ///     ascii::Char::SmallA,
+    ///     uppercase_a.to_lowercase(),
+    /// );
+    /// ```
+    ///
+    /// [`make_lowercase`]: Self::make_lowercase
+    #[must_use = "to lowercase the value in-place, use `make_lowercase()`"]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn to_lowercase(self) -> Self {
+        let lowercase_byte = self.to_u8().to_ascii_lowercase();
+        // SAFETY: Setting the 6th bit won't convert ASCII to non-ASCII.
+        unsafe { Self::from_u8_unchecked(lowercase_byte) }
+    }
+
+    /// Checks that two values are a case-insensitive match.
+    ///
+    /// This is equivalent to `to_lowercase(a) == to_lowercase(b)`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let lowercase_a = ascii::Char::SmallA;
+    /// let uppercase_a = ascii::Char::CapitalA;
+    ///
+    /// assert!(lowercase_a.eq_ignore_case(uppercase_a));
+    /// ```
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn eq_ignore_case(self, other: Self) -> bool {
+        // FIXME(const-hack) `arg.to_u8().to_ascii_lowercase()` -> `arg.to_lowercase()`
+        // once `PartialEq` is const for `Self`.
+        self.to_u8().to_ascii_lowercase() == other.to_u8().to_ascii_lowercase()
+    }
+
+    /// Converts this value to its upper case equivalent in-place.
+    ///
+    /// Letters 'a' to 'z' are mapped to 'A' to 'Z'.
+    ///
+    /// To return a new uppercased value without modifying the existing one, use
+    /// [`to_uppercase`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let mut letter_a = ascii::Char::SmallA;
+    ///
+    /// letter_a.make_uppercase();
+    ///
+    /// assert_eq!(ascii::Char::CapitalA, letter_a);
+    /// ```
+    ///
+    /// [`to_uppercase`]: Self::to_uppercase
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn make_uppercase(&mut self) {
+        *self = self.to_uppercase();
+    }
+
+    /// Converts this value to its lower case equivalent in-place.
+    ///
+    /// Letters 'A' to 'Z' are mapped to 'a' to 'z'.
+    ///
+    /// To return a new lowercased value without modifying the existing one, use
+    /// [`to_lowercase`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let mut letter_a = ascii::Char::CapitalA;
+    ///
+    /// letter_a.make_lowercase();
+    ///
+    /// assert_eq!(ascii::Char::SmallA, letter_a);
+    /// ```
+    ///
+    /// [`to_lowercase`]: Self::to_lowercase
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn make_lowercase(&mut self) {
+        *self = self.to_lowercase();
+    }
+
+    /// Checks if the value is an alphabetic character:
+    ///
+    /// - 0x41 'A' ..= 0x5A 'Z', or
+    /// - 0x61 'a' ..= 0x7A 'z'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    /// let uppercase_g = ascii::Char::CapitalG;
+    /// let a = ascii::Char::SmallA;
+    /// let g = ascii::Char::SmallG;
+    /// let zero = ascii::Char::Digit0;
+    /// let percent = ascii::Char::PercentSign;
+    /// let space = ascii::Char::Space;
+    /// let lf = ascii::Char::LineFeed;
+    /// let esc = ascii::Char::Escape;
+    ///
+    /// assert!(uppercase_a.is_alphabetic());
+    /// assert!(uppercase_g.is_alphabetic());
+    /// assert!(a.is_alphabetic());
+    /// assert!(g.is_alphabetic());
+    /// assert!(!zero.is_alphabetic());
+    /// assert!(!percent.is_alphabetic());
+    /// assert!(!space.is_alphabetic());
+    /// assert!(!lf.is_alphabetic());
+    /// assert!(!esc.is_alphabetic());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn is_alphabetic(self) -> bool {
+        self.to_u8().is_ascii_alphabetic()
+    }
+
+    /// Checks if the value is an uppercase character:
+    /// 0x41 'A' ..= 0x5A 'Z'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    /// let uppercase_g = ascii::Char::CapitalG;
+    /// let a = ascii::Char::SmallA;
+    /// let g = ascii::Char::SmallG;
+    /// let zero = ascii::Char::Digit0;
+    /// let percent = ascii::Char::PercentSign;
+    /// let space = ascii::Char::Space;
+    /// let lf = ascii::Char::LineFeed;
+    /// let esc = ascii::Char::Escape;
+    ///
+    /// assert!(uppercase_a.is_uppercase());
+    /// assert!(uppercase_g.is_uppercase());
+    /// assert!(!a.is_uppercase());
+    /// assert!(!g.is_uppercase());
+    /// assert!(!zero.is_uppercase());
+    /// assert!(!percent.is_uppercase());
+    /// assert!(!space.is_uppercase());
+    /// assert!(!lf.is_uppercase());
+    /// assert!(!esc.is_uppercase());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn is_uppercase(self) -> bool {
+        self.to_u8().is_ascii_uppercase()
+    }
+
+    /// Checks if the value is a lowercase character:
+    /// 0x61 'a' ..= 0x7A 'z'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    /// let uppercase_g = ascii::Char::CapitalG;
+    /// let a = ascii::Char::SmallA;
+    /// let g = ascii::Char::SmallG;
+    /// let zero = ascii::Char::Digit0;
+    /// let percent = ascii::Char::PercentSign;
+    /// let space = ascii::Char::Space;
+    /// let lf = ascii::Char::LineFeed;
+    /// let esc = ascii::Char::Escape;
+    ///
+    /// assert!(!uppercase_a.is_lowercase());
+    /// assert!(!uppercase_g.is_lowercase());
+    /// assert!(a.is_lowercase());
+    /// assert!(g.is_lowercase());
+    /// assert!(!zero.is_lowercase());
+    /// assert!(!percent.is_lowercase());
+    /// assert!(!space.is_lowercase());
+    /// assert!(!lf.is_lowercase());
+    /// assert!(!esc.is_lowercase());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn is_lowercase(self) -> bool {
+        self.to_u8().is_ascii_lowercase()
+    }
+
+    /// Checks if the value is an alphanumeric character:
+    ///
+    /// - 0x41 'A' ..= 0x5A 'Z', or
+    /// - 0x61 'a' ..= 0x7A 'z', or
+    /// - 0x30 '0' ..= 0x39 '9'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    /// let uppercase_g = ascii::Char::CapitalG;
+    /// let a = ascii::Char::SmallA;
+    /// let g = ascii::Char::SmallG;
+    /// let zero = ascii::Char::Digit0;
+    /// let percent = ascii::Char::PercentSign;
+    /// let space = ascii::Char::Space;
+    /// let lf = ascii::Char::LineFeed;
+    /// let esc = ascii::Char::Escape;
+    ///
+    /// assert!(uppercase_a.is_alphanumeric());
+    /// assert!(uppercase_g.is_alphanumeric());
+    /// assert!(a.is_alphanumeric());
+    /// assert!(g.is_alphanumeric());
+    /// assert!(zero.is_alphanumeric());
+    /// assert!(!percent.is_alphanumeric());
+    /// assert!(!space.is_alphanumeric());
+    /// assert!(!lf.is_alphanumeric());
+    /// assert!(!esc.is_alphanumeric());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn is_alphanumeric(self) -> bool {
+        self.to_u8().is_ascii_alphanumeric()
+    }
+
+    /// Checks if the value is a decimal digit:
+    /// 0x30 '0' ..= 0x39 '9'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    /// let uppercase_g = ascii::Char::CapitalG;
+    /// let a = ascii::Char::SmallA;
+    /// let g = ascii::Char::SmallG;
+    /// let zero = ascii::Char::Digit0;
+    /// let percent = ascii::Char::PercentSign;
+    /// let space = ascii::Char::Space;
+    /// let lf = ascii::Char::LineFeed;
+    /// let esc = ascii::Char::Escape;
+    ///
+    /// assert!(!uppercase_a.is_digit());
+    /// assert!(!uppercase_g.is_digit());
+    /// assert!(!a.is_digit());
+    /// assert!(!g.is_digit());
+    /// assert!(zero.is_digit());
+    /// assert!(!percent.is_digit());
+    /// assert!(!space.is_digit());
+    /// assert!(!lf.is_digit());
+    /// assert!(!esc.is_digit());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn is_digit(self) -> bool {
+        self.to_u8().is_ascii_digit()
+    }
+
+    /// Checks if the value is an octal digit:
+    /// 0x30 '0' ..= 0x37 '7'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants, is_ascii_octdigit)]
+    ///
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    /// let a = ascii::Char::SmallA;
+    /// let zero = ascii::Char::Digit0;
+    /// let seven = ascii::Char::Digit7;
+    /// let eight = ascii::Char::Digit8;
+    /// let percent = ascii::Char::PercentSign;
+    /// let lf = ascii::Char::LineFeed;
+    /// let esc = ascii::Char::Escape;
+    ///
+    /// assert!(!uppercase_a.is_octdigit());
+    /// assert!(!a.is_octdigit());
+    /// assert!(zero.is_octdigit());
+    /// assert!(seven.is_octdigit());
+    /// assert!(!eight.is_octdigit());
+    /// assert!(!percent.is_octdigit());
+    /// assert!(!lf.is_octdigit());
+    /// assert!(!esc.is_octdigit());
+    /// ```
+    #[must_use]
+    // This is blocked on two unstable features. Please ensure both are
+    // stabilized before marking this method as stable.
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    // #[unstable(feature = "is_ascii_octdigit", issue = "101288")]
+    #[inline]
+    pub const fn is_octdigit(self) -> bool {
+        self.to_u8().is_ascii_octdigit()
+    }
+
+    /// Checks if the value is a hexadecimal digit:
+    ///
+    /// - 0x30 '0' ..= 0x39 '9', or
+    /// - 0x41 'A' ..= 0x46 'F', or
+    /// - 0x61 'a' ..= 0x66 'f'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    /// let uppercase_g = ascii::Char::CapitalG;
+    /// let a = ascii::Char::SmallA;
+    /// let g = ascii::Char::SmallG;
+    /// let zero = ascii::Char::Digit0;
+    /// let percent = ascii::Char::PercentSign;
+    /// let space = ascii::Char::Space;
+    /// let lf = ascii::Char::LineFeed;
+    /// let esc = ascii::Char::Escape;
+    ///
+    /// assert!(uppercase_a.is_hexdigit());
+    /// assert!(!uppercase_g.is_hexdigit());
+    /// assert!(a.is_hexdigit());
+    /// assert!(!g.is_hexdigit());
+    /// assert!(zero.is_hexdigit());
+    /// assert!(!percent.is_hexdigit());
+    /// assert!(!space.is_hexdigit());
+    /// assert!(!lf.is_hexdigit());
+    /// assert!(!esc.is_hexdigit());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn is_hexdigit(self) -> bool {
+        self.to_u8().is_ascii_hexdigit()
+    }
+
+    /// Checks if the value is a punctuation character:
+    ///
+    /// - 0x21 ..= 0x2F `! " # $ % & ' ( ) * + , - . /`, or
+    /// - 0x3A ..= 0x40 `: ; < = > ? @`, or
+    /// - 0x5B ..= 0x60 `` [ \ ] ^ _ ` ``, or
+    /// - 0x7B ..= 0x7E `{ | } ~`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    /// let uppercase_g = ascii::Char::CapitalG;
+    /// let a = ascii::Char::SmallA;
+    /// let g = ascii::Char::SmallG;
+    /// let zero = ascii::Char::Digit0;
+    /// let percent = ascii::Char::PercentSign;
+    /// let space = ascii::Char::Space;
+    /// let lf = ascii::Char::LineFeed;
+    /// let esc = ascii::Char::Escape;
+    ///
+    /// assert!(!uppercase_a.is_punctuation());
+    /// assert!(!uppercase_g.is_punctuation());
+    /// assert!(!a.is_punctuation());
+    /// assert!(!g.is_punctuation());
+    /// assert!(!zero.is_punctuation());
+    /// assert!(percent.is_punctuation());
+    /// assert!(!space.is_punctuation());
+    /// assert!(!lf.is_punctuation());
+    /// assert!(!esc.is_punctuation());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn is_punctuation(self) -> bool {
+        self.to_u8().is_ascii_punctuation()
+    }
+
+    /// Checks if the value is a graphic character:
+    /// 0x21 '!' ..= 0x7E '~'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    /// let uppercase_g = ascii::Char::CapitalG;
+    /// let a = ascii::Char::SmallA;
+    /// let g = ascii::Char::SmallG;
+    /// let zero = ascii::Char::Digit0;
+    /// let percent = ascii::Char::PercentSign;
+    /// let space = ascii::Char::Space;
+    /// let lf = ascii::Char::LineFeed;
+    /// let esc = ascii::Char::Escape;
+    ///
+    /// assert!(uppercase_a.is_graphic());
+    /// assert!(uppercase_g.is_graphic());
+    /// assert!(a.is_graphic());
+    /// assert!(g.is_graphic());
+    /// assert!(zero.is_graphic());
+    /// assert!(percent.is_graphic());
+    /// assert!(!space.is_graphic());
+    /// assert!(!lf.is_graphic());
+    /// assert!(!esc.is_graphic());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn is_graphic(self) -> bool {
+        self.to_u8().is_ascii_graphic()
+    }
+
+    /// Checks if the value is a whitespace character:
+    /// 0x20 SPACE, 0x09 HORIZONTAL TAB, 0x0A LINE FEED,
+    /// 0x0C FORM FEED, or 0x0D CARRIAGE RETURN.
+    ///
+    /// Rust uses the WhatWG Infra Standard's [definition of ASCII
+    /// whitespace][infra-aw]. There are several other definitions in
+    /// wide use. For instance, [the POSIX locale][pct] includes
+    /// 0x0B VERTICAL TAB as well as all the above characters,
+    /// but—from the very same specification—[the default rule for
+    /// "field splitting" in the Bourne shell][bfs] considers *only*
+    /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
+    ///
+    /// If you are writing a program that will process an existing
+    /// file format, check what that format's definition of whitespace is
+    /// before using this function.
+    ///
+    /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
+    /// [pct]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
+    /// [bfs]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    /// let uppercase_g = ascii::Char::CapitalG;
+    /// let a = ascii::Char::SmallA;
+    /// let g = ascii::Char::SmallG;
+    /// let zero = ascii::Char::Digit0;
+    /// let percent = ascii::Char::PercentSign;
+    /// let space = ascii::Char::Space;
+    /// let lf = ascii::Char::LineFeed;
+    /// let esc = ascii::Char::Escape;
+    ///
+    /// assert!(!uppercase_a.is_whitespace());
+    /// assert!(!uppercase_g.is_whitespace());
+    /// assert!(!a.is_whitespace());
+    /// assert!(!g.is_whitespace());
+    /// assert!(!zero.is_whitespace());
+    /// assert!(!percent.is_whitespace());
+    /// assert!(space.is_whitespace());
+    /// assert!(lf.is_whitespace());
+    /// assert!(!esc.is_whitespace());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn is_whitespace(self) -> bool {
+        self.to_u8().is_ascii_whitespace()
+    }
+
+    /// Checks if the value is a control character:
+    /// 0x00 NUL ..= 0x1F UNIT SEPARATOR, or 0x7F DELETE.
+    /// Note that most whitespace characters are control
+    /// characters, but SPACE is not.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let uppercase_a = ascii::Char::CapitalA;
+    /// let uppercase_g = ascii::Char::CapitalG;
+    /// let a = ascii::Char::SmallA;
+    /// let g = ascii::Char::SmallG;
+    /// let zero = ascii::Char::Digit0;
+    /// let percent = ascii::Char::PercentSign;
+    /// let space = ascii::Char::Space;
+    /// let lf = ascii::Char::LineFeed;
+    /// let esc = ascii::Char::Escape;
+    ///
+    /// assert!(!uppercase_a.is_control());
+    /// assert!(!uppercase_g.is_control());
+    /// assert!(!a.is_control());
+    /// assert!(!g.is_control());
+    /// assert!(!zero.is_control());
+    /// assert!(!percent.is_control());
+    /// assert!(!space.is_control());
+    /// assert!(lf.is_control());
+    /// assert!(esc.is_control());
+    /// ```
+    #[must_use]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub const fn is_control(self) -> bool {
+        self.to_u8().is_ascii_control()
+    }
+
+    /// Returns an iterator that produces an escaped version of a
+    /// character.
+    ///
+    /// The behavior is identical to
+    /// [`ascii::escape_default`](crate::ascii::escape_default).
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_char, ascii_char_variants)]
+    /// use std::ascii;
+    ///
+    /// let zero = ascii::Char::Digit0;
+    /// let tab = ascii::Char::CharacterTabulation;
+    /// let cr = ascii::Char::CarriageReturn;
+    /// let lf = ascii::Char::LineFeed;
+    /// let apostrophe = ascii::Char::Apostrophe;
+    /// let double_quote = ascii::Char::QuotationMark;
+    /// let backslash = ascii::Char::ReverseSolidus;
+    ///
+    /// assert_eq!("0", zero.escape_ascii().to_string());
+    /// assert_eq!("\\t", tab.escape_ascii().to_string());
+    /// assert_eq!("\\r", cr.escape_ascii().to_string());
+    /// assert_eq!("\\n", lf.escape_ascii().to_string());
+    /// assert_eq!("\\'", apostrophe.escape_ascii().to_string());
+    /// assert_eq!("\\\"", double_quote.escape_ascii().to_string());
+    /// assert_eq!("\\\\", backslash.escape_ascii().to_string());
+    /// ```
+    #[must_use = "this returns the escaped character as an iterator, \
+                  without modifying the original"]
+    #[unstable(feature = "ascii_char", issue = "110998")]
+    #[inline]
+    pub fn escape_ascii(self) -> super::EscapeDefault {
+        super::escape_default(self.to_u8())
+    }
 }
 
 macro_rules! into_int_impl {
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 1a2a5182567..b2607e45324 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -885,10 +885,10 @@ pub const fn without_provenance<T>(addr: usize) -> *const T {
 /// This is useful for initializing types which lazily allocate, like
 /// `Vec::new` does.
 ///
-/// Note that the pointer value may potentially represent a valid pointer to
-/// a `T`, which means this must not be used as a "not yet initialized"
-/// sentinel value. Types that lazily allocate must track initialization by
-/// some other means.
+/// Note that the address of the returned pointer may potentially
+/// be that of a valid pointer, which means this must not be used
+/// as a "not yet initialized" sentinel value.
+/// Types that lazily allocate must track initialization by some other means.
 #[inline(always)]
 #[must_use]
 #[stable(feature = "strict_provenance", since = "1.84.0")]
@@ -928,10 +928,10 @@ pub const fn without_provenance_mut<T>(addr: usize) -> *mut T {
 /// This is useful for initializing types which lazily allocate, like
 /// `Vec::new` does.
 ///
-/// Note that the pointer value may potentially represent a valid pointer to
-/// a `T`, which means this must not be used as a "not yet initialized"
-/// sentinel value. Types that lazily allocate must track initialization by
-/// some other means.
+/// Note that the address of the returned pointer may potentially
+/// be that of a valid pointer, which means this must not be used
+/// as a "not yet initialized" sentinel value.
+/// Types that lazily allocate must track initialization by some other means.
 #[inline(always)]
 #[must_use]
 #[stable(feature = "strict_provenance", since = "1.84.0")]
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 8667361fecc..e72aa1da2cb 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -109,10 +109,10 @@ impl<T: Sized> NonNull<T> {
     /// This is useful for initializing types which lazily allocate, like
     /// `Vec::new` does.
     ///
-    /// Note that the pointer value may potentially represent a valid pointer to
-    /// a `T`, which means this must not be used as a "not yet initialized"
-    /// sentinel value. Types that lazily allocate must track initialization by
-    /// some other means.
+    /// Note that the address of the returned pointer may potentially
+    /// be that of a valid pointer, which means this must not be used
+    /// as a "not yet initialized" sentinel value.
+    /// Types that lazily allocate must track initialization by some other means.
     ///
     /// # Examples
     ///
diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs
index e9e13f9e97f..4302c1b1e44 100644
--- a/library/core/src/ptr/unique.rs
+++ b/library/core/src/ptr/unique.rs
@@ -63,10 +63,10 @@ impl<T: Sized> Unique<T> {
     /// This is useful for initializing types which lazily allocate, like
     /// `Vec::new` does.
     ///
-    /// Note that the pointer value may potentially represent a valid pointer to
-    /// a `T`, which means this must not be used as a "not yet initialized"
-    /// sentinel value. Types that lazily allocate must track initialization by
-    /// some other means.
+    /// Note that the address of the returned pointer may potentially
+    /// be that of a valid pointer, which means this must not be used
+    /// as a "not yet initialized" sentinel value.
+    /// Types that lazily allocate must track initialization by some other means.
     #[must_use]
     #[inline]
     pub const fn dangling() -> Self {
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 0c537530647..25355efd20e 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -281,9 +281,11 @@
 #![feature(cfg_target_thread_local)]
 #![feature(cfi_encoding)]
 #![feature(char_max_len)]
+#![feature(const_trait_impl)]
 #![feature(core_float_math)]
 #![feature(decl_macro)]
 #![feature(deprecated_suggestion)]
+#![feature(derive_const)]
 #![feature(doc_cfg)]
 #![feature(doc_cfg_hide)]
 #![feature(doc_masked)]
@@ -329,6 +331,10 @@
 #![feature(bstr_internals)]
 #![feature(char_internals)]
 #![feature(clone_to_uninit)]
+#![feature(const_cmp)]
+#![feature(const_ops)]
+#![feature(const_option_ops)]
+#![feature(const_try)]
 #![feature(core_intrinsics)]
 #![feature(core_io_borrowed_buf)]
 #![feature(drop_guard)]
diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs
index cff4f20b5a8..5e8d2f8e78e 100644
--- a/library/std/src/panic.rs
+++ b/library/std/src/panic.rs
@@ -60,6 +60,7 @@ impl<'a> PanicHookInfo<'a> {
     /// Returns the payload associated with the panic.
     ///
     /// This will commonly, but not always, be a `&'static str` or [`String`].
+    /// If you only care about such payloads, use [`payload_as_str`] instead.
     ///
     /// A invocation of the `panic!()` macro in Rust 2021 or later will always result in a
     /// panic payload of type `&'static str` or `String`.
@@ -69,6 +70,7 @@ impl<'a> PanicHookInfo<'a> {
     /// can result in a panic payload other than a `&'static str` or `String`.
     ///
     /// [`String`]: ../../std/string/struct.String.html
+    /// [`payload_as_str`]: PanicHookInfo::payload_as_str
     ///
     /// # Examples
     ///
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index e7ba6936435..3b52804d6be 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -2678,7 +2678,6 @@ impl Path {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(path_file_prefix)]
     /// use std::path::Path;
     ///
     /// assert_eq!("foo", Path::new("foo.rs").file_prefix().unwrap());
@@ -2693,7 +2692,7 @@ impl Path {
     ///
     /// [`Path::file_stem`]: Path::file_stem
     ///
-    #[unstable(feature = "path_file_prefix", issue = "86319")]
+    #[stable(feature = "path_file_prefix", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     pub fn file_prefix(&self) -> Option<&OsStr> {
         self.file_name().map(split_file_at_dot).and_then(|(before, _after)| Some(before))
diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs
index f76a5f96c87..89a427ab88b 100644
--- a/library/std/src/sys/pal/hermit/time.rs
+++ b/library/std/src/sys/pal/hermit/time.rs
@@ -25,8 +25,15 @@ impl Timespec {
         Timespec { t: timespec { tv_sec, tv_nsec } }
     }
 
-    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
-        if self >= other {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
+        // FIXME: const PartialOrd
+        let mut cmp = self.t.tv_sec - other.t.tv_sec;
+        if cmp == 0 {
+            cmp = self.t.tv_nsec as i64 - other.t.tv_nsec as i64;
+        }
+
+        if cmp >= 0 {
             Ok(if self.t.tv_nsec >= other.t.tv_nsec {
                 Duration::new(
                     (self.t.tv_sec - other.t.tv_sec) as u64,
@@ -46,20 +53,22 @@ impl Timespec {
         }
     }
 
-    fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.t.tv_sec.checked_add_unsigned(other.as_secs())?;
 
         // Nano calculations can't overflow because nanos are <1B which fit
         // in a u32.
-        let mut nsec = other.subsec_nanos() + u32::try_from(self.t.tv_nsec).unwrap();
-        if nsec >= NSEC_PER_SEC.try_into().unwrap() {
-            nsec -= u32::try_from(NSEC_PER_SEC).unwrap();
+        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
+        if nsec >= NSEC_PER_SEC as u32 {
+            nsec -= NSEC_PER_SEC as u32;
             secs = secs.checked_add(1)?;
         }
         Some(Timespec { t: timespec { tv_sec: secs, tv_nsec: nsec as _ } })
     }
 
-    fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.t.tv_sec.checked_sub_unsigned(other.as_secs())?;
 
         // Similar to above, nanos can't overflow.
@@ -213,15 +222,18 @@ impl SystemTime {
         SystemTime(time)
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         self.0.sub_timespec(&other.0)
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add_duration(other)?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub_duration(other)?))
     }
 }
diff --git a/library/std/src/sys/pal/sgx/time.rs b/library/std/src/sys/pal/sgx/time.rs
index db4cf2804bf..603dae952ab 100644
--- a/library/std/src/sys/pal/sgx/time.rs
+++ b/library/std/src/sys/pal/sgx/time.rs
@@ -32,15 +32,22 @@ impl SystemTime {
         SystemTime(usercalls::insecure_time())
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        // FIXME: ok_or_else with const closures
+        match self.0.checked_sub(other.0) {
+            Some(duration) => Ok(duration),
+            None => Err(other.0 - self.0),
+        }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
diff --git a/library/std/src/sys/pal/solid/time.rs b/library/std/src/sys/pal/solid/time.rs
index c39d715c6a6..e35e60df1a0 100644
--- a/library/std/src/sys/pal/solid/time.rs
+++ b/library/std/src/sys/pal/solid/time.rs
@@ -39,7 +39,8 @@ impl SystemTime {
         Self(t)
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         if self.0 >= other.0 {
             Ok(Duration::from_secs((self.0 as u64).wrapping_sub(other.0 as u64)))
         } else {
@@ -47,11 +48,13 @@ impl SystemTime {
         }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add_unsigned(other.as_secs())?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub_unsigned(other.as_secs())?))
     }
 }
diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs
index a5ab7690327..df5611b2ddd 100644
--- a/library/std/src/sys/pal/uefi/time.rs
+++ b/library/std/src/sys/pal/uefi/time.rs
@@ -80,19 +80,32 @@ impl SystemTime {
             .unwrap_or_else(|| panic!("time not implemented on this platform"))
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        // FIXME: ok_or_else with const closures
+        match self.0.checked_sub(other.0) {
+            Some(duration) => Ok(duration),
+            None => Err(other.0 - self.0),
+        }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
-        let temp = Self(self.0.checked_add(*other)?);
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+        let temp = self.0.checked_add(*other)?;
 
         // Check if can be represented in UEFI
-        if temp <= MAX_UEFI_TIME { Some(temp) } else { None }
+        // FIXME: const PartialOrd
+        let mut cmp = temp.as_secs() - MAX_UEFI_TIME.0.as_secs();
+        if cmp == 0 {
+            cmp = temp.subsec_nanos() as u64 - MAX_UEFI_TIME.0.subsec_nanos() as u64;
+        }
+
+        if cmp <= 0 { Some(SystemTime(temp)) } else { None }
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
-        self.0.checked_sub(*other).map(Self)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+        Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
 
diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs
index bd7f74fea6a..328fe0bc960 100644
--- a/library/std/src/sys/pal/unix/time.rs
+++ b/library/std/src/sys/pal/unix/time.rs
@@ -38,15 +38,18 @@ impl SystemTime {
         SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) }
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         self.t.sub_timespec(&other.t)
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime { t: self.t.checked_add_duration(other)? })
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime { t: self.t.checked_sub_duration(other)? })
     }
 }
@@ -133,8 +136,15 @@ impl Timespec {
         Timespec::new(t.tv_sec as i64, t.tv_nsec as i64).unwrap()
     }
 
-    pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
-        if self >= other {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
+        // FIXME: const PartialOrd
+        let mut cmp = self.tv_sec - other.tv_sec;
+        if cmp == 0 {
+            cmp = self.tv_nsec.as_inner() as i64 - other.tv_nsec.as_inner() as i64;
+        }
+
+        if cmp >= 0 {
             // NOTE(eddyb) two aspects of this `if`-`else` are required for LLVM
             // to optimize it into a branchless form (see also #75545):
             //
@@ -169,7 +179,8 @@ impl Timespec {
         }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.tv_sec.checked_add_unsigned(other.as_secs())?;
 
         // Nano calculations can't overflow because nanos are <1B which fit
@@ -179,10 +190,11 @@ impl Timespec {
             nsec -= NSEC_PER_SEC as u32;
             secs = secs.checked_add(1)?;
         }
-        Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) })
+        Some(unsafe { Timespec::new_unchecked(secs, nsec as i64) })
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<Timespec> {
         let mut secs = self.tv_sec.checked_sub_unsigned(other.as_secs())?;
 
         // Similar to above, nanos can't overflow.
@@ -191,7 +203,7 @@ impl Timespec {
             nsec += NSEC_PER_SEC as i32;
             secs = secs.checked_sub(1)?;
         }
-        Some(unsafe { Timespec::new_unchecked(secs, nsec.into()) })
+        Some(unsafe { Timespec::new_unchecked(secs, nsec as i64) })
     }
 
     #[allow(dead_code)]
diff --git a/library/std/src/sys/pal/unsupported/time.rs b/library/std/src/sys/pal/unsupported/time.rs
index 6d67b538a96..0c387917044 100644
--- a/library/std/src/sys/pal/unsupported/time.rs
+++ b/library/std/src/sys/pal/unsupported/time.rs
@@ -31,15 +31,22 @@ impl SystemTime {
         panic!("time not implemented on this platform")
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        // FIXME: ok_or_else with const closures
+        match self.0.checked_sub(other.0) {
+            Some(duration) => Ok(duration),
+            None => Err(other.0 - self.0),
+        }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
diff --git a/library/std/src/sys/pal/wasi/time.rs b/library/std/src/sys/pal/wasi/time.rs
index 0d8d0b59ac1..892661b312b 100644
--- a/library/std/src/sys/pal/wasi/time.rs
+++ b/library/std/src/sys/pal/wasi/time.rs
@@ -43,23 +43,34 @@ impl SystemTime {
         SystemTime(current_time(wasi::CLOCKID_REALTIME))
     }
 
-    pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
         SystemTime(Duration::from_nanos(ts))
     }
 
-    pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
-        self.0.as_nanos().try_into().ok()
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> {
+        // FIXME: const TryInto
+        let ns = self.0.as_nanos();
+        if ns <= u64::MAX as u128 { Some(ns as u64) } else { None }
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        // FIXME: ok_or_else with const closures
+        match self.0.checked_sub(other.0) {
+            Some(duration) => Ok(duration),
+            None => Err(other.0 - self.0),
+        }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs
index 68126bd8d2f..a948c07e0a3 100644
--- a/library/std/src/sys/pal/windows/time.rs
+++ b/library/std/src/sys/pal/windows/time.rs
@@ -72,7 +72,8 @@ impl SystemTime {
         }
     }
 
-    fn from_intervals(intervals: i64) -> SystemTime {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    const fn from_intervals(intervals: i64) -> SystemTime {
         SystemTime {
             t: c::FILETIME {
                 dwLowDateTime: intervals as u32,
@@ -81,11 +82,13 @@ impl SystemTime {
         }
     }
 
-    fn intervals(&self) -> i64 {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    const fn intervals(&self) -> i64 {
         (self.t.dwLowDateTime as i64) | ((self.t.dwHighDateTime as i64) << 32)
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
         let me = self.intervals();
         let other = other.intervals();
         if me >= other {
@@ -95,12 +98,14 @@ impl SystemTime {
         }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         let intervals = self.intervals().checked_add(checked_dur2intervals(other)?)?;
         Some(SystemTime::from_intervals(intervals))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         let intervals = self.intervals().checked_sub(checked_dur2intervals(other)?)?;
         Some(SystemTime::from_intervals(intervals))
     }
@@ -150,15 +155,18 @@ impl Hash for SystemTime {
     }
 }
 
-fn checked_dur2intervals(dur: &Duration) -> Option<i64> {
-    dur.as_secs()
+#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+const fn checked_dur2intervals(dur: &Duration) -> Option<i64> {
+    // FIXME: const TryInto
+    let secs = dur
+        .as_secs()
         .checked_mul(INTERVALS_PER_SEC)?
-        .checked_add(dur.subsec_nanos() as u64 / 100)?
-        .try_into()
-        .ok()
+        .checked_add(dur.subsec_nanos() as u64 / 100)?;
+    if secs <= i64::MAX as u64 { Some(secs.cast_signed()) } else { None }
 }
 
-fn intervals2dur(intervals: u64) -> Duration {
+#[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+const fn intervals2dur(intervals: u64) -> Duration {
     Duration::new(intervals / INTERVALS_PER_SEC, ((intervals % INTERVALS_PER_SEC) * 100) as u32)
 }
 
diff --git a/library/std/src/sys/pal/xous/time.rs b/library/std/src/sys/pal/xous/time.rs
index ae8be81c0b7..d737416436e 100644
--- a/library/std/src/sys/pal/xous/time.rs
+++ b/library/std/src/sys/pal/xous/time.rs
@@ -43,15 +43,22 @@ impl SystemTime {
         SystemTime { 0: Duration::from_millis((upper as u64) << 32 | lower as u64) }
     }
 
-    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
-        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        // FIXME: ok_or_else with const closures
+        match self.0.checked_sub(other.0) {
+            Some(duration) => Ok(duration),
+            None => Err(other.0 - self.0),
+        }
     }
 
-    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_add(*other)?))
     }
 
-    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
         Some(SystemTime(self.0.checked_sub(*other)?))
     }
 }
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index cd0683f44c9..07bb41f1496 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -551,8 +551,13 @@ impl SystemTime {
     /// println!("{difference:?}");
     /// ```
     #[stable(feature = "time2", since = "1.8.0")]
-    pub fn duration_since(&self, earlier: SystemTime) -> Result<Duration, SystemTimeError> {
-        self.0.sub_time(&earlier.0).map_err(SystemTimeError)
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn duration_since(&self, earlier: SystemTime) -> Result<Duration, SystemTimeError> {
+        // FIXME: map_err in const
+        match self.0.sub_time(&earlier.0) {
+            Ok(time) => Ok(time),
+            Err(err) => Err(SystemTimeError(err)),
+        }
     }
 
     /// Returns the difference from this system time to the
@@ -589,7 +594,8 @@ impl SystemTime {
     /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None`
     /// otherwise.
     #[stable(feature = "time_checked_add", since = "1.34.0")]
-    pub fn checked_add(&self, duration: Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_add(&self, duration: Duration) -> Option<SystemTime> {
         self.0.checked_add_duration(&duration).map(SystemTime)
     }
 
@@ -597,13 +603,15 @@ impl SystemTime {
     /// `SystemTime` (which means it's inside the bounds of the underlying data structure), `None`
     /// otherwise.
     #[stable(feature = "time_checked_add", since = "1.34.0")]
-    pub fn checked_sub(&self, duration: Duration) -> Option<SystemTime> {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn checked_sub(&self, duration: Duration) -> Option<SystemTime> {
         self.0.checked_sub_duration(&duration).map(SystemTime)
     }
 }
 
 #[stable(feature = "time2", since = "1.8.0")]
-impl Add<Duration> for SystemTime {
+#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
+impl const Add<Duration> for SystemTime {
     type Output = SystemTime;
 
     /// # Panics
@@ -616,14 +624,16 @@ impl Add<Duration> for SystemTime {
 }
 
 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
-impl AddAssign<Duration> for SystemTime {
+#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
+impl const AddAssign<Duration> for SystemTime {
     fn add_assign(&mut self, other: Duration) {
         *self = *self + other;
     }
 }
 
 #[stable(feature = "time2", since = "1.8.0")]
-impl Sub<Duration> for SystemTime {
+#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
+impl const Sub<Duration> for SystemTime {
     type Output = SystemTime;
 
     fn sub(self, dur: Duration) -> SystemTime {
@@ -632,7 +642,8 @@ impl Sub<Duration> for SystemTime {
 }
 
 #[stable(feature = "time_augmented_assignment", since = "1.9.0")]
-impl SubAssign<Duration> for SystemTime {
+#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
+impl const SubAssign<Duration> for SystemTime {
     fn sub_assign(&mut self, other: Duration) {
         *self = *self - other;
     }
@@ -699,7 +710,8 @@ impl SystemTimeError {
     /// ```
     #[must_use]
     #[stable(feature = "time2", since = "1.8.0")]
-    pub fn duration(&self) -> Duration {
+    #[rustc_const_unstable(feature = "const_system_time", issue = "144517")]
+    pub const fn duration(&self) -> Duration {
         self.0
     }
 }
diff --git a/library/std/tests/path.rs b/library/std/tests/path.rs
index 901d2770f20..e1576a0d423 100644
--- a/library/std/tests/path.rs
+++ b/library/std/tests/path.rs
@@ -1,10 +1,4 @@
-#![feature(
-    clone_to_uninit,
-    path_add_extension,
-    path_file_prefix,
-    maybe_uninit_slice,
-    normalize_lexically
-)]
+#![feature(clone_to_uninit, path_add_extension, maybe_uninit_slice, normalize_lexically)]
 
 use std::clone::CloneToUninit;
 use std::ffi::OsStr;
diff --git a/library/test/src/cli.rs b/library/test/src/cli.rs
index 8840714a662..1b3f9e2564c 100644
--- a/library/test/src/cli.rs
+++ b/library/test/src/cli.rs
@@ -162,18 +162,17 @@ tests whose names contain the filter are run. Multiple filter strings may
 be passed, which will run all tests matching any of the filters.
 
 By default, all tests are run in parallel. This can be altered with the
---test-threads flag or the RUST_TEST_THREADS environment variable when running
-tests (set it to 1).
+--test-threads flag when running tests (set it to 1).
 
-By default, the tests are run in alphabetical order. Use --shuffle or set
-RUST_TEST_SHUFFLE to run the tests in random order. Pass the generated
-"shuffle seed" to --shuffle-seed (or set RUST_TEST_SHUFFLE_SEED) to run the
-tests in the same order again. Note that --shuffle and --shuffle-seed do not
-affect whether the tests are run in parallel.
+By default, the tests are run in alphabetical order. Use --shuffle to run
+the tests in random order. Pass the generated "shuffle seed" to
+--shuffle-seed to run the tests in the same order again. Note that
+--shuffle and --shuffle-seed do not affect whether the tests are run in
+parallel.
 
 All tests have their standard output and standard error captured by default.
-This can be overridden with the --no-capture flag or setting RUST_TEST_NOCAPTURE
-environment variable to a value other than "0". Logging is not captured by default.
+This can be overridden with the --no-capture flag to a value other than "0".
+Logging is not captured by default.
 
 Test Attributes:
 
diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs
index 0364c664ba5..5865df67b66 100644
--- a/src/bootstrap/src/bin/rustc.rs
+++ b/src/bootstrap/src/bin/rustc.rs
@@ -258,7 +258,7 @@ fn main() {
         eprintln!("{prefix} libdir: {libdir:?}");
     }
 
-    maybe_dump(format!("stage{stage}-rustc"), &cmd);
+    maybe_dump(format!("stage{}-rustc", stage + 1), &cmd);
 
     let start = Instant::now();
     let (child, status) = {
diff --git a/src/bootstrap/src/bin/rustdoc.rs b/src/bootstrap/src/bin/rustdoc.rs
index a338b9c8080..efb51bdce1e 100644
--- a/src/bootstrap/src/bin/rustdoc.rs
+++ b/src/bootstrap/src/bin/rustdoc.rs
@@ -56,11 +56,11 @@ fn main() {
     // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`.
     // We also declare that the flag is expected, which we need to do to not
     // get warnings about it being unexpected.
-    if stage == "0" {
+    if stage == 0 {
         cmd.arg("--cfg=bootstrap");
     }
 
-    maybe_dump(format!("stage{stage}-rustdoc"), &cmd);
+    maybe_dump(format!("stage{}-rustdoc", stage + 1), &cmd);
 
     if verbose > 1 {
         eprintln!(
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index f931aae3c2e..0cbf8f55e99 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -72,7 +72,6 @@ impl Step for Std {
 
     fn run(self, builder: &Builder<'_>) {
         let build_compiler = self.build_compiler;
-        let stage = build_compiler.stage;
         let target = self.target;
 
         let mut cargo = builder::Cargo::new(
@@ -94,10 +93,12 @@ impl Step for Std {
             cargo.arg("-p").arg(krate);
         }
 
-        let _guard = builder.msg_check(
+        let _guard = builder.msg(
+            Kind::Check,
             format_args!("library artifacts{}", crate_description(&self.crates)),
+            Mode::Std,
+            self.build_compiler,
             target,
-            Some(stage),
         );
 
         let stamp = build_stamp::libstd_stamp(builder, build_compiler, target).with_prefix("check");
@@ -136,7 +137,13 @@ impl Step for Std {
 
         let stamp =
             build_stamp::libstd_stamp(builder, build_compiler, target).with_prefix("check-test");
-        let _guard = builder.msg_check("library test/bench/example targets", target, Some(stage));
+        let _guard = builder.msg(
+            Kind::Check,
+            "library test/bench/example targets",
+            Mode::Std,
+            self.build_compiler,
+            target,
+        );
         run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
     }
 
@@ -227,10 +234,12 @@ impl Step for Rustc {
             cargo.arg("-p").arg(krate);
         }
 
-        let _guard = builder.msg_check(
+        let _guard = builder.msg(
+            Kind::Check,
             format_args!("compiler artifacts{}", crate_description(&self.crates)),
+            Mode::Rustc,
+            self.build_compiler,
             target,
-            None,
         );
 
         let stamp =
@@ -357,7 +366,13 @@ impl Step for CodegenBackend {
             .arg(builder.src.join(format!("compiler/{}/Cargo.toml", backend.crate_name())));
         rustc_cargo_env(builder, &mut cargo, target);
 
-        let _guard = builder.msg_check(backend.crate_name(), target, None);
+        let _guard = builder.msg(
+            Kind::Check,
+            backend.crate_name(),
+            Mode::Codegen,
+            self.build_compiler,
+            target,
+        );
 
         let stamp = build_stamp::codegen_backend_stamp(builder, build_compiler, target, &backend)
             .with_prefix("check");
@@ -482,14 +497,7 @@ fn run_tool_check_step(
     let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, mode, target))
         .with_prefix(&format!("{display_name}-check"));
 
-    let stage = match mode {
-        // Mode::ToolRustc is included here because of how msg_sysroot_tool prints stages
-        Mode::Std | Mode::ToolRustc => build_compiler.stage,
-        _ => build_compiler.stage + 1,
-    };
-
-    let _guard =
-        builder.msg_tool(builder.kind, mode, display_name, stage, &build_compiler.host, &target);
+    let _guard = builder.msg(builder.kind, display_name, mode, build_compiler, target);
     run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
 }
 
diff --git a/src/bootstrap/src/core/build_steps/clean.rs b/src/bootstrap/src/core/build_steps/clean.rs
index f67569d1486..8712aeb81eb 100644
--- a/src/bootstrap/src/core/build_steps/clean.rs
+++ b/src/bootstrap/src/core/build_steps/clean.rs
@@ -129,7 +129,7 @@ fn clean_specific_stage(build: &Build, stage: u32) {
 
         for entry in entries {
             let entry = t!(entry);
-            let stage_prefix = format!("stage{stage}");
+            let stage_prefix = format!("stage{}", stage + 1);
 
             // if current entry is not related with the target stage, continue
             if !entry.file_name().to_str().unwrap_or("").contains(&stage_prefix) {
diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs
index 93c767bdd25..4d734fe5c66 100644
--- a/src/bootstrap/src/core/build_steps/clippy.rs
+++ b/src/bootstrap/src/core/build_steps/clippy.rs
@@ -143,11 +143,11 @@ impl Step for Std {
 
     fn run(self, builder: &Builder<'_>) {
         let target = self.target;
-        let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
+        let build_compiler = builder.compiler(builder.top_stage, builder.config.host_target);
 
         let mut cargo = builder::Cargo::new(
             builder,
-            compiler,
+            build_compiler,
             Mode::Std,
             SourceType::InTree,
             target,
@@ -160,14 +160,19 @@ impl Step for Std {
             cargo.arg("-p").arg(krate);
         }
 
-        let _guard =
-            builder.msg_clippy(format_args!("library{}", crate_description(&self.crates)), target);
+        let _guard = builder.msg(
+            Kind::Clippy,
+            format_args!("library{}", crate_description(&self.crates)),
+            Mode::Std,
+            build_compiler,
+            target,
+        );
 
         run_cargo(
             builder,
             cargo,
             lint_args(builder, &self.config, IGNORED_RULES_FOR_STD_AND_RUSTC),
-            &build_stamp::libstd_stamp(builder, compiler, target),
+            &build_stamp::libstd_stamp(builder, build_compiler, target),
             vec![],
             true,
             false,
@@ -203,33 +208,33 @@ impl Step for Rustc {
     /// This will lint the compiler for a particular stage of the build using
     /// the `compiler` targeting the `target` architecture.
     fn run(self, builder: &Builder<'_>) {
-        let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
+        let build_compiler = builder.compiler(builder.top_stage, builder.config.host_target);
         let target = self.target;
 
         if !builder.download_rustc() {
-            if compiler.stage != 0 {
+            if build_compiler.stage != 0 {
                 // If we're not in stage 0, then we won't have a std from the beta
                 // compiler around. That means we need to make sure there's one in
                 // the sysroot for the compiler to find. Otherwise, we're going to
                 // fail when building crates that need to generate code (e.g., build
                 // scripts and their dependencies).
-                builder.std(compiler, compiler.host);
-                builder.std(compiler, target);
+                builder.std(build_compiler, build_compiler.host);
+                builder.std(build_compiler, target);
             } else {
-                builder.ensure(check::Std::new(compiler, target));
+                builder.ensure(check::Std::new(build_compiler, target));
             }
         }
 
         let mut cargo = builder::Cargo::new(
             builder,
-            compiler,
+            build_compiler,
             Mode::Rustc,
             SourceType::InTree,
             target,
             Kind::Clippy,
         );
 
-        rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);
+        rustc_cargo(builder, &mut cargo, target, &build_compiler, &self.crates);
 
         // Explicitly pass -p for all compiler crates -- this will force cargo
         // to also lint the tests/benches/examples for these crates, rather
@@ -238,14 +243,19 @@ impl Step for Rustc {
             cargo.arg("-p").arg(krate);
         }
 
-        let _guard =
-            builder.msg_clippy(format_args!("compiler{}", crate_description(&self.crates)), target);
+        let _guard = builder.msg(
+            Kind::Clippy,
+            format_args!("compiler{}", crate_description(&self.crates)),
+            Mode::Rustc,
+            build_compiler,
+            target,
+        );
 
         run_cargo(
             builder,
             cargo,
             lint_args(builder, &self.config, IGNORED_RULES_FOR_STD_AND_RUSTC),
-            &build_stamp::librustc_stamp(builder, compiler, target),
+            &build_stamp::librustc_stamp(builder, build_compiler, target),
             vec![],
             true,
             false,
@@ -284,16 +294,16 @@ macro_rules! lint_any {
             }
 
             fn run(self, builder: &Builder<'_>) -> Self::Output {
-                let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
+                let build_compiler = builder.compiler(builder.top_stage, builder.config.host_target);
                 let target = self.target;
 
                 if !builder.download_rustc() {
-                    builder.ensure(check::Rustc::new(builder, compiler, target));
+                    builder.ensure(check::Rustc::new(builder, build_compiler, target));
                 };
 
                 let cargo = prepare_tool_cargo(
                     builder,
-                    compiler,
+                    build_compiler,
                     Mode::ToolRustc,
                     target,
                     Kind::Clippy,
@@ -302,17 +312,16 @@ macro_rules! lint_any {
                     &[],
                 );
 
-                let _guard = builder.msg_tool(
+                let _guard = builder.msg(
                     Kind::Clippy,
-                    Mode::ToolRustc,
                     $readable_name,
-                    compiler.stage,
-                    &compiler.host,
-                    &target,
+                    Mode::ToolRustc,
+                    build_compiler,
+                    target,
                 );
 
                 let stringified_name = stringify!($name).to_lowercase();
-                let stamp = BuildStamp::new(&builder.cargo_out(compiler, Mode::ToolRustc, target))
+                let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, Mode::ToolRustc, target))
                     .with_prefix(&format!("{}-check", stringified_name));
 
                 run_cargo(
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 4519731ada7..c8feba48d84 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -159,7 +159,7 @@ impl Step for Std {
             return;
         }
 
-        let compiler = if builder.download_rustc() && self.force_recompile {
+        let build_compiler = if builder.download_rustc() && self.force_recompile {
             // When there are changes in the library tree with CI-rustc, we want to build
             // the stageN library and that requires using stageN-1 compiler.
             builder.compiler(self.compiler.stage.saturating_sub(1), builder.config.host_target)
@@ -173,7 +173,8 @@ impl Step for Std {
             && builder.config.is_host_target(target)
             && !self.force_recompile
         {
-            let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false });
+            let sysroot =
+                builder.ensure(Sysroot { compiler: build_compiler, force_recompile: false });
             cp_rustc_component_to_ci_sysroot(
                 builder,
                 &sysroot,
@@ -182,53 +183,58 @@ impl Step for Std {
             return;
         }
 
-        if builder.config.keep_stage.contains(&compiler.stage)
-            || builder.config.keep_stage_std.contains(&compiler.stage)
+        if builder.config.keep_stage.contains(&build_compiler.stage)
+            || builder.config.keep_stage_std.contains(&build_compiler.stage)
         {
             trace!(keep_stage = ?builder.config.keep_stage);
             trace!(keep_stage_std = ?builder.config.keep_stage_std);
 
             builder.info("WARNING: Using a potentially old libstd. This may not behave well.");
 
-            builder.ensure(StartupObjects { compiler, target });
+            builder.ensure(StartupObjects { compiler: build_compiler, target });
 
-            self.copy_extra_objects(builder, &compiler, target);
+            self.copy_extra_objects(builder, &build_compiler, target);
 
-            builder.ensure(StdLink::from_std(self, compiler));
+            builder.ensure(StdLink::from_std(self, build_compiler));
             return;
         }
 
-        let mut target_deps = builder.ensure(StartupObjects { compiler, target });
+        let mut target_deps = builder.ensure(StartupObjects { compiler: build_compiler, target });
 
-        let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
+        let compiler_to_use =
+            builder.compiler_for(build_compiler.stage, build_compiler.host, target);
         trace!(?compiler_to_use);
 
-        if compiler_to_use != compiler
+        if compiler_to_use != build_compiler
             // Never uplift std unless we have compiled stage 1; if stage 1 is compiled,
             // uplift it from there.
             //
             // FIXME: improve `fn compiler_for` to avoid adding stage condition here.
-            && compiler.stage > 1
+            && build_compiler.stage > 1
         {
-            trace!(?compiler_to_use, ?compiler, "compiler != compiler_to_use, uplifting library");
+            trace!(
+                ?compiler_to_use,
+                ?build_compiler,
+                "build_compiler != compiler_to_use, uplifting library"
+            );
 
             builder.std(compiler_to_use, target);
             let msg = if compiler_to_use.host == target {
                 format!(
                     "Uplifting library (stage{} -> stage{})",
-                    compiler_to_use.stage, compiler.stage
+                    compiler_to_use.stage, build_compiler.stage
                 )
             } else {
                 format!(
                     "Uplifting library (stage{}:{} -> stage{}:{})",
-                    compiler_to_use.stage, compiler_to_use.host, compiler.stage, target
+                    compiler_to_use.stage, compiler_to_use.host, build_compiler.stage, target
                 )
             };
             builder.info(&msg);
 
             // Even if we're not building std this stage, the new sysroot must
             // still contain the third party objects needed by various targets.
-            self.copy_extra_objects(builder, &compiler, target);
+            self.copy_extra_objects(builder, &build_compiler, target);
 
             builder.ensure(StdLink::from_std(self, compiler_to_use));
             return;
@@ -236,11 +242,11 @@ impl Step for Std {
 
         trace!(
             ?compiler_to_use,
-            ?compiler,
+            ?build_compiler,
             "compiler == compiler_to_use, handling not-cross-compile scenario"
         );
 
-        target_deps.extend(self.copy_extra_objects(builder, &compiler, target));
+        target_deps.extend(self.copy_extra_objects(builder, &build_compiler, target));
 
         // We build a sysroot for mir-opt tests using the same trick that Miri does: A check build
         // with -Zalways-encode-mir. This frees us from the need to have a target linker, and the
@@ -249,7 +255,7 @@ impl Step for Std {
             trace!("building special sysroot for mir-opt tests");
             let mut cargo = builder::Cargo::new_for_mir_opt_tests(
                 builder,
-                compiler,
+                build_compiler,
                 Mode::Std,
                 SourceType::InTree,
                 target,
@@ -262,7 +268,7 @@ impl Step for Std {
             trace!("building regular sysroot");
             let mut cargo = builder::Cargo::new(
                 builder,
-                compiler,
+                build_compiler,
                 Mode::Std,
                 SourceType::InTree,
                 target,
@@ -285,16 +291,16 @@ impl Step for Std {
 
         let _guard = builder.msg(
             Kind::Build,
-            compiler.stage,
             format_args!("library artifacts{}", crate_description(&self.crates)),
-            compiler.host,
+            Mode::Std,
+            build_compiler,
             target,
         );
         run_cargo(
             builder,
             cargo,
             vec![],
-            &build_stamp::libstd_stamp(builder, compiler, target),
+            &build_stamp::libstd_stamp(builder, build_compiler, target),
             target_deps,
             self.is_for_mir_opt_tests, // is_check
             false,
@@ -302,7 +308,7 @@ impl Step for Std {
 
         builder.ensure(StdLink::from_std(
             self,
-            builder.compiler(compiler.stage, builder.config.host_target),
+            builder.compiler(build_compiler.stage, builder.config.host_target),
         ));
     }
 
@@ -1126,11 +1132,11 @@ impl Step for Rustc {
             cargo.env("RUSTC_BOLT_LINK_FLAGS", "1");
         }
 
-        let _guard = builder.msg_rustc_tool(
+        let _guard = builder.msg(
             Kind::Build,
-            build_compiler.stage,
             format_args!("compiler artifacts{}", crate_description(&self.crates)),
-            build_compiler.host,
+            Mode::Rustc,
+            build_compiler,
             target,
         );
         let stamp = build_stamp::librustc_stamp(builder, build_compiler, target);
@@ -1603,13 +1609,8 @@ impl Step for GccCodegenBackend {
         let gcc = builder.ensure(Gcc { target });
         add_cg_gcc_cargo_flags(&mut cargo, &gcc);
 
-        let _guard = builder.msg_rustc_tool(
-            Kind::Build,
-            build_compiler.stage,
-            "codegen backend gcc",
-            build_compiler.host,
-            target,
-        );
+        let _guard =
+            builder.msg(Kind::Build, "codegen backend gcc", Mode::Codegen, build_compiler, target);
         let files = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false);
         write_codegen_backend_stamp(stamp, files, builder.config.dry_run())
     }
@@ -1687,11 +1688,11 @@ impl Step for CraneliftCodegenBackend {
             .arg(builder.src.join("compiler/rustc_codegen_cranelift/Cargo.toml"));
         rustc_cargo_env(builder, &mut cargo, target);
 
-        let _guard = builder.msg_rustc_tool(
+        let _guard = builder.msg(
             Kind::Build,
-            build_compiler.stage,
             "codegen backend cranelift",
-            build_compiler.host,
+            Mode::Codegen,
+            build_compiler,
             target,
         );
         let files = run_cargo(builder, cargo, vec![], &stamp, vec![], false, false);
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index ca7a6dc8e07..6f0d5203d11 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -239,7 +239,7 @@ impl Step for TheBook {
     fn run(self, builder: &Builder<'_>) {
         builder.require_submodule("src/doc/book", None);
 
-        let compiler = self.build_compiler;
+        let build_compiler = self.build_compiler;
         let target = self.target;
 
         let absolute_path = builder.src.join("src/doc/book");
@@ -273,20 +273,20 @@ impl Step for TheBook {
         let shared_assets = builder.ensure(SharedAssets { target });
 
         // build the redirect pages
-        let _guard = builder.msg_doc(compiler, "book redirect pages", target);
+        let _guard = builder.msg(Kind::Doc, "book redirect pages", None, build_compiler, target);
         for file in t!(fs::read_dir(redirect_path)) {
             let file = t!(file);
             let path = file.path();
             let path = path.to_str().unwrap();
 
-            invoke_rustdoc(builder, compiler, &shared_assets, target, path);
+            invoke_rustdoc(builder, build_compiler, &shared_assets, target, path);
         }
     }
 }
 
 fn invoke_rustdoc(
     builder: &Builder<'_>,
-    compiler: Compiler,
+    build_compiler: Compiler,
     shared_assets: &SharedAssetsPaths,
     target: TargetSelection,
     markdown: &str,
@@ -298,7 +298,7 @@ fn invoke_rustdoc(
     let header = builder.src.join("src/doc/redirect.inc");
     let footer = builder.src.join("src/doc/footer.inc");
 
-    let mut cmd = builder.rustdoc_cmd(compiler);
+    let mut cmd = builder.rustdoc_cmd(build_compiler);
 
     let out = out.join("book");
 
@@ -362,7 +362,7 @@ impl Step for Standalone {
     fn run(self, builder: &Builder<'_>) {
         let target = self.target;
         let build_compiler = self.build_compiler;
-        let _guard = builder.msg_doc(build_compiler, "standalone", target);
+        let _guard = builder.msg(Kind::Doc, "standalone", None, build_compiler, target);
         let out = builder.doc_out(target);
         t!(fs::create_dir_all(&out));
 
@@ -469,7 +469,7 @@ impl Step for Releases {
     fn run(self, builder: &Builder<'_>) {
         let target = self.target;
         let build_compiler = self.build_compiler;
-        let _guard = builder.msg_doc(build_compiler, "releases", target);
+        let _guard = builder.msg(Kind::Doc, "releases", None, build_compiler, target);
         let out = builder.doc_out(target);
         t!(fs::create_dir_all(&out));
 
@@ -784,7 +784,7 @@ fn doc_std(
 
     let description =
         format!("library{} in {} format", crate_description(requested_crates), format.as_str());
-    let _guard = builder.msg_doc(build_compiler, description, target);
+    let _guard = builder.msg(Kind::Doc, description, None, build_compiler, target);
 
     cargo.into_cmd().run(builder);
     builder.cp_link_r(&out_dir, out);
@@ -861,11 +861,11 @@ impl Step for Rustc {
         let build_compiler = self.build_compiler;
         builder.std(build_compiler, builder.config.host_target);
 
-        let _guard = builder.msg_rustc_tool(
+        let _guard = builder.msg(
             Kind::Doc,
-            build_compiler.stage,
             format!("compiler{}", crate_description(&self.crates)),
-            build_compiler.host,
+            Mode::Rustc,
+            build_compiler,
             target,
         );
 
@@ -1059,7 +1059,7 @@ macro_rules! tool_doc {
                 let proc_macro_out_dir = builder.stage_out(build_compiler, mode).join("doc");
                 symlink_dir_force(&builder.config, &out, &proc_macro_out_dir);
 
-                let _guard = builder.msg_doc(build_compiler, stringify!($tool).to_lowercase(), target);
+                let _guard = builder.msg(Kind::Doc, stringify!($tool).to_lowercase(), None, build_compiler, target);
                 cargo.into_cmd().run(builder);
 
                 if !builder.config.dry_run() {
@@ -1314,13 +1314,8 @@ impl Step for RustcBook {
         // bootstrap.toml), then this needs to explicitly update the dylib search
         // path.
         builder.add_rustc_lib_path(self.build_compiler, &mut cmd);
-        let doc_generator_guard = builder.msg(
-            Kind::Run,
-            self.build_compiler.stage,
-            "lint-docs",
-            self.build_compiler.host,
-            self.target,
-        );
+        let doc_generator_guard =
+            builder.msg(Kind::Run, "lint-docs", None, self.build_compiler, self.target);
         cmd.run(builder);
         drop(doc_generator_guard);
 
diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs
index 32eec8cefab..666f2715224 100644
--- a/src/bootstrap/src/core/build_steps/install.rs
+++ b/src/bootstrap/src/core/build_steps/install.rs
@@ -68,7 +68,13 @@ fn install_sh(
     host: Option<TargetSelection>,
     tarball: &GeneratedTarball,
 ) {
-    let _guard = builder.msg(Kind::Install, stage, package, host, host);
+    let _guard = builder.msg(
+        Kind::Install,
+        package,
+        None,
+        (host.unwrap_or(builder.host_target), stage),
+        host,
+    );
 
     let prefix = default_path(&builder.config.prefix, "/usr/local");
     let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc"));
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 2f933baa4a4..f1be0af3183 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -161,8 +161,7 @@ You can skip linkcheck with --skip src/tools/linkchecker"
         let linkchecker = builder.tool_cmd(Tool::Linkchecker);
 
         // Run the linkchecker.
-        let _guard =
-            builder.msg(Kind::Test, compiler.stage, "Linkcheck", bootstrap_host, bootstrap_host);
+        let _guard = builder.msg(Kind::Test, "Linkcheck", None, compiler, bootstrap_host);
         let _time = helpers::timeit(builder);
         linkchecker.delay_failure().arg(builder.out.join(host).join("doc")).run(builder);
     }
@@ -541,8 +540,7 @@ impl Miri {
         cargo.env("MIRI_SYSROOT", &miri_sysroot);
 
         let mut cargo = BootstrapCommand::from(cargo);
-        let _guard =
-            builder.msg(Kind::Build, compiler.stage, "miri sysroot", compiler.host, target);
+        let _guard = builder.msg(Kind::Build, "miri sysroot", Mode::ToolRustc, compiler, target);
         cargo.run(builder);
 
         // # Determine where Miri put its sysroot.
@@ -643,7 +641,8 @@ impl Step for Miri {
         cargo.env("MIRI_TEST_TARGET", target.rustc_target_arg());
 
         {
-            let _guard = builder.msg_rustc_tool(Kind::Test, stage, "miri", host, target);
+            let _guard =
+                builder.msg(Kind::Test, "miri", Mode::ToolRustc, miri.build_compiler, target);
             let _time = helpers::timeit(builder);
             cargo.run(builder);
         }
@@ -659,11 +658,11 @@ impl Step for Miri {
             cargo.args(["tests/pass", "tests/panic"]);
 
             {
-                let _guard = builder.msg_rustc_tool(
+                let _guard = builder.msg(
                     Kind::Test,
-                    stage,
                     "miri (mir-opt-level 4)",
-                    host,
+                    Mode::ToolRustc,
+                    miri.build_compiler,
                     target,
                 );
                 let _time = helpers::timeit(builder);
@@ -703,7 +702,7 @@ impl Step for CargoMiri {
         }
 
         // This compiler runs on the host, we'll just use it for the target.
-        let compiler = builder.compiler(stage, host);
+        let build_compiler = builder.compiler(stage, host);
 
         // Run `cargo miri test`.
         // This is just a smoke test (Miri's own CI invokes this in a bunch of different ways and ensures
@@ -711,7 +710,7 @@ impl Step for CargoMiri {
         // itself executes properly under Miri, and that all the logic in `cargo-miri` does not explode.
         let mut cargo = tool::prepare_tool_cargo(
             builder,
-            compiler,
+            build_compiler,
             Mode::ToolStd, // it's unclear what to use here, we're not building anything just doing a smoke test!
             target,
             Kind::MiriTest,
@@ -736,7 +735,8 @@ impl Step for CargoMiri {
         // Finally, run everything.
         let mut cargo = BootstrapCommand::from(cargo);
         {
-            let _guard = builder.msg_rustc_tool(Kind::Test, stage, "cargo-miri", host, target);
+            let _guard =
+                builder.msg(Kind::Test, "cargo-miri", Mode::ToolRustc, (host, stage), target);
             let _time = helpers::timeit(builder);
             cargo.run(builder);
         }
@@ -830,7 +830,7 @@ impl Step for Clippy {
 
     /// Runs `cargo test` for clippy.
     fn run(self, builder: &Builder<'_>) {
-        let host = self.compilers.target();
+        let target = self.compilers.target();
 
         // We need to carefully distinguish the compiler that builds clippy, and the compiler
         // that is linked into the clippy being tested. `target_compiler` is the latter,
@@ -844,7 +844,7 @@ impl Step for Clippy {
             builder,
             build_compiler,
             Mode::ToolRustc,
-            host,
+            target,
             Kind::Test,
             "src/tools/clippy",
             SourceType::InTree,
@@ -858,7 +858,7 @@ impl Step for Clippy {
         cargo.env("HOST_LIBS", host_libs);
 
         // Build the standard library that the tests can use.
-        builder.std(target_compiler, host);
+        builder.std(target_compiler, target);
         cargo.env("TEST_SYSROOT", builder.sysroot(target_compiler));
         cargo.env("TEST_RUSTC", builder.rustc(target_compiler));
         cargo.env("TEST_RUSTC_LIB", builder.rustc_libdir(target_compiler));
@@ -881,9 +881,9 @@ impl Step for Clippy {
         }
 
         cargo.add_rustc_lib_path(builder);
-        let cargo = prepare_cargo_test(cargo, &[], &[], host, builder);
+        let cargo = prepare_cargo_test(cargo, &[], &[], target, builder);
 
-        let _guard = builder.msg_rustc_tool(Kind::Test, build_compiler.stage, "clippy", host, host);
+        let _guard = builder.msg(Kind::Test, "clippy", Mode::ToolRustc, build_compiler, target);
 
         // Clippy reports errors if it blessed the outputs
         if cargo.allow_failure().run(builder) {
@@ -990,9 +990,9 @@ impl Step for RustdocJSStd {
         ));
         let _guard = builder.msg(
             Kind::Test,
-            builder.top_stage,
             "rustdoc-js-std",
-            builder.config.host_target,
+            None,
+            (builder.config.host_target, builder.top_stage),
             self.target,
         );
         command.run(builder);
@@ -1141,13 +1141,7 @@ impl Step for RustdocGUI {
         }
 
         let _time = helpers::timeit(builder);
-        let _guard = builder.msg_rustc_tool(
-            Kind::Test,
-            self.compiler.stage,
-            "rustdoc-gui",
-            self.compiler.host,
-            self.target,
-        );
+        let _guard = builder.msg(Kind::Test, "rustdoc-gui", None, self.compiler, self.target);
         try_run_tests(builder, &mut cmd, true);
     }
 }
@@ -2237,9 +2231,10 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
 
         let _group = builder.msg(
             Kind::Test,
-            compiler.stage,
             format!("compiletest suite={suite} mode={mode}"),
-            compiler.host,
+            // FIXME: compiletest sometimes behaves as ToolStd, we could expose that difference here
+            Mode::ToolBootstrap,
+            compiler,
             target,
         );
         try_run_tests(builder, &mut cmd, false);
@@ -2381,9 +2376,9 @@ impl BookTest {
         builder.add_rust_test_threads(&mut rustbook_cmd);
         let _guard = builder.msg(
             Kind::Test,
-            compiler.stage,
             format_args!("mdbook {}", self.path.display()),
-            compiler.host,
+            None,
+            compiler,
             compiler.host,
         );
         let _time = helpers::timeit(builder);
@@ -2402,8 +2397,7 @@ impl BookTest {
 
         builder.std(compiler, host);
 
-        let _guard =
-            builder.msg(Kind::Test, compiler.stage, format!("book {}", self.name), host, host);
+        let _guard = builder.msg(Kind::Test, format!("book {}", self.name), None, compiler, host);
 
         // Do a breadth-first traversal of the `src/doc` directory and just run
         // tests for all files that end in `*.md`
@@ -2547,9 +2541,9 @@ impl Step for ErrorIndex {
 
         let guard = builder.msg(
             Kind::Test,
-            target_compiler.stage,
             "error-index",
-            target_compiler.host,
+            None,
+            self.compilers.build_compiler(),
             target_compiler.host,
         );
         let _time = helpers::timeit(builder);
@@ -2650,9 +2644,8 @@ fn run_cargo_test<'a>(
     let compiler = cargo.compiler();
     let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, target, builder);
     let _time = helpers::timeit(builder);
-    let _group = description.into().and_then(|what| {
-        builder.msg_rustc_tool(Kind::Test, compiler.stage, what, compiler.host, target)
-    });
+    let _group =
+        description.into().and_then(|what| builder.msg(Kind::Test, what, None, compiler, target));
 
     #[cfg(feature = "build-metrics")]
     builder.metrics.begin_test_suite(
@@ -3176,8 +3169,9 @@ impl Step for Bootstrap {
     /// Tests the build system itself.
     fn run(self, builder: &Builder<'_>) {
         let host = builder.config.host_target;
-        let compiler = builder.compiler(0, host);
-        let _guard = builder.msg(Kind::Test, 0, "bootstrap", host, host);
+        let build_compiler = builder.compiler(0, host);
+        let _guard =
+            builder.msg(Kind::Test, "bootstrap", Mode::ToolBootstrap, build_compiler, host);
 
         // Some tests require cargo submodule to be present.
         builder.build.require_submodule("src/tools/cargo", None);
@@ -3196,7 +3190,7 @@ impl Step for Bootstrap {
 
         let mut cargo = tool::prepare_tool_cargo(
             builder,
-            compiler,
+            build_compiler,
             Mode::ToolBootstrap,
             host,
             Kind::Test,
@@ -3276,9 +3270,9 @@ impl Step for TierCheck {
 
         let _guard = builder.msg(
             Kind::Test,
-            self.compiler.stage,
             "platform support check",
-            self.compiler.host,
+            None,
+            self.compiler,
             self.compiler.host,
         );
         BootstrapCommand::from(cargo).delay_failure().run(builder);
@@ -3326,10 +3320,10 @@ impl Step for RustInstaller {
     /// Ensure the version placeholder replacement tool builds
     fn run(self, builder: &Builder<'_>) {
         let bootstrap_host = builder.config.host_target;
-        let compiler = builder.compiler(0, bootstrap_host);
+        let build_compiler = builder.compiler(0, bootstrap_host);
         let cargo = tool::prepare_tool_cargo(
             builder,
-            compiler,
+            build_compiler,
             Mode::ToolBootstrap,
             bootstrap_host,
             Kind::Test,
@@ -3338,13 +3332,8 @@ impl Step for RustInstaller {
             &[],
         );
 
-        let _guard = builder.msg(
-            Kind::Test,
-            compiler.stage,
-            "rust-installer",
-            bootstrap_host,
-            bootstrap_host,
-        );
+        let _guard =
+            builder.msg(Kind::Test, "rust-installer", None, build_compiler, bootstrap_host);
         run_cargo_test(cargo, &[], &[], None, bootstrap_host, builder);
 
         // We currently don't support running the test.sh script outside linux(?) environments.
@@ -3355,7 +3344,7 @@ impl Step for RustInstaller {
         }
 
         let mut cmd = command(builder.src.join("src/tools/rust-installer/test.sh"));
-        let tmpdir = testdir(builder, compiler.host).join("rust-installer");
+        let tmpdir = testdir(builder, build_compiler.host).join("rust-installer");
         let _ = std::fs::remove_dir_all(&tmpdir);
         let _ = std::fs::create_dir_all(&tmpdir);
         cmd.current_dir(&tmpdir);
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 42f59f00e5a..793e6b629c9 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -26,7 +26,7 @@ use crate::core::builder::{
 use crate::core::config::{DebuginfoLevel, RustcLto, TargetSelection};
 use crate::utils::exec::{BootstrapCommand, command};
 use crate::utils::helpers::{add_dylib_path, exe, t};
-use crate::{Compiler, FileType, Kind, Mode, gha};
+use crate::{Compiler, FileType, Kind, Mode};
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub enum SourceType {
@@ -58,28 +58,6 @@ struct ToolBuild {
     artifact_kind: ToolArtifactKind,
 }
 
-impl Builder<'_> {
-    #[track_caller]
-    pub(crate) fn msg_tool(
-        &self,
-        kind: Kind,
-        mode: Mode,
-        tool: &str,
-        build_stage: u32,
-        host: &TargetSelection,
-        target: &TargetSelection,
-    ) -> Option<gha::Group> {
-        match mode {
-            // depends on compiler stage, different to host compiler
-            Mode::ToolRustc => {
-                self.msg_rustc_tool(kind, build_stage, format_args!("tool {tool}"), *host, *target)
-            }
-            // doesn't depend on compiler, same as host compiler
-            _ => self.msg(kind, build_stage, format_args!("tool {tool}"), *host, *target),
-        }
-    }
-}
-
 /// Result of the tool build process. Each `Step` in this module is responsible
 /// for using this type as `type Output = ToolBuildResult;`
 #[derive(Clone)]
@@ -166,14 +144,8 @@ impl Step for ToolBuild {
 
         cargo.args(self.cargo_args);
 
-        let _guard = builder.msg_tool(
-            Kind::Build,
-            self.mode,
-            self.tool,
-            self.build_compiler.stage,
-            &self.build_compiler.host,
-            &self.target,
-        );
+        let _guard =
+            builder.msg(Kind::Build, self.tool, self.mode, self.build_compiler, self.target);
 
         // we check this below
         let build_success = compile::stream_cargo(builder, cargo, vec![], &mut |_| {});
@@ -380,13 +352,13 @@ pub(crate) fn get_tool_target_compiler(
 /// tools directory.
 fn copy_link_tool_bin(
     builder: &Builder<'_>,
-    compiler: Compiler,
+    build_compiler: Compiler,
     target: TargetSelection,
     mode: Mode,
     name: &str,
 ) -> PathBuf {
-    let cargo_out = builder.cargo_out(compiler, mode, target).join(exe(name, target));
-    let bin = builder.tools_dir(compiler).join(exe(name, target));
+    let cargo_out = builder.cargo_out(build_compiler, mode, target).join(exe(name, target));
+    let bin = builder.tools_dir(build_compiler).join(exe(name, target));
     builder.copy_link(&cargo_out, &bin, FileType::Executable);
     bin
 }
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index 163a498d4b4..de4b941ac90 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -1597,7 +1597,7 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s
         cmd.env("CARGO", &self.initial_cargo);
         // Need to add the `run_compiler` libs. Those are the libs produces *by* `build_compiler`
         // in `tool::ToolBuild` step, so they match the Miri we just built. However this means they
-        // are actually living one stage up, i.e. we are running `stage0-tools-bin/miri` with the
+        // are actually living one stage up, i.e. we are running `stage1-tools-bin/miri` with the
         // libraries in `stage1/lib`. This is an unfortunate off-by-1 caused (possibly) by the fact
         // that Miri doesn't have an "assemble" step like rustc does that would cross the stage boundary.
         // We can't use `add_rustc_lib_path` as that's a NOP on Windows but we do need these libraries
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 4abf386e5de..0b65ebc0671 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -410,6 +410,25 @@ forward! {
     download_rustc() -> bool,
 }
 
+/// A mostly temporary helper struct before we can migrate everything in bootstrap to use
+/// the concept of a build compiler.
+struct HostAndStage {
+    host: TargetSelection,
+    stage: u32,
+}
+
+impl From<(TargetSelection, u32)> for HostAndStage {
+    fn from((host, stage): (TargetSelection, u32)) -> Self {
+        Self { host, stage }
+    }
+}
+
+impl From<Compiler> for HostAndStage {
+    fn from(compiler: Compiler) -> Self {
+        Self { host: compiler.host, stage: compiler.stage }
+    }
+}
+
 impl Build {
     /// Creates a new set of build configuration from the `flags` on the command
     /// line and the filesystem `config`.
@@ -859,14 +878,17 @@ impl Build {
         if self.config.rust_optimize.is_release() { "release" } else { "debug" }
     }
 
-    fn tools_dir(&self, compiler: Compiler) -> PathBuf {
-        let out = self.out.join(compiler.host).join(format!("stage{}-tools-bin", compiler.stage));
+    fn tools_dir(&self, build_compiler: Compiler) -> PathBuf {
+        let out = self
+            .out
+            .join(build_compiler.host)
+            .join(format!("stage{}-tools-bin", build_compiler.stage + 1));
         t!(fs::create_dir_all(&out));
         out
     }
 
     /// Returns the root directory for all output generated in a particular
-    /// stage when running with a particular host compiler.
+    /// stage when being built with a particular build compiler.
     ///
     /// The mode indicates what the root directory is for.
     fn stage_out(&self, build_compiler: Compiler, mode: Mode) -> PathBuf {
@@ -876,15 +898,17 @@ impl Build {
             (None, "bootstrap-tools")
         }
         fn staged_tool(build_compiler: Compiler) -> (Option<u32>, &'static str) {
-            (Some(build_compiler.stage), "tools")
+            (Some(build_compiler.stage + 1), "tools")
         }
 
         let (stage, suffix) = match mode {
+            // Std is special, stage N std is built with stage N rustc
             Mode::Std => (Some(build_compiler.stage), "std"),
-            Mode::Rustc => (Some(build_compiler.stage), "rustc"),
-            Mode::Codegen => (Some(build_compiler.stage), "codegen"),
+            // The rest of things are built with stage N-1 rustc
+            Mode::Rustc => (Some(build_compiler.stage + 1), "rustc"),
+            Mode::Codegen => (Some(build_compiler.stage + 1), "codegen"),
             Mode::ToolBootstrap => bootstrap_tool(),
-            Mode::ToolStd | Mode::ToolRustc => (Some(build_compiler.stage), "tools"),
+            Mode::ToolStd | Mode::ToolRustc => (Some(build_compiler.stage + 1), "tools"),
             Mode::ToolTarget => {
                 // If we're not cross-compiling (the common case), share the target directory with
                 // bootstrap tools to reuse the build cache.
@@ -907,8 +931,8 @@ impl Build {
     /// Returns the root output directory for all Cargo output in a given stage,
     /// running a particular compiler, whether or not we're building the
     /// standard library, and targeting the specified architecture.
-    fn cargo_out(&self, compiler: Compiler, mode: Mode, target: TargetSelection) -> PathBuf {
-        self.stage_out(compiler, mode).join(target).join(self.cargo_dir())
+    fn cargo_out(&self, build_compiler: Compiler, mode: Mode, target: TargetSelection) -> PathBuf {
+        self.stage_out(build_compiler, mode).join(target).join(self.cargo_dir())
     }
 
     /// Root output directory of LLVM for `target`
@@ -1067,45 +1091,14 @@ impl Build {
         }
     }
 
-    #[must_use = "Groups should not be dropped until the Step finishes running"]
-    #[track_caller]
-    fn msg_clippy(
-        &self,
-        what: impl Display,
-        target: impl Into<Option<TargetSelection>>,
-    ) -> Option<gha::Group> {
-        self.msg(Kind::Clippy, self.config.stage, what, self.config.host_target, target)
-    }
-
-    #[must_use = "Groups should not be dropped until the Step finishes running"]
-    #[track_caller]
-    fn msg_check(
-        &self,
-        what: impl Display,
-        target: impl Into<Option<TargetSelection>>,
-        custom_stage: Option<u32>,
-    ) -> Option<gha::Group> {
-        self.msg(
-            Kind::Check,
-            custom_stage.unwrap_or(self.config.stage),
-            what,
-            self.config.host_target,
-            target,
-        )
-    }
-
-    #[must_use = "Groups should not be dropped until the Step finishes running"]
-    #[track_caller]
-    fn msg_doc(
-        &self,
-        compiler: Compiler,
-        what: impl Display,
-        target: impl Into<Option<TargetSelection>> + Copy,
-    ) -> Option<gha::Group> {
-        self.msg(Kind::Doc, compiler.stage, what, compiler.host, target.into())
-    }
-
-    /// Return a `Group` guard for a [`Step`] that is built for each `--stage`.
+    /// Return a `Group` guard for a [`Step`] that:
+    /// - Performs `action`
+    /// - On `what`
+    ///   - Where `what` possibly corresponds to a `mode`
+    /// - `action` is performed using the given build compiler (`host_and_stage`).
+    ///   - Since some steps do not use the concept of a build compiler yet, it is also possible
+    ///     to pass the host and stage explicitly.
+    /// - With a given `target`.
     ///
     /// [`Step`]: crate::core::builder::Step
     #[must_use = "Groups should not be dropped until the Step finishes running"]
@@ -1113,19 +1106,36 @@ impl Build {
     fn msg(
         &self,
         action: impl Into<Kind>,
-        stage: u32,
         what: impl Display,
-        host: impl Into<Option<TargetSelection>>,
+        mode: impl Into<Option<Mode>>,
+        host_and_stage: impl Into<HostAndStage>,
         target: impl Into<Option<TargetSelection>>,
     ) -> Option<gha::Group> {
+        let host_and_stage = host_and_stage.into();
+        let actual_stage = match mode.into() {
+            // Std has the same stage as the compiler that builds it
+            Some(Mode::Std) => host_and_stage.stage,
+            // Other things have stage corresponding to their build compiler + 1
+            Some(
+                Mode::Rustc
+                | Mode::Codegen
+                | Mode::ToolBootstrap
+                | Mode::ToolTarget
+                | Mode::ToolStd
+                | Mode::ToolRustc,
+            )
+            | None => host_and_stage.stage + 1,
+        };
+
         let action = action.into().description();
-        let msg = |fmt| format!("{action} stage{stage} {what}{fmt}");
+        let msg = |fmt| format!("{action} stage{actual_stage} {what}{fmt}");
         let msg = if let Some(target) = target.into() {
-            let host = host.into().unwrap();
+            let build_stage = host_and_stage.stage;
+            let host = host_and_stage.host;
             if host == target {
-                msg(format_args!(" ({target})"))
+                msg(format_args!(" (stage{build_stage} -> stage{actual_stage}, {target})"))
             } else {
-                msg(format_args!(" ({host} -> {target})"))
+                msg(format_args!(" (stage{build_stage}:{host} -> stage{actual_stage}:{target})"))
             }
         } else {
             msg(format_args!(""))
@@ -1149,27 +1159,6 @@ impl Build {
         self.group(&msg)
     }
 
-    #[must_use = "Groups should not be dropped until the Step finishes running"]
-    #[track_caller]
-    fn msg_rustc_tool(
-        &self,
-        action: impl Into<Kind>,
-        build_stage: u32,
-        what: impl Display,
-        host: TargetSelection,
-        target: TargetSelection,
-    ) -> Option<gha::Group> {
-        let action = action.into().description();
-        let msg = |fmt| format!("{action} {what} {fmt}");
-
-        let msg = if host == target {
-            msg(format_args!("(stage{build_stage} -> stage{}, {target})", build_stage + 1))
-        } else {
-            msg(format_args!("(stage{build_stage}:{host} -> stage{}:{target})", build_stage + 1))
-        };
-        self.group(&msg)
-    }
-
     #[track_caller]
     fn group(&self, msg: &str) -> Option<gha::Group> {
         match self.config.get_dry_run() {
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 091956e7e5f..cd7fba39a84 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -496,4 +496,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Warning,
         summary: "It is no longer possible to `x doc` with stage 0. All doc commands have to be on stage 1+.",
     },
+    ChangeInfo {
+        change_id: 145295,
+        severity: ChangeSeverity::Warning,
+        summary: "The names of stageN directories in the build directory have been consolidated with the new (post-stage-0-redesign) staging scheme. Some tools and binaries might be located in a different build directory than before.",
+    },
 ];
diff --git a/src/bootstrap/src/utils/shared_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs
index 9428e221f41..d620cc4bbb6 100644
--- a/src/bootstrap/src/utils/shared_helpers.rs
+++ b/src/bootstrap/src/utils/shared_helpers.rs
@@ -81,10 +81,11 @@ pub fn parse_rustc_verbose() -> usize {
 }
 
 /// Parses the value of the "RUSTC_STAGE" environment variable and returns it as a `String`.
+/// This is the stage of the *build compiler*, which we are wrapping using a rustc/rustdoc wrapper.
 ///
 /// If "RUSTC_STAGE" was not set, the program will be terminated with 101.
-pub fn parse_rustc_stage() -> String {
-    env::var("RUSTC_STAGE").unwrap_or_else(|_| {
+pub fn parse_rustc_stage() -> u32 {
+    env::var("RUSTC_STAGE").ok().and_then(|v| v.parse().ok()).unwrap_or_else(|| {
         // Don't panic here; it's reasonable to try and run these shims directly. Give a helpful error instead.
         eprintln!("rustc shim: FATAL: RUSTC_STAGE was not set");
         eprintln!("rustc shim: NOTE: use `x.py build -vvv` to see all environment variables set by bootstrap");
diff --git a/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile b/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile
index 2b8a3f829c6..e726329753f 100644
--- a/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile
+++ b/src/ci/docker/host-aarch64/dist-aarch64-linux/Dockerfile
@@ -96,7 +96,7 @@ ENV RUST_CONFIGURE_ARGS \
       --set rust.codegen-units=1
 
 ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \
-      ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci --  python3 ../x.py dist \
+      ./build/$HOSTS/stage1-tools-bin/opt-dist linux-ci --  python3 ../x.py dist \
       --host $HOSTS --target $HOSTS --include-default-paths build-manifest bootstrap
 
 ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=clang
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh
index 924bdbc7615..4c95d4a401e 100755
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh
@@ -4,7 +4,7 @@ set -eux
 
 python3 ../x.py build --set rust.debug=true opt-dist
 
-./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \
+./build/$HOSTS/stage1-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \
     --host $HOSTS --target $HOSTS \
     --include-default-paths \
     build-manifest bootstrap
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index 48c570bfa11..ae13d14c380 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -656,7 +656,7 @@ auto:
         --enable-full-tools
         --enable-profiler
         --set rust.codegen-units=1
-      SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage0-tools-bin/opt-dist windows-ci -- python x.py dist bootstrap --include-default-paths
+      SCRIPT: python x.py build --set rust.debug=true opt-dist && PGO_HOST=x86_64-pc-windows-msvc ./build/x86_64-pc-windows-msvc/stage1-tools-bin/opt-dist windows-ci -- python x.py dist bootstrap --include-default-paths
       DIST_REQUIRE_ALL_TOOLS: 1
       CODEGEN_BACKENDS: llvm,cranelift
     <<: *job-windows-8c
diff --git a/src/doc/rustc-dev-guide/src/building/optimized-build.md b/src/doc/rustc-dev-guide/src/building/optimized-build.md
index 863ed9749fb..46def66d178 100644
--- a/src/doc/rustc-dev-guide/src/building/optimized-build.md
+++ b/src/doc/rustc-dev-guide/src/building/optimized-build.md
@@ -118,7 +118,7 @@ Here is an example of how can `opt-dist` be used locally (outside of CI):
     ```
 3. Run the tool with the `local` mode and provide necessary parameters:
     ```bash
-    ./build/host/stage0-tools-bin/opt-dist local \
+    ./build/host/stage1-tools-bin/opt-dist local \
       --target-triple <target> \ # select target, e.g. "x86_64-unknown-linux-gnu"
       --checkout-dir <path>    \ # path to rust checkout, e.g. "."
       --llvm-dir <path>        \ # path to built LLVM toolchain, e.g. "/foo/bar/llvm/install"
diff --git a/src/doc/rustc/src/tests/index.md b/src/doc/rustc/src/tests/index.md
index 12de69a4c9e..7609ed23351 100644
--- a/src/doc/rustc/src/tests/index.md
+++ b/src/doc/rustc/src/tests/index.md
@@ -164,7 +164,7 @@ Sets the number of threads to use for running tests in parallel. By default,
 uses the amount of concurrency available on the hardware as indicated by
 [`available_parallelism`].
 
-This can also be specified with the `RUST_TEST_THREADS` environment variable.
+Deprecated: this can also be specified with the `RUST_TEST_THREADS` environment variable.
 
 #### `--force-run-in-process`
 
@@ -186,7 +186,7 @@ docs](../../unstable-book/compiler-flags/report-time.html) for more information.
 
 Runs the tests in random order, as opposed to the default alphabetical order.
 
-This may also be specified by setting the `RUST_TEST_SHUFFLE` environment
+Deprecated: this may also be specified by setting the `RUST_TEST_SHUFFLE` environment
 variable to anything but `0`.
 
 The random number generator seed that is output can be passed to
@@ -209,7 +209,7 @@ the tests in the same order both times.
 _SEED_ is any 64-bit unsigned integer, for example, one produced by
 [`--shuffle`](#--shuffle).
 
-This can also be specified with the `RUST_TEST_SHUFFLE_SEED` environment
+Deprecated: this can also be specified with the `RUST_TEST_SHUFFLE_SEED` environment
 variable.
 
 ⚠️ 🚧 This option is [unstable](#unstable-options), and requires the `-Z
@@ -231,7 +231,7 @@ Does not capture the stdout and stderr of the test, and allows tests to print
 to the console. Usually the output is captured, and only displayed if the test
 fails.
 
-This may also be specified by setting the `RUST_TEST_NOCAPTURE` environment
+Deprecated: this may also be specified by setting the `RUST_TEST_NOCAPTURE` environment
 variable to anything but `0`.
 
 `--nocapture` is a deprecated alias for `--no-capture`.
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index d02952eb487..b16924babd1 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -190,5 +190,5 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
 /// and a rustc warning would be triggered, see #15301
 fn fn_is_externally_exported(cx: &LateContext<'_>, def_id: DefId) -> bool {
     let attrs = cx.tcx.codegen_fn_attrs(def_id);
-    attrs.contains_extern_indicator()
+    attrs.contains_extern_indicator(cx.tcx, def_id)
 }
diff --git a/src/tools/clippy/tests/missing-test-files.rs b/src/tools/clippy/tests/missing-test-files.rs
index 565dcd73f58..63f960c92fa 100644
--- a/src/tools/clippy/tests/missing-test-files.rs
+++ b/src/tools/clippy/tests/missing-test-files.rs
@@ -1,6 +1,6 @@
 #![warn(rust_2018_idioms, unused_lifetimes)]
 #![allow(clippy::assertions_on_constants)]
-#![feature(path_file_prefix)]
+#![cfg_attr(bootstrap, feature(path_file_prefix))]
 
 use std::cmp::Ordering;
 use std::ffi::OsStr;
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index ae1b25f8857..d9e374c414c 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -279,7 +279,7 @@ impl rustc_driver::Callbacks for MiriBeRustCompilerCalls {
                                 return None;
                             }
                             let codegen_fn_attrs = tcx.codegen_fn_attrs(local_def_id);
-                            if codegen_fn_attrs.contains_extern_indicator()
+                            if codegen_fn_attrs.contains_extern_indicator(tcx, local_def_id.into())
                                 || codegen_fn_attrs
                                     .flags
                                     .contains(CodegenFnAttrFlags::USED_COMPILER)
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 43cb1c9ae05..a8e2151afe6 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -132,7 +132,7 @@ pub fn iter_exported_symbols<'tcx>(
     for def_id in crate_items.definitions() {
         let exported = tcx.def_kind(def_id).has_codegen_attrs() && {
             let codegen_attrs = tcx.codegen_fn_attrs(def_id);
-            codegen_attrs.contains_extern_indicator()
+            codegen_attrs.contains_extern_indicator(tcx, def_id.into())
                 || codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
                 || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_COMPILER)
                 || codegen_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER)
diff --git a/tests/run-make/wasm-panic-small/rmake.rs b/tests/run-make/wasm-panic-small/rmake.rs
index e69fbac9635..ea0b6faf037 100644
--- a/tests/run-make/wasm-panic-small/rmake.rs
+++ b/tests/run-make/wasm-panic-small/rmake.rs
@@ -24,5 +24,5 @@ fn test(cfg: &str) {
 
     let bytes = rfs::read("foo.wasm");
     println!("{}", bytes.len());
-    assert!(bytes.len() < 40_000);
+    assert!(bytes.len() < 40_000, "bytes len was: {}", bytes.len());
 }
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
index b93cb2ea006..c91fd600068 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
@@ -71,6 +71,7 @@
 //~^^ WARN this was previously accepted by the compiler
 #![must_use]
 //~^ WARN `#[must_use]` has no effect
+//~| HELP remove the attribute
 // see issue-43106-gating-of-stable.rs
 // see issue-43106-gating-of-unstable.rs
 // see issue-43106-gating-of-deprecated.rs
@@ -599,16 +600,20 @@ mod deprecated {
 }
 
 #[must_use] //~ WARN `#[must_use]` has no effect
+//~^ HELP remove the attribute
 mod must_use {
     mod inner { #![must_use] } //~ WARN `#[must_use]` has no effect
+    //~^ HELP remove the attribute
 
     #[must_use] fn f() { }
 
     #[must_use] struct S;
 
     #[must_use] type T = S; //~ WARN `#[must_use]` has no effect
+    //~^ HELP remove the attribute
 
     #[must_use] impl S { } //~ WARN `#[must_use]` has no effect
+    //~^ HELP remove the attribute
 }
 
 #[windows_subsystem = "windows"]
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
index f2ae50b75a3..e0ea5382faa 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
@@ -1,5 +1,5 @@
 warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:397:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:398:17
    |
 LL |     mod inner { #![macro_escape] }
    |                 ^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL |     mod inner { #![macro_escape] }
    = help: try an outer attribute: `#[macro_use]`
 
 warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:394:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:395:1
    |
 LL | #[macro_escape]
    | ^^^^^^^^^^^^^^^
@@ -43,151 +43,151 @@ LL | #![deny(x5100)]
    |         ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:96:8
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:97:8
    |
 LL | #[warn(x5400)]
    |        ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:99:25
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:100:25
    |
 LL |     mod inner { #![warn(x5400)] }
    |                         ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:102:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:103:12
    |
 LL |     #[warn(x5400)] fn f() { }
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:105:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:106:12
    |
 LL |     #[warn(x5400)] struct S;
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:108:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:109:12
    |
 LL |     #[warn(x5400)] type T = S;
    |            ^^^^^
 
 warning: unknown lint: `x5400`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:111:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:112:12
    |
 LL |     #[warn(x5400)] impl S { }
    |            ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:115:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:116:9
    |
 LL | #[allow(x5300)]
    |         ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:118:26
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:119:26
    |
 LL |     mod inner { #![allow(x5300)] }
    |                          ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:121:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:122:13
    |
 LL |     #[allow(x5300)] fn f() { }
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:124:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:125:13
    |
 LL |     #[allow(x5300)] struct S;
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:127:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:128:13
    |
 LL |     #[allow(x5300)] type T = S;
    |             ^^^^^
 
 warning: unknown lint: `x5300`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:130:13
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:131:13
    |
 LL |     #[allow(x5300)] impl S { }
    |             ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:134:10
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:135:10
    |
 LL | #[forbid(x5200)]
    |          ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:137:27
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:138:27
    |
 LL |     mod inner { #![forbid(x5200)] }
    |                           ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:140:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:141:14
    |
 LL |     #[forbid(x5200)] fn f() { }
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:143:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:144:14
    |
 LL |     #[forbid(x5200)] struct S;
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:146:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:147:14
    |
 LL |     #[forbid(x5200)] type T = S;
    |              ^^^^^
 
 warning: unknown lint: `x5200`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:149:14
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:150:14
    |
 LL |     #[forbid(x5200)] impl S { }
    |              ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:153:8
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:154:8
    |
 LL | #[deny(x5100)]
    |        ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:156:25
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:157:25
    |
 LL |     mod inner { #![deny(x5100)] }
    |                         ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:159:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:160:12
    |
 LL |     #[deny(x5100)] fn f() { }
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:162:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:163:12
    |
 LL |     #[deny(x5100)] struct S;
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:165:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:166:12
    |
 LL |     #[deny(x5100)] type T = S;
    |            ^^^^^
 
 warning: unknown lint: `x5100`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:168:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:169:12
    |
 LL |     #[deny(x5100)] impl S { }
    |            ^^^^^
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:189:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:190:1
    |
 LL | #[macro_export]
    | ^^^^^^^^^^^^^^^
@@ -199,13 +199,13 @@ LL | #![warn(unused_attributes, unknown_lints)]
    |         ^^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on trait implementation blocks
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:257:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:258:1
    |
 LL | #[automatically_derived]
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:281:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:282:1
    |
 LL |   #[no_mangle]
    |   ^^^^^^^^^^^^
@@ -220,31 +220,31 @@ LL | | }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: `#[should_panic]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:321:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:322:1
    |
 LL | #[should_panic]
    | ^^^^^^^^^^^^^^^
 
 warning: `#[ignore]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:339:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:340:1
    |
 LL | #[ignore]
    | ^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:374:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:375:1
    |
 LL | #[reexport_test_harness_main = "2900"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:414:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:415:1
    |
 LL | #[no_std]
    | ^^^^^^^^^
 
 warning: attribute should be applied to a function definition
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:450:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:451:1
    |
 LL |   #[cold]
    |   ^^^^^^^
@@ -260,7 +260,7 @@ LL | | }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:479:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:480:1
    |
 LL |   #[link_name = "1900"]
    |   ^^^^^^^^^^^^^^^^^^^^^
@@ -276,7 +276,7 @@ LL | | }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:518:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:519:1
    |
 LL |   #[link_section = "1800"]
    |   ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -292,7 +292,7 @@ LL | | }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:550:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:1
    |
 LL |   #[link()]
    |   ^^^^^^^^^
@@ -308,55 +308,55 @@ LL | | }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: `#[must_use]` has no effect when applied to a module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:601:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:602:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:614:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:619:1
    |
 LL | #[windows_subsystem = "windows"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:635:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:640:1
    |
 LL | #[crate_name = "0900"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:654:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:659:1
    |
 LL | #[crate_type = "0800"]
    | ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:673:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:678:1
    |
 LL | #[feature(x0600)]
    | ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:693:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:698:1
    |
 LL | #[no_main]
    | ^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:712:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:717:1
    |
 LL | #[no_builtins]
    | ^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:731:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:736:1
    |
 LL | #[recursion_limit="0200"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:750:1
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:755:1
    |
 LL | #[type_length_limit="0100"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -418,7 +418,7 @@ LL | #![cold]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: the feature `rust1` has been stable since 1.0.0 and no longer requires an attribute to enable
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:85:12
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:86:12
    |
 LL | #![feature(rust1)]
    |            ^^^^^
@@ -426,121 +426,121 @@ LL | #![feature(rust1)]
    = note: `#[warn(stable_features)]` on by default
 
 warning: `#[macro_use]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:176:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:177:5
    |
 LL |     #[macro_use] fn f() { }
    |     ^^^^^^^^^^^^
 
 warning: `#[macro_use]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:179:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:180:5
    |
 LL |     #[macro_use] struct S;
    |     ^^^^^^^^^^^^
 
 warning: `#[macro_use]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:182:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:183:5
    |
 LL |     #[macro_use] type T = S;
    |     ^^^^^^^^^^^^
 
 warning: `#[macro_use]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:185:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:186:5
    |
 LL |     #[macro_use] impl S { }
    |     ^^^^^^^^^^^^
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:192:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:193:17
    |
 LL |     mod inner { #![macro_export] }
    |                 ^^^^^^^^^^^^^^^^
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:195:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:196:5
    |
 LL |     #[macro_export] fn f() { }
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:198:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:199:5
    |
 LL |     #[macro_export] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:201:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:202:5
    |
 LL |     #[macro_export] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_export]` only has an effect on macro definitions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:204:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:205:5
    |
 LL |     #[macro_export] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[path]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:244:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:245:5
    |
 LL |     #[path = "3800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: `#[path]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:247:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:248:5
    |
 LL |     #[path = "3800"]  struct S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: `#[path]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:250:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:251:5
    |
 LL |     #[path = "3800"] type T = S;
    |     ^^^^^^^^^^^^^^^^
 
 warning: `#[path]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:253:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:254:5
    |
 LL |     #[path = "3800"] impl S { }
    |     ^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on trait implementation blocks
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:260:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:261:17
    |
 LL |     mod inner { #![automatically_derived] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on trait implementation blocks
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:263:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:264:5
    |
 LL |     #[automatically_derived] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on trait implementation blocks
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:266:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:267:5
    |
 LL |     #[automatically_derived] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on trait implementation blocks
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:269:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:270:5
    |
 LL |     #[automatically_derived] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on trait implementation blocks
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:272:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:273:5
    |
 LL |     #[automatically_derived] trait W { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[automatically_derived]` only has an effect on trait implementation blocks
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:275:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:276:5
    |
 LL |     #[automatically_derived] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:286:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:287:17
    |
 LL |     mod inner { #![no_mangle] }
    |     ------------^^^^^^^^^^^^^-- not a free function, impl method or static
@@ -548,7 +548,7 @@ LL |     mod inner { #![no_mangle] }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:293:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:294:5
    |
 LL |     #[no_mangle] struct S;
    |     ^^^^^^^^^^^^ --------- not a free function, impl method or static
@@ -556,7 +556,7 @@ LL |     #[no_mangle] struct S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:298:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:299:5
    |
 LL |     #[no_mangle] type T = S;
    |     ^^^^^^^^^^^^ ----------- not a free function, impl method or static
@@ -564,7 +564,7 @@ LL |     #[no_mangle] type T = S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:303:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:304:5
    |
 LL |     #[no_mangle] impl S { }
    |     ^^^^^^^^^^^^ ---------- not a free function, impl method or static
@@ -572,7 +572,7 @@ LL |     #[no_mangle] impl S { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:309:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:310:9
    |
 LL |         #[no_mangle] fn foo();
    |         ^^^^^^^^^^^^ --------- not a free function, impl method or static
@@ -580,7 +580,7 @@ LL |         #[no_mangle] fn foo();
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a free function, impl method or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:314:9
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:315:9
    |
 LL |         #[no_mangle] fn bar() {}
    |         ^^^^^^^^^^^^ ----------- not a free function, impl method or static
@@ -588,163 +588,163 @@ LL |         #[no_mangle] fn bar() {}
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: `#[should_panic]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:324:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:325:17
    |
 LL |     mod inner { #![should_panic] }
    |                 ^^^^^^^^^^^^^^^^
 
 warning: `#[should_panic]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:329:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:330:5
    |
 LL |     #[should_panic] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[should_panic]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:332:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:333:5
    |
 LL |     #[should_panic] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[should_panic]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:335:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:336:5
    |
 LL |     #[should_panic] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[ignore]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:342:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:343:17
    |
 LL |     mod inner { #![ignore] }
    |                 ^^^^^^^^^^
 
 warning: `#[ignore]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:347:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:348:5
    |
 LL |     #[ignore] struct S;
    |     ^^^^^^^^^
 
 warning: `#[ignore]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:350:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:351:5
    |
 LL |     #[ignore] type T = S;
    |     ^^^^^^^^^
 
 warning: `#[ignore]` only has an effect on functions
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:353:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:354:5
    |
 LL |     #[ignore] impl S { }
    |     ^^^^^^^^^
 
 warning: `#[no_implicit_prelude]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:361:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:362:5
    |
 LL |     #[no_implicit_prelude] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[no_implicit_prelude]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:364:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:365:5
    |
 LL |     #[no_implicit_prelude] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[no_implicit_prelude]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:367:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:368:5
    |
 LL |     #[no_implicit_prelude] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[no_implicit_prelude]` only has an effect on modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:370:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:371:5
    |
 LL |     #[no_implicit_prelude] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:377:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:378:17
    |
 LL |     mod inner { #![reexport_test_harness_main="2900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:380:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:381:5
    |
 LL |     #[reexport_test_harness_main = "2900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:383:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:384:5
    |
 LL |     #[reexport_test_harness_main = "2900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:386:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:387:5
    |
 LL |     #[reexport_test_harness_main = "2900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:389:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:390:5
    |
 LL |     #[reexport_test_harness_main = "2900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: `#[macro_escape]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:401:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:402:5
    |
 LL |     #[macro_escape] fn f() { }
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_escape]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:404:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:405:5
    |
 LL |     #[macro_escape] struct S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_escape]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:407:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:408:5
    |
 LL |     #[macro_escape] type T = S;
    |     ^^^^^^^^^^^^^^^
 
 warning: `#[macro_escape]` only has an effect on `extern crate` and modules
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:410:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:411:5
    |
 LL |     #[macro_escape] impl S { }
    |     ^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:417:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:418:17
    |
 LL |     mod inner { #![no_std] }
    |                 ^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:420:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:421:5
    |
 LL |     #[no_std] fn f() { }
    |     ^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:423:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:424:5
    |
 LL |     #[no_std] struct S;
    |     ^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:426:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:427:5
    |
 LL |     #[no_std] type T = S;
    |     ^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:429:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:430:5
    |
 LL |     #[no_std] impl S { }
    |     ^^^^^^^^^
 
 warning: attribute should be applied to a function definition
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:456:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:457:17
    |
 LL |     mod inner { #![cold] }
    |     ------------^^^^^^^^-- not a function definition
@@ -752,7 +752,7 @@ LL |     mod inner { #![cold] }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function definition
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:463:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:464:5
    |
 LL |     #[cold] struct S;
    |     ^^^^^^^ --------- not a function definition
@@ -760,7 +760,7 @@ LL |     #[cold] struct S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function definition
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:468:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:469:5
    |
 LL |     #[cold] type T = S;
    |     ^^^^^^^ ----------- not a function definition
@@ -768,7 +768,7 @@ LL |     #[cold] type T = S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function definition
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:473:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:474:5
    |
 LL |     #[cold] impl S { }
    |     ^^^^^^^ ---------- not a function definition
@@ -776,7 +776,7 @@ LL |     #[cold] impl S { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:485:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:486:5
    |
 LL |     #[link_name = "1900"]
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -786,13 +786,13 @@ LL |     extern "C" { }
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 help: try `#[link(name = "1900")]` instead
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:485:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:486:5
    |
 LL |     #[link_name = "1900"]
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:492:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:493:17
    |
 LL |     mod inner { #![link_name="1900"] }
    |     ------------^^^^^^^^^^^^^^^^^^^^-- not a foreign function or static
@@ -800,7 +800,7 @@ LL |     mod inner { #![link_name="1900"] }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:497:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:498:5
    |
 LL |     #[link_name = "1900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^ ---------- not a foreign function or static
@@ -808,7 +808,7 @@ LL |     #[link_name = "1900"] fn f() { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:502:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:503:5
    |
 LL |     #[link_name = "1900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^ --------- not a foreign function or static
@@ -816,7 +816,7 @@ LL |     #[link_name = "1900"] struct S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:507:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:508:5
    |
 LL |     #[link_name = "1900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^ ----------- not a foreign function or static
@@ -824,7 +824,7 @@ LL |     #[link_name = "1900"] type T = S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a foreign function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:512:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:513:5
    |
 LL |     #[link_name = "1900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^ ---------- not a foreign function or static
@@ -832,7 +832,7 @@ LL |     #[link_name = "1900"] impl S { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:524:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:525:17
    |
 LL |     mod inner { #![link_section="1800"] }
    |     ------------^^^^^^^^^^^^^^^^^^^^^^^-- not a function or static
@@ -840,7 +840,7 @@ LL |     mod inner { #![link_section="1800"] }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:531:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:532:5
    |
 LL |     #[link_section = "1800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ --------- not a function or static
@@ -848,7 +848,7 @@ LL |     #[link_section = "1800"] struct S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:536:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:537:5
    |
 LL |     #[link_section = "1800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a function or static
@@ -856,7 +856,7 @@ LL |     #[link_section = "1800"] type T = S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to a function or static
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:541:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:542:5
    |
 LL |     #[link_section = "1800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a function or static
@@ -864,7 +864,7 @@ LL |     #[link_section = "1800"] impl S { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:556:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:557:17
    |
 LL |     mod inner { #![link()] }
    |     ------------^^^^^^^^^^-- not an `extern` block
@@ -872,7 +872,7 @@ LL |     mod inner { #![link()] }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:561:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:562:5
    |
 LL |     #[link()] fn f() { }
    |     ^^^^^^^^^ ---------- not an `extern` block
@@ -880,7 +880,7 @@ LL |     #[link()] fn f() { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:566:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:567:5
    |
 LL |     #[link()] struct S;
    |     ^^^^^^^^^ --------- not an `extern` block
@@ -888,7 +888,7 @@ LL |     #[link()] struct S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:571:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:572:5
    |
 LL |     #[link()] type T = S;
    |     ^^^^^^^^^ ----------- not an `extern` block
@@ -896,7 +896,7 @@ LL |     #[link()] type T = S;
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:576:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:577:5
    |
 LL |     #[link()] impl S { }
    |     ^^^^^^^^^ ---------- not an `extern` block
@@ -904,7 +904,7 @@ LL |     #[link()] impl S { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: attribute should be applied to an `extern` block with non-Rust ABI
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:581:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:582:5
    |
 LL |     #[link()] extern "Rust" {}
    |     ^^^^^^^^^
@@ -912,259 +912,259 @@ LL |     #[link()] extern "Rust" {}
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 warning: `#[must_use]` has no effect when applied to a module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:603:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:605:17
    |
 LL |     mod inner { #![must_use] }
    |                 ^^^^^^^^^^^^
 
 warning: `#[must_use]` has no effect when applied to a type alias
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:609:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:612:5
    |
 LL |     #[must_use] type T = S;
    |     ^^^^^^^^^^^
 
 warning: `#[must_use]` has no effect when applied to an inherent implementation block
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:611:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:615:5
    |
 LL |     #[must_use] impl S { }
    |     ^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:617:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:622:17
    |
 LL |     mod inner { #![windows_subsystem="windows"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:620:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:625:5
    |
 LL |     #[windows_subsystem = "windows"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:623:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:628:5
    |
 LL |     #[windows_subsystem = "windows"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:626:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:631:5
    |
 LL |     #[windows_subsystem = "windows"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:629:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:634:5
    |
 LL |     #[windows_subsystem = "windows"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:638:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:643:17
    |
 LL |     mod inner { #![crate_name="0900"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:641:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:646:5
    |
 LL |     #[crate_name = "0900"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:644:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:649:5
    |
 LL |     #[crate_name = "0900"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:647:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:652:5
    |
 LL |     #[crate_name = "0900"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:650:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:655:5
    |
 LL |     #[crate_name = "0900"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:657:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:662:17
    |
 LL |     mod inner { #![crate_type="0800"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:660:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:665:5
    |
 LL |     #[crate_type = "0800"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:663:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:668:5
    |
 LL |     #[crate_type = "0800"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:666:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:671:5
    |
 LL |     #[crate_type = "0800"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:669:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:674:5
    |
 LL |     #[crate_type = "0800"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:676:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:681:17
    |
 LL |     mod inner { #![feature(x0600)] }
    |                 ^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:679:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:684:5
    |
 LL |     #[feature(x0600)] fn f() { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:682:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:687:5
    |
 LL |     #[feature(x0600)] struct S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:685:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:690:5
    |
 LL |     #[feature(x0600)] type T = S;
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:688:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:693:5
    |
 LL |     #[feature(x0600)] impl S { }
    |     ^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:696:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:17
    |
 LL |     mod inner { #![no_main] }
    |                 ^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:699:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:704:5
    |
 LL |     #[no_main] fn f() { }
    |     ^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:702:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:707:5
    |
 LL |     #[no_main] struct S;
    |     ^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:705:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:710:5
    |
 LL |     #[no_main] type T = S;
    |     ^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:708:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:713:5
    |
 LL |     #[no_main] impl S { }
    |     ^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:715:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:720:17
    |
 LL |     mod inner { #![no_builtins] }
    |                 ^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:718:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:723:5
    |
 LL |     #[no_builtins] fn f() { }
    |     ^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:721:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:726:5
    |
 LL |     #[no_builtins] struct S;
    |     ^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:724:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:729:5
    |
 LL |     #[no_builtins] type T = S;
    |     ^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:727:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:732:5
    |
 LL |     #[no_builtins] impl S { }
    |     ^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:734:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:739:17
    |
 LL |     mod inner { #![recursion_limit="0200"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:737:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:742:5
    |
 LL |     #[recursion_limit="0200"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:740:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:745:5
    |
 LL |     #[recursion_limit="0200"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:743:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:748:5
    |
 LL |     #[recursion_limit="0200"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:746:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:751:5
    |
 LL |     #[recursion_limit="0200"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:753:17
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:758:17
    |
 LL |     mod inner { #![type_length_limit="0100"] }
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:756:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:761:5
    |
 LL |     #[type_length_limit="0100"] fn f() { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:759:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:764:5
    |
 LL |     #[type_length_limit="0100"] struct S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:762:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:767:5
    |
 LL |     #[type_length_limit="0100"] type T = S;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![foo]`
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:765:5
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:770:5
    |
 LL |     #[type_length_limit="0100"] impl S { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/unused/unused_attributes-must_use.fixed b/tests/ui/lint/unused/unused_attributes-must_use.fixed
new file mode 100644
index 00000000000..80d488296ea
--- /dev/null
+++ b/tests/ui/lint/unused/unused_attributes-must_use.fixed
@@ -0,0 +1,139 @@
+//@ run-rustfix
+
+#![allow(dead_code, path_statements)]
+#![deny(unused_attributes, unused_must_use)]
+#![feature(asm_experimental_arch, stmt_expr_attributes, trait_alias)]
+
+ //~ ERROR `#[must_use]` has no effect
+extern crate std as std2;
+
+ //~ ERROR `#[must_use]` has no effect
+mod test_mod {}
+
+ //~ ERROR `#[must_use]` has no effect
+use std::arch::global_asm;
+
+ //~ ERROR `#[must_use]` has no effect
+const CONST: usize = 4;
+ //~ ERROR `#[must_use]` has no effect
+#[no_mangle]
+static STATIC: usize = 4;
+
+#[must_use]
+struct X;
+
+#[must_use]
+enum Y {
+    Z,
+}
+
+#[must_use]
+union U {
+    unit: (),
+}
+
+ //~ ERROR `#[must_use]` has no effect
+impl U {
+    #[must_use]
+    fn method() -> i32 {
+        4
+    }
+}
+
+#[must_use]
+#[no_mangle]
+fn foo() -> i64 {
+    4
+}
+
+ //~ ERROR `#[must_use]` has no effect
+extern "Rust" {
+    #[link_name = "STATIC"]
+     //~ ERROR `#[must_use]` has no effect
+    static FOREIGN_STATIC: usize;
+
+    #[link_name = "foo"]
+    #[must_use]
+    fn foreign_foo() -> i64;
+}
+
+ //~ ERROR unused attribute
+global_asm!("");
+
+ //~ ERROR `#[must_use]` has no effect
+type UseMe = ();
+
+fn qux< T>(_: T) {} //~ ERROR `#[must_use]` has no effect
+
+#[must_use]
+trait Use {
+     //~ ERROR `#[must_use]` has no effect
+    const ASSOC_CONST: usize = 4;
+     //~ ERROR `#[must_use]` has no effect
+    type AssocTy;
+
+    #[must_use]
+    fn get_four(&self) -> usize {
+        4
+    }
+}
+
+ //~ ERROR `#[must_use]` has no effect
+impl Use for () {
+    type AssocTy = ();
+
+     //~ ERROR `#[must_use]` has no effect
+    fn get_four(&self) -> usize {
+        4
+    }
+}
+
+ //~ ERROR `#[must_use]` has no effect
+trait Alias = Use;
+
+ //~ ERROR `#[must_use]` has no effect
+macro_rules! cool_macro {
+    () => {
+        4
+    };
+}
+
+fn main() {
+     //~ ERROR `#[must_use]` has no effect
+    let x = || {};
+    x();
+
+    let x =  //~ ERROR `#[must_use]` has no effect
+    || {};
+    x();
+
+    let _ = X; //~ ERROR that must be used
+    let _ = Y::Z; //~ ERROR that must be used
+    let _ = U { unit: () }; //~ ERROR that must be used
+    let _ = U::method(); //~ ERROR that must be used
+    let _ = foo(); //~ ERROR that must be used
+
+    unsafe {
+        let _ = foreign_foo(); //~ ERROR that must be used
+    };
+
+    CONST;
+    STATIC;
+    unsafe { FOREIGN_STATIC };
+    cool_macro!();
+    qux(4);
+    let _ = ().get_four(); //~ ERROR that must be used
+
+    match Some(4) {
+         //~ ERROR `#[must_use]` has no effect
+        Some(res) => res,
+        None => 0,
+    };
+
+    struct PatternField {
+        foo: i32,
+    }
+    let s = PatternField {   foo: 123 }; //~ ERROR `#[must_use]` has no effect
+    let PatternField {  foo } = s; //~ ERROR `#[must_use]` has no effect
+    let _ = foo;
+}
diff --git a/tests/ui/lint/unused/unused_attributes-must_use.rs b/tests/ui/lint/unused/unused_attributes-must_use.rs
index 860fc5046d1..edefe8ed65e 100644
--- a/tests/ui/lint/unused/unused_attributes-must_use.rs
+++ b/tests/ui/lint/unused/unused_attributes-must_use.rs
@@ -1,3 +1,5 @@
+//@ run-rustfix
+
 #![allow(dead_code, path_statements)]
 #![deny(unused_attributes, unused_must_use)]
 #![feature(asm_experimental_arch, stmt_expr_attributes, trait_alias)]
@@ -133,4 +135,5 @@ fn main() {
     }
     let s = PatternField { #[must_use]  foo: 123 }; //~ ERROR `#[must_use]` has no effect
     let PatternField { #[must_use] foo } = s; //~ ERROR `#[must_use]` has no effect
+    let _ = foo;
 }
diff --git a/tests/ui/lint/unused/unused_attributes-must_use.stderr b/tests/ui/lint/unused/unused_attributes-must_use.stderr
index 862ffa42d80..27927cf37e9 100644
--- a/tests/ui/lint/unused/unused_attributes-must_use.stderr
+++ b/tests/ui/lint/unused/unused_attributes-must_use.stderr
@@ -1,154 +1,154 @@
 error: unused attribute `must_use`
-  --> $DIR/unused_attributes-must_use.rs:58:1
+  --> $DIR/unused_attributes-must_use.rs:60:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
    |
 note: the built-in attribute `must_use` will be ignored, since it's applied to the macro invocation `global_asm`
-  --> $DIR/unused_attributes-must_use.rs:59:1
+  --> $DIR/unused_attributes-must_use.rs:61:1
    |
 LL | global_asm!("");
    | ^^^^^^^^^^
 note: the lint level is defined here
-  --> $DIR/unused_attributes-must_use.rs:2:9
+  --> $DIR/unused_attributes-must_use.rs:4:9
    |
 LL | #![deny(unused_attributes, unused_must_use)]
    |         ^^^^^^^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to an extern crate
-  --> $DIR/unused_attributes-must_use.rs:5:1
+  --> $DIR/unused_attributes-must_use.rs:7:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a module
-  --> $DIR/unused_attributes-must_use.rs:8:1
+  --> $DIR/unused_attributes-must_use.rs:10:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a use
-  --> $DIR/unused_attributes-must_use.rs:11:1
+  --> $DIR/unused_attributes-must_use.rs:13:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a constant item
-  --> $DIR/unused_attributes-must_use.rs:14:1
+  --> $DIR/unused_attributes-must_use.rs:16:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a static item
-  --> $DIR/unused_attributes-must_use.rs:16:1
+  --> $DIR/unused_attributes-must_use.rs:18:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to an inherent implementation block
-  --> $DIR/unused_attributes-must_use.rs:33:1
+  --> $DIR/unused_attributes-must_use.rs:35:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a foreign module
-  --> $DIR/unused_attributes-must_use.rs:47:1
+  --> $DIR/unused_attributes-must_use.rs:49:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a type alias
-  --> $DIR/unused_attributes-must_use.rs:61:1
+  --> $DIR/unused_attributes-must_use.rs:63:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a type parameter
-  --> $DIR/unused_attributes-must_use.rs:64:8
+  --> $DIR/unused_attributes-must_use.rs:66:8
    |
 LL | fn qux<#[must_use] T>(_: T) {}
    |        ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to an trait implementation block
-  --> $DIR/unused_attributes-must_use.rs:79:1
+  --> $DIR/unused_attributes-must_use.rs:81:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a trait alias
-  --> $DIR/unused_attributes-must_use.rs:89:1
+  --> $DIR/unused_attributes-must_use.rs:91:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a macro def
-  --> $DIR/unused_attributes-must_use.rs:92:1
+  --> $DIR/unused_attributes-must_use.rs:94:1
    |
 LL | #[must_use]
    | ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a statement
-  --> $DIR/unused_attributes-must_use.rs:100:5
+  --> $DIR/unused_attributes-must_use.rs:102:5
    |
 LL |     #[must_use]
    |     ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a closure
-  --> $DIR/unused_attributes-must_use.rs:104:13
+  --> $DIR/unused_attributes-must_use.rs:106:13
    |
 LL |     let x = #[must_use]
    |             ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to an match arm
-  --> $DIR/unused_attributes-must_use.rs:126:9
+  --> $DIR/unused_attributes-must_use.rs:128:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a struct field
-  --> $DIR/unused_attributes-must_use.rs:134:28
+  --> $DIR/unused_attributes-must_use.rs:136:28
    |
 LL |     let s = PatternField { #[must_use]  foo: 123 };
    |                            ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a pattern field
-  --> $DIR/unused_attributes-must_use.rs:135:24
+  --> $DIR/unused_attributes-must_use.rs:137:24
    |
 LL |     let PatternField { #[must_use] foo } = s;
    |                        ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to an associated const
-  --> $DIR/unused_attributes-must_use.rs:68:5
+  --> $DIR/unused_attributes-must_use.rs:70:5
    |
 LL |     #[must_use]
    |     ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to an associated type
-  --> $DIR/unused_attributes-must_use.rs:70:5
+  --> $DIR/unused_attributes-must_use.rs:72:5
    |
 LL |     #[must_use]
    |     ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a provided trait method
-  --> $DIR/unused_attributes-must_use.rs:83:5
+  --> $DIR/unused_attributes-must_use.rs:85:5
    |
 LL |     #[must_use]
    |     ^^^^^^^^^^^
 
 error: `#[must_use]` has no effect when applied to a foreign static item
-  --> $DIR/unused_attributes-must_use.rs:50:5
+  --> $DIR/unused_attributes-must_use.rs:52:5
    |
 LL |     #[must_use]
    |     ^^^^^^^^^^^
 
 error: unused `X` that must be used
-  --> $DIR/unused_attributes-must_use.rs:108:5
+  --> $DIR/unused_attributes-must_use.rs:110:5
    |
 LL |     X;
    |     ^
    |
 note: the lint level is defined here
-  --> $DIR/unused_attributes-must_use.rs:2:28
+  --> $DIR/unused_attributes-must_use.rs:4:28
    |
 LL | #![deny(unused_attributes, unused_must_use)]
    |                            ^^^^^^^^^^^^^^^
@@ -158,7 +158,7 @@ LL |     let _ = X;
    |     +++++++
 
 error: unused `Y` that must be used
-  --> $DIR/unused_attributes-must_use.rs:109:5
+  --> $DIR/unused_attributes-must_use.rs:111:5
    |
 LL |     Y::Z;
    |     ^^^^
@@ -169,7 +169,7 @@ LL |     let _ = Y::Z;
    |     +++++++
 
 error: unused `U` that must be used
-  --> $DIR/unused_attributes-must_use.rs:110:5
+  --> $DIR/unused_attributes-must_use.rs:112:5
    |
 LL |     U { unit: () };
    |     ^^^^^^^^^^^^^^
@@ -180,7 +180,7 @@ LL |     let _ = U { unit: () };
    |     +++++++
 
 error: unused return value of `U::method` that must be used
-  --> $DIR/unused_attributes-must_use.rs:111:5
+  --> $DIR/unused_attributes-must_use.rs:113:5
    |
 LL |     U::method();
    |     ^^^^^^^^^^^
@@ -191,7 +191,7 @@ LL |     let _ = U::method();
    |     +++++++
 
 error: unused return value of `foo` that must be used
-  --> $DIR/unused_attributes-must_use.rs:112:5
+  --> $DIR/unused_attributes-must_use.rs:114:5
    |
 LL |     foo();
    |     ^^^^^
@@ -202,7 +202,7 @@ LL |     let _ = foo();
    |     +++++++
 
 error: unused return value of `foreign_foo` that must be used
-  --> $DIR/unused_attributes-must_use.rs:115:9
+  --> $DIR/unused_attributes-must_use.rs:117:9
    |
 LL |         foreign_foo();
    |         ^^^^^^^^^^^^^
@@ -213,7 +213,7 @@ LL |         let _ = foreign_foo();
    |         +++++++
 
 error: unused return value of `Use::get_four` that must be used
-  --> $DIR/unused_attributes-must_use.rs:123:5
+  --> $DIR/unused_attributes-must_use.rs:125:5
    |
 LL |     ().get_four();
    |     ^^^^^^^^^^^^^