about summary refs log tree commit diff
path: root/compiler/rustc_passes/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_passes/src')
-rw-r--r--compiler/rustc_passes/src/abi_test.rs20
-rw-r--r--compiler/rustc_passes/src/check_attr.rs152
-rw-r--r--compiler/rustc_passes/src/debugger_visualizer.rs22
-rw-r--r--compiler/rustc_passes/src/errors.rs23
-rw-r--r--compiler/rustc_passes/src/layout_test.rs18
-rw-r--r--compiler/rustc_passes/src/lib.rs4
-rw-r--r--compiler/rustc_passes/src/liveness.rs12
-rw-r--r--compiler/rustc_passes/src/naked_functions.rs33
8 files changed, 137 insertions, 147 deletions
diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs
index 671b7d7ad76..b139ed6a66c 100644
--- a/compiler/rustc_passes/src/abi_test.rs
+++ b/compiler/rustc_passes/src/abi_test.rs
@@ -9,7 +9,7 @@ use rustc_span::sym;
 use rustc_target::callconv::FnAbi;
 
 use super::layout_test::ensure_wf;
-use crate::errors::{AbiInvalidAttribute, AbiNe, AbiOf, UnrecognizedField};
+use crate::errors::{AbiInvalidAttribute, AbiNe, AbiOf, UnrecognizedArgument};
 
 pub fn test_abi(tcx: TyCtxt<'_>) {
     if !tcx.features().rustc_attrs() {
@@ -77,8 +77,8 @@ fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
     // The `..` are the names of fields to dump.
     let meta_items = attr.meta_item_list().unwrap_or_default();
     for meta_item in meta_items {
-        match meta_item.name_or_empty() {
-            sym::debug => {
+        match meta_item.name() {
+            Some(sym::debug) => {
                 let fn_name = tcx.item_name(item_def_id.into());
                 tcx.dcx().emit_err(AbiOf {
                     span: tcx.def_span(item_def_id),
@@ -88,8 +88,8 @@ fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
                 });
             }
 
-            name => {
-                tcx.dcx().emit_err(UnrecognizedField { span: meta_item.span(), name });
+            _ => {
+                tcx.dcx().emit_err(UnrecognizedArgument { span: meta_item.span() });
             }
         }
     }
@@ -118,8 +118,8 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
     }
     let meta_items = attr.meta_item_list().unwrap_or_default();
     for meta_item in meta_items {
-        match meta_item.name_or_empty() {
-            sym::debug => {
+        match meta_item.name() {
+            Some(sym::debug) => {
                 let ty::FnPtr(sig_tys, hdr) = ty.kind() else {
                     span_bug!(
                         meta_item.span(),
@@ -138,7 +138,7 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
                 let fn_name = tcx.item_name(item_def_id.into());
                 tcx.dcx().emit_err(AbiOf { span, fn_name, fn_abi: format!("{:#?}", abi) });
             }
-            sym::assert_eq => {
+            Some(sym::assert_eq) => {
                 let ty::Tuple(fields) = ty.kind() else {
                     span_bug!(
                         meta_item.span(),
@@ -188,8 +188,8 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
                     });
                 }
             }
-            name => {
-                tcx.dcx().emit_err(UnrecognizedField { span: meta_item.span(), name });
+            _ => {
+                tcx.dcx().emit_err(UnrecognizedArgument { span: meta_item.span() });
             }
         }
     }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 9161b23428a..f04b167889f 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -179,6 +179,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         [sym::rustc_as_ptr, ..] => {
                             self.check_applied_to_fn_or_method(hir_id, attr, span, target)
                         }
+                        [sym::rustc_no_implicit_autorefs, ..] => {
+                            self.check_applied_to_fn_or_method(hir_id, attr, span, target)
+                        }
                         [sym::rustc_never_returns_null_ptr, ..] => {
                             self.check_applied_to_fn_or_method(hir_id, attr, span, target)
                         }
@@ -523,9 +526,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     fn check_no_sanitize(&self, attr: &Attribute, span: Span, target: Target) {
         if let Some(list) = attr.meta_item_list() {
             for item in list.iter() {
-                let sym = item.name_or_empty();
+                let sym = item.name();
                 match sym {
-                    sym::address | sym::hwaddress => {
+                    Some(s @ sym::address | s @ sym::hwaddress) => {
                         let is_valid =
                             matches!(target, Target::Fn | Target::Method(..) | Target::Static);
                         if !is_valid {
@@ -533,7 +536,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                                 attr_span: item.span(),
                                 defn_span: span,
                                 accepted_kind: "a function or static",
-                                attr_str: sym.as_str(),
+                                attr_str: s.as_str(),
                             });
                         }
                     }
@@ -544,7 +547,10 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                                 attr_span: item.span(),
                                 defn_span: span,
                                 accepted_kind: "a function",
-                                attr_str: sym.as_str(),
+                                attr_str: &match sym {
+                                    Some(name) => name.to_string(),
+                                    None => "...".to_string(),
+                                },
                             });
                         }
                     }
@@ -561,12 +567,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         allowed_target: Target,
     ) {
         if target != allowed_target {
+            let path = attr.path();
+            let path: Vec<_> = path.iter().map(|s| s.as_str()).collect();
+            let attr_name = path.join("::");
             self.tcx.emit_node_span_lint(
                 UNUSED_ATTRIBUTES,
                 hir_id,
                 attr.span(),
                 errors::OnlyHasEffectOn {
-                    attr_name: attr.name_or_empty(),
+                    attr_name,
                     target_name: allowed_target.name().replace(' ', "_"),
                 },
             );
@@ -589,7 +598,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         // * `#[track_caller]`
         // * `#[test]`, `#[ignore]`, `#[should_panic]`
         //
-        // NOTE: when making changes to this list, check that `error_codes/E0736.md` remains accurate
+        // NOTE: when making changes to this list, check that `error_codes/E0736.md` remains
+        // accurate.
         const ALLOW_LIST: &[rustc_span::Symbol] = &[
             // conditional compilation
             sym::cfg_trace,
@@ -615,6 +625,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             sym::naked,
             sym::instruction_set,
             sym::repr,
+            sym::rustc_std_internal_symbol,
             // code generation
             sym::cold,
             // documentation
@@ -624,6 +635,21 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         match target {
             Target::Fn
             | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
+                let fn_sig = self.tcx.hir_node(hir_id).fn_sig().unwrap();
+                let abi = fn_sig.header.abi;
+                if abi.is_rustic_abi() && !self.tcx.features().naked_functions_rustic_abi() {
+                    feature_err(
+                        &self.tcx.sess,
+                        sym::naked_functions_rustic_abi,
+                        fn_sig.span,
+                        format!(
+                            "`#[naked]` is currently unstable on `extern \"{}\"` functions",
+                            abi.as_str()
+                        ),
+                    )
+                    .emit();
+                }
+
                 for other_attr in attrs {
                     // this covers "sugared doc comments" of the form `/// ...`
                     // it does not cover `#[doc = "..."]`, which is handled below
@@ -657,24 +683,21 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         }
                     }
 
-                    if !ALLOW_LIST.iter().any(|name| other_attr.has_name(*name)) {
+                    if !other_attr.has_any_name(ALLOW_LIST) {
+                        let path = other_attr.path();
+                        let path: Vec<_> = path.iter().map(|s| s.as_str()).collect();
+                        let other_attr_name = path.join("::");
+
                         self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
                             span: other_attr.span(),
                             naked_span: attr.span(),
-                            attr: other_attr.name_or_empty(),
+                            attr: other_attr_name,
                         });
 
                         return;
                     }
                 }
             }
-            // FIXME(#80564): We permit struct fields, match arms and macro defs to have an
-            // `#[naked]` attribute with just a lint, because we previously
-            // erroneously allowed it and some crates used it accidentally, to be compatible
-            // with crates depending on them, we can't throw an error here.
-            Target::Field | Target::Arm | Target::MacroDef => {
-                self.inline_attr_str_error_with_macro_def(hir_id, attr, "naked")
-            }
             _ => {
                 self.dcx().emit_err(errors::AttrShouldBeAppliedToFn {
                     attr_span: attr.span(),
@@ -1109,6 +1132,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             ItemKind::Trait(_, _, _, generics, _, items)
                 if generics.params.len() != 0
                     || items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {}
+            ItemKind::TyAlias(_, _, generics) if generics.params.len() != 0 => {}
             _ => {
                 self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() });
             }
@@ -1134,7 +1158,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     ) {
         match target {
             Target::Use | Target::ExternCrate => {
-                let do_inline = meta.name_or_empty() == sym::inline;
+                let do_inline = meta.has_name(sym::inline);
                 if let Some((prev_inline, prev_span)) = *specified_inline {
                     if do_inline != prev_inline {
                         let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]);
@@ -1244,8 +1268,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     fn check_test_attr(&self, meta: &MetaItemInner, hir_id: HirId) {
         if let Some(metas) = meta.meta_item_list() {
             for i_meta in metas {
-                match (i_meta.name_or_empty(), i_meta.meta_item()) {
-                    (sym::attr | sym::no_crate_inject, _) => {}
+                match (i_meta.name(), i_meta.meta_item()) {
+                    (Some(sym::attr | sym::no_crate_inject), _) => {}
                     (_, Some(m)) => {
                         self.tcx.emit_node_span_lint(
                             INVALID_DOC_ATTRIBUTES,
@@ -1306,61 +1330,63 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         if let Some(list) = attr.meta_item_list() {
             for meta in &list {
                 if let Some(i_meta) = meta.meta_item() {
-                    match i_meta.name_or_empty() {
-                        sym::alias => {
+                    match i_meta.name() {
+                        Some(sym::alias) => {
                             if self.check_attr_not_crate_level(meta, hir_id, "alias") {
                                 self.check_doc_alias(meta, hir_id, target, aliases);
                             }
                         }
 
-                        sym::keyword => {
+                        Some(sym::keyword) => {
                             if self.check_attr_not_crate_level(meta, hir_id, "keyword") {
                                 self.check_doc_keyword(meta, hir_id);
                             }
                         }
 
-                        sym::fake_variadic => {
+                        Some(sym::fake_variadic) => {
                             if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") {
                                 self.check_doc_fake_variadic(meta, hir_id);
                             }
                         }
 
-                        sym::search_unbox => {
+                        Some(sym::search_unbox) => {
                             if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") {
                                 self.check_doc_search_unbox(meta, hir_id);
                             }
                         }
 
-                        sym::test => {
+                        Some(sym::test) => {
                             if self.check_attr_crate_level(attr, meta, hir_id) {
                                 self.check_test_attr(meta, hir_id);
                             }
                         }
 
-                        sym::html_favicon_url
-                        | sym::html_logo_url
-                        | sym::html_playground_url
-                        | sym::issue_tracker_base_url
-                        | sym::html_root_url
-                        | sym::html_no_source => {
+                        Some(
+                            sym::html_favicon_url
+                            | sym::html_logo_url
+                            | sym::html_playground_url
+                            | sym::issue_tracker_base_url
+                            | sym::html_root_url
+                            | sym::html_no_source,
+                        ) => {
                             self.check_attr_crate_level(attr, meta, hir_id);
                         }
 
-                        sym::cfg_hide => {
+                        Some(sym::cfg_hide) => {
                             if self.check_attr_crate_level(attr, meta, hir_id) {
                                 self.check_doc_cfg_hide(meta, hir_id);
                             }
                         }
 
-                        sym::inline | sym::no_inline => {
+                        Some(sym::inline | sym::no_inline) => {
                             self.check_doc_inline(attr, meta, hir_id, target, specified_inline)
                         }
 
-                        sym::masked => self.check_doc_masked(attr, meta, hir_id, target),
+                        Some(sym::masked) => self.check_doc_masked(attr, meta, hir_id, target),
 
-                        sym::cfg | sym::hidden | sym::notable_trait => {}
+                        Some(sym::cfg | sym::hidden | sym::notable_trait) => {}
 
-                        sym::rust_logo => {
+                        Some(sym::rust_logo) => {
                             if self.check_attr_crate_level(attr, meta, hir_id)
                                 && !self.tcx.features().rustdoc_internals()
                             {
@@ -2283,7 +2309,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     }
 
     fn check_macro_use(&self, hir_id: HirId, attr: &Attribute, target: Target) {
-        let name = attr.name_or_empty();
+        let name = attr.name().unwrap();
         match target {
             Target::ExternCrate | Target::Mod => {}
             _ => {
@@ -2315,12 +2341,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     attr.span(),
                     errors::MacroExport::TooManyItems,
                 );
-            } else if meta_item_list[0].name_or_empty() != sym::local_inner_macros {
+            } else if !meta_item_list[0].has_name(sym::local_inner_macros) {
                 self.tcx.emit_node_span_lint(
                     INVALID_MACRO_EXPORT_ARGUMENTS,
                     hir_id,
                     meta_item_list[0].span(),
-                    errors::MacroExport::UnknownItem { name: meta_item_list[0].name_or_empty() },
+                    errors::MacroExport::InvalidArgument,
                 );
             }
         } else {
@@ -2365,33 +2391,28 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
 
         // Warn on useless empty attributes.
-        let note = if (matches!(
-            attr.name_or_empty(),
-            sym::macro_use
-                | sym::allow
-                | sym::expect
-                | sym::warn
-                | sym::deny
-                | sym::forbid
-                | sym::feature
-                | sym::target_feature
-        ) && attr.meta_item_list().is_some_and(|list| list.is_empty()))
+        let note = if attr.has_any_name(&[
+            sym::macro_use,
+            sym::allow,
+            sym::expect,
+            sym::warn,
+            sym::deny,
+            sym::forbid,
+            sym::feature,
+            sym::target_feature,
+        ]) && attr.meta_item_list().is_some_and(|list| list.is_empty())
         {
-            errors::UnusedNote::EmptyList { name: attr.name_or_empty() }
-        } else if matches!(
-            attr.name_or_empty(),
-            sym::allow | sym::warn | sym::deny | sym::forbid | sym::expect
-        ) && let Some(meta) = attr.meta_item_list()
+            errors::UnusedNote::EmptyList { name: attr.name().unwrap() }
+        } else if attr.has_any_name(&[sym::allow, sym::warn, sym::deny, sym::forbid, sym::expect])
+            && let Some(meta) = attr.meta_item_list()
             && let [meta] = meta.as_slice()
             && let Some(item) = meta.meta_item()
             && let MetaItemKind::NameValue(_) = &item.kind
             && item.path == sym::reason
         {
-            errors::UnusedNote::NoLints { name: attr.name_or_empty() }
-        } else if matches!(
-            attr.name_or_empty(),
-            sym::allow | sym::warn | sym::deny | sym::forbid | sym::expect
-        ) && let Some(meta) = attr.meta_item_list()
+            errors::UnusedNote::NoLints { name: attr.name().unwrap() }
+        } else if attr.has_any_name(&[sym::allow, sym::warn, sym::deny, sym::forbid, sym::expect])
+            && let Some(meta) = attr.meta_item_list()
             && meta.iter().any(|meta| {
                 meta.meta_item().map_or(false, |item| item.path == sym::linker_messages)
             })
@@ -2424,7 +2445,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     return;
                 }
             }
-        } else if attr.name_or_empty() == sym::default_method_body_is_const {
+        } else if attr.has_name(sym::default_method_body_is_const) {
             errors::UnusedNote::DefaultMethodBodyConst
         } else {
             return;
@@ -2881,10 +2902,11 @@ fn check_duplicates(
     if matches!(duplicates, WarnFollowingWordOnly) && !attr.is_word() {
         return;
     }
+    let attr_name = attr.name().unwrap();
     match duplicates {
         DuplicatesOk => {}
         WarnFollowing | FutureWarnFollowing | WarnFollowingWordOnly | FutureWarnPreceding => {
-            match seen.entry(attr.name_or_empty()) {
+            match seen.entry(attr_name) {
                 Entry::Occupied(mut entry) => {
                     let (this, other) = if matches!(duplicates, FutureWarnPreceding) {
                         let to_remove = entry.insert(attr.span());
@@ -2911,7 +2933,7 @@ fn check_duplicates(
                 }
             }
         }
-        ErrorFollowing | ErrorPreceding => match seen.entry(attr.name_or_empty()) {
+        ErrorFollowing | ErrorPreceding => match seen.entry(attr_name) {
             Entry::Occupied(mut entry) => {
                 let (this, other) = if matches!(duplicates, ErrorPreceding) {
                     let to_remove = entry.insert(attr.span());
@@ -2919,11 +2941,7 @@ fn check_duplicates(
                 } else {
                     (attr.span(), *entry.get())
                 };
-                tcx.dcx().emit_err(errors::UnusedMultiple {
-                    this,
-                    other,
-                    name: attr.name_or_empty(),
-                });
+                tcx.dcx().emit_err(errors::UnusedMultiple { this, other, name: attr_name });
             }
             Entry::Vacant(entry) => {
                 entry.insert(attr.span());
diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs
index 062d56a79a0..7a7a8175e55 100644
--- a/compiler/rustc_passes/src/debugger_visualizer.rs
+++ b/compiler/rustc_passes/src/debugger_visualizer.rs
@@ -28,17 +28,17 @@ impl DebuggerVisualizerCollector<'_> {
                 return;
             };
 
-            let (visualizer_type, visualizer_path) =
-                match (meta_item.name_or_empty(), meta_item.value_str()) {
-                    (sym::natvis_file, Some(value)) => (DebuggerVisualizerType::Natvis, value),
-                    (sym::gdb_script_file, Some(value)) => {
-                        (DebuggerVisualizerType::GdbPrettyPrinter, value)
-                    }
-                    (_, _) => {
-                        self.sess.dcx().emit_err(DebugVisualizerInvalid { span: meta_item.span });
-                        return;
-                    }
-                };
+            let (visualizer_type, visualizer_path) = match (meta_item.name(), meta_item.value_str())
+            {
+                (Some(sym::natvis_file), Some(value)) => (DebuggerVisualizerType::Natvis, value),
+                (Some(sym::gdb_script_file), Some(value)) => {
+                    (DebuggerVisualizerType::GdbPrettyPrinter, value)
+                }
+                (_, _) => {
+                    self.sess.dcx().emit_err(DebugVisualizerInvalid { span: meta_item.span });
+                    return;
+                }
+            };
 
             let file = match resolve_path(&self.sess, visualizer_path.as_str(), attr.span) {
                 Ok(file) => file,
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 4e3e0324205..b1b4b9ee927 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -5,7 +5,7 @@ use rustc_ast::Label;
 use rustc_errors::codes::*;
 use rustc_errors::{
     Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level,
-    MultiSpan, SubdiagMessageOp, Subdiagnostic,
+    MultiSpan, Subdiagnostic,
 };
 use rustc_hir::{self as hir, ExprKind, Target};
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@@ -756,7 +756,7 @@ pub(crate) enum MacroExport {
     OnDeclMacro,
 
     #[diag(passes_invalid_macro_export_arguments)]
-    UnknownItem { name: Symbol },
+    InvalidArgument,
 
     #[diag(passes_invalid_macro_export_arguments_too_many_items)]
     TooManyItems,
@@ -1045,11 +1045,10 @@ pub(crate) struct AbiInvalidAttribute {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_unrecognized_field)]
-pub(crate) struct UnrecognizedField {
+#[diag(passes_unrecognized_argument)]
+pub(crate) struct UnrecognizedArgument {
     #[primary_span]
     pub span: Span,
-    pub name: Symbol,
 }
 
 #[derive(Diagnostic)]
@@ -1197,10 +1196,6 @@ pub(crate) struct UnlabeledCfInWhileCondition<'a> {
     pub cf_type: &'a str,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(passes_undefined_naked_function_abi)]
-pub(crate) struct UndefinedNakedFunctionAbi;
-
 #[derive(Diagnostic)]
 #[diag(passes_no_patterns)]
 pub(crate) struct NoPatterns {
@@ -1254,7 +1249,7 @@ pub(crate) struct NakedFunctionIncompatibleAttribute {
     pub span: Span,
     #[label(passes_naked_attribute)]
     pub naked_span: Span,
-    pub attr: Symbol,
+    pub attr: String,
 }
 
 #[derive(Diagnostic)]
@@ -1437,7 +1432,7 @@ pub(crate) struct UselessAssignment<'a> {
 #[derive(LintDiagnostic)]
 #[diag(passes_only_has_effect_on)]
 pub(crate) struct OnlyHasEffectOn {
-    pub attr_name: Symbol,
+    pub attr_name: String,
     pub target_name: String,
 }
 
@@ -1856,11 +1851,7 @@ pub(crate) struct UnusedVariableStringInterp {
 }
 
 impl Subdiagnostic for UnusedVariableStringInterp {
-    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
-        self,
-        diag: &mut Diag<'_, G>,
-        _f: &F,
-    ) {
+    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
         diag.span_label(self.lit, crate::fluent_generated::passes_maybe_string_interpolation);
         diag.multipart_suggestion(
             crate::fluent_generated::passes_string_interpolation_only_works,
diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs
index d4512c9417e..a19faf0fa83 100644
--- a/compiler/rustc_passes/src/layout_test.rs
+++ b/compiler/rustc_passes/src/layout_test.rs
@@ -13,7 +13,7 @@ use rustc_trait_selection::traits;
 
 use crate::errors::{
     LayoutAbi, LayoutAlign, LayoutHomogeneousAggregate, LayoutInvalidAttribute, LayoutOf,
-    LayoutSize, UnrecognizedField,
+    LayoutSize, UnrecognizedArgument,
 };
 
 pub fn test_layout(tcx: TyCtxt<'_>) {
@@ -79,28 +79,28 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
             // The `..` are the names of fields to dump.
             let meta_items = attr.meta_item_list().unwrap_or_default();
             for meta_item in meta_items {
-                match meta_item.name_or_empty() {
+                match meta_item.name() {
                     // FIXME: this never was about ABI and now this dump arg is confusing
-                    sym::abi => {
+                    Some(sym::abi) => {
                         tcx.dcx().emit_err(LayoutAbi {
                             span,
                             abi: format!("{:?}", ty_layout.backend_repr),
                         });
                     }
 
-                    sym::align => {
+                    Some(sym::align) => {
                         tcx.dcx().emit_err(LayoutAlign {
                             span,
                             align: format!("{:?}", ty_layout.align),
                         });
                     }
 
-                    sym::size => {
+                    Some(sym::size) => {
                         tcx.dcx()
                             .emit_err(LayoutSize { span, size: format!("{:?}", ty_layout.size) });
                     }
 
-                    sym::homogeneous_aggregate => {
+                    Some(sym::homogeneous_aggregate) => {
                         tcx.dcx().emit_err(LayoutHomogeneousAggregate {
                             span,
                             homogeneous_aggregate: format!(
@@ -111,15 +111,15 @@ fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
                         });
                     }
 
-                    sym::debug => {
+                    Some(sym::debug) => {
                         let normalized_ty = tcx.normalize_erasing_regions(typing_env, ty);
                         // FIXME: using the `Debug` impl here isn't ideal.
                         let ty_layout = format!("{:#?}", *ty_layout);
                         tcx.dcx().emit_err(LayoutOf { span, normalized_ty, ty_layout });
                     }
 
-                    name => {
-                        tcx.dcx().emit_err(UnrecognizedField { span: meta_item.span(), name });
+                    _ => {
+                        tcx.dcx().emit_err(UnrecognizedArgument { span: meta_item.span() });
                     }
                 }
             }
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 6f6115af96c..424bce9d4d4 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -6,10 +6,10 @@
 
 // tidy-alphabetical-start
 #![allow(internal_features)]
-#![cfg_attr(doc, recursion_limit = "256")] // FIXME(nnethercote): will be removed by #124141
+#![cfg_attr(bootstrap, feature(let_chains))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
-#![feature(let_chains)]
+#![feature(box_patterns)]
 #![feature(map_try_insert)]
 #![feature(rustdoc_internals)]
 #![feature(try_blocks)]
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index 06eb76c30c5..4e9b7fd44d4 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -578,8 +578,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     where
         F: FnMut(Variable) -> bool,
     {
-        for var_idx in 0..self.ir.var_kinds.len() {
-            let var = Variable::from(var_idx);
+        for var in self.ir.var_kinds.indices() {
             if test(var) {
                 write!(wr, " {var:?}")?;
             }
@@ -609,8 +608,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         debug!(
             "^^ liveness computation results for body {} (entry={:?})",
             {
-                for ln_idx in 0..self.ir.lnks.len() {
-                    debug!("{:?}", self.ln_str(LiveNode::from(ln_idx)));
+                for ln_idx in self.ir.lnks.indices() {
+                    debug!("{:?}", self.ln_str(ln_idx));
                 }
                 hir_id
             },
@@ -1021,7 +1020,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
             }
 
             hir::ExprKind::Call(ref f, args) => {
-                let succ = self.check_is_ty_uninhabited(expr, succ);
+                let is_ctor = |f: &Expr<'_>| matches!(f.kind, hir::ExprKind::Path(hir::QPath::Resolved(_, path)) if matches!(path.res, rustc_hir::def::Res::Def(rustc_hir::def::DefKind::Ctor(_, _), _)));
+                let succ =
+                    if !is_ctor(f) { self.check_is_ty_uninhabited(expr, succ) } else { succ };
+
                 let succ = self.propagate_through_exprs(args, succ);
                 self.propagate_through_expr(f, succ)
             }
diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs
index d35aedf9a56..3c9f8b72c36 100644
--- a/compiler/rustc_passes/src/naked_functions.rs
+++ b/compiler/rustc_passes/src/naked_functions.rs
@@ -1,6 +1,5 @@
 //! Checks validity of naked functions.
 
-use rustc_abi::ExternAbi;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{LocalDefId, LocalModDefId};
@@ -10,12 +9,11 @@ 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, sym};
 
 use crate::errors::{
     NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns,
-    ParamsNotAllowed, UndefinedNakedFunctionAbi,
+    ParamsNotAllowed,
 };
 
 pub(crate) fn provide(providers: &mut Providers) {
@@ -29,26 +27,21 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
             continue;
         }
 
-        let (fn_header, body_id) = match tcx.hir_node_by_def_id(def_id) {
+        let body = match tcx.hir_node_by_def_id(def_id) {
             hir::Node::Item(hir::Item {
-                kind: hir::ItemKind::Fn { sig, body: body_id, .. },
-                ..
+                kind: hir::ItemKind::Fn { body: body_id, .. }, ..
             })
             | hir::Node::TraitItem(hir::TraitItem {
-                kind: hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)),
+                kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)),
                 ..
             })
             | hir::Node::ImplItem(hir::ImplItem {
-                kind: hir::ImplItemKind::Fn(sig, body_id),
-                ..
-            }) => (sig.header, *body_id),
+                kind: hir::ImplItemKind::Fn(_, body_id), ..
+            }) => tcx.hir_body(*body_id),
             _ => continue,
         };
 
-        let body = tcx.hir_body(body_id);
-
         if tcx.has_attr(def_id, sym::naked) {
-            check_abi(tcx, def_id, fn_header.abi);
             check_no_patterns(tcx, body.params);
             check_no_parameters_use(tcx, body);
             check_asm(tcx, def_id, body);
@@ -60,20 +53,6 @@ fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     }
 }
 
-/// Checks that function uses non-Rust ABI.
-fn check_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, abi: ExternAbi) {
-    if abi == ExternAbi::Rust {
-        let hir_id = tcx.local_def_id_to_hir_id(def_id);
-        let span = tcx.def_span(def_id);
-        tcx.emit_node_span_lint(
-            UNDEFINED_NAKED_FUNCTION_ABI,
-            hir_id,
-            span,
-            UndefinedNakedFunctionAbi,
-        );
-    }
-}
-
 /// Checks that parameters don't use patterns. Mirrors the checks for function declarations.
 fn check_no_patterns(tcx: TyCtxt<'_>, params: &[hir::Param<'_>]) {
     for param in params {