about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/ast.rs28
-rw-r--r--compiler/rustc_borrowck/src/lib.rs1
-rw-r--r--compiler/rustc_borrowck/src/polonius/loan_invalidations.rs1
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl24
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs128
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs27
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs13
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs64
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0787.md5
-rw-r--r--compiler/rustc_errors/src/lib.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs2
-rw-r--r--compiler/rustc_infer/src/errors.rs (renamed from compiler/rustc_infer/src/errors/mod.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/at.rs17
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs113
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs27
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/table.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs12
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs16
-rw-r--r--compiler/rustc_infer/src/infer/relate/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/relate/type_relating.rs4
-rw-r--r--compiler/rustc_infer/src/infer/resolve.rs14
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/type_variable.rs45
-rw-r--r--compiler/rustc_infer/src/lib.rs3
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs6
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs6
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs24
-rw-r--r--compiler/rustc_middle/src/mir/terminator.rs1
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs1
-rw-r--r--compiler/rustc_middle/src/thir.rs3
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs8
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs10
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs19
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs1
-rw-r--r--compiler/rustc_mir_build/src/thir/print.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs1
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs42
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs11
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs30
-rw-r--r--compiler/rustc_passes/messages.ftl18
-rw-r--r--compiler/rustc_passes/src/errors.rs22
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs94
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs1
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/raw_vec.rs12
-rw-r--r--library/alloc/src/string.rs38
-rw-r--r--library/alloc/src/vec/mod.rs55
-rw-r--r--library/std/build.rs5
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs1
-rw-r--r--src/bootstrap/src/core/sanity.rs4
-rw-r--r--src/tools/build_helper/src/git.rs64
-rw-r--r--src/tools/rustfmt/src/parse/macros/asm.rs2
-rw-r--r--tests/assembly/aarch64-naked-fn-no-bti-prolog.rs4
-rw-r--r--tests/assembly/x86_64-naked-fn-no-cet-prolog.rs4
-rw-r--r--tests/codegen/cffi/c-variadic-naked.rs3
-rw-r--r--tests/codegen/naked-asan.rs2
-rw-r--r--tests/codegen/naked-fn/aligned.rs4
-rw-r--r--tests/codegen/naked-fn/naked-functions.rs6
-rw-r--r--tests/codegen/naked-fn/naked-nocoverage.rs4
-rw-r--r--tests/codegen/naked-fn/naked-noinline.rs4
-rw-r--r--tests/coverage/closure_macro.cov-map8
-rw-r--r--tests/coverage/closure_macro_async.cov-map8
-rw-r--r--tests/crashes/124375.rs4
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir91
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir91
-rw-r--r--tests/run-make/naked-symbol-visibility/a_rust_dylib.rs12
-rw-r--r--tests/ui/asm/naked-functions-ffi.rs4
-rw-r--r--tests/ui/asm/naked-functions-instruction-set.rs6
-rw-r--r--tests/ui/asm/naked-functions-testattrs.rs10
-rw-r--r--tests/ui/asm/naked-functions-unused.aarch64.stderr16
-rw-r--r--tests/ui/asm/naked-functions-unused.rs42
-rw-r--r--tests/ui/asm/naked-functions-unused.x86_64.stderr16
-rw-r--r--tests/ui/asm/naked-functions.rs94
-rw-r--r--tests/ui/asm/naked-functions.stderr244
-rw-r--r--tests/ui/asm/naked-invalid-attr.rs13
-rw-r--r--tests/ui/asm/naked-invalid-attr.stderr6
-rw-r--r--tests/ui/asm/naked-with-invalid-repr-attr.rs12
-rw-r--r--tests/ui/asm/naked-with-invalid-repr-attr.stderr12
-rw-r--r--tests/ui/asm/named-asm-labels.rs10
-rw-r--r--tests/ui/asm/named-asm-labels.stderr18
-rw-r--r--tests/ui/consts/issue-94675.rs2
-rw-r--r--tests/ui/consts/issue-94675.stderr10
-rw-r--r--tests/ui/feature-gates/feature-gate-naked_functions.rs13
-rw-r--r--tests/ui/feature-gates/feature-gate-naked_functions.stderr48
-rw-r--r--tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs6
93 files changed, 913 insertions, 991 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 37f429cce44..733c2d93114 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2278,7 +2278,7 @@ impl InlineAsmOptions {
     pub const COUNT: usize = Self::all().bits().count_ones() as usize;
 
     pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
-    pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW).union(Self::NORETURN);
+    pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
 
     pub fn human_readable_names(&self) -> Vec<&'static str> {
         let mut options = vec![];
@@ -2434,6 +2434,32 @@ pub enum AsmMacro {
     NakedAsm,
 }
 
+impl AsmMacro {
+    pub const fn macro_name(self) -> &'static str {
+        match self {
+            AsmMacro::Asm => "asm",
+            AsmMacro::GlobalAsm => "global_asm",
+            AsmMacro::NakedAsm => "naked_asm",
+        }
+    }
+
+    pub const fn is_supported_option(self, option: InlineAsmOptions) -> bool {
+        match self {
+            AsmMacro::Asm => true,
+            AsmMacro::GlobalAsm => InlineAsmOptions::GLOBAL_OPTIONS.contains(option),
+            AsmMacro::NakedAsm => InlineAsmOptions::NAKED_OPTIONS.contains(option),
+        }
+    }
+
+    pub const fn diverges(self, options: InlineAsmOptions) -> bool {
+        match self {
+            AsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
+            AsmMacro::GlobalAsm => true,
+            AsmMacro::NakedAsm => true,
+        }
+    }
+}
+
 /// Inline assembly.
 ///
 /// E.g., `asm!("NOP");`.
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 3b0b3ee1a74..fad4d790be4 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -742,6 +742,7 @@ impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
             }
 
             TerminatorKind::InlineAsm {
+                asm_macro: _,
                 template: _,
                 operands,
                 options: _,
diff --git a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
index afd811a0efb..d1b65943199 100644
--- a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
+++ b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
@@ -169,6 +169,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'a, 'tcx> {
                 }
             }
             TerminatorKind::InlineAsm {
+                asm_macro: _,
                 template: _,
                 operands,
                 options: _,
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 9695df9c87e..b25892242b5 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -12,9 +12,9 @@ builtin_macros_asm_duplicate_arg = duplicate argument named `{$name}`
 builtin_macros_asm_expected_comma = expected token: `,`
     .label = expected `,`
 
-builtin_macros_asm_expected_other = expected operand, {$is_global_asm ->
-    [true] options
-    *[false] clobber_abi, options
+builtin_macros_asm_expected_other = expected operand, {$is_inline_asm ->
+    [false] options
+    *[true] clobber_abi, options
     }, or additional template string
 
 builtin_macros_asm_expected_string_literal = expected string literal
@@ -51,6 +51,15 @@ builtin_macros_asm_sym_no_path = expected a path for argument to `sym`
 
 builtin_macros_asm_underscore_input = _ cannot be used for input operands
 
+builtin_macros_asm_unsupported_clobber_abi = `clobber_abi` cannot be used with `{$macro_name}!`
+
+builtin_macros_asm_unsupported_operand = the `{$symbol}` operand cannot be used with `{$macro_name}!`
+    .label = the `{$symbol}` operand is not meaningful for global-scoped inline assembly, remove it
+
+builtin_macros_asm_unsupported_option = the `{$symbol}` option cannot be used with `{$macro_name}!`
+    .label = the `{$symbol}` option is not meaningful for global-scoped inline assembly
+    .suggestion = remove this option
+
 builtin_macros_assert_missing_comma = unexpected string literal
     .suggestion = try adding a comma
 
@@ -194,15 +203,6 @@ builtin_macros_format_unused_args = multiple unused formatting arguments
 
 builtin_macros_format_use_positional = consider using a positional formatting argument instead
 
-builtin_macros_global_asm_clobber_abi = `clobber_abi` cannot be used with `global_asm!`
-
-builtin_macros_global_asm_unsupported_operand = the `{$symbol}` operand cannot be used with `global_asm!`
-    .label = the `{$symbol}` operand is not meaningful for global-scoped inline assembly, remove it
-
-builtin_macros_global_asm_unsupported_option = the `{$symbol}` option cannot be used with `global_asm!`
-    .label = the `{$symbol}` option is not meaningful for global-scoped inline assembly
-    .suggestion = remove this option
-
 builtin_macros_invalid_crate_attribute = invalid crate attribute
 
 builtin_macros_multiple_default_attrs = multiple `#[default]` attributes
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 75dbb3d8e6a..9ae48024f44 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -37,15 +37,23 @@ pub struct AsmArgs {
 /// - `Ok(true)` if the current token matches the keyword, and was expected
 /// - `Ok(false)` if the current token does not match the keyword
 /// - `Err(_)` if the current token matches the keyword, but was not expected
-fn eat_operand_keyword<'a>(p: &mut Parser<'a>, symbol: Symbol, expect: bool) -> PResult<'a, bool> {
-    if expect {
+fn eat_operand_keyword<'a>(
+    p: &mut Parser<'a>,
+    symbol: Symbol,
+    asm_macro: AsmMacro,
+) -> PResult<'a, bool> {
+    if matches!(asm_macro, AsmMacro::Asm) {
         Ok(p.eat_keyword(symbol))
     } else {
         let span = p.token.span;
         if p.eat_keyword_noexpect(symbol) {
             // in gets printed as `r#in` otherwise
             let symbol = if symbol == kw::In { "in" } else { symbol.as_str() };
-            Err(p.dcx().create_err(errors::GlobalAsmUnsupportedOperand { span, symbol }))
+            Err(p.dcx().create_err(errors::AsmUnsupportedOperand {
+                span,
+                symbol,
+                macro_name: asm_macro.macro_name(),
+            }))
         } else {
             Ok(false)
         }
@@ -56,10 +64,10 @@ fn parse_args<'a>(
     ecx: &ExtCtxt<'a>,
     sp: Span,
     tts: TokenStream,
-    is_global_asm: bool,
+    asm_macro: AsmMacro,
 ) -> PResult<'a, AsmArgs> {
     let mut p = ecx.new_parser_from_tts(tts);
-    parse_asm_args(&mut p, sp, is_global_asm)
+    parse_asm_args(&mut p, sp, asm_macro)
 }
 
 // Primarily public for rustfmt consumption.
@@ -67,7 +75,7 @@ fn parse_args<'a>(
 pub fn parse_asm_args<'a>(
     p: &mut Parser<'a>,
     sp: Span,
-    is_global_asm: bool,
+    asm_macro: AsmMacro,
 ) -> PResult<'a, AsmArgs> {
     let dcx = p.dcx();
 
@@ -110,7 +118,7 @@ pub fn parse_asm_args<'a>(
 
         // Parse options
         if p.eat_keyword(sym::options) {
-            parse_options(p, &mut args, is_global_asm)?;
+            parse_options(p, &mut args, asm_macro)?;
             allow_templates = false;
             continue;
         }
@@ -129,7 +137,7 @@ pub fn parse_asm_args<'a>(
         };
 
         let mut explicit_reg = false;
-        let op = if eat_operand_keyword(p, kw::In, !is_global_asm)? {
+        let op = if eat_operand_keyword(p, kw::In, asm_macro)? {
             let reg = parse_reg(p, &mut explicit_reg)?;
             if p.eat_keyword(kw::Underscore) {
                 let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
@@ -137,15 +145,15 @@ pub fn parse_asm_args<'a>(
             }
             let expr = p.parse_expr()?;
             ast::InlineAsmOperand::In { reg, expr }
-        } else if eat_operand_keyword(p, sym::out, !is_global_asm)? {
+        } else if eat_operand_keyword(p, sym::out, asm_macro)? {
             let reg = parse_reg(p, &mut explicit_reg)?;
             let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
             ast::InlineAsmOperand::Out { reg, expr, late: false }
-        } else if eat_operand_keyword(p, sym::lateout, !is_global_asm)? {
+        } else if eat_operand_keyword(p, sym::lateout, asm_macro)? {
             let reg = parse_reg(p, &mut explicit_reg)?;
             let expr = if p.eat_keyword(kw::Underscore) { None } else { Some(p.parse_expr()?) };
             ast::InlineAsmOperand::Out { reg, expr, late: true }
-        } else if eat_operand_keyword(p, sym::inout, !is_global_asm)? {
+        } else if eat_operand_keyword(p, sym::inout, asm_macro)? {
             let reg = parse_reg(p, &mut explicit_reg)?;
             if p.eat_keyword(kw::Underscore) {
                 let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
@@ -159,7 +167,7 @@ pub fn parse_asm_args<'a>(
             } else {
                 ast::InlineAsmOperand::InOut { reg, expr, late: false }
             }
-        } else if eat_operand_keyword(p, sym::inlateout, !is_global_asm)? {
+        } else if eat_operand_keyword(p, sym::inlateout, asm_macro)? {
             let reg = parse_reg(p, &mut explicit_reg)?;
             if p.eat_keyword(kw::Underscore) {
                 let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
@@ -173,7 +181,7 @@ pub fn parse_asm_args<'a>(
             } else {
                 ast::InlineAsmOperand::InOut { reg, expr, late: true }
             }
-        } else if eat_operand_keyword(p, sym::label, !is_global_asm)? {
+        } else if eat_operand_keyword(p, sym::label, asm_macro)? {
             let block = p.parse_block()?;
             ast::InlineAsmOperand::Label { block }
         } else if p.eat_keyword(kw::Const) {
@@ -205,7 +213,7 @@ pub fn parse_asm_args<'a>(
                 _ => {
                     let err = dcx.create_err(errors::AsmExpectedOther {
                         span: template.span,
-                        is_global_asm,
+                        is_inline_asm: matches!(asm_macro, AsmMacro::Asm),
                     });
                     return Err(err);
                 }
@@ -301,20 +309,25 @@ pub fn parse_asm_args<'a>(
         dcx.emit_err(errors::AsmMayUnwind { labels_sp });
     }
 
-    if args.clobber_abis.len() > 0 {
-        if is_global_asm {
-            let err = dcx.create_err(errors::GlobalAsmClobberAbi {
-                spans: args.clobber_abis.iter().map(|(_, span)| *span).collect(),
-            });
+    if !args.clobber_abis.is_empty() {
+        match asm_macro {
+            AsmMacro::GlobalAsm | AsmMacro::NakedAsm => {
+                let err = dcx.create_err(errors::AsmUnsupportedClobberAbi {
+                    spans: args.clobber_abis.iter().map(|(_, span)| *span).collect(),
+                    macro_name: asm_macro.macro_name(),
+                });
 
-            // Bail out now since this is likely to confuse later stages
-            return Err(err);
-        }
-        if !regclass_outputs.is_empty() {
-            dcx.emit_err(errors::AsmClobberNoReg {
-                spans: regclass_outputs,
-                clobbers: args.clobber_abis.iter().map(|(_, span)| *span).collect(),
-            });
+                // Bail out now since this is likely to confuse later stages
+                return Err(err);
+            }
+            AsmMacro::Asm => {
+                if !regclass_outputs.is_empty() {
+                    dcx.emit_err(errors::AsmClobberNoReg {
+                        spans: regclass_outputs,
+                        clobbers: args.clobber_abis.iter().map(|(_, span)| *span).collect(),
+                    });
+                }
+            }
         }
     }
 
@@ -335,10 +348,15 @@ fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
 ///
 /// This function must be called immediately after the option token is parsed.
 /// Otherwise, the suggestion will be incorrect.
-fn err_unsupported_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
+fn err_unsupported_option(p: &Parser<'_>, asm_macro: AsmMacro, symbol: Symbol, span: Span) {
     // Tool-only output
     let full_span = if p.token == token::Comma { span.to(p.token.span) } else { span };
-    p.dcx().emit_err(errors::GlobalAsmUnsupportedOption { span, symbol, full_span });
+    p.dcx().emit_err(errors::AsmUnsupportedOption {
+        span,
+        symbol,
+        full_span,
+        macro_name: asm_macro.macro_name(),
+    });
 }
 
 /// Try to set the provided option in the provided `AsmArgs`.
@@ -349,12 +367,12 @@ fn err_unsupported_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
 fn try_set_option<'a>(
     p: &Parser<'a>,
     args: &mut AsmArgs,
-    is_global_asm: bool,
+    asm_macro: AsmMacro,
     symbol: Symbol,
     option: ast::InlineAsmOptions,
 ) {
-    if is_global_asm && !ast::InlineAsmOptions::GLOBAL_OPTIONS.contains(option) {
-        err_unsupported_option(p, symbol, p.prev_token.span);
+    if !asm_macro.is_supported_option(option) {
+        err_unsupported_option(p, asm_macro, symbol, p.prev_token.span);
     } else if args.options.contains(option) {
         err_duplicate_option(p, symbol, p.prev_token.span);
     } else {
@@ -365,7 +383,7 @@ fn try_set_option<'a>(
 fn parse_options<'a>(
     p: &mut Parser<'a>,
     args: &mut AsmArgs,
-    is_global_asm: bool,
+    asm_macro: AsmMacro,
 ) -> PResult<'a, ()> {
     let span_start = p.prev_token.span;
 
@@ -386,15 +404,14 @@ fn parse_options<'a>(
 
         'blk: {
             for (symbol, option) in OPTIONS {
-                let kw_matched =
-                    if !is_global_asm || ast::InlineAsmOptions::GLOBAL_OPTIONS.contains(option) {
-                        p.eat_keyword(symbol)
-                    } else {
-                        p.eat_keyword_noexpect(symbol)
-                    };
+                let kw_matched = if asm_macro.is_supported_option(option) {
+                    p.eat_keyword(symbol)
+                } else {
+                    p.eat_keyword_noexpect(symbol)
+                };
 
                 if kw_matched {
-                    try_set_option(p, args, is_global_asm, symbol, option);
+                    try_set_option(p, args, asm_macro, symbol, option);
                     break 'blk;
                 }
             }
@@ -483,7 +500,7 @@ fn parse_reg<'a>(
 
 fn expand_preparsed_asm(
     ecx: &mut ExtCtxt<'_>,
-    asm_macro: ast::AsmMacro,
+    asm_macro: AsmMacro,
     args: AsmArgs,
 ) -> ExpandResult<Result<ast::InlineAsm, ErrorGuaranteed>, ()> {
     let mut template = vec![];
@@ -797,7 +814,7 @@ pub(super) fn expand_asm<'cx>(
     sp: Span,
     tts: TokenStream,
 ) -> MacroExpanderResult<'cx> {
-    ExpandResult::Ready(match parse_args(ecx, sp, tts, false) {
+    ExpandResult::Ready(match parse_args(ecx, sp, tts, AsmMacro::Asm) {
         Ok(args) => {
             let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, AsmMacro::Asm, args) else {
                 return ExpandResult::Retry(());
@@ -826,29 +843,20 @@ pub(super) fn expand_naked_asm<'cx>(
     sp: Span,
     tts: TokenStream,
 ) -> MacroExpanderResult<'cx> {
-    ExpandResult::Ready(match parse_args(ecx, sp, tts, false) {
+    ExpandResult::Ready(match parse_args(ecx, sp, tts, AsmMacro::NakedAsm) {
         Ok(args) => {
             let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, AsmMacro::NakedAsm, args)
             else {
                 return ExpandResult::Retry(());
             };
             let expr = match mac {
-                Ok(mut inline_asm) => {
-                    // for future compatibility, we always set the NORETURN option.
-                    //
-                    // When we turn `asm!` into `naked_asm!` with this implementation, we can drop
-                    // the `options(noreturn)`, which makes the upgrade smooth when `naked_asm!`
-                    // starts disallowing the `noreturn` option in the future
-                    inline_asm.options |= ast::InlineAsmOptions::NORETURN;
-
-                    P(ast::Expr {
-                        id: ast::DUMMY_NODE_ID,
-                        kind: ast::ExprKind::InlineAsm(P(inline_asm)),
-                        span: sp,
-                        attrs: ast::AttrVec::new(),
-                        tokens: None,
-                    })
-                }
+                Ok(inline_asm) => P(ast::Expr {
+                    id: ast::DUMMY_NODE_ID,
+                    kind: ast::ExprKind::InlineAsm(P(inline_asm)),
+                    span: sp,
+                    attrs: ast::AttrVec::new(),
+                    tokens: None,
+                }),
                 Err(guar) => DummyResult::raw_expr(sp, Some(guar)),
             };
             MacEager::expr(expr)
@@ -865,7 +873,7 @@ pub(super) fn expand_global_asm<'cx>(
     sp: Span,
     tts: TokenStream,
 ) -> MacroExpanderResult<'cx> {
-    ExpandResult::Ready(match parse_args(ecx, sp, tts, true) {
+    ExpandResult::Ready(match parse_args(ecx, sp, tts, AsmMacro::GlobalAsm) {
         Ok(args) => {
             let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, AsmMacro::GlobalAsm, args)
             else {
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index 4fffffb91c8..f13ca224a45 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -751,7 +751,7 @@ pub(crate) struct AsmExpectedOther {
     #[primary_span]
     #[label(builtin_macros_asm_expected_other)]
     pub(crate) span: Span,
-    pub(crate) is_global_asm: bool,
+    pub(crate) is_inline_asm: bool,
 }
 
 #[derive(Diagnostic)]
@@ -799,13 +799,6 @@ pub(crate) struct AsmMayUnwind {
     pub(crate) labels_sp: Vec<Span>,
 }
 
-#[derive(Diagnostic)]
-#[diag(builtin_macros_global_asm_clobber_abi)]
-pub(crate) struct GlobalAsmClobberAbi {
-    #[primary_span]
-    pub(crate) spans: Vec<Span>,
-}
-
 pub(crate) struct AsmClobberNoReg {
     pub(crate) spans: Vec<Span>,
     pub(crate) clobbers: Vec<Span>,
@@ -841,23 +834,33 @@ pub(crate) struct AsmOptAlreadyprovided {
 }
 
 #[derive(Diagnostic)]
-#[diag(builtin_macros_global_asm_unsupported_option)]
-pub(crate) struct GlobalAsmUnsupportedOption {
+#[diag(builtin_macros_asm_unsupported_option)]
+pub(crate) struct AsmUnsupportedOption {
     #[primary_span]
     #[label]
     pub(crate) span: Span,
     pub(crate) symbol: Symbol,
     #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
     pub(crate) full_span: Span,
+    pub(crate) macro_name: &'static str,
 }
 
 #[derive(Diagnostic)]
-#[diag(builtin_macros_global_asm_unsupported_operand)]
-pub(crate) struct GlobalAsmUnsupportedOperand<'a> {
+#[diag(builtin_macros_asm_unsupported_operand)]
+pub(crate) struct AsmUnsupportedOperand<'a> {
     #[primary_span]
     #[label]
     pub(crate) span: Span,
     pub(crate) symbol: &'a str,
+    pub(crate) macro_name: &'static str,
+}
+
+#[derive(Diagnostic)]
+#[diag(builtin_macros_asm_unsupported_clobber_abi)]
+pub(crate) struct AsmUnsupportedClobberAbi {
+    #[primary_span]
+    pub(crate) spans: Vec<Span>,
+    pub(crate) macro_name: &'static str,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs
index 5e535ff62e1..9fc0318df5d 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs
@@ -726,6 +726,12 @@ pub macro global_asm() {
     /* compiler built-in */
 }
 
+#[rustc_builtin_macro]
+#[rustc_macro_transparency = "semitransparent"]
+pub macro naked_asm() {
+    /* compiler built-in */
+}
+
 pub static A_STATIC: u8 = 42;
 
 #[lang = "panic_location"]
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
index ccbd5a78485..e47431e0f87 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
@@ -390,7 +390,7 @@ global_asm! {
 #[naked]
 extern "C" fn naked_test() {
     unsafe {
-        asm!("ret", options(noreturn));
+        naked_asm!("ret");
     }
 }
 
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 09680622069..a681e6d9f3c 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -8,6 +8,7 @@ use rustc_ast::InlineAsmOptions;
 use rustc_codegen_ssa::base::is_call_from_compiler_builtins_to_upstream_monomorphization;
 use rustc_index::IndexVec;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
+use rustc_middle::mir::InlineAsmMacro;
 use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::layout::FnAbiOf;
@@ -57,6 +58,7 @@ pub(crate) fn codegen_fn<'tcx>(
 
         match &mir.basic_blocks[START_BLOCK].terminator().kind {
             TerminatorKind::InlineAsm {
+                asm_macro: InlineAsmMacro::NakedAsm,
                 template,
                 operands,
                 options,
@@ -498,6 +500,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
                 "tail calls are not yet supported in `rustc_codegen_cranelift` backend"
             ),
             TerminatorKind::InlineAsm {
+                asm_macro: _,
                 template,
                 operands,
                 options,
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 125d3b908c7..be9a6d9a90e 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -3,7 +3,9 @@ use std::cmp;
 use rustc_ast as ast;
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_hir::lang_items::LangItem;
-use rustc_middle::mir::{self, AssertKind, BasicBlock, SwitchTargets, UnwindTerminateReason};
+use rustc_middle::mir::{
+    self, AssertKind, BasicBlock, InlineAsmMacro, SwitchTargets, UnwindTerminateReason,
+};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, ValidityRequirement};
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::{self, Instance, Ty};
@@ -1133,6 +1135,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         &mut self,
         helper: TerminatorCodegenHelper<'tcx>,
         bx: &mut Bx,
+        asm_macro: InlineAsmMacro,
         terminator: &mir::Terminator<'tcx>,
         template: &[ast::InlineAsmTemplatePiece],
         operands: &[mir::InlineAsmOperand<'tcx>],
@@ -1203,11 +1206,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             &operands,
             options,
             line_spans,
-            if options.contains(InlineAsmOptions::NORETURN) {
-                None
-            } else {
-                targets.get(0).copied()
-            },
+            if asm_macro.diverges(options) { None } else { targets.get(0).copied() },
             unwind,
             instance,
             mergeable_succ,
@@ -1381,6 +1380,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
 
             mir::TerminatorKind::InlineAsm {
+                asm_macro,
                 template,
                 ref operands,
                 options,
@@ -1390,6 +1390,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             } => self.codegen_asm_terminator(
                 helper,
                 bx,
+                asm_macro,
                 terminator,
                 template,
                 operands,
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 0f796c31222..89d49ba046e 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -395,7 +395,7 @@ pub trait Machine<'tcx>: Sized {
     ///
     /// This should take care of jumping to the next block (one of `targets`) when asm goto
     /// is triggered, `targets[0]` when the assembly falls through, or diverge in case of
-    /// `InlineAsmOptions::NORETURN` being set.
+    /// naked_asm! or `InlineAsmOptions::NORETURN` being set.
     fn eval_inline_asm(
         _ecx: &mut InterpCx<'tcx, Self>,
         _template: &'tcx [InlineAsmTemplatePiece],
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 291664d556a..3b5af113e99 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -113,28 +113,47 @@ impl<Prov: Provenance> Immediate<Prov> {
     }
 
     /// Assert that this immediate is a valid value for the given ABI.
-    pub fn assert_matches_abi(self, abi: Abi, cx: &impl HasDataLayout) {
+    pub fn assert_matches_abi(self, abi: Abi, msg: &str, cx: &impl HasDataLayout) {
         match (self, abi) {
             (Immediate::Scalar(scalar), Abi::Scalar(s)) => {
-                assert_eq!(scalar.size(), s.size(cx));
+                assert_eq!(scalar.size(), s.size(cx), "{msg}: scalar value has wrong size");
                 if !matches!(s.primitive(), abi::Pointer(..)) {
                     // This is not a pointer, it should not carry provenance.
-                    assert!(matches!(scalar, Scalar::Int(..)));
+                    assert!(
+                        matches!(scalar, Scalar::Int(..)),
+                        "{msg}: scalar value should be an integer, but has provenance"
+                    );
                 }
             }
             (Immediate::ScalarPair(a_val, b_val), Abi::ScalarPair(a, b)) => {
-                assert_eq!(a_val.size(), a.size(cx));
+                assert_eq!(
+                    a_val.size(),
+                    a.size(cx),
+                    "{msg}: first component of scalar pair has wrong size"
+                );
                 if !matches!(a.primitive(), abi::Pointer(..)) {
-                    assert!(matches!(a_val, Scalar::Int(..)));
+                    assert!(
+                        matches!(a_val, Scalar::Int(..)),
+                        "{msg}: first component of scalar pair should be an integer, but has provenance"
+                    );
                 }
-                assert_eq!(b_val.size(), b.size(cx));
+                assert_eq!(
+                    b_val.size(),
+                    b.size(cx),
+                    "{msg}: second component of scalar pair has wrong size"
+                );
                 if !matches!(b.primitive(), abi::Pointer(..)) {
-                    assert!(matches!(b_val, Scalar::Int(..)));
+                    assert!(
+                        matches!(b_val, Scalar::Int(..)),
+                        "{msg}: second component of scalar pair should be an integer, but has provenance"
+                    );
                 }
             }
-            (Immediate::Uninit, _) => {}
+            (Immediate::Uninit, _) => {
+                assert!(abi.is_sized(), "{msg}: unsized immediates are not a thing");
+            }
             _ => {
-                bug!("value {self:?} does not match ABI {abi:?})",)
+                bug!("{msg}: value {self:?} does not match ABI {abi:?})",)
             }
         }
     }
@@ -241,6 +260,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
 
     #[inline(always)]
     pub fn from_immediate(imm: Immediate<Prov>, layout: TyAndLayout<'tcx>) -> Self {
+        // Without a `cx` we cannot call `assert_matches_abi`.
         debug_assert!(
             match (imm, layout.abi) {
                 (Immediate::Scalar(..), Abi::Scalar(..)) => true,
@@ -261,7 +281,6 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
 
     #[inline]
     pub fn from_scalar_int(s: ScalarInt, layout: TyAndLayout<'tcx>) -> Self {
-        assert_eq!(s.size(), layout.size);
         Self::from_scalar(Scalar::from(s), layout)
     }
 
@@ -334,7 +353,10 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
     /// given layout.
     // Not called `offset` to avoid confusion with the trait method.
     fn offset_(&self, offset: Size, layout: TyAndLayout<'tcx>, cx: &impl HasDataLayout) -> Self {
-        debug_assert!(layout.is_sized(), "unsized immediates are not a thing");
+        // Verify that the input matches its type.
+        if cfg!(debug_assertions) {
+            self.assert_matches_abi(self.layout.abi, "invalid input to Immediate::offset", cx);
+        }
         // `ImmTy` have already been checked to be in-bounds, so we can just check directly if this
         // remains in-bounds. This cannot actually be violated since projections are type-checked
         // and bounds-checked.
@@ -368,32 +390,14 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
             // the field covers the entire type
             _ if layout.size == self.layout.size => {
                 assert_eq!(offset.bytes(), 0);
-                assert!(
-                    match (self.layout.abi, layout.abi) {
-                        (Abi::Scalar(l), Abi::Scalar(r)) => l.size(cx) == r.size(cx),
-                        (Abi::ScalarPair(l1, l2), Abi::ScalarPair(r1, r2)) =>
-                            l1.size(cx) == r1.size(cx) && l2.size(cx) == r2.size(cx),
-                        _ => false,
-                    },
-                    "cannot project into {} immediate with equally-sized field {}\nouter ABI: {:#?}\nfield ABI: {:#?}",
-                    self.layout.ty,
-                    layout.ty,
-                    self.layout.abi,
-                    layout.abi,
-                );
                 **self
             }
             // extract fields from types with `ScalarPair` ABI
             (Immediate::ScalarPair(a_val, b_val), Abi::ScalarPair(a, b)) => {
-                assert_matches!(layout.abi, Abi::Scalar(..));
                 Immediate::from(if offset.bytes() == 0 {
-                    // It is "okay" to transmute from `usize` to a pointer (GVN relies on that).
-                    // So only compare the size.
-                    assert_eq!(layout.size, a.size(cx));
                     a_val
                 } else {
                     assert_eq!(offset, a.size(cx).align_to(b.align(cx).abi));
-                    assert_eq!(layout.size, b.size(cx));
                     b_val
                 })
             }
@@ -405,6 +409,8 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
                 self.layout
             ),
         };
+        // Ensure the new layout matches the new value.
+        inner_val.assert_matches_abi(layout.abi, "invalid field type in Immediate::offset", cx);
 
         ImmTy::from_immediate(inner_val, layout)
     }
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 49656e10f2a..81b926a1b65 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -658,7 +658,11 @@ where
                 // Things can ge wrong in quite weird ways when this is violated.
                 // Unfortunately this is too expensive to do in release builds.
                 if cfg!(debug_assertions) {
-                    src.assert_matches_abi(local_layout.abi, self);
+                    src.assert_matches_abi(
+                        local_layout.abi,
+                        "invalid immediate for given destination place",
+                        self,
+                    );
                 }
             }
             Left(mplace) => {
@@ -679,7 +683,7 @@ where
     ) -> InterpResult<'tcx> {
         // We use the sizes from `value` below.
         // Ensure that matches the type of the place it is written to.
-        value.assert_matches_abi(layout.abi, self);
+        value.assert_matches_abi(layout.abi, "invalid immediate for given destination place", self);
         // Note that it is really important that the type here is the right one, and matches the
         // type things are read at. In case `value` is a `ScalarPair`, we don't do any magic here
         // to handle padding properly, which is only correct if we never look at this data with the
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index cc49d7cebf4..e636090a324 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -82,6 +82,10 @@ pub trait Projectable<'tcx, Prov: Provenance>: Sized + std::fmt::Debug {
         self.offset_with_meta(offset, OffsetMode::Inbounds, MemPlaceMeta::None, layout, ecx)
     }
 
+    /// This does an offset-by-zero, which is effectively a transmute. Note however that
+    /// not all transmutes are supported by all projectables -- specifically, if this is an
+    /// `OpTy` or `ImmTy`, the new layout must have almost the same ABI as the old one
+    /// (only changing the `valid_range` is allowed and turning integers into pointers).
     fn transmute<M: Machine<'tcx, Provenance = Prov>>(
         &self,
         layout: TyAndLayout<'tcx>,
diff --git a/compiler/rustc_error_codes/src/error_codes/E0787.md b/compiler/rustc_error_codes/src/error_codes/E0787.md
index cee50829270..f5c5faa066b 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0787.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0787.md
@@ -11,11 +11,10 @@ pub extern "C" fn f() -> u32 {
 }
 ```
 
-The naked functions must be defined using a single inline assembly
-block.
+The naked function must be defined using a single `naked_asm!` assembly block.
 
 The execution must never fall through past the end of the assembly
-code so the block must use `noreturn` option. The asm block can also
+code, so it must either return or diverge. The asm block can also
 use `att_syntax` and `raw` options, but others options are not allowed.
 
 The asm block must not contain any operands other than `const` and
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index e5560be4531..94365a89adc 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -925,18 +925,6 @@ impl<'a> DiagCtxtHandle<'a> {
         self.inner.borrow_mut().emit_stashed_diagnostics()
     }
 
-    /// This excludes lint errors, and delayed bugs.
-    #[inline]
-    pub fn err_count_excluding_lint_errs(&self) -> usize {
-        let inner = self.inner.borrow();
-        inner.err_guars.len()
-            + inner
-                .stashed_diagnostics
-                .values()
-                .filter(|(diag, guar)| guar.is_some() && diag.is_lint.is_none())
-                .count()
-    }
-
     /// This excludes delayed bugs.
     #[inline]
     pub fn err_count(&self) -> usize {
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 2d718295374..95ca3e66472 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -3507,7 +3507,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     fn check_expr_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>) -> Ty<'tcx> {
-        let mut diverge = asm.options.contains(ast::InlineAsmOptions::NORETURN);
+        let mut diverge = asm.asm_macro.diverges(asm.options);
 
         for (op, _op_sp) in asm.operands {
             match op {
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors.rs
index 76ea9c3433d..76ea9c3433d 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors.rs
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 6ce47db8b9b..183973af4f9 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -82,7 +82,6 @@ impl<'tcx> InferCtxt<'tcx> {
             reported_trait_errors: self.reported_trait_errors.clone(),
             reported_signature_mismatch: self.reported_signature_mismatch.clone(),
             tainted_by_errors: self.tainted_by_errors.clone(),
-            err_count_on_creation: self.err_count_on_creation,
             universe: self.universe.clone(),
             intercrate,
             next_trait_solver: self.next_trait_solver,
@@ -382,21 +381,7 @@ impl<'tcx> ToTrace<'tcx> for ty::GenericArg<'tcx> {
                 (GenericArgKind::Const(a), GenericArgKind::Const(b)) => {
                     ValuePairs::Terms(ExpectedFound::new(true, a.into(), b.into()))
                 }
-
-                (
-                    GenericArgKind::Lifetime(_),
-                    GenericArgKind::Type(_) | GenericArgKind::Const(_),
-                )
-                | (
-                    GenericArgKind::Type(_),
-                    GenericArgKind::Lifetime(_) | GenericArgKind::Const(_),
-                )
-                | (
-                    GenericArgKind::Const(_),
-                    GenericArgKind::Lifetime(_) | GenericArgKind::Type(_),
-                ) => {
-                    bug!("relating different kinds: {a:?} {b:?}")
-                }
+                _ => bug!("relating different kinds: {a:?} {b:?}"),
             },
         }
     }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 040264586f6..e7bd2562a4f 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -14,7 +14,8 @@ use region_constraints::{
     GenericKind, RegionConstraintCollector, RegionConstraintStorage, VarInfos, VerifyBound,
 };
 pub use relate::StructurallyRelateAliases;
-pub use relate::combine::{CombineFields, PredicateEmittingRelation};
+use relate::combine::CombineFields;
+pub use relate::combine::PredicateEmittingRelation;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_data_structures::sync::Lrc;
@@ -50,23 +51,22 @@ use snapshot::undo_log::InferCtxtUndoLogs;
 use tracing::{debug, instrument};
 use type_variable::TypeVariableOrigin;
 
-use crate::infer::relate::RelateResult;
 use crate::traits::{self, ObligationCause, ObligationInspector, PredicateObligation, TraitEngine};
 
 pub mod at;
 pub mod canonical;
 mod context;
-pub mod free_regions;
+mod free_regions;
 mod freshen;
 mod lexical_region_resolve;
-pub mod opaque_types;
+mod opaque_types;
 pub mod outlives;
 mod projection;
 pub mod region_constraints;
 pub mod relate;
 pub mod resolve;
 pub(crate) mod snapshot;
-pub mod type_variable;
+mod type_variable;
 
 #[must_use]
 #[derive(Debug)]
@@ -76,8 +76,7 @@ pub struct InferOk<'tcx, T> {
 }
 pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
 
-pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
-pub type FixupResult<T> = Result<T, FixupError>; // "fixup result"
+pub(crate) type FixupResult<T> = Result<T, FixupError>; // "fixup result"
 
 pub(crate) type UnificationTable<'a, 'tcx, T> = ut::UnificationTable<
     ut::InPlace<T, &'a mut ut::UnificationStorage<T>, &'a mut InferCtxtUndoLogs<'tcx>>,
@@ -202,7 +201,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
     }
 
     #[inline]
-    pub fn opaque_types(&mut self) -> opaque_types::OpaqueTypeTable<'_, 'tcx> {
+    fn opaque_types(&mut self) -> opaque_types::OpaqueTypeTable<'_, 'tcx> {
         self.opaque_type_storage.with_log(&mut self.undo_log)
     }
 
@@ -280,27 +279,14 @@ pub struct InferCtxt<'tcx> {
     pub reported_signature_mismatch: RefCell<FxHashSet<(Span, Option<Span>)>>,
 
     /// When an error occurs, we want to avoid reporting "derived"
-    /// errors that are due to this original failure. Normally, we
-    /// handle this with the `err_count_on_creation` count, which
-    /// basically just tracks how many errors were reported when we
-    /// started type-checking a fn and checks to see if any new errors
-    /// have been reported since then. Not great, but it works.
-    ///
-    /// However, when errors originated in other passes -- notably
-    /// resolve -- this heuristic breaks down. Therefore, we have this
-    /// auxiliary flag that one can set whenever one creates a
-    /// type-error that is due to an error in a prior pass.
+    /// errors that are due to this original failure. We have this
+    /// flag that one can set whenever one creates a type-error that
+    /// is due to an error in a prior pass.
     ///
     /// Don't read this flag directly, call `is_tainted_by_errors()`
     /// and `set_tainted_by_errors()`.
     tainted_by_errors: Cell<Option<ErrorGuaranteed>>,
 
-    /// Track how many errors were reported when this infcx is created.
-    /// If the number of errors increases, that's also a sign (like
-    /// `tainted_by_errors`) to avoid reporting certain kinds of errors.
-    // FIXME(matthewjasper) Merge into `tainted_by_errors`
-    err_count_on_creation: usize,
-
     /// What is the innermost universe we have created? Starts out as
     /// `UniverseIndex::root()` but grows from there as we enter
     /// universal quantifiers.
@@ -509,46 +495,41 @@ pub enum NllRegionVariableOrigin {
     },
 }
 
-// FIXME(eddyb) investigate overlap between this and `TyOrConstInferVar`.
 #[derive(Copy, Clone, Debug)]
-pub enum FixupError {
-    UnresolvedIntTy(IntVid),
-    UnresolvedFloatTy(FloatVid),
-    UnresolvedTy(TyVid),
-    UnresolvedConst(ConstVid),
-    UnresolvedEffect(EffectVid),
-}
-
-/// See the `region_obligations` field for more information.
-#[derive(Clone, Debug)]
-pub struct RegionObligation<'tcx> {
-    pub sub_region: ty::Region<'tcx>,
-    pub sup_type: Ty<'tcx>,
-    pub origin: SubregionOrigin<'tcx>,
+pub struct FixupError {
+    unresolved: TyOrConstInferVar,
 }
 
 impl fmt::Display for FixupError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use self::FixupError::*;
+        use TyOrConstInferVar::*;
 
-        match *self {
-            UnresolvedIntTy(_) => write!(
+        match self.unresolved {
+            TyInt(_) => write!(
                 f,
                 "cannot determine the type of this integer; \
                  add a suffix to specify the type explicitly"
             ),
-            UnresolvedFloatTy(_) => write!(
+            TyFloat(_) => write!(
                 f,
                 "cannot determine the type of this number; \
                  add a suffix to specify the type explicitly"
             ),
-            UnresolvedTy(_) => write!(f, "unconstrained type"),
-            UnresolvedConst(_) => write!(f, "unconstrained const value"),
-            UnresolvedEffect(_) => write!(f, "unconstrained effect value"),
+            Ty(_) => write!(f, "unconstrained type"),
+            Const(_) => write!(f, "unconstrained const value"),
+            Effect(_) => write!(f, "unconstrained effect value"),
         }
     }
 }
 
+/// See the `region_obligations` field for more information.
+#[derive(Clone, Debug)]
+pub struct RegionObligation<'tcx> {
+    pub sub_region: ty::Region<'tcx>,
+    pub sup_type: Ty<'tcx>,
+    pub origin: SubregionOrigin<'tcx>,
+}
+
 /// Used to configure inference contexts before their creation.
 pub struct InferCtxtBuilder<'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -588,14 +569,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
         self
     }
 
-    pub fn with_defining_opaque_types(
-        mut self,
-        defining_opaque_types: &'tcx ty::List<LocalDefId>,
-    ) -> Self {
-        self.defining_opaque_types = defining_opaque_types;
-        self
-    }
-
     pub fn with_next_trait_solver(mut self, next_trait_solver: bool) -> Self {
         self.next_trait_solver = next_trait_solver;
         self
@@ -624,14 +597,15 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
     /// the bound values in `C` to their instantiated values in `V`
     /// (in other words, `S(C) = V`).
     pub fn build_with_canonical<T>(
-        self,
+        mut self,
         span: Span,
         canonical: &Canonical<'tcx, T>,
     ) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>)
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
-        let infcx = self.with_defining_opaque_types(canonical.defining_opaque_types).build();
+        self.defining_opaque_types = canonical.defining_opaque_types;
+        let infcx = self.build();
         let (value, args) = infcx.instantiate_canonical(span, canonical);
         (infcx, value, args)
     }
@@ -657,7 +631,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
             reported_trait_errors: Default::default(),
             reported_signature_mismatch: Default::default(),
             tainted_by_errors: Cell::new(None),
-            err_count_on_creation: tcx.dcx().err_count_excluding_lint_errs(),
             universe: Cell::new(ty::UniverseIndex::ROOT),
             intercrate,
             next_trait_solver,
@@ -919,28 +892,16 @@ impl<'tcx> InferCtxt<'tcx> {
         ty::Const::new_var(self.tcx, vid)
     }
 
-    pub fn next_const_var_id(&self, origin: ConstVariableOrigin) -> ConstVid {
-        self.inner
-            .borrow_mut()
-            .const_unification_table()
-            .new_key(ConstVariableValue::Unknown { origin, universe: self.universe() })
-            .vid
-    }
-
-    fn next_int_var_id(&self) -> IntVid {
-        self.inner.borrow_mut().int_unification_table().new_key(ty::IntVarValue::Unknown)
-    }
-
     pub fn next_int_var(&self) -> Ty<'tcx> {
-        Ty::new_int_var(self.tcx, self.next_int_var_id())
-    }
-
-    fn next_float_var_id(&self) -> FloatVid {
-        self.inner.borrow_mut().float_unification_table().new_key(ty::FloatVarValue::Unknown)
+        let next_int_var_id =
+            self.inner.borrow_mut().int_unification_table().new_key(ty::IntVarValue::Unknown);
+        Ty::new_int_var(self.tcx, next_int_var_id)
     }
 
     pub fn next_float_var(&self) -> Ty<'tcx> {
-        Ty::new_float_var(self.tcx, self.next_float_var_id())
+        let next_float_var_id =
+            self.inner.borrow_mut().float_unification_table().new_key(ty::FloatVarValue::Unknown);
+        Ty::new_float_var(self.tcx, next_float_var_id)
     }
 
     /// Creates a fresh region variable with the next available index.
@@ -1353,7 +1314,7 @@ impl<'tcx> InferCtxt<'tcx> {
     }
 
     /// See the [`region_constraints::RegionConstraintCollector::verify_generic_bound`] method.
-    pub fn verify_generic_bound(
+    pub(crate) fn verify_generic_bound(
         &self,
         origin: SubregionOrigin<'tcx>,
         kind: GenericKind<'tcx>,
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index ba0a9b14ccb..5a2ffbf029e 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -13,16 +13,15 @@ use rustc_middle::ty::{
 use rustc_span::Span;
 use tracing::{debug, instrument};
 
+use super::DefineOpaqueTypes;
 use crate::errors::OpaqueHiddenTypeDiag;
 use crate::infer::{InferCtxt, InferOk};
 use crate::traits::{self, Obligation};
 
 mod table;
 
-pub type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
-pub use table::{OpaqueTypeStorage, OpaqueTypeTable};
-
-use super::DefineOpaqueTypes;
+pub(crate) type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
+pub(crate) use table::{OpaqueTypeStorage, OpaqueTypeTable};
 
 /// Information about the opaque types whose values we
 /// are inferring in this function (these are the `impl Trait` that
@@ -385,9 +384,9 @@ impl<'tcx> InferCtxt<'tcx> {
 ///
 /// We ignore any type parameters because impl trait values are assumed to
 /// capture all the in-scope type parameters.
-pub struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP: FnMut(ty::Region<'tcx>)> {
-    pub tcx: TyCtxt<'tcx>,
-    pub op: OP,
+struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP: FnMut(ty::Region<'tcx>)> {
+    tcx: TyCtxt<'tcx>,
+    op: OP,
 }
 
 impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP>
@@ -463,20 +462,6 @@ where
     }
 }
 
-pub enum UseKind {
-    DefiningUse,
-    OpaqueUse,
-}
-
-impl UseKind {
-    pub fn is_defining(self) -> bool {
-        match self {
-            UseKind::DefiningUse => true,
-            UseKind::OpaqueUse => false,
-        }
-    }
-}
-
 impl<'tcx> InferCtxt<'tcx> {
     #[instrument(skip(self), level = "debug")]
     fn register_hidden_type(
diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs
index 4aa2ccab0e7..047d8edad3d 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/table.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs
@@ -7,7 +7,7 @@ use super::{OpaqueTypeDecl, OpaqueTypeMap};
 use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};
 
 #[derive(Default, Debug, Clone)]
-pub struct OpaqueTypeStorage<'tcx> {
+pub(crate) struct OpaqueTypeStorage<'tcx> {
     /// Opaque types found in explicit return types and their
     /// associated fresh inference variable. Writeback resolves these
     /// variables to get the concrete type, which can be used to
@@ -46,7 +46,7 @@ impl<'tcx> Drop for OpaqueTypeStorage<'tcx> {
     }
 }
 
-pub struct OpaqueTypeTable<'a, 'tcx> {
+pub(crate) struct OpaqueTypeTable<'a, 'tcx> {
     storage: &'a mut OpaqueTypeStorage<'tcx>,
 
     undo_log: &'a mut InferCtxtUndoLogs<'tcx>,
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index f5c873b0375..a270f9322f3 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -14,7 +14,7 @@ pub mod env;
 pub mod for_liveness;
 pub mod obligations;
 pub mod test_type_match;
-pub mod verify;
+pub(crate) mod verify;
 
 #[instrument(level = "debug", skip(param_env), ret)]
 pub fn explicit_outlives_bounds<'tcx>(
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index 74a80a1b9aa..247fbc25965 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -15,7 +15,7 @@ use crate::infer::{GenericKind, VerifyBound};
 /// via a "delegate" of type `D` -- this is usually the `infcx`, which
 /// accrues them into the `region_obligations` code, but for NLL we
 /// use something else.
-pub struct VerifyBoundCx<'cx, 'tcx> {
+pub(crate) struct VerifyBoundCx<'cx, 'tcx> {
     tcx: TyCtxt<'tcx>,
     region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
     /// During borrowck, if there are no outlives bounds on a generic
@@ -28,7 +28,7 @@ pub struct VerifyBoundCx<'cx, 'tcx> {
 }
 
 impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
-    pub fn new(
+    pub(crate) fn new(
         tcx: TyCtxt<'tcx>,
         region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
         implicit_region_bound: Option<ty::Region<'tcx>>,
@@ -38,7 +38,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
     }
 
     #[instrument(level = "debug", skip(self))]
-    pub fn param_or_placeholder_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
+    pub(crate) fn param_or_placeholder_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
         // Start with anything like `T: 'a` we can scrape from the
         // environment. If the environment contains something like
         // `for<'a> T: 'a`, then we know that `T` outlives everything.
@@ -92,7 +92,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
     /// the clause from the environment only applies if `'0 = 'a`,
     /// which we don't know yet. But we would still include `'b` in
     /// this list.
-    pub fn approx_declared_bounds_from_env(
+    pub(crate) fn approx_declared_bounds_from_env(
         &self,
         alias_ty: ty::AliasTy<'tcx>,
     ) -> Vec<ty::PolyTypeOutlivesPredicate<'tcx>> {
@@ -101,7 +101,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
     }
 
     #[instrument(level = "debug", skip(self))]
-    pub fn alias_bound(&self, alias_ty: ty::AliasTy<'tcx>) -> VerifyBound<'tcx> {
+    pub(crate) fn alias_bound(&self, alias_ty: ty::AliasTy<'tcx>) -> VerifyBound<'tcx> {
         let alias_ty_as_ty = alias_ty.to_ty(self.tcx);
 
         // Search the env for where clauses like `P: 'a`.
@@ -285,7 +285,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
     ///
     /// This is for simplicity, and because we are not really smart
     /// enough to cope with such bounds anywhere.
-    pub fn declared_bounds_from_definition(
+    pub(crate) fn declared_bounds_from_definition(
         &self,
         alias_ty: ty::AliasTy<'tcx>,
     ) -> impl Iterator<Item = ty::Region<'tcx>> {
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index f22cfed0b71..4411f8db72a 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -304,7 +304,7 @@ pub struct RegionVariableInfo {
     pub universe: ty::UniverseIndex,
 }
 
-pub struct RegionSnapshot {
+pub(crate) struct RegionSnapshot {
     any_unifications: bool,
 }
 
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index 4a8c7387ddc..450437f2176 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -33,7 +33,7 @@ use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace, relate};
 use crate::traits::{Obligation, PredicateObligation};
 
 #[derive(Clone)]
-pub struct CombineFields<'infcx, 'tcx> {
+pub(crate) struct CombineFields<'infcx, 'tcx> {
     pub infcx: &'infcx InferCtxt<'tcx>,
     // Immutable fields
     pub trace: TypeTrace<'tcx>,
@@ -47,7 +47,7 @@ pub struct CombineFields<'infcx, 'tcx> {
 }
 
 impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
-    pub fn new(
+    pub(crate) fn new(
         infcx: &'infcx InferCtxt<'tcx>,
         trace: TypeTrace<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -283,22 +283,22 @@ impl<'tcx> InferCtxt<'tcx> {
 }
 
 impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
-    pub fn tcx(&self) -> TyCtxt<'tcx> {
+    pub(crate) fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
-    pub fn equate<'a>(
+    pub(crate) fn equate<'a>(
         &'a mut self,
         structurally_relate_aliases: StructurallyRelateAliases,
     ) -> TypeRelating<'a, 'infcx, 'tcx> {
         TypeRelating::new(self, structurally_relate_aliases, ty::Invariant)
     }
 
-    pub fn sub<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
+    pub(crate) fn sub<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
         TypeRelating::new(self, StructurallyRelateAliases::No, ty::Covariant)
     }
 
-    pub fn sup<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
+    pub(crate) fn sup<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
         TypeRelating::new(self, StructurallyRelateAliases::No, ty::Contravariant)
     }
 
@@ -310,14 +310,14 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
         LatticeOp::new(self, LatticeOpKind::Glb)
     }
 
-    pub fn register_obligations(
+    pub(crate) fn register_obligations(
         &mut self,
         obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
     ) {
         self.goals.extend(obligations);
     }
 
-    pub fn register_predicates(
+    pub(crate) fn register_predicates(
         &mut self,
         obligations: impl IntoIterator<Item: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
     ) {
diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs
index edc0c4f078a..85158faa65d 100644
--- a/compiler/rustc_infer/src/infer/relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/relate/mod.rs
@@ -5,7 +5,7 @@
 pub use rustc_middle::ty::relate::RelateResult;
 pub use rustc_next_trait_solver::relate::*;
 
-pub use self::combine::{CombineFields, PredicateEmittingRelation};
+pub use self::combine::PredicateEmittingRelation;
 
 #[allow(hidden_glob_reexports)]
 pub(super) mod combine;
diff --git a/compiler/rustc_infer/src/infer/relate/type_relating.rs b/compiler/rustc_infer/src/infer/relate/type_relating.rs
index 7acfea643dd..7537ceec307 100644
--- a/compiler/rustc_infer/src/infer/relate/type_relating.rs
+++ b/compiler/rustc_infer/src/infer/relate/type_relating.rs
@@ -13,7 +13,7 @@ use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases}
 use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
 
 /// Enforce that `a` is equal to or a subtype of `b`.
-pub struct TypeRelating<'combine, 'a, 'tcx> {
+pub(crate) struct TypeRelating<'combine, 'a, 'tcx> {
     // Immutable except for the `InferCtxt` and the
     // resulting nested `goals`.
     fields: &'combine mut CombineFields<'a, 'tcx>,
@@ -49,7 +49,7 @@ pub struct TypeRelating<'combine, 'a, 'tcx> {
 }
 
 impl<'combine, 'infcx, 'tcx> TypeRelating<'combine, 'infcx, 'tcx> {
-    pub fn new(
+    pub(crate) fn new(
         f: &'combine mut CombineFields<'infcx, 'tcx>,
         structurally_relate_aliases: StructurallyRelateAliases,
         ambient_variance: ty::Variance,
diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs
index 671a66d504f..025c3a629fa 100644
--- a/compiler/rustc_infer/src/infer/resolve.rs
+++ b/compiler/rustc_infer/src/infer/resolve.rs
@@ -121,8 +121,6 @@ where
     value.try_fold_with(&mut FullTypeResolver { infcx })
 }
 
-// N.B. This type is not public because the protocol around checking the
-// `err` field is not enforceable otherwise.
 struct FullTypeResolver<'a, 'tcx> {
     infcx: &'a InferCtxt<'tcx>,
 }
@@ -138,11 +136,13 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> {
         if !t.has_infer() {
             Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects...
         } else {
+            use super::TyOrConstInferVar::*;
+
             let t = self.infcx.shallow_resolve(t);
             match *t.kind() {
-                ty::Infer(ty::TyVar(vid)) => Err(FixupError::UnresolvedTy(vid)),
-                ty::Infer(ty::IntVar(vid)) => Err(FixupError::UnresolvedIntTy(vid)),
-                ty::Infer(ty::FloatVar(vid)) => Err(FixupError::UnresolvedFloatTy(vid)),
+                ty::Infer(ty::TyVar(vid)) => Err(FixupError { unresolved: Ty(vid) }),
+                ty::Infer(ty::IntVar(vid)) => Err(FixupError { unresolved: TyInt(vid) }),
+                ty::Infer(ty::FloatVar(vid)) => Err(FixupError { unresolved: TyFloat(vid) }),
                 ty::Infer(_) => {
                     bug!("Unexpected type in full type resolver: {:?}", t);
                 }
@@ -171,13 +171,13 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for FullTypeResolver<'a, 'tcx> {
             let c = self.infcx.shallow_resolve_const(c);
             match c.kind() {
                 ty::ConstKind::Infer(InferConst::Var(vid)) => {
-                    return Err(FixupError::UnresolvedConst(vid));
+                    return Err(FixupError { unresolved: super::TyOrConstInferVar::Const(vid) });
                 }
                 ty::ConstKind::Infer(InferConst::Fresh(_)) => {
                     bug!("Unexpected const in full const resolver: {:?}", c);
                 }
                 ty::ConstKind::Infer(InferConst::EffectVar(evid)) => {
-                    return Err(FixupError::UnresolvedEffect(evid));
+                    return Err(FixupError { unresolved: super::TyOrConstInferVar::Effect(evid) });
                 }
                 _ => {}
             }
diff --git a/compiler/rustc_infer/src/infer/snapshot/mod.rs b/compiler/rustc_infer/src/infer/snapshot/mod.rs
index 964fb1f6819..07a482c2f9a 100644
--- a/compiler/rustc_infer/src/infer/snapshot/mod.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/mod.rs
@@ -5,7 +5,7 @@ use tracing::{debug, instrument};
 use super::InferCtxt;
 use super::region_constraints::RegionSnapshot;
 
-mod fudge;
+pub(crate) mod fudge;
 pub(crate) mod undo_log;
 
 use undo_log::{Snapshot, UndoLog};
diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs
index 7eb2c20e0d8..c50477b2922 100644
--- a/compiler/rustc_infer/src/infer/type_variable.rs
+++ b/compiler/rustc_infer/src/infer/type_variable.rs
@@ -20,7 +20,7 @@ impl<'tcx> Rollback<sv::UndoLog<ut::Delegate<TyVidEqKey<'tcx>>>> for TypeVariabl
 }
 
 #[derive(Clone)]
-pub struct TypeVariableStorage<'tcx> {
+pub(crate) struct TypeVariableStorage<'tcx> {
     /// The origins of each type variable.
     values: IndexVec<TyVid, TypeVariableData>,
     /// Two variables are unified in `eq_relations` when we have a
@@ -29,7 +29,7 @@ pub struct TypeVariableStorage<'tcx> {
     eq_relations: ut::UnificationTableStorage<TyVidEqKey<'tcx>>,
 }
 
-pub struct TypeVariableTable<'a, 'tcx> {
+pub(crate) struct TypeVariableTable<'a, 'tcx> {
     storage: &'a mut TypeVariableStorage<'tcx>,
 
     undo_log: &'a mut InferCtxtUndoLogs<'tcx>,
@@ -50,7 +50,7 @@ pub(crate) struct TypeVariableData {
 }
 
 #[derive(Copy, Clone, Debug)]
-pub enum TypeVariableValue<'tcx> {
+pub(crate) enum TypeVariableValue<'tcx> {
     Known { value: Ty<'tcx> },
     Unknown { universe: ty::UniverseIndex },
 }
@@ -58,14 +58,14 @@ pub enum TypeVariableValue<'tcx> {
 impl<'tcx> TypeVariableValue<'tcx> {
     /// If this value is known, returns the type it is known to be.
     /// Otherwise, `None`.
-    pub fn known(&self) -> Option<Ty<'tcx>> {
+    pub(crate) fn known(&self) -> Option<Ty<'tcx>> {
         match *self {
             TypeVariableValue::Unknown { .. } => None,
             TypeVariableValue::Known { value } => Some(value),
         }
     }
 
-    pub fn is_unknown(&self) -> bool {
+    pub(crate) fn is_unknown(&self) -> bool {
         match *self {
             TypeVariableValue::Unknown { .. } => true,
             TypeVariableValue::Known { .. } => false,
@@ -74,7 +74,7 @@ impl<'tcx> TypeVariableValue<'tcx> {
 }
 
 impl<'tcx> TypeVariableStorage<'tcx> {
-    pub fn new() -> TypeVariableStorage<'tcx> {
+    pub(crate) fn new() -> TypeVariableStorage<'tcx> {
         TypeVariableStorage {
             values: Default::default(),
             eq_relations: ut::UnificationTableStorage::new(),
@@ -105,14 +105,14 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
     ///
     /// Note that this function does not return care whether
     /// `vid` has been unified with something else or not.
-    pub fn var_origin(&self, vid: ty::TyVid) -> TypeVariableOrigin {
+    pub(crate) fn var_origin(&self, vid: ty::TyVid) -> TypeVariableOrigin {
         self.storage.values[vid].origin
     }
 
     /// Records that `a == b`, depending on `dir`.
     ///
     /// Precondition: neither `a` nor `b` are known.
-    pub fn equate(&mut self, a: ty::TyVid, b: ty::TyVid) {
+    pub(crate) fn equate(&mut self, a: ty::TyVid, b: ty::TyVid) {
         debug_assert!(self.probe(a).is_unknown());
         debug_assert!(self.probe(b).is_unknown());
         self.eq_relations().union(a, b);
@@ -121,7 +121,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
     /// Instantiates `vid` with the type `ty`.
     ///
     /// Precondition: `vid` must not have been previously instantiated.
-    pub fn instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>) {
+    pub(crate) fn instantiate(&mut self, vid: ty::TyVid, ty: Ty<'tcx>) {
         let vid = self.root_var(vid);
         debug_assert!(!ty.is_ty_var(), "instantiating ty var with var: {vid:?} {ty:?}");
         debug_assert!(self.probe(vid).is_unknown());
@@ -143,7 +143,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
     /// - `origin`: indicates *why* the type variable was created.
     ///   The code in this module doesn't care, but it can be useful
     ///   for improving error messages.
-    pub fn new_var(
+    pub(crate) fn new_var(
         &mut self,
         universe: ty::UniverseIndex,
         origin: TypeVariableOrigin,
@@ -158,7 +158,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
     }
 
     /// Returns the number of type variables created thus far.
-    pub fn num_vars(&self) -> usize {
+    pub(crate) fn num_vars(&self) -> usize {
         self.storage.values.len()
     }
 
@@ -167,42 +167,29 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
     /// will yield the same root variable (per the union-find
     /// algorithm), so `root_var(a) == root_var(b)` implies that `a ==
     /// b` (transitively).
-    pub fn root_var(&mut self, vid: ty::TyVid) -> ty::TyVid {
+    pub(crate) fn root_var(&mut self, vid: ty::TyVid) -> ty::TyVid {
         self.eq_relations().find(vid).vid
     }
 
     /// Retrieves the type to which `vid` has been instantiated, if
     /// any.
-    pub fn probe(&mut self, vid: ty::TyVid) -> TypeVariableValue<'tcx> {
+    pub(crate) fn probe(&mut self, vid: ty::TyVid) -> TypeVariableValue<'tcx> {
         self.inlined_probe(vid)
     }
 
     /// An always-inlined variant of `probe`, for very hot call sites.
     #[inline(always)]
-    pub fn inlined_probe(&mut self, vid: ty::TyVid) -> TypeVariableValue<'tcx> {
+    pub(crate) fn inlined_probe(&mut self, vid: ty::TyVid) -> TypeVariableValue<'tcx> {
         self.eq_relations().inlined_probe_value(vid)
     }
 
-    /// If `t` is a type-inference variable, and it has been
-    /// instantiated, then return the with which it was
-    /// instantiated. Otherwise, returns `t`.
-    pub fn replace_if_possible(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
-        match *t.kind() {
-            ty::Infer(ty::TyVar(v)) => match self.probe(v) {
-                TypeVariableValue::Unknown { .. } => t,
-                TypeVariableValue::Known { value } => value,
-            },
-            _ => t,
-        }
-    }
-
     #[inline]
     fn eq_relations(&mut self) -> super::UnificationTable<'_, 'tcx, TyVidEqKey<'tcx>> {
         self.storage.eq_relations.with_log(self.undo_log)
     }
 
     /// Returns a range of the type variables created during the snapshot.
-    pub fn vars_since_snapshot(
+    pub(crate) fn vars_since_snapshot(
         &mut self,
         value_count: usize,
     ) -> (Range<TyVid>, Vec<TypeVariableOrigin>) {
@@ -215,7 +202,7 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
 
     /// Returns indices of all variables that are not yet
     /// instantiated.
-    pub fn unresolved_variables(&mut self) -> Vec<ty::TyVid> {
+    pub(crate) fn unresolved_variables(&mut self) -> Vec<ty::TyVid> {
         (0..self.num_vars())
             .filter_map(|i| {
                 let vid = ty::TyVid::from_usize(i);
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 934484bf915..a04b2bb2b08 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -19,10 +19,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(assert_matches)]
-#![feature(box_patterns)]
 #![feature(extend_one)]
-#![feature(if_let_guard)]
-#![feature(iter_intersperse)]
 #![feature(iterator_try_collect)]
 #![feature(let_chains)]
 #![feature(rustdoc_internals)]
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index e1b710b72f6..a123059df8f 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2925,16 +2925,16 @@ declare_lint! {
     /// ```rust
     /// #![feature(asm_experimental_arch, naked_functions)]
     ///
-    /// use std::arch::asm;
+    /// use std::arch::naked_asm;
     ///
     /// #[naked]
     /// pub fn default_abi() -> u32 {
-    ///     unsafe { asm!("", options(noreturn)); }
+    ///     unsafe { naked_asm!(""); }
     /// }
     ///
     /// #[naked]
     /// pub extern "Rust" fn rust_abi() -> u32 {
-    ///     unsafe { asm!("", options(noreturn)); }
+    ///     unsafe { naked_asm!(""); }
     /// }
     /// ```
     ///
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 48789565218..9cafe804a8e 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -4,7 +4,7 @@ use std::fs;
 use std::io::{self, Write as _};
 use std::path::{Path, PathBuf};
 
-use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
+use rustc_ast::InlineAsmTemplatePiece;
 use rustc_middle::mir::interpret::{
     AllocBytes, AllocId, Allocation, GlobalAlloc, Pointer, Provenance, alloc_range,
     read_target_uint,
@@ -1024,9 +1024,9 @@ impl<'tcx> TerminatorKind<'tcx> {
                 vec!["real".into(), "unwind".into()]
             }
             FalseUnwind { unwind: _, .. } => vec!["real".into()],
-            InlineAsm { options, ref targets, unwind, .. } => {
+            InlineAsm { asm_macro, options, ref targets, unwind, .. } => {
                 let mut vec = Vec::with_capacity(targets.len() + 1);
-                if !options.contains(InlineAsmOptions::NORETURN) {
+                if !asm_macro.diverges(options) {
                     vec.push("return".into());
                 }
                 vec.resize(targets.len(), "label".into());
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 1722a7a1f35..c610fac80f6 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -605,6 +605,25 @@ impl CallSource {
     }
 }
 
+#[derive(Clone, Copy, Debug, TyEncodable, TyDecodable, Hash, HashStable, PartialEq)]
+#[derive(TypeFoldable, TypeVisitable)]
+/// The macro that an inline assembly block was created by
+pub enum InlineAsmMacro {
+    /// The `asm!` macro
+    Asm,
+    /// The `naked_asm!` macro
+    NakedAsm,
+}
+
+impl InlineAsmMacro {
+    pub const fn diverges(self, options: InlineAsmOptions) -> bool {
+        match self {
+            InlineAsmMacro::Asm => options.contains(InlineAsmOptions::NORETURN),
+            InlineAsmMacro::NakedAsm => true,
+        }
+    }
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // Terminators
 
@@ -859,6 +878,9 @@ pub enum TerminatorKind<'tcx> {
     /// Block ends with an inline assembly block. This is a terminator since
     /// inline assembly is allowed to diverge.
     InlineAsm {
+        /// Macro used to create this inline asm: one of `asm!` or `naked_asm!`
+        asm_macro: InlineAsmMacro,
+
         /// The template for the inline assembly, with placeholders.
         template: &'tcx [InlineAsmTemplatePiece],
 
@@ -874,7 +896,7 @@ pub enum TerminatorKind<'tcx> {
 
         /// Valid targets for the inline assembly.
         /// The first element is the fallthrough destination, unless
-        /// InlineAsmOptions::NORETURN is set.
+        /// asm_macro == InlineAsmMacro::NakedAsm or InlineAsmOptions::NORETURN is set.
         targets: Box<[BasicBlock]>,
 
         /// Action to be taken if the inline assembly unwinds. This is present
diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs
index 783952fb9cb..b919f5726db 100644
--- a/compiler/rustc_middle/src/mir/terminator.rs
+++ b/compiler/rustc_middle/src/mir/terminator.rs
@@ -666,6 +666,7 @@ impl<'tcx> TerminatorKind<'tcx> {
             },
 
             InlineAsm {
+                asm_macro: _,
                 template: _,
                 ref operands,
                 options: _,
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 64898a8495e..9f9ee8497b6 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -576,6 +576,7 @@ macro_rules! make_mir_visitor {
                     }
 
                     TerminatorKind::InlineAsm {
+                        asm_macro: _,
                         template: _,
                         operands,
                         options: _,
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index e614d41899a..fe865b8a515 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -12,7 +12,7 @@ use std::cmp::Ordering;
 use std::fmt;
 use std::ops::Index;
 
-use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
+use rustc_ast::{AsmMacro, InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
@@ -173,6 +173,7 @@ pub struct ClosureExpr<'tcx> {
 
 #[derive(Clone, Debug, HashStable)]
 pub struct InlineAsmExpr<'tcx> {
+    pub asm_macro: AsmMacro,
     pub template: &'tcx [InlineAsmTemplatePiece],
     pub operands: Box<[InlineAsmOperand<'tcx>]>,
     pub options: InlineAsmOptions,
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 58e2ebaeaf8..36f0e3d890c 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -148,7 +148,13 @@ pub fn walk_expr<'thir, 'tcx: 'thir, V: Visitor<'thir, 'tcx>>(
         NamedConst { def_id: _, args: _, user_ty: _ } => {}
         ConstParam { param: _, def_id: _ } => {}
         StaticRef { alloc_id: _, ty: _, def_id: _ } => {}
-        InlineAsm(box InlineAsmExpr { ref operands, template: _, options: _, line_spans: _ }) => {
+        InlineAsm(box InlineAsmExpr {
+            asm_macro: _,
+            ref operands,
+            template: _,
+            options: _,
+            line_spans: _,
+        }) => {
             for op in &**operands {
                 use InlineAsmOperand::*;
                 match op {
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 61c03922ac0..4c7bcb1bf2e 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -212,15 +212,7 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for ty::GenericArg<'tcx> {
             (ty::GenericArgKind::Const(a_ct), ty::GenericArgKind::Const(b_ct)) => {
                 Ok(relation.relate(a_ct, b_ct)?.into())
             }
-            (ty::GenericArgKind::Lifetime(unpacked), x) => {
-                bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
-            }
-            (ty::GenericArgKind::Type(unpacked), x) => {
-                bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
-            }
-            (ty::GenericArgKind::Const(unpacked), x) => {
-                bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
-            }
+            _ => bug!("impossible case reached: can't relate: {a:?} with {b:?}"),
         }
     }
 }
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 86fe447f399..dc317feb20c 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -2,7 +2,7 @@
 
 use std::iter;
 
-use rustc_ast::InlineAsmOptions;
+use rustc_ast::{AsmMacro, InlineAsmOptions};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir as hir;
@@ -384,6 +384,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 block.unit()
             }
             ExprKind::InlineAsm(box InlineAsmExpr {
+                asm_macro,
                 template,
                 ref operands,
                 options,
@@ -392,11 +393,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 use rustc_middle::{mir, thir};
 
                 let destination_block = this.cfg.start_new_block();
-                let mut targets = if options.contains(InlineAsmOptions::NORETURN) {
-                    vec![]
-                } else {
-                    vec![destination_block]
-                };
+                let mut targets =
+                    if asm_macro.diverges(options) { vec![] } else { vec![destination_block] };
 
                 let operands = operands
                     .into_iter()
@@ -474,7 +472,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     this.cfg.push_assign_unit(block, source_info, destination, this.tcx);
                 }
 
+                let asm_macro = match asm_macro {
+                    AsmMacro::Asm => InlineAsmMacro::Asm,
+                    AsmMacro::GlobalAsm => {
+                        span_bug!(expr_span, "unexpected global_asm! in inline asm")
+                    }
+                    AsmMacro::NakedAsm => InlineAsmMacro::NakedAsm,
+                };
+
                 this.cfg.terminate(block, source_info, TerminatorKind::InlineAsm {
+                    asm_macro,
                     template,
                     operands,
                     options,
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 2ffad0b4834..abf486af962 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -672,6 +672,7 @@ impl<'tcx> Cx<'tcx> {
             }
 
             hir::ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(Box::new(InlineAsmExpr {
+                asm_macro: asm.asm_macro,
                 template: asm.template,
                 operands: asm
                     .operands
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index 61317925d09..dae13df4054 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -818,10 +818,12 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
     }
 
     fn print_inline_asm_expr(&mut self, expr: &InlineAsmExpr<'tcx>, depth_lvl: usize) {
-        let InlineAsmExpr { template, operands, options, line_spans } = expr;
+        let InlineAsmExpr { asm_macro, template, operands, options, line_spans } = expr;
 
         print_indented!(self, "InlineAsmExpr {", depth_lvl);
 
+        print_indented!(self, format!("asm_macro: {:?}", asm_macro), depth_lvl + 1);
+
         print_indented!(self, "template: [", depth_lvl + 1);
         for template_piece in template.iter() {
             print_indented!(self, format!("{:?}", template_piece), depth_lvl + 2);
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 3c8be2f73e1..162245cb950 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -481,6 +481,7 @@ impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
                 }
             }
             TerminatorKind::InlineAsm {
+                asm_macro: _,
                 template: _,
                 ref operands,
                 options: _,
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index ef4031c5c03..94088156756 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -4,6 +4,7 @@ use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph::DirectedGraph;
 use rustc_index::IndexVec;
+use rustc_index::bit_set::BitSet;
 use rustc_middle::bug;
 use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId, Op};
 use tracing::{debug, debug_span, instrument};
@@ -13,13 +14,13 @@ use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, TraverseCoverage
 /// The coverage counter or counter expression associated with a particular
 /// BCB node or BCB edge.
 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
-pub(super) enum BcbCounter {
+enum BcbCounter {
     Counter { id: CounterId },
     Expression { id: ExpressionId },
 }
 
 impl BcbCounter {
-    pub(super) fn as_term(&self) -> CovTerm {
+    fn as_term(&self) -> CovTerm {
         match *self {
             BcbCounter::Counter { id, .. } => CovTerm::Counter(id),
             BcbCounter::Expression { id, .. } => CovTerm::Expression(id),
@@ -78,21 +79,22 @@ impl CoverageCounters {
     /// counters or counter expressions for nodes and edges as required.
     pub(super) fn make_bcb_counters(
         basic_coverage_blocks: &CoverageGraph,
-        bcb_needs_counter: impl Fn(BasicCoverageBlock) -> bool,
+        bcb_needs_counter: &BitSet<BasicCoverageBlock>,
     ) -> Self {
-        let num_bcbs = basic_coverage_blocks.num_nodes();
+        let mut counters = MakeBcbCounters::new(basic_coverage_blocks, bcb_needs_counter);
+        counters.make_bcb_counters();
 
-        let mut this = Self {
+        counters.coverage_counters
+    }
+
+    fn with_num_bcbs(num_bcbs: usize) -> Self {
+        Self {
             counter_increment_sites: IndexVec::new(),
             bcb_counters: IndexVec::from_elem_n(None, num_bcbs),
             bcb_edge_counters: FxHashMap::default(),
             expressions: IndexVec::new(),
             expressions_memo: FxHashMap::default(),
-        };
-
-        MakeBcbCounters::new(&mut this, basic_coverage_blocks).make_bcb_counters(bcb_needs_counter);
-
-        this
+        }
     }
 
     /// Shared helper used by [`Self::make_phys_node_counter`] and
@@ -218,8 +220,8 @@ impl CoverageCounters {
         }
     }
 
-    pub(super) fn bcb_counter(&self, bcb: BasicCoverageBlock) -> Option<BcbCounter> {
-        self.bcb_counters[bcb]
+    pub(super) fn term_for_bcb(&self, bcb: BasicCoverageBlock) -> Option<CovTerm> {
+        self.bcb_counters[bcb].map(|counter| counter.as_term())
     }
 
     /// Returns an iterator over all the nodes/edges in the coverage graph that
@@ -265,19 +267,25 @@ impl CoverageCounters {
 
 /// Helper struct that allows counter creation to inspect the BCB graph.
 struct MakeBcbCounters<'a> {
-    coverage_counters: &'a mut CoverageCounters,
+    coverage_counters: CoverageCounters,
     basic_coverage_blocks: &'a CoverageGraph,
+    bcb_needs_counter: &'a BitSet<BasicCoverageBlock>,
 }
 
 impl<'a> MakeBcbCounters<'a> {
     fn new(
-        coverage_counters: &'a mut CoverageCounters,
         basic_coverage_blocks: &'a CoverageGraph,
+        bcb_needs_counter: &'a BitSet<BasicCoverageBlock>,
     ) -> Self {
-        Self { coverage_counters, basic_coverage_blocks }
+        assert_eq!(basic_coverage_blocks.num_nodes(), bcb_needs_counter.domain_size());
+        Self {
+            coverage_counters: CoverageCounters::with_num_bcbs(basic_coverage_blocks.num_nodes()),
+            basic_coverage_blocks,
+            bcb_needs_counter,
+        }
     }
 
-    fn make_bcb_counters(&mut self, bcb_needs_counter: impl Fn(BasicCoverageBlock) -> bool) {
+    fn make_bcb_counters(&mut self) {
         debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
 
         // Traverse the coverage graph, ensuring that every node that needs a
@@ -290,7 +298,7 @@ impl<'a> MakeBcbCounters<'a> {
         let mut traversal = TraverseCoverageGraphWithLoops::new(self.basic_coverage_blocks);
         while let Some(bcb) = traversal.next() {
             let _span = debug_span!("traversal", ?bcb).entered();
-            if bcb_needs_counter(bcb) {
+            if self.bcb_needs_counter.contains(bcb) {
                 self.make_node_counter_and_out_edge_counters(&traversal, bcb);
             }
         }
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 104f340c8d6..79482ba3919 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -94,9 +94,8 @@ fn instrument_function_for_coverage<'tcx>(tcx: TyCtxt<'tcx>, mir_body: &mut mir:
         return;
     }
 
-    let bcb_has_counter_mappings = |bcb| bcbs_with_counter_mappings.contains(bcb);
     let coverage_counters =
-        CoverageCounters::make_bcb_counters(&basic_coverage_blocks, bcb_has_counter_mappings);
+        CoverageCounters::make_bcb_counters(&basic_coverage_blocks, &bcbs_with_counter_mappings);
 
     let mappings = create_mappings(tcx, &hir_info, &extracted_mappings, &coverage_counters);
     if mappings.is_empty() {
@@ -153,12 +152,8 @@ fn create_mappings<'tcx>(
         &source_file.name.for_scope(tcx.sess, RemapPathScopeComponents::MACRO).to_string_lossy(),
     );
 
-    let term_for_bcb = |bcb| {
-        coverage_counters
-            .bcb_counter(bcb)
-            .expect("all BCBs with spans were given counters")
-            .as_term()
-    };
+    let term_for_bcb =
+        |bcb| coverage_counters.term_for_bcb(bcb).expect("all BCBs with spans were given counters");
     let region_for_span = |span: Span| make_source_region(source_map, file_name, span, body_span);
 
     // Fully destructure the mappings struct to make sure we don't miss any kinds.
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 0bb46675e9a..daf868559bc 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -103,7 +103,7 @@ use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::DUMMY_SP;
 use rustc_span::def_id::DefId;
-use rustc_target::abi::{self, Abi, FIRST_VARIANT, FieldIdx, Size, VariantIdx};
+use rustc_target::abi::{self, Abi, FIRST_VARIANT, FieldIdx, Primitive, Size, VariantIdx};
 use smallvec::SmallVec;
 use tracing::{debug, instrument, trace};
 
@@ -568,13 +568,29 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 CastKind::Transmute => {
                     let value = self.evaluated[value].as_ref()?;
                     let to = self.ecx.layout_of(to).ok()?;
-                    // `offset` for immediates only supports scalar/scalar-pair ABIs,
-                    // so bail out if the target is not one.
+                    // `offset` for immediates generally only supports projections that match the
+                    // type of the immediate. However, as a HACK, we exploit that it can also do
+                    // limited transmutes: it only works between types with the same layout, and
+                    // cannot transmute pointers to integers.
                     if value.as_mplace_or_imm().is_right() {
-                        match (value.layout.abi, to.abi) {
-                            (Abi::Scalar(..), Abi::Scalar(..)) => {}
-                            (Abi::ScalarPair(..), Abi::ScalarPair(..)) => {}
-                            _ => return None,
+                        let can_transmute = match (value.layout.abi, to.abi) {
+                            (Abi::Scalar(s1), Abi::Scalar(s2)) => {
+                                s1.size(&self.ecx) == s2.size(&self.ecx)
+                                    && !matches!(s1.primitive(), Primitive::Pointer(..))
+                            }
+                            (Abi::ScalarPair(a1, b1), Abi::ScalarPair(a2, b2)) => {
+                                a1.size(&self.ecx) == a2.size(&self.ecx) &&
+                                b1.size(&self.ecx) == b2.size(&self.ecx) &&
+                                // The alignment of the second component determines its offset, so that also needs to match.
+                                b1.align(&self.ecx) == b2.align(&self.ecx) &&
+                                // None of the inputs may be a pointer.
+                                !matches!(a1.primitive(), Primitive::Pointer(..))
+                                    && !matches!(b1.primitive(), Primitive::Pointer(..))
+                            }
+                            _ => false,
+                        };
+                        if !can_transmute {
+                            return None;
                         }
                     }
                     value.offset(Size::ZERO, to, &self.ecx).discard_err()?
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index f2682acf8aa..be76d6cef2b 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -488,24 +488,18 @@ passes_naked_asm_outside_naked_fn =
     the `naked_asm!` macro can only be used in functions marked with `#[naked]`
 
 passes_naked_functions_asm_block =
-    naked functions must contain a single asm block
-    .label_multiple_asm = multiple asm blocks are unsupported in naked functions
-    .label_non_asm = non-asm is unsupported in naked functions
-
-passes_naked_functions_asm_options =
-    asm options unsupported in naked functions: {$unsupported_options}
+    naked functions must contain a single `naked_asm!` invocation
+    .label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions
+    .label_non_asm = not allowed in naked functions
 
 passes_naked_functions_incompatible_attribute =
     attribute incompatible with `#[naked]`
     .label = the `{$attr}` attribute is incompatible with `#[naked]`
     .naked_attribute = function marked with `#[naked]` here
 
-passes_naked_functions_must_use_noreturn =
-    asm in naked functions must use `noreturn` option
-    .suggestion = consider specifying that the asm block is responsible for returning from the function
-
-passes_naked_functions_operands =
-    only `const` and `sym` operands are supported in naked functions
+passes_naked_functions_must_naked_asm =
+    the `asm!` macro is not allowed in naked functions
+    .label = consider using the `naked_asm!` macro instead
 
 passes_no_link =
     attribute should be applied to an `extern crate` item
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 29a087bf759..4f00c90fa3b 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1187,27 +1187,11 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for NakedFunctionsAsmBlock {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_naked_functions_operands, code = E0787)]
-pub(crate) struct NakedFunctionsOperands {
-    #[primary_span]
-    pub unsupported_operands: Vec<Span>,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_naked_functions_asm_options, code = E0787)]
-pub(crate) struct NakedFunctionsAsmOptions {
-    #[primary_span]
-    pub span: Span,
-    pub unsupported_options: String,
-}
-
-#[derive(Diagnostic)]
-#[diag(passes_naked_functions_must_use_noreturn, code = E0787)]
-pub(crate) struct NakedFunctionsMustUseNoreturn {
+#[diag(passes_naked_functions_must_naked_asm, code = E0787)]
+pub(crate) struct NakedFunctionsMustNakedAsm {
     #[primary_span]
+    #[label]
     pub span: Span,
-    #[suggestion(code = ", options(noreturn)", applicability = "machine-applicable")]
-    pub last_span: Span,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index 8d3f7e0231f..b2f8d7dadff 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -1,13 +1,13 @@
 //! Checks validity of naked functions.
 
-use rustc_ast::InlineAsmOptions;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{LocalDefId, LocalModDefId};
 use rustc_hir::intravisit::Visitor;
-use rustc_hir::{ExprKind, HirIdSet, InlineAsmOperand, StmtKind};
+use rustc_hir::{ExprKind, HirIdSet, StmtKind};
 use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_middle::query::Providers;
+use rustc_middle::span_bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI;
 use rustc_span::Span;
@@ -15,9 +15,8 @@ use rustc_span::symbol::sym;
 use rustc_target::spec::abi::Abi;
 
 use crate::errors::{
-    NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsAsmOptions,
-    NakedFunctionsMustUseNoreturn, NakedFunctionsOperands, NoPatterns, ParamsNotAllowed,
-    UndefinedNakedFunctionAbi,
+    NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns,
+    ParamsNotAllowed, UndefinedNakedFunctionAbi,
 };
 
 pub(crate) fn provide(providers: &mut Providers) {
@@ -119,23 +118,28 @@ impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> {
 
 /// Checks that function body contains a single inline assembly block.
 fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<'tcx>) {
-    let mut this = CheckInlineAssembly { tcx, items: Vec::new() };
+    let mut this = CheckInlineAssembly { items: Vec::new() };
     this.visit_body(body);
-    if let [(ItemKind::Asm | ItemKind::Err, _)] = this.items[..] {
+    if let [(ItemKind::NakedAsm | ItemKind::Err, _)] = this.items[..] {
         // Ok.
     } else {
         let mut must_show_error = false;
-        let mut has_asm = false;
+        let mut has_naked_asm = false;
         let mut has_err = false;
         let mut multiple_asms = vec![];
         let mut non_asms = vec![];
         for &(kind, span) in &this.items {
             match kind {
-                ItemKind::Asm if has_asm => {
+                ItemKind::NakedAsm if has_naked_asm => {
                     must_show_error = true;
                     multiple_asms.push(span);
                 }
-                ItemKind::Asm => has_asm = true,
+                ItemKind::NakedAsm => has_naked_asm = true,
+                ItemKind::InlineAsm => {
+                    has_err = true;
+
+                    tcx.dcx().emit_err(NakedFunctionsMustNakedAsm { span });
+                }
                 ItemKind::NonAsm => {
                     must_show_error = true;
                     non_asms.push(span);
@@ -157,20 +161,20 @@ fn check_asm<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<
     }
 }
 
-struct CheckInlineAssembly<'tcx> {
-    tcx: TyCtxt<'tcx>,
+struct CheckInlineAssembly {
     items: Vec<(ItemKind, Span)>,
 }
 
 #[derive(Copy, Clone)]
 enum ItemKind {
-    Asm,
+    NakedAsm,
+    InlineAsm,
     NonAsm,
     Err,
 }
 
-impl<'tcx> CheckInlineAssembly<'tcx> {
-    fn check_expr(&mut self, expr: &'tcx hir::Expr<'tcx>, span: Span) {
+impl CheckInlineAssembly {
+    fn check_expr<'tcx>(&mut self, expr: &'tcx hir::Expr<'tcx>, span: Span) {
         match expr.kind {
             ExprKind::ConstBlock(..)
             | ExprKind::Array(..)
@@ -204,10 +208,17 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
                 self.items.push((ItemKind::NonAsm, span));
             }
 
-            ExprKind::InlineAsm(asm) => {
-                self.items.push((ItemKind::Asm, span));
-                self.check_inline_asm(asm, span);
-            }
+            ExprKind::InlineAsm(asm) => match asm.asm_macro {
+                rustc_ast::AsmMacro::Asm => {
+                    self.items.push((ItemKind::InlineAsm, span));
+                }
+                rustc_ast::AsmMacro::NakedAsm => {
+                    self.items.push((ItemKind::NakedAsm, span));
+                }
+                rustc_ast::AsmMacro::GlobalAsm => {
+                    span_bug!(span, "`global_asm!` is not allowed in this position")
+                }
+            },
 
             ExprKind::DropTemps(..) | ExprKind::Block(..) => {
                 hir::intravisit::walk_expr(self, expr);
@@ -218,52 +229,9 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
             }
         }
     }
-
-    fn check_inline_asm(&self, asm: &'tcx hir::InlineAsm<'tcx>, span: Span) {
-        let unsupported_operands: Vec<Span> = asm
-            .operands
-            .iter()
-            .filter_map(|&(ref op, op_sp)| match op {
-                InlineAsmOperand::Const { .. }
-                | InlineAsmOperand::SymFn { .. }
-                | InlineAsmOperand::SymStatic { .. } => None,
-                InlineAsmOperand::In { .. }
-                | InlineAsmOperand::Out { .. }
-                | InlineAsmOperand::InOut { .. }
-                | InlineAsmOperand::SplitInOut { .. }
-                | InlineAsmOperand::Label { .. } => Some(op_sp),
-            })
-            .collect();
-        if !unsupported_operands.is_empty() {
-            self.tcx.dcx().emit_err(NakedFunctionsOperands { unsupported_operands });
-        }
-
-        let unsupported_options = asm.options.difference(InlineAsmOptions::NAKED_OPTIONS);
-        if !unsupported_options.is_empty() {
-            self.tcx.dcx().emit_err(NakedFunctionsAsmOptions {
-                span,
-                unsupported_options: unsupported_options
-                    .human_readable_names()
-                    .into_iter()
-                    .map(|name| format!("`{name}`"))
-                    .collect::<Vec<_>>()
-                    .join(", "),
-            });
-        }
-
-        if !asm.options.contains(InlineAsmOptions::NORETURN) {
-            let last_span = asm
-                .operands
-                .last()
-                .map_or_else(|| asm.template_strs.last().unwrap().2, |op| op.1)
-                .shrink_to_hi();
-
-            self.tcx.dcx().emit_err(NakedFunctionsMustUseNoreturn { span, last_span });
-        }
-    }
 }
 
-impl<'tcx> Visitor<'tcx> for CheckInlineAssembly<'tcx> {
+impl<'tcx> Visitor<'tcx> for CheckInlineAssembly {
     fn visit_stmt(&mut self, stmt: &'tcx hir::Stmt<'tcx>) {
         match stmt.kind {
             StmtKind::Item(..) => {}
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index 0dbbc338e73..dbae4b7e719 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -655,6 +655,7 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
                 }
             }
             mir::TerminatorKind::InlineAsm {
+                asm_macro: _,
                 template,
                 operands,
                 options,
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index ff5ddd16e07..c60c0743c7e 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -115,6 +115,7 @@
 #![feature(const_option)]
 #![feature(const_pin)]
 #![feature(const_size_of_val)]
+#![feature(const_vec_string_slice)]
 #![feature(core_intrinsics)]
 #![feature(deprecated_suggestion)]
 #![feature(deref_pure_trait)]
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 436e0596e3d..8fdca8c4200 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -280,7 +280,7 @@ impl<T, A: Allocator> RawVec<T, A> {
     /// `Unique::dangling()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
     /// be careful.
     #[inline]
-    pub fn ptr(&self) -> *mut T {
+    pub const fn ptr(&self) -> *mut T {
         self.inner.ptr()
     }
 
@@ -293,7 +293,7 @@ impl<T, A: Allocator> RawVec<T, A> {
     ///
     /// This will always be `usize::MAX` if `T` is zero-sized.
     #[inline]
-    pub fn capacity(&self) -> usize {
+    pub const fn capacity(&self) -> usize {
         self.inner.capacity(size_of::<T>())
     }
 
@@ -488,17 +488,17 @@ impl<A: Allocator> RawVecInner<A> {
     }
 
     #[inline]
-    fn ptr<T>(&self) -> *mut T {
+    const fn ptr<T>(&self) -> *mut T {
         self.non_null::<T>().as_ptr()
     }
 
     #[inline]
-    fn non_null<T>(&self) -> NonNull<T> {
-        self.ptr.cast().into()
+    const fn non_null<T>(&self) -> NonNull<T> {
+        self.ptr.cast().as_non_null_ptr()
     }
 
     #[inline]
-    fn capacity(&self, elem_size: usize) -> usize {
+    const fn capacity(&self, elem_size: usize) -> usize {
         if elem_size == 0 { usize::MAX } else { self.cap.0 }
     }
 
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index ee878e879e9..82dbf030608 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -1059,7 +1059,8 @@ impl String {
     #[inline]
     #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_bytes(self) -> Vec<u8> {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn into_bytes(self) -> Vec<u8> {
         self.vec
     }
 
@@ -1076,8 +1077,11 @@ impl String {
     #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
     #[cfg_attr(not(test), rustc_diagnostic_item = "string_as_str")]
-    pub fn as_str(&self) -> &str {
-        self
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn as_str(&self) -> &str {
+        // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
+        // at construction.
+        unsafe { str::from_utf8_unchecked(self.vec.as_slice()) }
     }
 
     /// Converts a `String` into a mutable string slice.
@@ -1096,8 +1100,11 @@ impl String {
     #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
     #[cfg_attr(not(test), rustc_diagnostic_item = "string_as_mut_str")]
-    pub fn as_mut_str(&mut self) -> &mut str {
-        self
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn as_mut_str(&mut self) -> &mut str {
+        // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
+        // at construction.
+        unsafe { str::from_utf8_unchecked_mut(self.vec.as_mut_slice()) }
     }
 
     /// Appends a given string slice onto the end of this `String`.
@@ -1168,7 +1175,8 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn capacity(&self) -> usize {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn capacity(&self) -> usize {
         self.vec.capacity()
     }
 
@@ -1431,8 +1439,9 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn as_bytes(&self) -> &[u8] {
-        &self.vec
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn as_bytes(&self) -> &[u8] {
+        self.vec.as_slice()
     }
 
     /// Shortens this `String` to the specified length.
@@ -1784,7 +1793,8 @@ impl String {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
         &mut self.vec
     }
 
@@ -1805,8 +1815,9 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
     #[rustc_confusables("length", "size")]
-    pub fn len(&self) -> usize {
+    pub const fn len(&self) -> usize {
         self.vec.len()
     }
 
@@ -1824,7 +1835,8 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_empty(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn is_empty(&self) -> bool {
         self.len() == 0
     }
 
@@ -2589,7 +2601,7 @@ impl ops::Deref for String {
 
     #[inline]
     fn deref(&self) -> &str {
-        unsafe { str::from_utf8_unchecked(&self.vec) }
+        self.as_str()
     }
 }
 
@@ -2600,7 +2612,7 @@ unsafe impl ops::DerefPure for String {}
 impl ops::DerefMut for String {
     #[inline]
     fn deref_mut(&mut self) -> &mut str {
-        unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }
+        self.as_mut_str()
     }
 }
 
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 1984cfeefc1..830512ceee8 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1240,7 +1240,8 @@ impl<T, A: Allocator> Vec<T, A> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn capacity(&self) -> usize {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn capacity(&self) -> usize {
         self.buf.capacity()
     }
 
@@ -1548,8 +1549,22 @@ impl<T, A: Allocator> Vec<T, A> {
     #[inline]
     #[stable(feature = "vec_as_slice", since = "1.7.0")]
     #[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_slice")]
-    pub fn as_slice(&self) -> &[T] {
-        self
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn as_slice(&self) -> &[T] {
+        // SAFETY: `slice::from_raw_parts` requires pointee is a contiguous, aligned buffer of size
+        // `len` containing properly-initialized `T`s. Data must not be mutated for the returned
+        // lifetime. Further, `len * mem::size_of::<T>` <= `ISIZE::MAX`, and allocation does not
+        // "wrap" through overflowing memory addresses.
+        //
+        // * Vec API guarantees that self.buf:
+        //      * contains only properly-initialized items within 0..len
+        //      * is aligned, contiguous, and valid for `len` reads
+        //      * obeys size and address-wrapping constraints
+        //
+        // * We only construct `&mut` references to `self.buf` through `&mut self` methods; borrow-
+        //   check ensures that it is not possible to mutably alias `self.buf` within the
+        //   returned lifetime.
+        unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
     }
 
     /// Extracts a mutable slice of the entire vector.
@@ -1566,8 +1581,22 @@ impl<T, A: Allocator> Vec<T, A> {
     #[inline]
     #[stable(feature = "vec_as_slice", since = "1.7.0")]
     #[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_mut_slice")]
-    pub fn as_mut_slice(&mut self) -> &mut [T] {
-        self
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn as_mut_slice(&mut self) -> &mut [T] {
+        // SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of
+        // size `len` containing properly-initialized `T`s. Data must not be accessed through any
+        // other pointer for the returned lifetime. Further, `len * mem::size_of::<T>` <=
+        // `ISIZE::MAX` and allocation does not "wrap" through overflowing memory addresses.
+        //
+        // * Vec API guarantees that self.buf:
+        //      * contains only properly-initialized items within 0..len
+        //      * is aligned, contiguous, and valid for `len` reads
+        //      * obeys size and address-wrapping constraints
+        //
+        // * We only construct references to `self.buf` through `&self` and `&mut self` methods;
+        //   borrow-check ensures that it is not possible to construct a reference to `self.buf`
+        //   within the returned lifetime.
+        unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
     }
 
     /// Returns a raw pointer to the vector's buffer, or a dangling raw pointer
@@ -1624,9 +1653,10 @@ impl<T, A: Allocator> Vec<T, A> {
     /// [`as_ptr`]: Vec::as_ptr
     /// [`as_non_null`]: Vec::as_non_null
     #[stable(feature = "vec_as_ptr", since = "1.37.0")]
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
     #[rustc_never_returns_null_ptr]
     #[inline]
-    pub fn as_ptr(&self) -> *const T {
+    pub const fn as_ptr(&self) -> *const T {
         // We shadow the slice method of the same name to avoid going through
         // `deref`, which creates an intermediate reference.
         self.buf.ptr()
@@ -1685,9 +1715,10 @@ impl<T, A: Allocator> Vec<T, A> {
     /// [`as_ptr`]: Vec::as_ptr
     /// [`as_non_null`]: Vec::as_non_null
     #[stable(feature = "vec_as_ptr", since = "1.37.0")]
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
     #[rustc_never_returns_null_ptr]
     #[inline]
-    pub fn as_mut_ptr(&mut self) -> *mut T {
+    pub const fn as_mut_ptr(&mut self) -> *mut T {
         // We shadow the slice method of the same name to avoid going through
         // `deref_mut`, which creates an intermediate reference.
         self.buf.ptr()
@@ -2628,8 +2659,9 @@ impl<T, A: Allocator> Vec<T, A> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
     #[rustc_confusables("length", "size")]
-    pub fn len(&self) -> usize {
+    pub const fn len(&self) -> usize {
         self.len
     }
 
@@ -2646,7 +2678,8 @@ impl<T, A: Allocator> Vec<T, A> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[cfg_attr(not(test), rustc_diagnostic_item = "vec_is_empty")]
-    pub fn is_empty(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn is_empty(&self) -> bool {
         self.len() == 0
     }
 
@@ -3197,7 +3230,7 @@ impl<T, A: Allocator> ops::Deref for Vec<T, A> {
 
     #[inline]
     fn deref(&self) -> &[T] {
-        unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
+        self.as_slice()
     }
 }
 
@@ -3205,7 +3238,7 @@ impl<T, A: Allocator> ops::Deref for Vec<T, A> {
 impl<T, A: Allocator> ops::DerefMut for Vec<T, A> {
     #[inline]
     fn deref_mut(&mut self) -> &mut [T] {
-        unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
+        self.as_mut_slice()
     }
 }
 
diff --git a/library/std/build.rs b/library/std/build.rs
index 7d37d4e9d7d..032326556bd 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -7,6 +7,7 @@ fn main() {
     let target_vendor =
         env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set");
     let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
+    let target_abi = env::var("CARGO_CFG_TARGET_ABI").expect("CARGO_CFG_TARGET_ABI was not set");
     let target_pointer_width: u32 = env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
         .expect("CARGO_CFG_TARGET_POINTER_WIDTH was not set")
         .parse()
@@ -101,7 +102,7 @@ fn main() {
         // Unsupported <https://github.com/llvm/llvm-project/issues/94434>
         ("arm64ec", _) => false,
         // MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
-        ("x86_64", "windows") if target_env == "gnu" => false,
+        ("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false,
         // Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
         ("csky", _) => false,
         ("hexagon", _) => false,
@@ -129,7 +130,7 @@ fn main() {
         // ABI unsupported  <https://github.com/llvm/llvm-project/issues/41838>
         ("sparc", _) => false,
         // MinGW ABI bugs <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>
-        ("x86_64", "windows") if target_env == "gnu" => false,
+        ("x86_64", "windows") if target_env == "gnu" && target_abi != "llvm" => false,
         // 64-bit Linux is about the only platform to have f128 symbols by default
         (_, "linux") if target_pointer_width == 64 => true,
         // Almost all OSs are missing symbol. compiler-builtins will have to add them.
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 952d8d73328..5ca4321d855 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -93,6 +93,7 @@ fn get_modified_rs_files(build: &Builder<'_>) -> Result<Option<Vec<String>>, Str
     if !verify_rustfmt_version(build) {
         return Ok(None);
     }
+
     get_git_modified_files(&build.config.git_config(), Some(&build.config.src), &["rs"])
 }
 
diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs
index 11260f87d00..6fbdd76ed5b 100644
--- a/src/bootstrap/src/core/sanity.rs
+++ b/src/bootstrap/src/core/sanity.rs
@@ -13,8 +13,6 @@ use std::ffi::{OsStr, OsString};
 use std::path::PathBuf;
 use std::{env, fs};
 
-use build_helper::git::warn_old_master_branch;
-
 use crate::Build;
 #[cfg(not(feature = "bootstrap-self-test"))]
 use crate::builder::Builder;
@@ -382,6 +380,4 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
     if let Some(ref s) = build.config.ccache {
         cmd_finder.must_have(s);
     }
-
-    warn_old_master_branch(&build.config.git_config(), &build.config.src);
 }
diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs
index 10c5476cd8f..1e28d552fe6 100644
--- a/src/tools/build_helper/src/git.rs
+++ b/src/tools/build_helper/src/git.rs
@@ -196,67 +196,3 @@ pub fn get_git_untracked_files(
         .collect();
     Ok(Some(files))
 }
-
-/// Print a warning if the branch returned from `updated_master_branch` is old
-///
-/// For certain configurations of git repository, this remote will not be
-/// updated when running `git pull`.
-///
-/// This can result in formatting thousands of files instead of a dozen,
-/// so we should warn the user something is wrong.
-pub fn warn_old_master_branch(config: &GitConfig<'_>, git_dir: &Path) {
-    if crate::ci::CiEnv::is_ci() {
-        // this warning is useless in CI,
-        // and CI probably won't have the right branches anyway.
-        return;
-    }
-    // this will be overwritten by the actual name, if possible
-    let mut updated_master = "the upstream master branch".to_string();
-    match warn_old_master_branch_(config, git_dir, &mut updated_master) {
-        Ok(branch_is_old) => {
-            if !branch_is_old {
-                return;
-            }
-            // otherwise fall through and print the rest of the warning
-        }
-        Err(err) => {
-            eprintln!("warning: unable to check if {updated_master} is old due to error: {err}")
-        }
-    }
-    eprintln!(
-        "warning: {updated_master} is used to determine if files have been modified\n\
-         warning: if it is not updated, this may cause files to be needlessly reformatted"
-    );
-}
-
-pub fn warn_old_master_branch_(
-    config: &GitConfig<'_>,
-    git_dir: &Path,
-    updated_master: &mut String,
-) -> Result<bool, Box<dyn std::error::Error>> {
-    use std::time::Duration;
-    *updated_master = updated_master_branch(config, Some(git_dir))?;
-    let branch_path = git_dir.join(".git/refs/remotes").join(&updated_master);
-    const WARN_AFTER: Duration = Duration::from_secs(60 * 60 * 24 * 10);
-    let meta = match std::fs::metadata(&branch_path) {
-        Ok(meta) => meta,
-        Err(err) => {
-            let gcd = git_common_dir(&git_dir)?;
-            if branch_path.starts_with(&gcd) {
-                return Err(Box::new(err));
-            }
-            std::fs::metadata(Path::new(&gcd).join("refs/remotes").join(&updated_master))?
-        }
-    };
-    if meta.modified()?.elapsed()? > WARN_AFTER {
-        eprintln!("warning: {updated_master} has not been updated in 10 days");
-        Ok(true)
-    } else {
-        Ok(false)
-    }
-}
-
-fn git_common_dir(dir: &Path) -> Result<String, String> {
-    output_result(Command::new("git").arg("-C").arg(dir).arg("rev-parse").arg("--git-common-dir"))
-        .map(|x| x.trim().to_string())
-}
diff --git a/src/tools/rustfmt/src/parse/macros/asm.rs b/src/tools/rustfmt/src/parse/macros/asm.rs
index 5ee083da539..58c8d21bd7a 100644
--- a/src/tools/rustfmt/src/parse/macros/asm.rs
+++ b/src/tools/rustfmt/src/parse/macros/asm.rs
@@ -7,5 +7,5 @@ use crate::rewrite::RewriteContext;
 pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option<AsmArgs> {
     let ts = mac.args.tokens.clone();
     let mut parser = super::build_parser(context, ts);
-    parse_asm_args(&mut parser, mac.span(), false).ok()
+    parse_asm_args(&mut parser, mac.span(), ast::AsmMacro::Asm).ok()
 }
diff --git a/tests/assembly/aarch64-naked-fn-no-bti-prolog.rs b/tests/assembly/aarch64-naked-fn-no-bti-prolog.rs
index 8ee6f6792e9..46e627eaa00 100644
--- a/tests/assembly/aarch64-naked-fn-no-bti-prolog.rs
+++ b/tests/assembly/aarch64-naked-fn-no-bti-prolog.rs
@@ -5,7 +5,7 @@
 
 #![crate_type = "lib"]
 #![feature(naked_functions)]
-use std::arch::asm;
+use std::arch::naked_asm;
 
 // The problem at hand: Rust has adopted a fairly strict meaning for "naked functions",
 // meaning "no prologue whatsoever, no, really, not one instruction."
@@ -17,5 +17,5 @@ use std::arch::asm;
 pub unsafe extern "C" fn _hlt() -> ! {
     // CHECK-NOT: hint #34
     // CHECK: hlt #0x1
-    asm!("hlt #1", options(noreturn))
+    naked_asm!("hlt #1")
 }
diff --git a/tests/assembly/x86_64-naked-fn-no-cet-prolog.rs b/tests/assembly/x86_64-naked-fn-no-cet-prolog.rs
index a5683874182..54e1d93c68b 100644
--- a/tests/assembly/x86_64-naked-fn-no-cet-prolog.rs
+++ b/tests/assembly/x86_64-naked-fn-no-cet-prolog.rs
@@ -5,7 +5,7 @@
 
 #![crate_type = "lib"]
 #![feature(naked_functions)]
-use std::arch::asm;
+use std::arch::naked_asm;
 
 // The problem at hand: Rust has adopted a fairly strict meaning for "naked functions",
 // meaning "no prologue whatsoever, no, really, not one instruction."
@@ -17,7 +17,7 @@ use std::arch::asm;
 pub unsafe extern "sysv64" fn will_halt() -> ! {
     // CHECK-NOT: endbr{{32|64}}
     // CHECK: hlt
-    asm!("hlt", options(noreturn))
+    naked_asm!("hlt")
 }
 
 // what about aarch64?
diff --git a/tests/codegen/cffi/c-variadic-naked.rs b/tests/codegen/cffi/c-variadic-naked.rs
index 807873ea368..24b69c5f59e 100644
--- a/tests/codegen/cffi/c-variadic-naked.rs
+++ b/tests/codegen/cffi/c-variadic-naked.rs
@@ -12,8 +12,7 @@
 pub unsafe extern "C" fn c_variadic(_: usize, _: ...) {
     // CHECK-NOT: va_start
     // CHECK-NOT: alloca
-    core::arch::asm! {
+    core::arch::naked_asm! {
         "ret",
-        options(noreturn),
     }
 }
diff --git a/tests/codegen/naked-asan.rs b/tests/codegen/naked-asan.rs
index ac36018eed3..bcaa60baeff 100644
--- a/tests/codegen/naked-asan.rs
+++ b/tests/codegen/naked-asan.rs
@@ -14,7 +14,7 @@
 #[no_mangle]
 pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) {
     unsafe {
-        core::arch::asm!("ud2", options(noreturn));
+        core::arch::naked_asm!("ud2");
     }
 }
 
diff --git a/tests/codegen/naked-fn/aligned.rs b/tests/codegen/naked-fn/aligned.rs
index d5faac44836..3bbd67981e5 100644
--- a/tests/codegen/naked-fn/aligned.rs
+++ b/tests/codegen/naked-fn/aligned.rs
@@ -4,7 +4,7 @@
 
 #![crate_type = "lib"]
 #![feature(naked_functions, fn_align)]
-use std::arch::asm;
+use std::arch::naked_asm;
 
 // CHECK: Function Attrs: naked
 // CHECK-NEXT: define{{.*}}void @naked_empty()
@@ -16,5 +16,5 @@ pub unsafe extern "C" fn naked_empty() {
     // CHECK-NEXT: start:
     // CHECK-NEXT: call void asm
     // CHECK-NEXT: unreachable
-    asm!("ret", options(noreturn));
+    naked_asm!("ret");
 }
diff --git a/tests/codegen/naked-fn/naked-functions.rs b/tests/codegen/naked-fn/naked-functions.rs
index 307745a921c..3f7447af599 100644
--- a/tests/codegen/naked-fn/naked-functions.rs
+++ b/tests/codegen/naked-fn/naked-functions.rs
@@ -4,7 +4,7 @@
 
 #![crate_type = "lib"]
 #![feature(naked_functions)]
-use std::arch::asm;
+use std::arch::naked_asm;
 
 // CHECK: Function Attrs: naked
 // CHECK-NEXT: define{{.*}}void @naked_empty()
@@ -14,7 +14,7 @@ pub unsafe extern "C" fn naked_empty() {
     // CHECK-NEXT: {{.+}}:
     // CHECK-NEXT: call void asm
     // CHECK-NEXT: unreachable
-    asm!("ret", options(noreturn));
+    naked_asm!("ret");
 }
 
 // CHECK: Function Attrs: naked
@@ -25,5 +25,5 @@ pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize
     // CHECK-NEXT: {{.+}}:
     // CHECK-NEXT: call void asm
     // CHECK-NEXT: unreachable
-    asm!("lea rax, [rdi + rsi]", "ret", options(noreturn));
+    naked_asm!("lea rax, [rdi + rsi]", "ret");
 }
diff --git a/tests/codegen/naked-fn/naked-nocoverage.rs b/tests/codegen/naked-fn/naked-nocoverage.rs
index d73c5b7fd26..f63661bcd3a 100644
--- a/tests/codegen/naked-fn/naked-nocoverage.rs
+++ b/tests/codegen/naked-fn/naked-nocoverage.rs
@@ -6,7 +6,7 @@
 //@ compile-flags: -Cinstrument-coverage
 #![crate_type = "lib"]
 #![feature(naked_functions)]
-use std::arch::asm;
+use std::arch::naked_asm;
 
 #[naked]
 #[no_mangle]
@@ -15,5 +15,5 @@ pub unsafe extern "C" fn f() {
     // CHECK-NEXT:  start:
     // CHECK-NEXT:    call void asm
     // CHECK-NEXT:    unreachable
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
diff --git a/tests/codegen/naked-fn/naked-noinline.rs b/tests/codegen/naked-fn/naked-noinline.rs
index c1e8f368249..6ea36d96783 100644
--- a/tests/codegen/naked-fn/naked-noinline.rs
+++ b/tests/codegen/naked-fn/naked-noinline.rs
@@ -5,7 +5,7 @@
 #![crate_type = "lib"]
 #![feature(naked_functions)]
 
-use std::arch::asm;
+use std::arch::naked_asm;
 
 #[naked]
 #[no_mangle]
@@ -15,7 +15,7 @@ pub unsafe extern "C" fn f() {
     // CHECK:       define {{(dso_local )?}}void @f() unnamed_addr [[ATTR:#[0-9]+]]
     // CHECK-NEXT:  start:
     // CHECK-NEXT:    call void asm
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[no_mangle]
diff --git a/tests/coverage/closure_macro.cov-map b/tests/coverage/closure_macro.cov-map
index eb5f94d1080..fb4a137d4c8 100644
--- a/tests/coverage/closure_macro.cov-map
+++ b/tests/coverage/closure_macro.cov-map
@@ -23,19 +23,19 @@ Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
 
 Function name: closure_macro::main::{closure#0}
-Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 00, 05, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 00, 00, 17, 00, 1e, 07, 02, 09, 00, 0a]
+Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 0d, 05, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 0d, 00, 17, 00, 1e, 07, 02, 09, 00, 0a]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
-- expression 2 operands: lhs = Counter(2), rhs = Zero
+- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 5
 - Code(Counter(0)) at (prev + 16, 28) to (start + 3, 33)
 - Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39)
 - Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22)
     = (c0 - c1)
-- Code(Zero) at (prev + 0, 23) to (start + 0, 30)
+- Code(Counter(3)) at (prev + 0, 23) to (start + 0, 30)
 - Code(Expression(1, Add)) at (prev + 2, 9) to (start + 0, 10)
-    = (c1 + (c2 + Zero))
+    = (c1 + (c2 + c3))
 
diff --git a/tests/coverage/closure_macro_async.cov-map b/tests/coverage/closure_macro_async.cov-map
index 4d0597f58bf..091e87909f9 100644
--- a/tests/coverage/closure_macro_async.cov-map
+++ b/tests/coverage/closure_macro_async.cov-map
@@ -31,19 +31,19 @@ Number of file 0 mappings: 6
 - Code(Counter(0)) at (prev + 3, 1) to (start + 0, 2)
 
 Function name: closure_macro_async::test::{closure#0}::{closure#0}
-Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 00, 05, 01, 15, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 00, 00, 17, 00, 1e, 07, 02, 09, 00, 0a]
+Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 0d, 05, 01, 15, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 0d, 00, 17, 00, 1e, 07, 02, 09, 00, 0a]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
 - expression 0 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
-- expression 2 operands: lhs = Counter(2), rhs = Zero
+- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 5
 - Code(Counter(0)) at (prev + 21, 28) to (start + 3, 33)
 - Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39)
 - Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22)
     = (c0 - c1)
-- Code(Zero) at (prev + 0, 23) to (start + 0, 30)
+- Code(Counter(3)) at (prev + 0, 23) to (start + 0, 30)
 - Code(Expression(1, Add)) at (prev + 2, 9) to (start + 0, 10)
-    = (c1 + (c2 + Zero))
+    = (c1 + (c2 + c3))
 
diff --git a/tests/crashes/124375.rs b/tests/crashes/124375.rs
index 7165655178d..1d877caeb8b 100644
--- a/tests/crashes/124375.rs
+++ b/tests/crashes/124375.rs
@@ -3,9 +3,9 @@
 //@ only-x86_64
 #![crate_type = "lib"]
 #![feature(naked_functions)]
-use std::arch::asm;
+use std::arch::naked_asm;
 
 #[naked]
 pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
-    asm!("lea rax, [rdi + rsi]", "ret", options(noreturn));
+    naked_asm!("lea rax, [rdi + rsi]", "ret");
 }
diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
index 0ad7f5910a0..4d964b0afb7 100644
--- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
@@ -5,66 +5,61 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     let mut _0: &[u8];
     scope 1 (inlined <Vec<u8> as Deref>::deref) {
         debug self => _1;
-        let mut _6: usize;
-        scope 2 (inlined Vec::<u8>::as_ptr) {
+        scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _2: &alloc::raw_vec::RawVec<u8>;
-            scope 3 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
-                debug self => _2;
-                let mut _3: &alloc::raw_vec::RawVecInner;
-                scope 4 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
-                    debug self => _3;
-                    scope 5 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
+            let mut _6: usize;
+            scope 3 (inlined Vec::<u8>::as_ptr) {
+                debug self => _1;
+                let mut _2: &alloc::raw_vec::RawVec<u8>;
+                scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
+                    debug self => _2;
+                    let mut _3: &alloc::raw_vec::RawVecInner;
+                    scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
                         debug self => _3;
-                        let mut _4: std::ptr::NonNull<u8>;
-                        scope 6 (inlined Unique::<u8>::cast::<u8>) {
-                            debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                            debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                            scope 7 (inlined NonNull::<u8>::cast::<u8>) {
-                                debug self => _4;
-                                scope 8 (inlined NonNull::<u8>::as_ptr) {
+                        scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
+                            debug self => _3;
+                            let mut _4: std::ptr::NonNull<u8>;
+                            scope 7 (inlined Unique::<u8>::cast::<u8>) {
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
+                                scope 8 (inlined NonNull::<u8>::cast::<u8>) {
                                     debug self => _4;
-                                    let mut _5: *const u8;
+                                    scope 9 (inlined NonNull::<u8>::as_ptr) {
+                                        debug self => _4;
+                                        let mut _5: *const u8;
+                                    }
                                 }
                             }
-                        }
-                        scope 9 (inlined #[track_caller] <Unique<u8> as Into<NonNull<u8>>>::into) {
-                            debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                            debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                            scope 10 (inlined <NonNull<u8> as From<Unique<u8>>>::from) {
-                                debug ((unique: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                                debug ((unique: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                                scope 11 (inlined Unique::<u8>::as_non_null_ptr) {
-                                    debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                                    debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                                }
+                            scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
+                        scope 11 (inlined NonNull::<u8>::as_ptr) {
+                            debug self => _4;
+                        }
                     }
-                    scope 12 (inlined NonNull::<u8>::as_ptr) {
-                        debug self => _4;
-                    }
-                }
-            }
-        }
-        scope 13 (inlined std::slice::from_raw_parts::<'_, u8>) {
-            debug data => _5;
-            debug len => _6;
-            let _7: *const [u8];
-            scope 14 (inlined core::ub_checks::check_language_ub) {
-                scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
                 }
             }
-            scope 16 (inlined std::mem::size_of::<u8>) {
-            }
-            scope 17 (inlined align_of::<u8>) {
-            }
-            scope 18 (inlined slice_from_raw_parts::<u8>) {
+            scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
                 debug data => _5;
                 debug len => _6;
-                scope 19 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
-                    debug data_pointer => _5;
-                    debug metadata => _6;
+                let _7: *const [u8];
+                scope 13 (inlined core::ub_checks::check_language_ub) {
+                    scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
+                    }
+                }
+                scope 15 (inlined std::mem::size_of::<u8>) {
+                }
+                scope 16 (inlined align_of::<u8>) {
+                }
+                scope 17 (inlined slice_from_raw_parts::<u8>) {
+                    debug data => _5;
+                    debug len => _6;
+                    scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
+                        debug data_pointer => _5;
+                        debug metadata => _6;
+                    }
                 }
             }
         }
diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
index 0ad7f5910a0..4d964b0afb7 100644
--- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
@@ -5,66 +5,61 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     let mut _0: &[u8];
     scope 1 (inlined <Vec<u8> as Deref>::deref) {
         debug self => _1;
-        let mut _6: usize;
-        scope 2 (inlined Vec::<u8>::as_ptr) {
+        scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _2: &alloc::raw_vec::RawVec<u8>;
-            scope 3 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
-                debug self => _2;
-                let mut _3: &alloc::raw_vec::RawVecInner;
-                scope 4 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
-                    debug self => _3;
-                    scope 5 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
+            let mut _6: usize;
+            scope 3 (inlined Vec::<u8>::as_ptr) {
+                debug self => _1;
+                let mut _2: &alloc::raw_vec::RawVec<u8>;
+                scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
+                    debug self => _2;
+                    let mut _3: &alloc::raw_vec::RawVecInner;
+                    scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
                         debug self => _3;
-                        let mut _4: std::ptr::NonNull<u8>;
-                        scope 6 (inlined Unique::<u8>::cast::<u8>) {
-                            debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                            debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                            scope 7 (inlined NonNull::<u8>::cast::<u8>) {
-                                debug self => _4;
-                                scope 8 (inlined NonNull::<u8>::as_ptr) {
+                        scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
+                            debug self => _3;
+                            let mut _4: std::ptr::NonNull<u8>;
+                            scope 7 (inlined Unique::<u8>::cast::<u8>) {
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
+                                scope 8 (inlined NonNull::<u8>::cast::<u8>) {
                                     debug self => _4;
-                                    let mut _5: *const u8;
+                                    scope 9 (inlined NonNull::<u8>::as_ptr) {
+                                        debug self => _4;
+                                        let mut _5: *const u8;
+                                    }
                                 }
                             }
-                        }
-                        scope 9 (inlined #[track_caller] <Unique<u8> as Into<NonNull<u8>>>::into) {
-                            debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                            debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                            scope 10 (inlined <NonNull<u8> as From<Unique<u8>>>::from) {
-                                debug ((unique: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                                debug ((unique: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                                scope 11 (inlined Unique::<u8>::as_non_null_ptr) {
-                                    debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                                    debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                                }
+                            scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
+                        scope 11 (inlined NonNull::<u8>::as_ptr) {
+                            debug self => _4;
+                        }
                     }
-                    scope 12 (inlined NonNull::<u8>::as_ptr) {
-                        debug self => _4;
-                    }
-                }
-            }
-        }
-        scope 13 (inlined std::slice::from_raw_parts::<'_, u8>) {
-            debug data => _5;
-            debug len => _6;
-            let _7: *const [u8];
-            scope 14 (inlined core::ub_checks::check_language_ub) {
-                scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
                 }
             }
-            scope 16 (inlined std::mem::size_of::<u8>) {
-            }
-            scope 17 (inlined align_of::<u8>) {
-            }
-            scope 18 (inlined slice_from_raw_parts::<u8>) {
+            scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
                 debug data => _5;
                 debug len => _6;
-                scope 19 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
-                    debug data_pointer => _5;
-                    debug metadata => _6;
+                let _7: *const [u8];
+                scope 13 (inlined core::ub_checks::check_language_ub) {
+                    scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
+                    }
+                }
+                scope 15 (inlined std::mem::size_of::<u8>) {
+                }
+                scope 16 (inlined align_of::<u8>) {
+                }
+                scope 17 (inlined slice_from_raw_parts::<u8>) {
+                    debug data => _5;
+                    debug len => _6;
+                    scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
+                        debug data_pointer => _5;
+                        debug metadata => _6;
+                    }
                 }
             }
         }
diff --git a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs
index f00123f006b..8dd19e613bf 100644
--- a/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs
+++ b/tests/run-make/naked-symbol-visibility/a_rust_dylib.rs
@@ -1,7 +1,7 @@
 #![feature(naked_functions, asm_const, linkage)]
 #![crate_type = "dylib"]
 
-use std::arch::asm;
+use std::arch::naked_asm;
 
 pub trait TraitWithConst {
     const COUNT: u32;
@@ -28,7 +28,7 @@ extern "C" fn private_vanilla() -> u32 {
 
 #[naked]
 extern "C" fn private_naked() -> u32 {
-    unsafe { asm!("mov rax, 42", "ret", options(noreturn)) }
+    unsafe { naked_asm!("mov rax, 42", "ret") }
 }
 
 #[no_mangle]
@@ -39,7 +39,7 @@ pub extern "C" fn public_vanilla() -> u32 {
 #[naked]
 #[no_mangle]
 pub extern "C" fn public_naked() -> u32 {
-    unsafe { asm!("mov rax, 42", "ret", options(noreturn)) }
+    unsafe { naked_asm!("mov rax, 42", "ret") }
 }
 
 pub extern "C" fn public_vanilla_generic<T: TraitWithConst>() -> u32 {
@@ -48,7 +48,7 @@ pub extern "C" fn public_vanilla_generic<T: TraitWithConst>() -> u32 {
 
 #[naked]
 pub extern "C" fn public_naked_generic<T: TraitWithConst>() -> u32 {
-    unsafe { asm!("mov rax, {}", "ret", const T::COUNT, options(noreturn)) }
+    unsafe { naked_asm!("mov rax, {}", "ret", const T::COUNT) }
 }
 
 #[linkage = "external"]
@@ -59,7 +59,7 @@ extern "C" fn vanilla_external_linkage() -> u32 {
 #[naked]
 #[linkage = "external"]
 extern "C" fn naked_external_linkage() -> u32 {
-    unsafe { asm!("mov rax, 42", "ret", options(noreturn)) }
+    unsafe { naked_asm!("mov rax, 42", "ret") }
 }
 
 #[cfg(not(windows))]
@@ -72,7 +72,7 @@ extern "C" fn vanilla_weak_linkage() -> u32 {
 #[cfg(not(windows))]
 #[linkage = "weak"]
 extern "C" fn naked_weak_linkage() -> u32 {
-    unsafe { asm!("mov rax, 42", "ret", options(noreturn)) }
+    unsafe { naked_asm!("mov rax, 42", "ret") }
 }
 
 // functions that are declared in an `extern "C"` block are currently not exported
diff --git a/tests/ui/asm/naked-functions-ffi.rs b/tests/ui/asm/naked-functions-ffi.rs
index 93d23885b13..b78d1e6a0d1 100644
--- a/tests/ui/asm/naked-functions-ffi.rs
+++ b/tests/ui/asm/naked-functions-ffi.rs
@@ -3,13 +3,13 @@
 #![feature(naked_functions)]
 #![crate_type = "lib"]
 
-use std::arch::asm;
+use std::arch::naked_asm;
 
 #[naked]
 pub extern "C" fn naked(p: char) -> u128 {
     //~^ WARN uses type `char`
     //~| WARN uses type `u128`
     unsafe {
-        asm!("", options(noreturn));
+        naked_asm!("");
     }
 }
diff --git a/tests/ui/asm/naked-functions-instruction-set.rs b/tests/ui/asm/naked-functions-instruction-set.rs
index b81b65cff74..37c7b52c191 100644
--- a/tests/ui/asm/naked-functions-instruction-set.rs
+++ b/tests/ui/asm/naked-functions-instruction-set.rs
@@ -8,7 +8,7 @@
 #![no_core]
 
 #[rustc_builtin_macro]
-macro_rules! asm {
+macro_rules! naked_asm {
     () => {};
 }
 
@@ -19,12 +19,12 @@ trait Sized {}
 #[naked]
 #[instruction_set(arm::t32)]
 unsafe extern "C" fn test_thumb() {
-    asm!("bx lr", options(noreturn));
+    naked_asm!("bx lr");
 }
 
 #[no_mangle]
 #[naked]
 #[instruction_set(arm::t32)]
 unsafe extern "C" fn test_arm() {
-    asm!("bx lr", options(noreturn));
+    naked_asm!("bx lr");
 }
diff --git a/tests/ui/asm/naked-functions-testattrs.rs b/tests/ui/asm/naked-functions-testattrs.rs
index 12943ac0378..7e373270e9f 100644
--- a/tests/ui/asm/naked-functions-testattrs.rs
+++ b/tests/ui/asm/naked-functions-testattrs.rs
@@ -6,13 +6,13 @@
 #![feature(test)]
 #![crate_type = "lib"]
 
-use std::arch::asm;
+use std::arch::naked_asm;
 
 #[test]
 #[naked]
 //~^ ERROR [E0736]
 fn test_naked() {
-    unsafe { asm!("", options(noreturn)) };
+    unsafe { naked_asm!("") };
 }
 
 #[should_panic]
@@ -20,7 +20,7 @@ fn test_naked() {
 #[naked]
 //~^ ERROR [E0736]
 fn test_naked_should_panic() {
-    unsafe { asm!("", options(noreturn)) };
+    unsafe { naked_asm!("") };
 }
 
 #[ignore]
@@ -28,12 +28,12 @@ fn test_naked_should_panic() {
 #[naked]
 //~^ ERROR [E0736]
 fn test_naked_ignore() {
-    unsafe { asm!("", options(noreturn)) };
+    unsafe { naked_asm!("") };
 }
 
 #[bench]
 #[naked]
 //~^ ERROR [E0736]
 fn bench_naked() {
-    unsafe { asm!("", options(noreturn)) };
+    unsafe { naked_asm!("") };
 }
diff --git a/tests/ui/asm/naked-functions-unused.aarch64.stderr b/tests/ui/asm/naked-functions-unused.aarch64.stderr
index 8d3c300e058..ea63ced1aab 100644
--- a/tests/ui/asm/naked-functions-unused.aarch64.stderr
+++ b/tests/ui/asm/naked-functions-unused.aarch64.stderr
@@ -18,49 +18,49 @@ LL |     pub extern "C" fn function(a: usize, b: usize) -> usize {
    |                                          ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:26:38
+  --> $DIR/naked-functions-unused.rs:28:38
    |
 LL |         pub extern "C" fn associated(a: usize, b: usize) -> usize {
    |                                      ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:26:48
+  --> $DIR/naked-functions-unused.rs:28:48
    |
 LL |         pub extern "C" fn associated(a: usize, b: usize) -> usize {
    |                                                ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:32:41
+  --> $DIR/naked-functions-unused.rs:36:41
    |
 LL |         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
    |                                         ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:32:51
+  --> $DIR/naked-functions-unused.rs:36:51
    |
 LL |         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
    |                                                   ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:40:40
+  --> $DIR/naked-functions-unused.rs:46:40
    |
 LL |         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
    |                                        ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:40:50
+  --> $DIR/naked-functions-unused.rs:46:50
    |
 LL |         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
    |                                                  ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:46:43
+  --> $DIR/naked-functions-unused.rs:54:43
    |
 LL |         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
    |                                           ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:46:53
+  --> $DIR/naked-functions-unused.rs:54:53
    |
 LL |         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
    |                                                     ^ help: if this is intentional, prefix it with an underscore: `_b`
diff --git a/tests/ui/asm/naked-functions-unused.rs b/tests/ui/asm/naked-functions-unused.rs
index 745d30e6a84..c27037819a4 100644
--- a/tests/ui/asm/naked-functions-unused.rs
+++ b/tests/ui/asm/naked-functions-unused.rs
@@ -17,7 +17,9 @@ pub mod normal {
     pub extern "C" fn function(a: usize, b: usize) -> usize {
         //~^ ERROR unused variable: `a`
         //~| ERROR unused variable: `b`
-        unsafe { asm!("", options(noreturn)); }
+        unsafe {
+            asm!("", options(noreturn));
+        }
     }
 
     pub struct Normal;
@@ -26,13 +28,17 @@ pub mod normal {
         pub extern "C" fn associated(a: usize, b: usize) -> usize {
             //~^ ERROR unused variable: `a`
             //~| ERROR unused variable: `b`
-            unsafe { asm!("", options(noreturn)); }
+            unsafe {
+                asm!("", options(noreturn));
+            }
         }
 
         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
             //~^ ERROR unused variable: `a`
             //~| ERROR unused variable: `b`
-            unsafe { asm!("", options(noreturn)); }
+            unsafe {
+                asm!("", options(noreturn));
+            }
         }
     }
 
@@ -40,23 +46,29 @@ pub mod normal {
         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
             //~^ ERROR unused variable: `a`
             //~| ERROR unused variable: `b`
-            unsafe { asm!("", options(noreturn)); }
+            unsafe {
+                asm!("", options(noreturn));
+            }
         }
 
         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
             //~^ ERROR unused variable: `a`
             //~| ERROR unused variable: `b`
-            unsafe { asm!("", options(noreturn)); }
+            unsafe {
+                asm!("", options(noreturn));
+            }
         }
     }
 }
 
 pub mod naked {
-    use std::arch::asm;
+    use std::arch::naked_asm;
 
     #[naked]
     pub extern "C" fn function(a: usize, b: usize) -> usize {
-        unsafe { asm!("", options(noreturn)); }
+        unsafe {
+            naked_asm!("");
+        }
     }
 
     pub struct Naked;
@@ -64,24 +76,32 @@ pub mod naked {
     impl Naked {
         #[naked]
         pub extern "C" fn associated(a: usize, b: usize) -> usize {
-            unsafe { asm!("", options(noreturn)); }
+            unsafe {
+                naked_asm!("");
+            }
         }
 
         #[naked]
         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
-            unsafe { asm!("", options(noreturn)); }
+            unsafe {
+                naked_asm!("");
+            }
         }
     }
 
     impl super::Trait for Naked {
         #[naked]
         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
-            unsafe { asm!("", options(noreturn)); }
+            unsafe {
+                naked_asm!("");
+            }
         }
 
         #[naked]
         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
-            unsafe { asm!("", options(noreturn)); }
+            unsafe {
+                naked_asm!("");
+            }
         }
     }
 }
diff --git a/tests/ui/asm/naked-functions-unused.x86_64.stderr b/tests/ui/asm/naked-functions-unused.x86_64.stderr
index 8d3c300e058..ea63ced1aab 100644
--- a/tests/ui/asm/naked-functions-unused.x86_64.stderr
+++ b/tests/ui/asm/naked-functions-unused.x86_64.stderr
@@ -18,49 +18,49 @@ LL |     pub extern "C" fn function(a: usize, b: usize) -> usize {
    |                                          ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:26:38
+  --> $DIR/naked-functions-unused.rs:28:38
    |
 LL |         pub extern "C" fn associated(a: usize, b: usize) -> usize {
    |                                      ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:26:48
+  --> $DIR/naked-functions-unused.rs:28:48
    |
 LL |         pub extern "C" fn associated(a: usize, b: usize) -> usize {
    |                                                ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:32:41
+  --> $DIR/naked-functions-unused.rs:36:41
    |
 LL |         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
    |                                         ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:32:51
+  --> $DIR/naked-functions-unused.rs:36:51
    |
 LL |         pub extern "C" fn method(&self, a: usize, b: usize) -> usize {
    |                                                   ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:40:40
+  --> $DIR/naked-functions-unused.rs:46:40
    |
 LL |         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
    |                                        ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:40:50
+  --> $DIR/naked-functions-unused.rs:46:50
    |
 LL |         extern "C" fn trait_associated(a: usize, b: usize) -> usize {
    |                                                  ^ help: if this is intentional, prefix it with an underscore: `_b`
 
 error: unused variable: `a`
-  --> $DIR/naked-functions-unused.rs:46:43
+  --> $DIR/naked-functions-unused.rs:54:43
    |
 LL |         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
    |                                           ^ help: if this is intentional, prefix it with an underscore: `_a`
 
 error: unused variable: `b`
-  --> $DIR/naked-functions-unused.rs:46:53
+  --> $DIR/naked-functions-unused.rs:54:53
    |
 LL |         extern "C" fn trait_method(&self, a: usize, b: usize) -> usize {
    |                                                     ^ help: if this is intentional, prefix it with an underscore: `_b`
diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs
index 116a84506c5..5c58f1498cc 100644
--- a/tests/ui/asm/naked-functions.rs
+++ b/tests/ui/asm/naked-functions.rs
@@ -6,7 +6,13 @@
 #![feature(asm_unwind, linkage)]
 #![crate_type = "lib"]
 
-use std::arch::asm;
+use std::arch::{asm, naked_asm};
+
+#[naked]
+pub unsafe extern "C" fn inline_asm_macro() {
+    asm!("", options(raw));
+    //~^ERROR the `asm!` macro is not allowed in naked functions
+}
 
 #[repr(C)]
 pub struct P {
@@ -25,12 +31,12 @@ pub unsafe extern "C" fn patterns(
     P { x, y }: P,
     //~^ ERROR patterns not allowed in naked function parameters
 ) {
-    asm!("", options(noreturn))
+    naked_asm!("")
 }
 
 #[naked]
 pub unsafe extern "C" fn inc(a: u32) -> u32 {
-    //~^ ERROR naked functions must contain a single asm block
+    //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     a + 1
     //~^ ERROR referencing function parameters is not allowed in naked functions
 }
@@ -38,20 +44,19 @@ pub unsafe extern "C" fn inc(a: u32) -> u32 {
 #[naked]
 #[allow(asm_sub_register)]
 pub unsafe extern "C" fn inc_asm(a: u32) -> u32 {
-    asm!("/* {0} */", in(reg) a, options(noreturn));
-    //~^ ERROR referencing function parameters is not allowed in naked functions
-    //~| ERROR only `const` and `sym` operands are supported in naked functions
+    naked_asm!("/* {0} */", in(reg) a)
+    //~^ ERROR the `in` operand cannot be used with `naked_asm!`
 }
 
 #[naked]
 pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
-    //~^ ERROR naked functions must contain a single asm block
+    //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     (|| a + 1)()
 }
 
 #[naked]
 pub unsafe extern "C" fn unsupported_operands() {
-    //~^ ERROR naked functions must contain a single asm block
+    //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     let mut a = 0usize;
     let mut b = 0usize;
     let mut c = 0usize;
@@ -59,10 +64,9 @@ pub unsafe extern "C" fn unsupported_operands() {
     let mut e = 0usize;
     const F: usize = 0usize;
     static G: usize = 0usize;
-    asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
-         //~^ ERROR asm in naked functions must use `noreturn` option
+    naked_asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
          in(reg) a,
-         //~^ ERROR only `const` and `sym` operands are supported in naked functions
+         //~^ ERROR the `in` operand cannot be used with `naked_asm!`
          inlateout(reg) b,
          inout(reg) c,
          lateout(reg) d,
@@ -74,27 +78,23 @@ pub unsafe extern "C" fn unsupported_operands() {
 
 #[naked]
 pub extern "C" fn missing_assembly() {
-    //~^ ERROR naked functions must contain a single asm block
+    //~^ ERROR naked functions must contain a single `naked_asm!` invocation
 }
 
 #[naked]
 pub extern "C" fn too_many_asm_blocks() {
-    //~^ ERROR naked functions must contain a single asm block
+    //~^ ERROR naked functions must contain a single `naked_asm!` invocation
     unsafe {
-        asm!("");
-        //~^ ERROR asm in naked functions must use `noreturn` option
-        asm!("");
-        //~^ ERROR asm in naked functions must use `noreturn` option
-        asm!("");
-        //~^ ERROR asm in naked functions must use `noreturn` option
-        asm!("", options(noreturn));
+        naked_asm!("", options(noreturn));
+        //~^ ERROR the `noreturn` option cannot be used with `naked_asm!`
+        naked_asm!("");
     }
 }
 
 pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
     #[naked]
     pub extern "C" fn inner(y: usize) -> usize {
-        //~^ ERROR naked functions must contain a single asm block
+        //~^ ERROR naked functions must contain a single `naked_asm!` invocation
         *&y
         //~^ ERROR referencing function parameters is not allowed in naked functions
     }
@@ -103,40 +103,41 @@ pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
 
 #[naked]
 unsafe extern "C" fn invalid_options() {
-    asm!("", options(nomem, preserves_flags, noreturn));
-    //~^ ERROR asm options unsupported in naked functions: `nomem`, `preserves_flags`
+    naked_asm!("", options(nomem, preserves_flags));
+    //~^ ERROR the `nomem` option cannot be used with `naked_asm!`
+    //~| ERROR the `preserves_flags` option cannot be used with `naked_asm!`
 }
 
 #[naked]
 unsafe extern "C" fn invalid_options_continued() {
-    asm!("", options(readonly, nostack), options(pure));
-    //~^ ERROR asm with the `pure` option must have at least one output
-    //~| ERROR asm options unsupported in naked functions: `pure`, `readonly`, `nostack`
-    //~| ERROR asm in naked functions must use `noreturn` option
+    naked_asm!("", options(readonly, nostack), options(pure));
+    //~^ ERROR the `readonly` option cannot be used with `naked_asm!`
+    //~| ERROR the `nostack` option cannot be used with `naked_asm!`
+    //~| ERROR the `pure` option cannot be used with `naked_asm!`
 }
 
 #[naked]
 unsafe extern "C" fn invalid_may_unwind() {
-    asm!("", options(noreturn, may_unwind));
-    //~^ ERROR asm options unsupported in naked functions: `may_unwind`
+    naked_asm!("", options(may_unwind));
+    //~^ ERROR the `may_unwind` option cannot be used with `naked_asm!`
 }
 
 #[naked]
 pub unsafe fn default_abi() {
     //~^ WARN Rust ABI is unsupported in naked functions
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[naked]
 pub unsafe fn rust_abi() {
     //~^ WARN Rust ABI is unsupported in naked functions
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[naked]
 pub extern "C" fn valid_a<T>() -> T {
     unsafe {
-        asm!("", options(noreturn));
+        naked_asm!("");
     }
 }
 
@@ -145,7 +146,7 @@ pub extern "C" fn valid_b() {
     unsafe {
         {
             {
-                asm!("", options(noreturn));
+                naked_asm!("");
             };
         };
     }
@@ -153,13 +154,13 @@ pub extern "C" fn valid_b() {
 
 #[naked]
 pub unsafe extern "C" fn valid_c() {
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[cfg(target_arch = "x86_64")]
 #[naked]
 pub unsafe extern "C" fn valid_att_syntax() {
-    asm!("", options(noreturn, att_syntax));
+    naked_asm!("", options(att_syntax));
 }
 
 #[naked]
@@ -173,12 +174,12 @@ pub unsafe extern "C" fn allow_compile_error(a: u32) -> u32 {
 pub unsafe extern "C" fn allow_compile_error_and_asm(a: u32) -> u32 {
     compile_error!("this is a user specified error");
     //~^ ERROR this is a user specified error
-    asm!("", options(noreturn))
+    naked_asm!("")
 }
 
 #[naked]
 pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
-    asm!(invalid_syntax)
+    naked_asm!(invalid_syntax)
     //~^ ERROR asm template must be a string literal
 }
 
@@ -186,7 +187,7 @@ pub unsafe extern "C" fn invalid_asm_syntax(a: u32) -> u32 {
 #[cfg_attr(target_pointer_width = "64", no_mangle)]
 #[naked]
 pub unsafe extern "C" fn compatible_cfg_attributes() {
-    asm!("", options(noreturn, att_syntax));
+    naked_asm!("", options(att_syntax));
 }
 
 #[allow(dead_code)]
@@ -195,25 +196,24 @@ pub unsafe extern "C" fn compatible_cfg_attributes() {
 #[forbid(dead_code)]
 #[naked]
 pub unsafe extern "C" fn compatible_diagnostic_attributes() {
-    asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
 
 #[deprecated = "test"]
 #[naked]
 pub unsafe extern "C" fn compatible_deprecated_attributes() {
-    asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
 
 #[cfg(target_arch = "x86_64")]
 #[must_use]
 #[naked]
 pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
-    asm!(
+    naked_asm!(
         "
         mov rax, 42
         ret
         ",
-        options(noreturn)
     )
 }
 
@@ -222,20 +222,20 @@ pub unsafe extern "C" fn compatible_must_use_attributes() -> u64 {
 #[no_mangle]
 #[naked]
 pub unsafe extern "C" fn compatible_ffi_attributes_1() {
-    asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
 
 #[cold]
 #[naked]
 pub unsafe extern "C" fn compatible_codegen_attributes() {
-    asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
 
 #[cfg(target_arch = "x86_64")]
 #[target_feature(enable = "sse2")]
 #[naked]
 pub unsafe extern "C" fn compatible_target_feature() {
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[doc = "foo bar baz"]
@@ -244,11 +244,11 @@ pub unsafe extern "C" fn compatible_target_feature() {
 #[doc(alias = "ADocAlias")]
 #[naked]
 pub unsafe extern "C" fn compatible_doc_attributes() {
-    asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
 
 #[linkage = "external"]
 #[naked]
 pub unsafe extern "C" fn compatible_linkage() {
-    asm!("", options(noreturn, raw));
+    naked_asm!("", options(raw));
 }
diff --git a/tests/ui/asm/naked-functions.stderr b/tests/ui/asm/naked-functions.stderr
index 93c02e2fbef..0898f3620f2 100644
--- a/tests/ui/asm/naked-functions.stderr
+++ b/tests/ui/asm/naked-functions.stderr
@@ -1,193 +1,162 @@
-error: asm with the `pure` option must have at least one output
-  --> $DIR/naked-functions.rs:112:14
+error: the `in` operand cannot be used with `naked_asm!`
+  --> $DIR/naked-functions.rs:47:29
    |
-LL |     asm!("", options(readonly, nostack), options(pure));
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^
+LL |     naked_asm!("/* {0} */", in(reg) a)
+   |                             ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it
+
+error: the `in` operand cannot be used with `naked_asm!`
+  --> $DIR/naked-functions.rs:68:10
+   |
+LL |          in(reg) a,
+   |          ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it
+
+error: the `noreturn` option cannot be used with `naked_asm!`
+  --> $DIR/naked-functions.rs:88:32
+   |
+LL |         naked_asm!("", options(noreturn));
+   |                                ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly
+
+error: the `nomem` option cannot be used with `naked_asm!`
+  --> $DIR/naked-functions.rs:106:28
+   |
+LL |     naked_asm!("", options(nomem, preserves_flags));
+   |                            ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
+
+error: the `preserves_flags` option cannot be used with `naked_asm!`
+  --> $DIR/naked-functions.rs:106:35
+   |
+LL |     naked_asm!("", options(nomem, preserves_flags));
+   |                                   ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly
+
+error: the `readonly` option cannot be used with `naked_asm!`
+  --> $DIR/naked-functions.rs:113:28
+   |
+LL |     naked_asm!("", options(readonly, nostack), options(pure));
+   |                            ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly
+
+error: the `nostack` option cannot be used with `naked_asm!`
+  --> $DIR/naked-functions.rs:113:38
+   |
+LL |     naked_asm!("", options(readonly, nostack), options(pure));
+   |                                      ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly
+
+error: the `pure` option cannot be used with `naked_asm!`
+  --> $DIR/naked-functions.rs:113:56
+   |
+LL |     naked_asm!("", options(readonly, nostack), options(pure));
+   |                                                        ^^^^ the `pure` option is not meaningful for global-scoped inline assembly
+
+error: the `may_unwind` option cannot be used with `naked_asm!`
+  --> $DIR/naked-functions.rs:121:28
+   |
+LL |     naked_asm!("", options(may_unwind));
+   |                            ^^^^^^^^^^ the `may_unwind` option is not meaningful for global-scoped inline assembly
 
 error: this is a user specified error
-  --> $DIR/naked-functions.rs:168:5
+  --> $DIR/naked-functions.rs:169:5
    |
 LL |     compile_error!("this is a user specified error")
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this is a user specified error
-  --> $DIR/naked-functions.rs:174:5
+  --> $DIR/naked-functions.rs:175:5
    |
 LL |     compile_error!("this is a user specified error");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: asm template must be a string literal
-  --> $DIR/naked-functions.rs:181:10
+  --> $DIR/naked-functions.rs:182:16
    |
-LL |     asm!(invalid_syntax)
-   |          ^^^^^^^^^^^^^^
+LL |     naked_asm!(invalid_syntax)
+   |                ^^^^^^^^^^^^^^
+
+error[E0787]: the `asm!` macro is not allowed in naked functions
+  --> $DIR/naked-functions.rs:13:5
+   |
+LL |     asm!("", options(raw));
+   |     ^^^^^^^^^^^^^^^^^^^^^^ consider using the `naked_asm!` macro instead
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:19:5
+  --> $DIR/naked-functions.rs:25:5
    |
 LL |     mut a: u32,
    |     ^^^^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:21:5
+  --> $DIR/naked-functions.rs:27:5
    |
 LL |     &b: &i32,
    |     ^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:23:6
+  --> $DIR/naked-functions.rs:29:6
    |
 LL |     (None | Some(_)): Option<std::ptr::NonNull<u8>>,
    |      ^^^^^^^^^^^^^^
 
 error: patterns not allowed in naked function parameters
-  --> $DIR/naked-functions.rs:25:5
+  --> $DIR/naked-functions.rs:31:5
    |
 LL |     P { x, y }: P,
    |     ^^^^^^^^^^
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:34:5
+  --> $DIR/naked-functions.rs:40:5
    |
 LL |     a + 1
    |     ^
    |
    = help: follow the calling convention in asm block to use parameters
 
-error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:32:1
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
+  --> $DIR/naked-functions.rs:38:1
    |
 LL | pub unsafe extern "C" fn inc(a: u32) -> u32 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     a + 1
-   |     ----- non-asm is unsupported in naked functions
-
-error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:41:31
-   |
-LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
-   |                               ^
-   |
-   = help: follow the calling convention in asm block to use parameters
-
-error[E0787]: only `const` and `sym` operands are supported in naked functions
-  --> $DIR/naked-functions.rs:41:23
-   |
-LL |     asm!("/* {0} */", in(reg) a, options(noreturn));
-   |                       ^^^^^^^^^
+   |     ----- not allowed in naked functions
 
-error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:47:1
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
+  --> $DIR/naked-functions.rs:52:1
    |
 LL | pub unsafe extern "C" fn inc_closure(a: u32) -> u32 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     (|| a + 1)()
-   |     ------------ non-asm is unsupported in naked functions
+   |     ------------ not allowed in naked functions
 
-error[E0787]: only `const` and `sym` operands are supported in naked functions
-  --> $DIR/naked-functions.rs:64:10
-   |
-LL |          in(reg) a,
-   |          ^^^^^^^^^
-LL |
-LL |          inlateout(reg) b,
-   |          ^^^^^^^^^^^^^^^^
-LL |          inout(reg) c,
-   |          ^^^^^^^^^^^^
-LL |          lateout(reg) d,
-   |          ^^^^^^^^^^^^^^
-LL |          out(reg) e,
-   |          ^^^^^^^^^^
-
-error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:62:5
-   |
-LL | /     asm!("/* {0} {1} {2} {3} {4} {5} {6} */",
-LL | |
-LL | |          in(reg) a,
-LL | |
-...  |
-LL | |          sym G,
-LL | |     );
-   | |_____^
-   |
-help: consider specifying that the asm block is responsible for returning from the function
-   |
-LL |          sym G, options(noreturn),
-   |               +++++++++++++++++++
-
-error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:53:1
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
+  --> $DIR/naked-functions.rs:58:1
    |
 LL | pub unsafe extern "C" fn unsupported_operands() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     let mut a = 0usize;
-   |     ------------------- non-asm is unsupported in naked functions
+   |     ------------------- not allowed in naked functions
 LL |     let mut b = 0usize;
-   |     ------------------- non-asm is unsupported in naked functions
+   |     ------------------- not allowed in naked functions
 LL |     let mut c = 0usize;
-   |     ------------------- non-asm is unsupported in naked functions
+   |     ------------------- not allowed in naked functions
 LL |     let mut d = 0usize;
-   |     ------------------- non-asm is unsupported in naked functions
+   |     ------------------- not allowed in naked functions
 LL |     let mut e = 0usize;
-   |     ------------------- non-asm is unsupported in naked functions
+   |     ------------------- not allowed in naked functions
 
-error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:76:1
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
+  --> $DIR/naked-functions.rs:80:1
    |
 LL | pub extern "C" fn missing_assembly() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:84:9
-   |
-LL |         asm!("");
-   |         ^^^^^^^^
-   |
-help: consider specifying that the asm block is responsible for returning from the function
-   |
-LL |         asm!("", options(noreturn));
-   |                +++++++++++++++++++
-
-error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:86:9
-   |
-LL |         asm!("");
-   |         ^^^^^^^^
-   |
-help: consider specifying that the asm block is responsible for returning from the function
-   |
-LL |         asm!("", options(noreturn));
-   |                +++++++++++++++++++
-
-error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:88:9
-   |
-LL |         asm!("");
-   |         ^^^^^^^^
-   |
-help: consider specifying that the asm block is responsible for returning from the function
-   |
-LL |         asm!("", options(noreturn));
-   |                +++++++++++++++++++
-
-error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:81:1
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
+  --> $DIR/naked-functions.rs:85:1
    |
 LL | pub extern "C" fn too_many_asm_blocks() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 ...
-LL |         asm!("");
-   |         -------- multiple asm blocks are unsupported in naked functions
-LL |
-LL |         asm!("");
-   |         -------- multiple asm blocks are unsupported in naked functions
-LL |
-LL |         asm!("", options(noreturn));
-   |         --------------------------- multiple asm blocks are unsupported in naked functions
+LL |         naked_asm!("");
+   |         -------------- multiple `naked_asm!` invocations are not allowed in naked functions
 
 error: referencing function parameters is not allowed in naked functions
   --> $DIR/naked-functions.rs:98:11
@@ -197,46 +166,17 @@ LL |         *&y
    |
    = help: follow the calling convention in asm block to use parameters
 
-error[E0787]: naked functions must contain a single asm block
+error[E0787]: naked functions must contain a single `naked_asm!` invocation
   --> $DIR/naked-functions.rs:96:5
    |
 LL |     pub extern "C" fn inner(y: usize) -> usize {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         *&y
-   |         --- non-asm is unsupported in naked functions
-
-error[E0787]: asm options unsupported in naked functions: `nomem`, `preserves_flags`
-  --> $DIR/naked-functions.rs:106:5
-   |
-LL |     asm!("", options(nomem, preserves_flags, noreturn));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0787]: asm options unsupported in naked functions: `pure`, `readonly`, `nostack`
-  --> $DIR/naked-functions.rs:112:5
-   |
-LL |     asm!("", options(readonly, nostack), options(pure));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:112:5
-   |
-LL |     asm!("", options(readonly, nostack), options(pure));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: consider specifying that the asm block is responsible for returning from the function
-   |
-LL |     asm!("", options(noreturn), options(readonly, nostack), options(pure));
-   |            +++++++++++++++++++
-
-error[E0787]: asm options unsupported in naked functions: `may_unwind`
-  --> $DIR/naked-functions.rs:120:5
-   |
-LL |     asm!("", options(noreturn, may_unwind));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         --- not allowed in naked functions
 
 warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:125:1
+  --> $DIR/naked-functions.rs:126:1
    |
 LL | pub unsafe fn default_abi() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -244,11 +184,11 @@ LL | pub unsafe fn default_abi() {
    = note: `#[warn(undefined_naked_function_abi)]` on by default
 
 warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:131:1
+  --> $DIR/naked-functions.rs:132:1
    |
 LL | pub unsafe fn rust_abi() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 27 previous errors; 2 warnings emitted
+error: aborting due to 25 previous errors; 2 warnings emitted
 
 For more information about this error, try `rustc --explain E0787`.
diff --git a/tests/ui/asm/naked-invalid-attr.rs b/tests/ui/asm/naked-invalid-attr.rs
index 57edd57de99..4053c58fb51 100644
--- a/tests/ui/asm/naked-invalid-attr.rs
+++ b/tests/ui/asm/naked-invalid-attr.rs
@@ -4,7 +4,7 @@
 #![feature(naked_functions)]
 #![naked] //~ ERROR should be applied to a function definition
 
-use std::arch::asm;
+use std::arch::naked_asm;
 
 extern "C" {
     #[naked] //~ ERROR should be applied to a function definition
@@ -26,27 +26,28 @@ trait Invoke {
 impl Invoke for S {
     #[naked]
     extern "C" fn invoke(&self) {
-        unsafe { asm!("", options(noreturn)) }
+        unsafe { naked_asm!("") }
     }
 }
 
 #[naked]
 extern "C" fn ok() {
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
 
 impl S {
     #[naked]
     extern "C" fn g() {
-        unsafe { asm!("", options(noreturn)) }
+        unsafe { naked_asm!("") }
     }
 
     #[naked]
     extern "C" fn h(&self) {
-        unsafe { asm!("", options(noreturn)) }
+        unsafe { naked_asm!("") }
     }
 }
 
 fn main() {
-    #[naked] || {}; //~ ERROR should be applied to a function definition
+    #[naked] //~ ERROR should be applied to a function definition
+    || {};
 }
diff --git a/tests/ui/asm/naked-invalid-attr.stderr b/tests/ui/asm/naked-invalid-attr.stderr
index e8ddccc854a..640f9d9510d 100644
--- a/tests/ui/asm/naked-invalid-attr.stderr
+++ b/tests/ui/asm/naked-invalid-attr.stderr
@@ -13,8 +13,10 @@ LL | | }
 error: attribute should be applied to a function definition
   --> $DIR/naked-invalid-attr.rs:51:5
    |
-LL |     #[naked] || {};
-   |     ^^^^^^^^ ----- not a function definition
+LL |     #[naked]
+   |     ^^^^^^^^
+LL |     || {};
+   |     ----- not a function definition
 
 error: attribute should be applied to a function definition
   --> $DIR/naked-invalid-attr.rs:22:5
diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.rs b/tests/ui/asm/naked-with-invalid-repr-attr.rs
index 687fe1ad73d..18b9c1014c3 100644
--- a/tests/ui/asm/naked-with-invalid-repr-attr.rs
+++ b/tests/ui/asm/naked-with-invalid-repr-attr.rs
@@ -2,14 +2,14 @@
 #![feature(naked_functions)]
 #![feature(fn_align)]
 #![crate_type = "lib"]
-use std::arch::asm;
+use std::arch::naked_asm;
 
 #[repr(C)]
 //~^ ERROR attribute should be applied to a struct, enum, or union [E0517]
 #[naked]
 extern "C" fn example1() {
     //~^ NOTE not a struct, enum, or union
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
 
 #[repr(transparent)]
@@ -17,7 +17,7 @@ extern "C" fn example1() {
 #[naked]
 extern "C" fn example2() {
     //~^ NOTE not a struct, enum, or union
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
 
 #[repr(align(16), C)]
@@ -25,7 +25,7 @@ extern "C" fn example2() {
 #[naked]
 extern "C" fn example3() {
     //~^ NOTE not a struct, enum, or union
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
 
 // note: two errors because of packed and C
@@ -36,7 +36,7 @@ extern "C" fn example3() {
 extern "C" fn example4() {
     //~^ NOTE not a struct, enum, or union
     //~| NOTE not a struct or union
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
 
 #[repr(u8)]
@@ -44,5 +44,5 @@ extern "C" fn example4() {
 #[naked]
 extern "C" fn example5() {
     //~^ NOTE not an enum
-    unsafe { asm!("", options(noreturn)) }
+    unsafe { naked_asm!("") }
 }
diff --git a/tests/ui/asm/naked-with-invalid-repr-attr.stderr b/tests/ui/asm/naked-with-invalid-repr-attr.stderr
index 3740f17a9dc..8248a8c1657 100644
--- a/tests/ui/asm/naked-with-invalid-repr-attr.stderr
+++ b/tests/ui/asm/naked-with-invalid-repr-attr.stderr
@@ -6,7 +6,7 @@ LL |   #[repr(C)]
 ...
 LL | / extern "C" fn example1() {
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not a struct, enum, or union
 
@@ -18,7 +18,7 @@ LL |   #[repr(transparent)]
 ...
 LL | / extern "C" fn example2() {
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not a struct, enum, or union
 
@@ -30,7 +30,7 @@ LL |   #[repr(align(16), C)]
 ...
 LL | / extern "C" fn example3() {
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not a struct, enum, or union
 
@@ -43,7 +43,7 @@ LL |   #[repr(C, packed)]
 LL | / extern "C" fn example4() {
 LL | |
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not a struct, enum, or union
 
@@ -56,7 +56,7 @@ LL |   #[repr(C, packed)]
 LL | / extern "C" fn example4() {
 LL | |
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not a struct or union
 
@@ -68,7 +68,7 @@ LL |   #[repr(u8)]
 ...
 LL | / extern "C" fn example5() {
 LL | |
-LL | |     unsafe { asm!("", options(noreturn)) }
+LL | |     unsafe { naked_asm!("") }
 LL | | }
    | |_- not an enum
 
diff --git a/tests/ui/asm/named-asm-labels.rs b/tests/ui/asm/named-asm-labels.rs
index 043aab9029d..77831e679ed 100644
--- a/tests/ui/asm/named-asm-labels.rs
+++ b/tests/ui/asm/named-asm-labels.rs
@@ -12,7 +12,7 @@
 
 #![feature(naked_functions)]
 
-use std::arch::{asm, global_asm};
+use std::arch::{asm, global_asm, naked_asm};
 
 #[no_mangle]
 pub static FOO: usize = 42;
@@ -177,7 +177,7 @@ fn main() {
 // label or LTO can cause labels to break
 #[naked]
 pub extern "C" fn foo() -> i32 {
-    unsafe { asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1, options(noreturn)) }
+    unsafe { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) }
     //~^ ERROR avoid using named labels
 }
 
@@ -192,7 +192,7 @@ pub extern "C" fn bar() {
 pub extern "C" fn aaa() {
     fn _local() {}
 
-    unsafe { asm!(".Laaa: nop; ret;", options(noreturn)) } //~ ERROR avoid using named labels
+    unsafe { naked_asm!(".Laaa: nop; ret;") } //~ ERROR avoid using named labels
 }
 
 pub fn normal() {
@@ -202,7 +202,7 @@ pub fn normal() {
     pub extern "C" fn bbb() {
         fn _very_local() {}
 
-        unsafe { asm!(".Lbbb: nop; ret;", options(noreturn)) } //~ ERROR avoid using named labels
+        unsafe { naked_asm!(".Lbbb: nop; ret;") } //~ ERROR avoid using named labels
     }
 
     fn _local2() {}
@@ -221,7 +221,7 @@ fn closures() {
     || {
         #[naked]
         unsafe extern "C" fn _nested() {
-            asm!("ret;", options(noreturn));
+            naked_asm!("ret;");
         }
 
         unsafe {
diff --git a/tests/ui/asm/named-asm-labels.stderr b/tests/ui/asm/named-asm-labels.stderr
index e5e177fb8b8..44ce358c62b 100644
--- a/tests/ui/asm/named-asm-labels.stderr
+++ b/tests/ui/asm/named-asm-labels.stderr
@@ -475,10 +475,10 @@ LL |         #[warn(named_asm_labels)]
    |                ^^^^^^^^^^^^^^^^
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:180:20
+  --> $DIR/named-asm-labels.rs:180:26
    |
-LL |     unsafe { asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1, options(noreturn)) }
-   |                    ^^^^^
+LL |     unsafe { naked_asm!(".Lfoo: mov rax, {}; ret;", "nop", const 1) }
+   |                          ^^^^^
    |
    = help: only local labels of the form `<number>:` should be used in inline asm
    = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
@@ -493,19 +493,19 @@ LL |     unsafe { asm!(".Lbar: mov rax, {}; ret;", "nop", const 1, options(noret
    = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:195:20
+  --> $DIR/named-asm-labels.rs:195:26
    |
-LL |     unsafe { asm!(".Laaa: nop; ret;", options(noreturn)) }
-   |                    ^^^^^
+LL |     unsafe { naked_asm!(".Laaa: nop; ret;") }
+   |                          ^^^^^
    |
    = help: only local labels of the form `<number>:` should be used in inline asm
    = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
 
 error: avoid using named labels in inline assembly
-  --> $DIR/named-asm-labels.rs:205:24
+  --> $DIR/named-asm-labels.rs:205:30
    |
-LL |         unsafe { asm!(".Lbbb: nop; ret;", options(noreturn)) }
-   |                        ^^^^^
+LL |         unsafe { naked_asm!(".Lbbb: nop; ret;") }
+   |                              ^^^^^
    |
    = help: only local labels of the form `<number>:` should be used in inline asm
    = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information
diff --git a/tests/ui/consts/issue-94675.rs b/tests/ui/consts/issue-94675.rs
index 56c4b6ea36f..2e30eebb07b 100644
--- a/tests/ui/consts/issue-94675.rs
+++ b/tests/ui/consts/issue-94675.rs
@@ -1,6 +1,6 @@
 //@ known-bug: #103507
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, const_vec_string_slice)]
 
 struct Foo<'a> {
     bar: &'a mut Vec<usize>,
diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr
index ebfa09b2e5d..a85c5e10374 100644
--- a/tests/ui/consts/issue-94675.stderr
+++ b/tests/ui/consts/issue-94675.stderr
@@ -1,11 +1,3 @@
-error[E0015]: cannot call non-const fn `Vec::<u32>::len` in constant functions
-  --> $DIR/issue-94675.rs:11:27
-   |
-LL |         self.bar[0] = baz.len();
-   |                           ^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
 error[E0015]: cannot call non-const operator in constant functions
   --> $DIR/issue-94675.rs:11:17
    |
@@ -20,6 +12,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions.rs b/tests/ui/feature-gates/feature-gate-naked_functions.rs
index 36980fd74c2..5fe0bbdc774 100644
--- a/tests/ui/feature-gates/feature-gate-naked_functions.rs
+++ b/tests/ui/feature-gates/feature-gate-naked_functions.rs
@@ -1,19 +1,22 @@
 //@ needs-asm-support
 
-use std::arch::asm;
+use std::arch::naked_asm;
+//~^ ERROR use of unstable library feature 'naked_functions'
 
 #[naked]
 //~^ the `#[naked]` attribute is an experimental feature
 extern "C" fn naked() {
-    asm!("", options(noreturn))
-    //~^ ERROR: requires unsafe
+    naked_asm!("")
+    //~^ ERROR use of unstable library feature 'naked_functions'
+    //~| ERROR: requires unsafe
 }
 
 #[naked]
 //~^ the `#[naked]` attribute is an experimental feature
 extern "C" fn naked_2() -> isize {
-    asm!("", options(noreturn))
-    //~^ ERROR: requires unsafe
+    naked_asm!("")
+    //~^ ERROR use of unstable library feature 'naked_functions'
+    //~| ERROR: requires unsafe
 }
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions.stderr b/tests/ui/feature-gates/feature-gate-naked_functions.stderr
index ffdf31e147a..709234eb023 100644
--- a/tests/ui/feature-gates/feature-gate-naked_functions.stderr
+++ b/tests/ui/feature-gates/feature-gate-naked_functions.stderr
@@ -1,5 +1,25 @@
+error[E0658]: use of unstable library feature 'naked_functions'
+  --> $DIR/feature-gate-naked_functions.rs:9:5
+   |
+LL |     naked_asm!("")
+   |     ^^^^^^^^^
+   |
+   = note: see issue #90957 <https://github.com/rust-lang/rust/issues/90957> for more information
+   = help: add `#![feature(naked_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: use of unstable library feature 'naked_functions'
+  --> $DIR/feature-gate-naked_functions.rs:17:5
+   |
+LL |     naked_asm!("")
+   |     ^^^^^^^^^
+   |
+   = note: see issue #90957 <https://github.com/rust-lang/rust/issues/90957> for more information
+   = help: add `#![feature(naked_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
 error[E0658]: the `#[naked]` attribute is an experimental feature
-  --> $DIR/feature-gate-naked_functions.rs:5:1
+  --> $DIR/feature-gate-naked_functions.rs:6:1
    |
 LL | #[naked]
    | ^^^^^^^^
@@ -9,7 +29,7 @@ LL | #[naked]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the `#[naked]` attribute is an experimental feature
-  --> $DIR/feature-gate-naked_functions.rs:12:1
+  --> $DIR/feature-gate-naked_functions.rs:14:1
    |
 LL | #[naked]
    | ^^^^^^^^
@@ -18,23 +38,33 @@ LL | #[naked]
    = help: add `#![feature(naked_functions)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
+error[E0658]: use of unstable library feature 'naked_functions'
+  --> $DIR/feature-gate-naked_functions.rs:3:5
+   |
+LL | use std::arch::naked_asm;
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #90957 <https://github.com/rust-lang/rust/issues/90957> for more information
+   = help: add `#![feature(naked_functions)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
 error[E0133]: use of inline assembly is unsafe and requires unsafe function or block
-  --> $DIR/feature-gate-naked_functions.rs:8:5
+  --> $DIR/feature-gate-naked_functions.rs:9:5
    |
-LL |     asm!("", options(noreturn))
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of inline assembly
+LL |     naked_asm!("")
+   |     ^^^^^^^^^^^^^^ use of inline assembly
    |
    = note: inline assembly is entirely unchecked and can cause undefined behavior
 
 error[E0133]: use of inline assembly is unsafe and requires unsafe function or block
-  --> $DIR/feature-gate-naked_functions.rs:15:5
+  --> $DIR/feature-gate-naked_functions.rs:17:5
    |
-LL |     asm!("", options(noreturn))
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of inline assembly
+LL |     naked_asm!("")
+   |     ^^^^^^^^^^^^^^ use of inline assembly
    |
    = note: inline assembly is entirely unchecked and can cause undefined behavior
 
-error: aborting due to 4 previous errors
+error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0133, E0658.
 For more information about an error, try `rustc --explain E0133`.
diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
index 0c73b9abf35..0e85515fd10 100644
--- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
+++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
@@ -1,14 +1,14 @@
 //@ needs-asm-support
 #![feature(naked_functions)]
 
-use std::arch::asm;
+use std::arch::naked_asm;
 
 #[track_caller] //~ ERROR [E0736]
 //~^ ERROR `#[track_caller]` requires Rust ABI
 #[naked]
 extern "C" fn f() {
     unsafe {
-        asm!("", options(noreturn));
+        naked_asm!("");
     }
 }
 
@@ -20,7 +20,7 @@ impl S {
     #[naked]
     extern "C" fn g() {
         unsafe {
-            asm!("", options(noreturn));
+            naked_asm!("");
         }
     }
 }