about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs189
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs25
-rw-r--r--compiler/rustc_codegen_ssa/src/common.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs437
-rw-r--r--compiler/rustc_codegen_ssa/src/meth.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs15
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs11
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs64
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs2
15 files changed, 607 insertions, 182 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index a1c77ec0cfc..8ca7103ed48 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -11,7 +11,7 @@ use rustc_metadata::find_native_static_library;
 use rustc_metadata::fs::{emit_wrapper_file, METADATA_FILENAME};
 use rustc_middle::middle::dependency_format::Linkage;
 use rustc_middle::middle::exported_symbols::SymbolExportKind;
-use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Lto, Strip};
+use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
 use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SplitDwarfKind};
 use rustc_session::cstore::DllImport;
 use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
@@ -208,16 +208,16 @@ pub fn link_binary<'a>(
     Ok(())
 }
 
+// Crate type is not passed when calculating the dylibs to include for LTO. In that case all
+// crate types must use the same dependency formats.
 pub fn each_linked_rlib(
-    sess: &Session,
     info: &CrateInfo,
+    crate_type: Option<CrateType>,
     f: &mut dyn FnMut(CrateNum, &Path),
 ) -> Result<(), errors::LinkRlibError> {
     let crates = info.used_crates.iter();
-    let mut fmts = None;
 
-    let lto_active = matches!(sess.lto(), Lto::Fat | Lto::Thin);
-    if lto_active {
+    let fmts = if crate_type.is_none() {
         for combination in info.dependency_formats.iter().combinations(2) {
             let (ty1, list1) = &combination[0];
             let (ty2, list2) = &combination[1];
@@ -230,27 +230,23 @@ pub fn each_linked_rlib(
                 });
             }
         }
-    }
-
-    for (ty, list) in info.dependency_formats.iter() {
-        match ty {
-            CrateType::Executable
-            | CrateType::Staticlib
-            | CrateType::Cdylib
-            | CrateType::ProcMacro => {
-                fmts = Some(list);
-                break;
-            }
-            CrateType::Dylib if lto_active => {
-                fmts = Some(list);
-                break;
-            }
-            _ => {}
+        if info.dependency_formats.is_empty() {
+            return Err(errors::LinkRlibError::MissingFormat);
         }
-    }
-    let Some(fmts) = fmts else {
-        return Err(errors::LinkRlibError::MissingFormat);
+        &info.dependency_formats[0].1
+    } else {
+        let fmts = info
+            .dependency_formats
+            .iter()
+            .find_map(|&(ty, ref list)| if Some(ty) == crate_type { Some(list) } else { None });
+
+        let Some(fmts) = fmts else {
+            return Err(errors::LinkRlibError::MissingFormat);
+        };
+
+        fmts
     };
+
     for &cnum in crates {
         match fmts.get(cnum.as_usize() - 1) {
             Some(&Linkage::NotLinked | &Linkage::Dynamic | &Linkage::IncludedFromDylib) => continue,
@@ -516,64 +512,71 @@ fn link_staticlib<'a>(
     )?;
     let mut all_native_libs = vec![];
 
-    let res = each_linked_rlib(sess, &codegen_results.crate_info, &mut |cnum, path| {
-        let name = codegen_results.crate_info.crate_name[&cnum];
-        let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
-
-        // Here when we include the rlib into our staticlib we need to make a
-        // decision whether to include the extra object files along the way.
-        // These extra object files come from statically included native
-        // libraries, but they may be cfg'd away with #[link(cfg(..))].
-        //
-        // This unstable feature, though, only needs liblibc to work. The only
-        // use case there is where musl is statically included in liblibc.rlib,
-        // so if we don't want the included version we just need to skip it. As
-        // a result the logic here is that if *any* linked library is cfg'd away
-        // we just skip all object files.
-        //
-        // Clearly this is not sufficient for a general purpose feature, and
-        // we'd want to read from the library's metadata to determine which
-        // object files come from where and selectively skip them.
-        let skip_object_files = native_libs.iter().any(|lib| {
-            matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
-                && !relevant_lib(sess, lib)
-        });
+    let res = each_linked_rlib(
+        &codegen_results.crate_info,
+        Some(CrateType::Staticlib),
+        &mut |cnum, path| {
+            let name = codegen_results.crate_info.crate_name[&cnum];
+            let native_libs = &codegen_results.crate_info.native_libraries[&cnum];
+
+            // Here when we include the rlib into our staticlib we need to make a
+            // decision whether to include the extra object files along the way.
+            // These extra object files come from statically included native
+            // libraries, but they may be cfg'd away with #[link(cfg(..))].
+            //
+            // This unstable feature, though, only needs liblibc to work. The only
+            // use case there is where musl is statically included in liblibc.rlib,
+            // so if we don't want the included version we just need to skip it. As
+            // a result the logic here is that if *any* linked library is cfg'd away
+            // we just skip all object files.
+            //
+            // Clearly this is not sufficient for a general purpose feature, and
+            // we'd want to read from the library's metadata to determine which
+            // object files come from where and selectively skip them.
+            let skip_object_files = native_libs.iter().any(|lib| {
+                matches!(lib.kind, NativeLibKind::Static { bundle: None | Some(true), .. })
+                    && !relevant_lib(sess, lib)
+            });
 
-        let lto = are_upstream_rust_objects_already_included(sess)
-            && !ignored_for_lto(sess, &codegen_results.crate_info, cnum);
+            let lto = are_upstream_rust_objects_already_included(sess)
+                && !ignored_for_lto(sess, &codegen_results.crate_info, cnum);
 
-        // Ignoring obj file starting with the crate name
-        // as simple comparison is not enough - there
-        // might be also an extra name suffix
-        let obj_start = name.as_str().to_owned();
+            // Ignoring obj file starting with the crate name
+            // as simple comparison is not enough - there
+            // might be also an extra name suffix
+            let obj_start = name.as_str().to_owned();
 
-        ab.add_archive(
-            path,
-            Box::new(move |fname: &str| {
-                // Ignore metadata files, no matter the name.
-                if fname == METADATA_FILENAME {
-                    return true;
-                }
+            ab.add_archive(
+                path,
+                Box::new(move |fname: &str| {
+                    // Ignore metadata files, no matter the name.
+                    if fname == METADATA_FILENAME {
+                        return true;
+                    }
 
-                // Don't include Rust objects if LTO is enabled
-                if lto && looks_like_rust_object_file(fname) {
-                    return true;
-                }
+                    // Don't include Rust objects if LTO is enabled
+                    if lto && looks_like_rust_object_file(fname) {
+                        return true;
+                    }
 
-                // Otherwise if this is *not* a rust object and we're skipping
-                // objects then skip this file
-                if skip_object_files && (!fname.starts_with(&obj_start) || !fname.ends_with(".o")) {
-                    return true;
-                }
+                    // Otherwise if this is *not* a rust object and we're skipping
+                    // objects then skip this file
+                    if skip_object_files
+                        && (!fname.starts_with(&obj_start) || !fname.ends_with(".o"))
+                    {
+                        return true;
+                    }
 
-                // ok, don't skip this
-                false
-            }),
-        )
-        .unwrap();
+                    // ok, don't skip this
+                    false
+                }),
+            )
+            .unwrap();
 
-        all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
-    });
+            all_native_libs
+                .extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned());
+        },
+    );
     if let Err(e) = res {
         sess.emit_fatal(e);
     }
@@ -607,21 +610,21 @@ fn link_dwarf_object<'a>(
     }
 
     impl<Relocations> ThorinSession<Relocations> {
-        fn alloc_mmap<'arena>(&'arena self, data: Mmap) -> &'arena Mmap {
+        fn alloc_mmap(&self, data: Mmap) -> &Mmap {
             (*self.arena_mmap.alloc(data)).borrow()
         }
     }
 
     impl<Relocations> thorin::Session<Relocations> for ThorinSession<Relocations> {
-        fn alloc_data<'arena>(&'arena self, data: Vec<u8>) -> &'arena [u8] {
+        fn alloc_data(&self, data: Vec<u8>) -> &[u8] {
             (*self.arena_data.alloc(data)).borrow()
         }
 
-        fn alloc_relocation<'arena>(&'arena self, data: Relocations) -> &'arena Relocations {
+        fn alloc_relocation(&self, data: Relocations) -> &Relocations {
             (*self.arena_relocations.alloc(data)).borrow()
         }
 
-        fn read_input<'arena>(&'arena self, path: &Path) -> std::io::Result<&'arena [u8]> {
+        fn read_input(&self, path: &Path) -> std::io::Result<&[u8]> {
             let file = File::open(&path)?;
             let mmap = (unsafe { Mmap::map(file) })?;
             Ok(self.alloc_mmap(mmap))
@@ -1354,7 +1357,8 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
     if !lib_args.is_empty() {
         sess.emit_note(errors::StaticLibraryNativeArtifacts);
         // Prefix for greppability
-        sess.emit_note(errors::NativeStaticLibs { arguments: lib_args.join(" ") });
+        // Note: This must not be translated as tools are allowed to depend on this exact string.
+        sess.note_without_error(&format!("native-static-libs: {}", &lib_args.join(" ")));
     }
 }
 
@@ -2612,7 +2616,7 @@ fn add_static_crate<'a>(
             sess.target.no_builtins || !codegen_results.crate_info.is_no_builtins.contains(&cnum);
 
         let mut archive = archive_builder_builder.new_archive_builder(sess);
-        if let Err(e) = archive.add_archive(
+        if let Err(error) = archive.add_archive(
             cratepath,
             Box::new(move |f| {
                 if f == METADATA_FILENAME {
@@ -2652,7 +2656,7 @@ fn add_static_crate<'a>(
                 false
             }),
         ) {
-            sess.fatal(&format!("failed to build archive from rlib: {}", e));
+            sess.emit_fatal(errors::RlibArchiveBuildFailure { error });
         }
         if archive.build(&dst) {
             link_upstream(&dst);
@@ -2822,11 +2826,30 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
                     // Implement the "linker flavor" part of -Zgcc-ld
                     // by asking cc to use some kind of lld.
                     cmd.arg("-fuse-ld=lld");
+
                     if !flavor.is_gnu() {
                         // Tell clang to use a non-default LLD flavor.
                         // Gcc doesn't understand the target option, but we currently assume
                         // that gcc is not used for Apple and Wasm targets (#97402).
-                        cmd.arg(format!("--target={}", sess.target.llvm_target));
+                        //
+                        // Note that we don't want to do that by default on macOS: e.g. passing a
+                        // 10.7 target to LLVM works, but not to recent versions of clang/macOS, as
+                        // shown in issue #101653 and the discussion in PR #101792.
+                        //
+                        // It could be required in some cases of cross-compiling with
+                        // `-Zgcc-ld=lld`, but this is generally unspecified, and we don't know
+                        // which specific versions of clang, macOS SDK, host and target OS
+                        // combinations impact us here.
+                        //
+                        // So we do a simple first-approximation until we know more of what the
+                        // Apple targets require (and which would be handled prior to hitting this
+                        // `-Zgcc-ld=lld` codepath anyway), but the expectation is that until then
+                        // this should be manually passed if needed. We specify the target when
+                        // targeting a different linker flavor on macOS, and that's also always
+                        // the case when targeting WASM.
+                        if sess.target.linker_flavor != sess.host.linker_flavor {
+                            cmd.arg(format!("--target={}", sess.target.llvm_target));
+                        }
                     }
                 }
             }
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 22f534d909a..8cb7d74b90d 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -163,10 +163,10 @@ fn is_reachable_non_generic_provider_extern(tcx: TyCtxt<'_>, def_id: DefId) -> b
     tcx.reachable_non_generics(def_id.krate).contains_key(&def_id)
 }
 
-fn exported_symbols_provider_local<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn exported_symbols_provider_local(
+    tcx: TyCtxt<'_>,
     cnum: CrateNum,
-) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
+) -> &[(ExportedSymbol<'_>, SymbolExportInfo)] {
     assert_eq!(cnum, LOCAL_CRATE);
 
     if !tcx.sess.opts.output_types.should_codegen() {
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 12fca64968a..7aadcdd2228 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -1002,7 +1002,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
     let sess = tcx.sess;
 
     let mut each_linked_rlib_for_lto = Vec::new();
-    drop(link::each_linked_rlib(sess, crate_info, &mut |cnum, path| {
+    drop(link::each_linked_rlib(crate_info, None, &mut |cnum, path| {
         if link::ignored_for_lto(sess, crate_info, cnum) {
             return;
         }
@@ -1899,7 +1899,7 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
 
         // FIXME: time_llvm_passes support - does this use a global context or
         // something?
-        if sess.codegen_units() == 1 && sess.time_llvm_passes() {
+        if sess.codegen_units() == 1 && sess.opts.unstable_opts.time_llvm_passes {
             self.backend.print_pass_timings()
         }
 
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 664697e0eda..d318c15d342 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -5,6 +5,7 @@ use crate::back::write::{
     submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm, ComputedLtoType, OngoingCodegen,
 };
 use crate::common::{IntPredicate, RealPredicate, TypeKind};
+use crate::errors;
 use crate::meth;
 use crate::mir;
 use crate::mir::operand::OperandValue;
@@ -451,10 +452,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         let Some(llfn) = cx.declare_c_main(llfty) else {
             // FIXME: We should be smart and show a better diagnostic here.
             let span = cx.tcx().def_span(rust_main_def_id);
-            cx.sess()
-                .struct_span_err(span, "entry symbol `main` declared multiple times")
-                .help("did you use `#[no_mangle]` on `fn main`? Use `#[start]` instead")
-                .emit();
+            cx.sess().emit_err(errors::MultipleMainFunctions { span });
             cx.sess().abort_if_errors();
             bug!();
         };
@@ -595,8 +593,8 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
                 &metadata,
                 &exported_symbols::metadata_symbol_name(tcx),
             );
-            if let Err(err) = std::fs::write(&file_name, data) {
-                tcx.sess.fatal(&format!("error writing metadata object file: {}", err));
+            if let Err(error) = std::fs::write(&file_name, data) {
+                tcx.sess.emit_fatal(errors::MetadataObjectFileWrite { error });
             }
             Some(CompiledModule {
                 name: metadata_cgu_name,
@@ -681,7 +679,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
     });
 
     let mut total_codegen_time = Duration::new(0, 0);
-    let start_rss = tcx.sess.time_passes().then(|| get_resident_set_size());
+    let start_rss = tcx.sess.opts.unstable_opts.time_passes.then(|| get_resident_set_size());
 
     // The non-parallel compiler can only translate codegen units to LLVM IR
     // on a single thread, leading to a staircase effect where the N LLVM
@@ -781,7 +779,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
 
     // Since the main thread is sometimes blocked during codegen, we keep track
     // -Ztime-passes output manually.
-    if tcx.sess.time_passes() {
+    if tcx.sess.opts.unstable_opts.time_passes {
         let end_rss = get_resident_set_size();
 
         print_time_passes_entry(
@@ -815,11 +813,7 @@ impl CrateInfo {
         let subsystem = tcx.sess.first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem);
         let windows_subsystem = subsystem.map(|subsystem| {
             if subsystem != sym::windows && subsystem != sym::console {
-                tcx.sess.fatal(&format!(
-                    "invalid windows subsystem `{}`, only \
-                                     `windows` and `console` are allowed",
-                    subsystem
-                ));
+                tcx.sess.emit_fatal(errors::InvalidWindowsSubsystem { subsystem });
             }
             subsystem.to_string()
         });
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index c7f2e1966c1..b0fa7745667 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -2,6 +2,7 @@ use rustc_ast::{ast, MetaItemKind, NestedMetaItem};
 use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr};
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
 use rustc_hir::{lang_items, weak_lang_items::WEAK_LANG_ITEMS, LangItem};
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
@@ -60,6 +61,21 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
 
     let supported_target_features = tcx.supported_target_features(LOCAL_CRATE);
 
+    // In some cases, attribute are only valid on functions, but it's the `check_attr`
+    // pass that check that they aren't used anywhere else, rather this module.
+    // In these cases, we bail from performing further checks that are only meaningful for
+    // functions (such as calling `fn_sig`, which ICEs if given a non-function). We also
+    // report a delayed bug, just in case `check_attr` isn't doing its job.
+    let validate_fn_only_attr = |attr_sp| -> bool {
+        let def_kind = tcx.def_kind(did);
+        if let DefKind::Fn | DefKind::AssocFn | DefKind::Variant | DefKind::Ctor(..) = def_kind {
+            true
+        } else {
+            tcx.sess.delay_span_bug(attr_sp, "this attribute can only be applied to functions");
+            false
+        }
+    };
+
     let mut inline_span = None;
     let mut link_ordinal_span = None;
     let mut no_sanitize_span = None;
@@ -197,7 +213,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
                 }
             }
         } else if attr.has_name(sym::cmse_nonsecure_entry) {
-            if !matches!(tcx.fn_sig(did).abi(), abi::Abi::C { .. }) {
+            if validate_fn_only_attr(attr.span)
+                && !matches!(tcx.fn_sig(did).abi(), abi::Abi::C { .. })
+            {
                 struct_span_err!(
                     tcx.sess,
                     attr.span,
@@ -214,7 +232,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
         } else if attr.has_name(sym::thread_local) {
             codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL;
         } else if attr.has_name(sym::track_caller) {
-            if !tcx.is_closure(did.to_def_id()) && tcx.fn_sig(did).abi() != abi::Abi::Rust {
+            if !tcx.is_closure(did.to_def_id())
+                && validate_fn_only_attr(attr.span)
+                && tcx.fn_sig(did).abi() != abi::Abi::Rust
+            {
                 struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI")
                     .emit();
             }
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs
index 71f9179d02c..e1abb73a504 100644
--- a/compiler/rustc_codegen_ssa/src/common.rs
+++ b/compiler/rustc_codegen_ssa/src/common.rs
@@ -1,10 +1,8 @@
 #![allow(non_camel_case_types)]
 
-use rustc_errors::struct_span_err;
 use rustc_hir::LangItem;
 use rustc_middle::mir::interpret::ConstValue;
 use rustc_middle::ty::{self, layout::TyAndLayout, Ty, TyCtxt};
-use rustc_session::Session;
 use rustc_span::Span;
 
 use crate::base;
@@ -193,10 +191,6 @@ pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     }
 }
 
-pub fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
-    struct_span_err!(a, b, E0511, "{}", c).emit();
-}
-
 pub fn asm_const_to_str<'tcx>(
     tcx: TyCtxt<'tcx>,
     sp: Span,
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs
index 6e3f4f0b8ef..60e9b40e8fb 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs
@@ -10,7 +10,7 @@ pub mod type_names;
 /// NOTE: This is somewhat inconsistent right now: For empty enums and enums with a single
 ///       fieldless variant, we generate DW_TAG_struct_type, although a
 ///       DW_TAG_enumeration_type would be a better fit.
-pub fn wants_c_like_enum_debuginfo<'tcx>(enum_type_and_layout: TyAndLayout<'tcx>) -> bool {
+pub fn wants_c_like_enum_debuginfo(enum_type_and_layout: TyAndLayout<'_>) -> bool {
     match enum_type_and_layout.ty.kind() {
         ty::Adt(adt_def, _) => {
             if !adt_def.is_enum() {
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index 819c2678d6c..1599ccbb259 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -93,6 +93,7 @@ fn push_debuginfo_type_name<'tcx>(
                     Err(e) => {
                         // Computing the layout can still fail here, e.g. if the target architecture
                         // cannot represent the type. See https://github.com/rust-lang/rust/issues/94961.
+                        // FIXME: migrate once `rustc_middle::mir::interpret::InterpError` is translatable.
                         tcx.sess.fatal(&format!("{}", e));
                     }
                 }
@@ -509,7 +510,7 @@ pub fn compute_debuginfo_vtable_name<'tcx>(
         visited.clear();
         push_generic_params_internal(tcx, trait_ref.substs, &mut vtable_name, &mut visited);
     } else {
-        vtable_name.push_str("_");
+        vtable_name.push('_');
     }
 
     push_close_angle_bracket(cpp_like_debuginfo, &mut vtable_name);
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 0620000201f..d81252653df 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -6,7 +6,9 @@ use rustc_errors::{
     IntoDiagnosticArg,
 };
 use rustc_macros::Diagnostic;
+use rustc_middle::ty::Ty;
 use rustc_span::{Span, Symbol};
+use rustc_type_ir::FloatTy;
 use std::borrow::Cow;
 use std::io::Error;
 use std::path::{Path, PathBuf};
@@ -445,12 +447,6 @@ pub struct LinkerFileStem;
 pub struct StaticLibraryNativeArtifacts;
 
 #[derive(Diagnostic)]
-#[diag(codegen_ssa_native_static_libs)]
-pub struct NativeStaticLibs {
-    pub arguments: String,
-}
-
-#[derive(Diagnostic)]
 #[diag(codegen_ssa_link_script_unavailable)]
 pub struct LinkScriptUnavailable;
 
@@ -555,3 +551,432 @@ pub struct ExpectedUsedSymbol {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_multiple_main_functions)]
+#[help]
+pub struct MultipleMainFunctions {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_metadata_object_file_write)]
+pub struct MetadataObjectFileWrite {
+    pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_invalid_windows_subsystem)]
+pub struct InvalidWindowsSubsystem {
+    pub subsystem: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_erroneous_constant)]
+pub struct ErroneousConstant {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_polymorphic_constant_too_generic)]
+pub struct PolymorphicConstantTooGeneric {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_shuffle_indices_evaluation)]
+pub struct ShuffleIndicesEvaluation {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_missing_memory_ordering)]
+pub struct MissingMemoryOrdering;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_unknown_atomic_ordering)]
+pub struct UnknownAtomicOrdering;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_atomic_compare_exchange)]
+pub struct AtomicCompareExchange;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_unknown_atomic_operation)]
+pub struct UnknownAtomicOperation;
+
+#[derive(Diagnostic)]
+pub enum InvalidMonomorphization<'tcx> {
+    #[diag(codegen_ssa_invalid_monomorphization_basic_integer_type, code = "E0511")]
+    BasicIntegerType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_basic_float_type, code = "E0511")]
+    BasicFloatType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_float_to_int_unchecked, code = "E0511")]
+    FloatToIntUnchecked {
+        #[primary_span]
+        span: Span,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_floating_point_vector, code = "E0511")]
+    FloatingPointVector {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        f_ty: FloatTy,
+        in_ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_floating_point_type, code = "E0511")]
+    FloatingPointType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_unrecognized_intrinsic, code = "E0511")]
+    UnrecognizedIntrinsic {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_simd_argument, code = "E0511")]
+    SimdArgument {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_simd_input, code = "E0511")]
+    SimdInput {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_simd_first, code = "E0511")]
+    SimdFirst {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_simd_second, code = "E0511")]
+    SimdSecond {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_simd_third, code = "E0511")]
+    SimdThird {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_simd_return, code = "E0511")]
+    SimdReturn {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_invalid_bitmask, code = "E0511")]
+    InvalidBitmask {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        mask_ty: Ty<'tcx>,
+        expected_int_bits: u64,
+        expected_bytes: u64,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_return_length_input_type, code = "E0511")]
+    ReturnLengthInputType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_len: u64,
+        in_ty: Ty<'tcx>,
+        ret_ty: Ty<'tcx>,
+        out_len: u64,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_second_argument_length, code = "E0511")]
+    SecondArgumentLength {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_len: u64,
+        in_ty: Ty<'tcx>,
+        arg_ty: Ty<'tcx>,
+        out_len: u64,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_third_argument_length, code = "E0511")]
+    ThirdArgumentLength {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_len: u64,
+        in_ty: Ty<'tcx>,
+        arg_ty: Ty<'tcx>,
+        out_len: u64,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_return_integer_type, code = "E0511")]
+    ReturnIntegerType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ret_ty: Ty<'tcx>,
+        out_ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_simd_shuffle, code = "E0511")]
+    SimdShuffle {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_return_length, code = "E0511")]
+    ReturnLength {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_len: u64,
+        ret_ty: Ty<'tcx>,
+        out_len: u64,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_return_element, code = "E0511")]
+    ReturnElement {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_elem: Ty<'tcx>,
+        in_ty: Ty<'tcx>,
+        ret_ty: Ty<'tcx>,
+        out_ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_not_constant, code = "E0511")]
+    ShuffleIndexNotConstant {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        arg_idx: u64,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_shuffle_index_out_of_bounds, code = "E0511")]
+    ShuffleIndexOutOfBounds {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        arg_idx: u64,
+        total_len: u128,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_inserted_type, code = "E0511")]
+    InsertedType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_elem: Ty<'tcx>,
+        in_ty: Ty<'tcx>,
+        out_ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_return_type, code = "E0511")]
+    ReturnType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_elem: Ty<'tcx>,
+        in_ty: Ty<'tcx>,
+        ret_ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_expected_return_type, code = "E0511")]
+    ExpectedReturnType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_ty: Ty<'tcx>,
+        ret_ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_mismatched_lengths, code = "E0511")]
+    MismatchedLengths {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        m_len: u64,
+        v_len: u64,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_mask_type, code = "E0511")]
+    MaskType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_vector_argument, code = "E0511")]
+    VectorArgument {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_ty: Ty<'tcx>,
+        in_elem: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_cannot_return, code = "E0511")]
+    CannotReturn {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ret_ty: Ty<'tcx>,
+        expected_int_bits: u64,
+        expected_bytes: u64,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_expected_element_type, code = "E0511")]
+    ExpectedElementType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        expected_element: Ty<'tcx>,
+        second_arg: Ty<'tcx>,
+        in_elem: Ty<'tcx>,
+        in_ty: Ty<'tcx>,
+        mutability: ExpectedPointerMutability,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_third_arg_element_type, code = "E0511")]
+    ThirdArgElementType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        expected_element: Ty<'tcx>,
+        third_arg: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size, code = "E0511")]
+    UnsupportedSymbolOfSize {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        symbol: Symbol,
+        in_ty: Ty<'tcx>,
+        in_elem: Ty<'tcx>,
+        size: u64,
+        ret_ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_symbol, code = "E0511")]
+    UnsupportedSymbol {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        symbol: Symbol,
+        in_ty: Ty<'tcx>,
+        in_elem: Ty<'tcx>,
+        ret_ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_cast_fat_pointer, code = "E0511")]
+    CastFatPointer {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_expected_pointer, code = "E0511")]
+    ExpectedPointer {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_expected_usize, code = "E0511")]
+    ExpectedUsize {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        ty: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_cast, code = "E0511")]
+    UnsupportedCast {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_ty: Ty<'tcx>,
+        in_elem: Ty<'tcx>,
+        ret_ty: Ty<'tcx>,
+        out_elem: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_unsupported_operation, code = "E0511")]
+    UnsupportedOperation {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        in_ty: Ty<'tcx>,
+        in_elem: Ty<'tcx>,
+    },
+
+    #[diag(codegen_ssa_invalid_monomorphization_expected_vector_element_type, code = "E0511")]
+    ExpectedVectorElementType {
+        #[primary_span]
+        span: Span,
+        name: Symbol,
+        expected_element: Ty<'tcx>,
+        vector_type: Ty<'tcx>,
+    },
+}
+
+pub enum ExpectedPointerMutability {
+    Mut,
+    Not,
+}
+
+impl IntoDiagnosticArg for ExpectedPointerMutability {
+    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
+        match self {
+            ExpectedPointerMutability::Mut => DiagnosticArgValue::Str(Cow::Borrowed("*mut")),
+            ExpectedPointerMutability::Not => DiagnosticArgValue::Str(Cow::Borrowed("*_")),
+        }
+    }
+}
diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs
index d96ca921f1f..2421acab471 100644
--- a/compiler/rustc_codegen_ssa/src/meth.rs
+++ b/compiler/rustc_codegen_ssa/src/meth.rs
@@ -65,7 +65,7 @@ impl<'a, 'tcx> VirtualIndex {
 
 /// This takes a valid `self` receiver type and extracts the principal trait
 /// ref of the type.
-fn expect_dyn_trait_in_self<'tcx>(ty: Ty<'tcx>) -> ty::PolyExistentialTraitRef<'tcx> {
+fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> {
     for arg in ty.peel_refs().walk() {
         if let GenericArgKind::Type(ty) = arg.unpack() {
             if let ty::Dynamic(data, _, _) = ty.kind() {
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index c7617d2e464..dd1ac2c74ae 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -261,6 +261,9 @@ impl CleanupKind {
     }
 }
 
+/// MSVC requires unwinding code to be split to a tree of *funclets*, where each funclet can only
+/// branch to itself or to its parent. Luckily, the code we generates matches this pattern.
+/// Recover that structure in an analyze pass.
 pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKind> {
     fn discover_masters<'tcx>(
         result: &mut IndexVec<mir::BasicBlock, CleanupKind>,
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 3860138018b..978aff511bf 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -637,7 +637,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         self.set_debug_loc(bx, terminator.source_info);
 
         // Obtain the panic entry point.
-        let (fn_abi, llfn) = common::build_langcall(bx, Some(span), LangItem::PanicNoUnwind);
+        let (fn_abi, llfn) = common::build_langcall(bx, Some(span), LangItem::PanicCannotUnwind);
 
         // Codegen the actual panic invoke/call.
         let merging_succ = helper.do_call(self, bx, fn_abi, llfn, &[], None, None, &[], false);
@@ -663,12 +663,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         enum AssertIntrinsic {
             Inhabited,
             ZeroValid,
-            UninitValid,
+            MemUninitializedValid,
         }
         let panic_intrinsic = intrinsic.and_then(|i| match i {
             sym::assert_inhabited => Some(AssertIntrinsic::Inhabited),
             sym::assert_zero_valid => Some(AssertIntrinsic::ZeroValid),
-            sym::assert_uninit_valid => Some(AssertIntrinsic::UninitValid),
+            sym::assert_mem_uninitialized_valid => Some(AssertIntrinsic::MemUninitializedValid),
             _ => None,
         });
         if let Some(intrinsic) = panic_intrinsic {
@@ -679,7 +679,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             let do_panic = match intrinsic {
                 Inhabited => layout.abi.is_uninhabited(),
                 ZeroValid => !bx.tcx().permits_zero_init(layout),
-                UninitValid => !bx.tcx().permits_uninit_init(layout),
+                MemUninitializedValid => !bx.tcx().permits_uninit_init(layout),
             };
             Some(if do_panic {
                 let msg_str = with_no_visible_paths!({
@@ -698,11 +698,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     })
                 });
                 let msg = bx.const_str(&msg_str);
-                let location = self.get_caller_location(bx, source_info).immediate();
 
                 // Obtain the panic entry point.
                 let (fn_abi, llfn) =
-                    common::build_langcall(bx, Some(source_info.span), LangItem::Panic);
+                    common::build_langcall(bx, Some(source_info.span), LangItem::PanicNounwind);
 
                 // Codegen the actual panic invoke/call.
                 helper.do_call(
@@ -710,7 +709,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     bx,
                     fn_abi,
                     llfn,
-                    &[msg.0, msg.1, location],
+                    &[msg.0, msg.1],
                     target.as_ref().map(|bb| (ReturnDest::Nothing, *bb)),
                     cleanup,
                     &[],
@@ -1665,7 +1664,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             let llpersonality = self.cx.eh_personality();
             bx.cleanup_landing_pad(llpersonality);
 
-            let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicNoUnwind);
+            let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicCannotUnwind);
             let fn_ty = bx.fn_decl_backend_type(&fn_abi);
 
             let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &[], None);
diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index 53ff3c24096..14fe84a146d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
@@ -1,3 +1,4 @@
+use crate::errors;
 use crate::mir::operand::OperandRef;
 use crate::traits::*;
 use rustc_middle::mir;
@@ -44,10 +45,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         self.cx.tcx().const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).map_err(|err| {
             match err {
                 ErrorHandled::Reported(_) => {
-                    self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
+                    self.cx.tcx().sess.emit_err(errors::ErroneousConstant { span: constant.span });
                 }
                 ErrorHandled::TooGeneric => {
-                    span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err);
+                    self.cx
+                        .tcx()
+                        .sess
+                        .diagnostic()
+                        .emit_bug(errors::PolymorphicConstantTooGeneric { span: constant.span });
                 }
             }
             err
@@ -87,7 +92,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 (llval, c.ty())
             })
             .unwrap_or_else(|_| {
-                bx.tcx().sess.span_err(span, "could not evaluate shuffle_indices at compile time");
+                bx.tcx().sess.emit_err(errors::ShuffleIndicesEvaluation { span });
                 // We've errored, so we don't have to produce working code.
                 let ty = self.monomorphize(ty);
                 let llty = bx.backend_type(bx.layout_of(ty));
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index a75609260ed..766dc74cbbb 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -1,7 +1,9 @@
 use super::operand::{OperandRef, OperandValue};
 use super::place::PlaceRef;
 use super::FunctionCx;
-use crate::common::{span_invalid_monomorphization_error, IntPredicate};
+use crate::common::IntPredicate;
+use crate::errors;
+use crate::errors::InvalidMonomorphization;
 use crate::glue;
 use crate::meth;
 use crate::traits::*;
@@ -305,15 +307,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         _ => bug!(),
                     },
                     None => {
-                        span_invalid_monomorphization_error(
-                            bx.tcx().sess,
-                            span,
-                            &format!(
-                                "invalid monomorphization of `{}` intrinsic: \
-                                      expected basic integer type, found `{}`",
-                                name, ty
-                            ),
-                        );
+                        bx.tcx().sess.emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty });
                         return;
                     }
                 }
@@ -329,15 +323,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         _ => bug!(),
                     },
                     None => {
-                        span_invalid_monomorphization_error(
-                            bx.tcx().sess,
-                            span,
-                            &format!(
-                                "invalid monomorphization of `{}` intrinsic: \
-                                      expected basic float type, found `{}`",
-                                name, arg_tys[0]
-                            ),
-                        );
+                        bx.tcx().sess.emit_err(InvalidMonomorphization::BasicFloatType { span, name, ty: arg_tys[0] });
                         return;
                     }
                 }
@@ -345,29 +331,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
             sym::float_to_int_unchecked => {
                 if float_type_width(arg_tys[0]).is_none() {
-                    span_invalid_monomorphization_error(
-                        bx.tcx().sess,
-                        span,
-                        &format!(
-                            "invalid monomorphization of `float_to_int_unchecked` \
-                                  intrinsic: expected basic float type, \
-                                  found `{}`",
-                            arg_tys[0]
-                        ),
-                    );
+                    bx.tcx().sess.emit_err(InvalidMonomorphization::FloatToIntUnchecked { span, ty: arg_tys[0] });
                     return;
                 }
                 let Some((_width, signed)) = int_type_width_signed(ret_ty, bx.tcx()) else {
-                    span_invalid_monomorphization_error(
-                        bx.tcx().sess,
-                        span,
-                        &format!(
-                            "invalid monomorphization of `float_to_int_unchecked` \
-                                    intrinsic:  expected basic integer type, \
-                                    found `{}`",
-                            ret_ty
-                        ),
-                    );
+                    bx.tcx().sess.emit_err(InvalidMonomorphization::FloatToIntUnchecked { span, ty: ret_ty });
                     return;
                 };
                 if signed {
@@ -402,7 +370,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 use crate::common::{AtomicRmwBinOp, SynchronizationScope};
 
                 let Some((instruction, ordering)) = atomic.split_once('_') else {
-                    bx.sess().fatal("Atomic intrinsic missing memory ordering");
+                    bx.sess().emit_fatal(errors::MissingMemoryOrdering);
                 };
 
                 let parse_ordering = |bx: &Bx, s| match s {
@@ -412,25 +380,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     "release" => Release,
                     "acqrel" => AcquireRelease,
                     "seqcst" => SequentiallyConsistent,
-                    _ => bx.sess().fatal("unknown ordering in atomic intrinsic"),
+                    _ => bx.sess().emit_fatal(errors::UnknownAtomicOrdering),
                 };
 
                 let invalid_monomorphization = |ty| {
-                    span_invalid_monomorphization_error(
-                        bx.tcx().sess,
-                        span,
-                        &format!(
-                            "invalid monomorphization of `{}` intrinsic: \
-                                  expected basic integer type, found `{}`",
-                            name, ty
-                        ),
-                    );
+                    bx.tcx().sess.emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty });
                 };
 
                 match instruction {
                     "cxchg" | "cxchgweak" => {
                         let Some((success, failure)) = ordering.split_once('_') else {
-                            bx.sess().fatal("Atomic compare-exchange intrinsic missing failure memory ordering");
+                            bx.sess().emit_fatal(errors::AtomicCompareExchange);
                         };
                         let ty = substs.type_at(0);
                         if int_type_width_signed(ty, bx.tcx()).is_some() || ty.is_unsafe_ptr() {
@@ -529,7 +489,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             "min" => AtomicRmwBinOp::AtomicMin,
                             "umax" => AtomicRmwBinOp::AtomicUMax,
                             "umin" => AtomicRmwBinOp::AtomicUMin,
-                            _ => bx.sess().fatal("unknown atomic operation"),
+                            _ => bx.sess().emit_fatal(errors::UnknownAtomicOperation),
                         };
 
                         let ty = substs.type_at(0);
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index 0dabe96b602..da69fc8ecf7 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -419,7 +419,7 @@ pub fn from_target_feature(
 
 /// Computes the set of target features used in a function for the purposes of
 /// inline assembly.
-fn asm_target_features<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx FxHashSet<Symbol> {
+fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxHashSet<Symbol> {
     let mut target_features = tcx.sess.unstable_target_features.clone();
     if tcx.def_kind(did).has_codegen_attrs() {
         let attrs = tcx.codegen_fn_attrs(did);