From 4c80f50fc6dce4e35eebe1beaadd5fc3ecfe6f52 Mon Sep 17 00:00:00 2001
From: Jhonny Bill Mena <jhonnybillm@gmail.com>
Date: Sun, 30 Oct 2022 15:38:37 -0400
Subject: [PATCH 1/5] UPDATE - Complete link.rs migration to new diagnostics
 infraestructure

---
 compiler/rustc_codegen_ssa/src/back/link.rs   | 123 ++++++-----------
 compiler/rustc_codegen_ssa/src/errors.rs      | 130 ++++++++++++++++++
 .../locales/en-US/codegen_ssa.ftl             |  51 +++++++
 compiler/rustc_errors/src/diagnostic_impls.rs |   4 +-
 4 files changed, 227 insertions(+), 81 deletions(-)

diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 0dc0dee862c74..4c58d0b53f08d 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -919,29 +919,17 @@ fn link_natively<'a>(
                         )
                         .is_some();
 
-                        sess.note_without_error("`link.exe` returned an unexpected error");
+                        sess.emit_note(errors::LinkExeUnexpectedError);
                         if is_vs_installed && has_linker {
                             // the linker is broken
-                            sess.note_without_error(
-                                "the Visual Studio build tools may need to be repaired \
-                                using the Visual Studio installer",
-                            );
-                            sess.note_without_error(
-                                "or a necessary component may be missing from the \
-                                \"C++ build tools\" workload",
-                            );
+                            sess.emit_note(errors::RepairVSBuildTools);
+                            sess.emit_note(errors::MissingCppBuildToolComponent);
                         } else if is_vs_installed {
                             // the linker is not installed
-                            sess.note_without_error(
-                                "in the Visual Studio installer, ensure the \
-                                \"C++ build tools\" workload is selected",
-                            );
+                            sess.emit_note(errors::SelectCppBuildToolWorkload);
                         } else {
                             // visual studio is not installed
-                            sess.note_without_error(
-                                "you may need to install Visual Studio build tools with the \
-                                \"C++ build tools\" workload",
-                            );
+                            sess.emit_note(errors::VisualStudioNotInstalled);
                         }
                     }
                 }
@@ -954,35 +942,20 @@ fn link_natively<'a>(
         Err(e) => {
             let linker_not_found = e.kind() == io::ErrorKind::NotFound;
 
-            let mut linker_error = {
-                if linker_not_found {
-                    sess.struct_err(&format!("linker `{}` not found", linker_path.display()))
-                } else {
-                    sess.struct_err(&format!(
-                        "could not exec the linker `{}`",
-                        linker_path.display()
-                    ))
-                }
-            };
-
-            linker_error.note(&e.to_string());
-
-            if !linker_not_found {
-                linker_error.note(&format!("{:?}", &cmd));
+            if linker_not_found {
+                sess.emit_err(errors::LinkerNotFound { linker_path, error: e });
+            } else {
+                sess.emit_err(errors::UnableToExeLinker {
+                    linker_path,
+                    error: e,
+                    command_formatted: format!("{:?}", &cmd),
+                });
             }
 
-            linker_error.emit();
-
             if sess.target.is_like_msvc && linker_not_found {
-                sess.note_without_error(
-                    "the msvc targets depend on the msvc linker \
-                     but `link.exe` was not found",
-                );
-                sess.note_without_error(
-                    "please ensure that Visual Studio 2017 or later, or Build Tools \
-                     for Visual Studio were installed with the Visual C++ option.",
-                );
-                sess.note_without_error("VS Code is a different product, and is not sufficient.");
+                sess.emit_note(errors::MsvcMissingLinker);
+                sess.emit_note(errors::CheckInstalledVisualStudio);
+                sess.emit_note(errors::UnsufficientVSCodeProduct);
             }
             sess.abort_if_errors();
         }
@@ -1007,15 +980,13 @@ fn link_natively<'a>(
                     if !prog.status.success() {
                         let mut output = prog.stderr.clone();
                         output.extend_from_slice(&prog.stdout);
-                        sess.struct_warn(&format!(
-                            "processing debug info with `dsymutil` failed: {}",
-                            prog.status
-                        ))
-                        .note(&escape_string(&output))
-                        .emit();
+                        sess.emit_warning(errors::ProcessingDymutilFailed {
+                            status: prog.status,
+                            output: escape_string(&output),
+                        });
                     }
                 }
-                Err(e) => sess.fatal(&format!("unable to run `dsymutil`: {}", e)),
+                Err(error) => sess.emit_fatal(errors::UnableToRunDsymutil { error }),
             }
         }
 
@@ -1092,21 +1063,21 @@ fn strip_symbols_with_external_utility<'a>(
             if !prog.status.success() {
                 let mut output = prog.stderr.clone();
                 output.extend_from_slice(&prog.stdout);
-                sess.struct_warn(&format!(
-                    "stripping debug info with `{}` failed: {}",
-                    util, prog.status
-                ))
-                .note(&escape_string(&output))
-                .emit();
+                sess.emit_warning(errors::StrippingDebuInfoFailed {
+                    util,
+                    status: prog.status,
+                    output: escape_string(&output),
+                });
             }
         }
-        Err(e) => sess.fatal(&format!("unable to run `{}`: {}", util, e)),
+        Err(error) => sess.emit_fatal(errors::UnableToRun { util, error }),
     }
 }
 
 fn escape_string(s: &[u8]) -> String {
     match str::from_utf8(s) {
         Ok(s) => s.to_owned(),
+        // FIXME: return a type that can conform to IntoDiagnosticArg
         Err(_) => format!("Non-UTF-8 output: {}", s.escape_ascii()),
     }
 }
@@ -1251,7 +1222,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
             )),
             (Some(linker), None) => {
                 let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| {
-                    sess.fatal("couldn't extract file stem from specified linker")
+                    sess.emit_fatal(errors::LinkerFileStem);
                 });
 
                 let flavor = if stem == "emcc" {
@@ -1378,13 +1349,9 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
         })
         .collect();
     if !lib_args.is_empty() {
-        sess.note_without_error(
-            "Link against the following native artifacts when linking \
-                                 against this static library. The order and any duplication \
-                                 can be significant on some platforms.",
-        );
+        sess.emit_note(errors::StaticLibraryNativeArtifacts);
         // Prefix for greppability
-        sess.note_without_error(&format!("native-static-libs: {}", &lib_args.join(" ")));
+        sess.emit_note(errors::NativeStaticLibs { arguments: lib_args.join(" ") });
     }
 }
 
@@ -1688,14 +1655,14 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty
     match (crate_type, &sess.target.link_script) {
         (CrateType::Cdylib | CrateType::Executable, Some(script)) => {
             if !sess.target.linker_flavor.is_gnu() {
-                sess.fatal("can only use link script when linking with GNU-like linker");
+                sess.emit_fatal(errors::LinkScriptUnavailable);
             }
 
             let file_name = ["rustc", &sess.target.llvm_target, "linkfile.ld"].join("-");
 
             let path = tmpdir.join(file_name);
-            if let Err(e) = fs::write(&path, script.as_ref()) {
-                sess.fatal(&format!("failed to write link script to {}: {}", path.display(), e));
+            if let Err(error) = fs::write(&path, script.as_ref()) {
+                sess.emit_fatal(errors::LinkScriptWriteFailure { path, error });
             }
 
             cmd.arg("--script");
@@ -1841,8 +1808,8 @@ fn add_linked_symbol_object(
 
     let path = tmpdir.join("symbols.o");
     let result = std::fs::write(&path, file.write().unwrap());
-    if let Err(e) = result {
-        sess.fatal(&format!("failed to write {}: {}", path.display(), e));
+    if let Err(error) = result {
+        sess.emit_fatal(errors::FailedToWrite { path, error });
     }
     cmd.add_object(&path);
 }
@@ -2299,14 +2266,10 @@ fn collect_natvis_visualizers(
                 visualizer_paths.push(visualizer_out_file);
             }
             Err(error) => {
-                sess.warn(
-                    format!(
-                        "Unable to write debugger visualizer file `{}`: {} ",
-                        visualizer_out_file.display(),
-                        error
-                    )
-                    .as_str(),
-                );
+                sess.emit_warning(errors::UnableToWriteDebuggerVisualizer {
+                    path: visualizer_out_file,
+                    error,
+                });
             }
         };
     }
@@ -2641,7 +2604,7 @@ fn add_upstream_rust_crates<'a>(
                 || !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 {
@@ -2681,7 +2644,7 @@ fn add_upstream_rust_crates<'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);
@@ -2919,7 +2882,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
                 }
             }
         } else {
-            sess.fatal("option `-Z gcc-ld` is used even though linker flavor is not gcc");
+            sess.emit_fatal(errors::OptionGccOnly);
         }
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index ebb531f1c43a5..71fac123725cf 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -354,3 +354,133 @@ impl IntoDiagnostic<'_> for LinkingFailed<'_> {
         diag
     }
 }
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_link_exe_unexpected_error)]
+pub struct LinkExeUnexpectedError;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_repair_vs_build_tools)]
+pub struct RepairVSBuildTools;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_missing_cpp_build_tool_component)]
+pub struct MissingCppBuildToolComponent;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_select_cpp_build_tool_workload)]
+pub struct SelectCppBuildToolWorkload;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_visual_studio_not_installed)]
+pub struct VisualStudioNotInstalled;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_linker_not_found)]
+#[note]
+pub struct LinkerNotFound {
+    pub linker_path: PathBuf,
+    pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_unable_to_exe_linker)]
+#[note]
+#[note(command_note)]
+pub struct UnableToExeLinker {
+    pub linker_path: PathBuf,
+    pub error: Error,
+    pub command_formatted: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_msvc_missing_linker)]
+pub struct MsvcMissingLinker;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_check_installed_visual_studio)]
+pub struct CheckInstalledVisualStudio;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_unsufficient_vs_code_product)]
+pub struct UnsufficientVSCodeProduct;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_processing_dymutil_failed)]
+#[note]
+pub struct ProcessingDymutilFailed {
+    pub status: ExitStatus,
+    pub output: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_unable_to_run_dsymutil)]
+#[note]
+pub struct UnableToRunDsymutil {
+    pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_stripping_debu_info_failed)]
+#[note]
+pub struct StrippingDebuInfoFailed<'a> {
+    pub util: &'a str,
+    pub status: ExitStatus,
+    pub output: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_unable_to_run)]
+pub struct UnableToRun<'a> {
+    pub util: &'a str,
+    pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_linker_file_stem)]
+pub struct LinkerFileStem;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_static_library_native_artifacts)]
+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;
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_link_script_write_failure)]
+pub struct LinkScriptWriteFailure {
+    pub path: PathBuf,
+    pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_failed_to_write)]
+pub struct FailedToWrite {
+    pub path: PathBuf,
+    pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_unable_to_write_debugger_visualizer)]
+pub struct UnableToWriteDebuggerVisualizer {
+    pub path: PathBuf,
+    pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_rlib_archive_build_failure)]
+pub struct RlibArchiveBuildFailure {
+    pub error: Error,
+}
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_option_gcc_only)]
+pub struct OptionGccOnly;
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
index 966a421bcf08c..2e5c72ee6452a 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
@@ -119,3 +119,54 @@ codegen_ssa_thorin_object_read = {$error}
 codegen_ssa_thorin_object_write = {$error}
 codegen_ssa_thorin_gimli_read = {$error}
 codegen_ssa_thorin_gimli_write = {$error}
+
+codegen_ssa_link_exe_unexpected_error = `link.exe` returned an unexpected error
+
+codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer
+
+codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload
+
+codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected
+
+codegen_ssa_visual_studio_not_installed = you may need to install Visual Studio build tools with the "C++ build tools" workload
+
+codegen_ssa_linker_not_found = linker `{$linker_path}` not found
+    .note = {$error}
+
+codegen_ssa_unable_to_exe_linker = could not exec the linker `{$linker_path}`
+    .note = {$error}
+    .command_note = {$command_formatted}
+
+codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found
+
+codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option.
+
+codegen_ssa_unsufficient_vs_code_product = VS Code is a different product, and is not sufficient.
+
+codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status}
+    .note = {$output}
+
+codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error}
+
+codegen_ssa_stripping_debu_info_failed = stripping debug info with `{$util}` failed: {$status}
+    .note = {$output}
+
+codegen_ssa_unable_to_run = unable to run `{$util}`: {$error}
+
+codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker
+
+codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
+
+codegen_ssa_native_static_libs = native-static-libs: {$arguments}
+
+codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker
+
+codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error}
+
+codegen_ssa_failed_to_write = failed to write {$path}: {$error}
+
+codegen_ssa_unable_to_write_debugger_visualizer = Unable to write debugger visualizer file `{$path}`: {$error}
+
+codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib: {$error}
+
+codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index 7640b2919f78b..4f32e236b2dbb 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -13,6 +13,7 @@ use std::borrow::Cow;
 use std::fmt;
 use std::num::ParseIntError;
 use std::path::{Path, PathBuf};
+use std::process::ExitStatus;
 
 pub struct DiagnosticArgFromDisplay<'a>(pub &'a dyn fmt::Display);
 
@@ -66,7 +67,8 @@ into_diagnostic_arg_using_display!(
     ParseIntError,
     StackProtector,
     &TargetTriple,
-    SplitDebuginfo
+    SplitDebuginfo,
+    ExitStatus,
 );
 
 impl IntoDiagnosticArg for bool {

From 1f4c5a624fd7db58b32d6d9cfa063fbfe0a340a7 Mon Sep 17 00:00:00 2001
From: Jhonny Bill Mena <jhonnybillm@gmail.com>
Date: Mon, 31 Oct 2022 01:36:32 -0400
Subject: [PATCH 2/5] ADD - ExtractBundledLibsError. Migrated
 extract_bundled_libs to translatable diagnostics

---
 .../rustc_codegen_ssa/src/back/archive.rs     | 59 +++++++++++++------
 compiler/rustc_codegen_ssa/src/back/link.rs   |  2 +-
 compiler/rustc_codegen_ssa/src/errors.rs      | 48 +++++++++++++++
 .../locales/en-US/codegen_ssa.ftl             |  8 +++
 4 files changed, 98 insertions(+), 19 deletions(-)

diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index bb76ca5d2b941..b45fa2476875b 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -6,11 +6,12 @@ use rustc_span::symbol::Symbol;
 
 use object::read::archive::ArchiveFile;
 
-use std::fmt::Display;
 use std::fs::File;
 use std::io;
 use std::path::{Path, PathBuf};
 
+use crate::errors::{ExtractBundledLibsError, ExtractBundledLibsErrorKind::*};
+
 pub trait ArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a>;
 
@@ -28,32 +29,54 @@ pub trait ArchiveBuilderBuilder {
         is_direct_dependency: bool,
     ) -> PathBuf;
 
-    fn extract_bundled_libs(
-        &self,
-        rlib: &Path,
+    fn extract_bundled_libs<'a>(
+        &'a self,
+        rlib: &'a Path,
         outdir: &Path,
         bundled_lib_file_names: &FxHashSet<Symbol>,
-    ) -> Result<(), String> {
-        let message = |msg: &str, e: &dyn Display| format!("{} '{}': {}", msg, &rlib.display(), e);
+    ) -> Result<(), ExtractBundledLibsError<'_>> {
         let archive_map = unsafe {
-            Mmap::map(File::open(rlib).map_err(|e| message("failed to open file", &e))?)
-                .map_err(|e| message("failed to mmap file", &e))?
+            Mmap::map(File::open(rlib).map_err(|e| ExtractBundledLibsError {
+                kind: OpenFile,
+                rlib,
+                error: e.to_string(),
+            })?)
+            .map_err(|e| ExtractBundledLibsError {
+                kind: MmapFile,
+                rlib,
+                error: e.to_string(),
+            })?
         };
-        let archive = ArchiveFile::parse(&*archive_map)
-            .map_err(|e| message("failed to parse archive", &e))?;
+        let archive = ArchiveFile::parse(&*archive_map).map_err(|e| ExtractBundledLibsError {
+            kind: ParseArchive,
+            rlib,
+            error: e.to_string(),
+        })?;
 
         for entry in archive.members() {
-            let entry = entry.map_err(|e| message("failed to read entry", &e))?;
-            let data = entry
-                .data(&*archive_map)
-                .map_err(|e| message("failed to get data from archive member", &e))?;
-            let name = std::str::from_utf8(entry.name())
-                .map_err(|e| message("failed to convert name", &e))?;
+            let entry = entry.map_err(|e| ExtractBundledLibsError {
+                kind: ReadEntry,
+                rlib,
+                error: e.to_string(),
+            })?;
+            let data = entry.data(&*archive_map).map_err(|e| ExtractBundledLibsError {
+                kind: ArchiveMember,
+                rlib,
+                error: e.to_string(),
+            })?;
+            let name = std::str::from_utf8(entry.name()).map_err(|e| ExtractBundledLibsError {
+                kind: ConvertName,
+                rlib,
+                error: e.to_string(),
+            })?;
             if !bundled_lib_file_names.contains(&Symbol::intern(name)) {
                 continue; // We need to extract only native libraries.
             }
-            std::fs::write(&outdir.join(&name), data)
-                .map_err(|e| message("failed to write file", &e))?;
+            std::fs::write(&outdir.join(&name), data).map_err(|e| ExtractBundledLibsError {
+                kind: WriteFile,
+                rlib,
+                error: e.to_string(),
+            })?;
         }
         Ok(())
     }
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 4c58d0b53f08d..1277294b63419 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2447,7 +2447,7 @@ fn add_upstream_rust_crates<'a>(
                         let rlib = &src.rlib.as_ref().unwrap().0;
                         archive_builder_builder
                             .extract_bundled_libs(rlib, tmpdir, &bundled_libs)
-                            .unwrap_or_else(|e| sess.fatal(e));
+                            .unwrap_or_else(|e| sess.emit_fatal(e));
                     }
 
                     let mut last = (None, NativeLibKind::Unspecified, None);
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 71fac123725cf..0a2532ccc470e 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -484,3 +484,51 @@ pub struct RlibArchiveBuildFailure {
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_option_gcc_only)]
 pub struct OptionGccOnly;
+
+pub struct ExtractBundledLibsError<'a> {
+    pub kind: ExtractBundledLibsErrorKind,
+    pub rlib: &'a Path,
+    pub error: String,
+}
+
+pub enum ExtractBundledLibsErrorKind {
+    OpenFile,
+    MmapFile,
+    ParseArchive,
+    ReadEntry,
+    ArchiveMember,
+    ConvertName,
+    WriteFile,
+}
+
+impl IntoDiagnostic<'_, !> for ExtractBundledLibsError<'_> {
+    fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, !> {
+        let mut diag = match self.kind {
+            ExtractBundledLibsErrorKind::OpenFile => {
+                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_open_file)
+            }
+            ExtractBundledLibsErrorKind::MmapFile => {
+                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_mmap_file)
+            }
+            ExtractBundledLibsErrorKind::ParseArchive => {
+                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_parse_archive)
+            }
+            ExtractBundledLibsErrorKind::ReadEntry => {
+                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_read_entry)
+            }
+            ExtractBundledLibsErrorKind::ArchiveMember => {
+                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_archive_member)
+            }
+            ExtractBundledLibsErrorKind::ConvertName => {
+                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_convert_name)
+            }
+            ExtractBundledLibsErrorKind::WriteFile => {
+                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_write_file)
+            }
+        };
+
+        diag.set_arg("rlib", self.rlib);
+        diag.set_arg("error", self.error);
+        diag
+    }
+}
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
index 2e5c72ee6452a..a31e1658f5f00 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
@@ -170,3 +170,11 @@ codegen_ssa_unable_to_write_debugger_visualizer = Unable to write debugger visua
 codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib: {$error}
 
 codegen_ssa_option_gcc_only = option `-Z gcc-ld` is used even though linker flavor is not gcc
+
+codegen_ssa_extract_bundled_libs_open_file = failed to open file '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_mmap_file = failed to mmap file '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_parse_archive = failed to parse archive '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_convert_name = failed to convert name '{$rlib}': {$error}
+codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error}

From 2678765d08df633b4804d1ba03e090c3bed878bb Mon Sep 17 00:00:00 2001
From: Jhonny Bill Mena <jhonnybillm@gmail.com>
Date: Mon, 31 Oct 2022 01:51:58 -0400
Subject: [PATCH 3/5] FIX - Migrate missing errors in link.rs

---
 compiler/rustc_codegen_ssa/src/back/link.rs         |  8 ++++----
 compiler/rustc_codegen_ssa/src/errors.rs            | 13 +++++++++++++
 .../locales/en-US/codegen_ssa.ftl                   |  4 ++++
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 1277294b63419..1e6a2b6ecaa6d 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2776,14 +2776,14 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
         ("arm", "watchos") => "watchos",
         (_, "macos") => "macosx",
         _ => {
-            sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os));
+            sess.emit_err(errors::UnsupportedArch { arch, os });
             return;
         }
     };
     let sdk_root = match get_apple_sdk_root(sdk_name) {
         Ok(s) => s,
         Err(e) => {
-            sess.err(&e);
+            sess.emit_err(e);
             return;
         }
     };
@@ -2799,7 +2799,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
     }
 }
 
-fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
+fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootError<'_>> {
     // Following what clang does
     // (https://github.com/llvm/llvm-project/blob/
     // 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678)
@@ -2849,7 +2849,7 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
 
     match res {
         Ok(output) => Ok(output.trim().to_string()),
-        Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
+        Err(error) => Err(errors::AppleSdkRootError::SdkPath { sdk_name, error }),
     }
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 0a2532ccc470e..35eae30c4ba9d 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -532,3 +532,16 @@ impl IntoDiagnostic<'_, !> for ExtractBundledLibsError<'_> {
         diag
     }
 }
+
+#[derive(Diagnostic)]
+#[diag(codegen_ssa_unsupported_arch)]
+pub struct UnsupportedArch<'a> {
+    pub arch: &'a str,
+    pub os: &'a str,
+}
+
+#[derive(Diagnostic)]
+pub enum AppleSdkRootError<'a> {
+    #[diag(codegen_ssa_apple_sdk_error_sdk_path)]
+    SdkPath { sdk_name: &'a str, error: Error },
+}
diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
index a31e1658f5f00..ad0d758210175 100644
--- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
@@ -178,3 +178,7 @@ codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$
 codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error}
 codegen_ssa_extract_bundled_libs_convert_name = failed to convert name '{$rlib}': {$error}
 codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error}
+
+codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`
+
+codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {error}

From 28491a7b36a717e42081fc6ee788433feccb72e6 Mon Sep 17 00:00:00 2001
From: Jhonny Bill Mena <jhonnybillm@gmail.com>
Date: Thu, 3 Nov 2022 01:53:06 -0400
Subject: [PATCH 4/5] UPDATE - address PR Comments

FIX - StrippingDebugInfoFailed typo

DELETE - unneeded FIXME comment

UPDATE - only declare the error with ExtractBundledLibsError as an enum and use the Diagnostic derive macro
---
 .../rustc_codegen_ssa/src/back/archive.rs     | 56 ++++++----------
 compiler/rustc_codegen_ssa/src/back/link.rs   |  3 +-
 compiler/rustc_codegen_ssa/src/errors.rs      | 64 ++++++-------------
 3 files changed, 40 insertions(+), 83 deletions(-)

diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index b45fa2476875b..9113ddab048ab 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -10,7 +10,7 @@ use std::fs::File;
 use std::io;
 use std::path::{Path, PathBuf};
 
-use crate::errors::{ExtractBundledLibsError, ExtractBundledLibsErrorKind::*};
+use crate::errors::ExtractBundledLibsError;
 
 pub trait ArchiveBuilderBuilder {
     fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a>;
@@ -35,48 +35,30 @@ pub trait ArchiveBuilderBuilder {
         outdir: &Path,
         bundled_lib_file_names: &FxHashSet<Symbol>,
     ) -> Result<(), ExtractBundledLibsError<'_>> {
-        let archive_map = unsafe {
-            Mmap::map(File::open(rlib).map_err(|e| ExtractBundledLibsError {
-                kind: OpenFile,
-                rlib,
-                error: e.to_string(),
-            })?)
-            .map_err(|e| ExtractBundledLibsError {
-                kind: MmapFile,
-                rlib,
-                error: e.to_string(),
-            })?
-        };
-        let archive = ArchiveFile::parse(&*archive_map).map_err(|e| ExtractBundledLibsError {
-            kind: ParseArchive,
-            rlib,
-            error: e.to_string(),
-        })?;
+        let archive_map =
+            unsafe {
+                Mmap::map(File::open(rlib).map_err(|e| ExtractBundledLibsError::OpenFile {
+                    rlib,
+                    error: e.to_string(),
+                })?)
+                .map_err(|e| ExtractBundledLibsError::MmapFile { rlib, error: e.to_string() })?
+            };
+        let archive = ArchiveFile::parse(&*archive_map)
+            .map_err(|e| ExtractBundledLibsError::ParseArchive { rlib, error: e.to_string() })?;
 
         for entry in archive.members() {
-            let entry = entry.map_err(|e| ExtractBundledLibsError {
-                kind: ReadEntry,
-                rlib,
-                error: e.to_string(),
-            })?;
-            let data = entry.data(&*archive_map).map_err(|e| ExtractBundledLibsError {
-                kind: ArchiveMember,
-                rlib,
-                error: e.to_string(),
-            })?;
-            let name = std::str::from_utf8(entry.name()).map_err(|e| ExtractBundledLibsError {
-                kind: ConvertName,
-                rlib,
-                error: e.to_string(),
+            let entry = entry
+                .map_err(|e| ExtractBundledLibsError::ReadEntry { rlib, error: e.to_string() })?;
+            let data = entry.data(&*archive_map).map_err(|e| {
+                ExtractBundledLibsError::ArchiveMember { rlib, error: e.to_string() }
             })?;
+            let name = std::str::from_utf8(entry.name())
+                .map_err(|e| ExtractBundledLibsError::ConvertName { rlib, error: e.to_string() })?;
             if !bundled_lib_file_names.contains(&Symbol::intern(name)) {
                 continue; // We need to extract only native libraries.
             }
-            std::fs::write(&outdir.join(&name), data).map_err(|e| ExtractBundledLibsError {
-                kind: WriteFile,
-                rlib,
-                error: e.to_string(),
-            })?;
+            std::fs::write(&outdir.join(&name), data)
+                .map_err(|e| ExtractBundledLibsError::WriteFile { rlib, error: e.to_string() })?;
         }
         Ok(())
     }
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 1e6a2b6ecaa6d..6f0a8d0a54cba 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1063,7 +1063,7 @@ fn strip_symbols_with_external_utility<'a>(
             if !prog.status.success() {
                 let mut output = prog.stderr.clone();
                 output.extend_from_slice(&prog.stdout);
-                sess.emit_warning(errors::StrippingDebuInfoFailed {
+                sess.emit_warning(errors::StrippingDebugInfoFailed {
                     util,
                     status: prog.status,
                     output: escape_string(&output),
@@ -1077,7 +1077,6 @@ fn strip_symbols_with_external_utility<'a>(
 fn escape_string(s: &[u8]) -> String {
     match str::from_utf8(s) {
         Ok(s) => s.to_owned(),
-        // FIXME: return a type that can conform to IntoDiagnosticArg
         Err(_) => format!("Non-UTF-8 output: {}", s.escape_ascii()),
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 35eae30c4ba9d..265f466f2ca37 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -423,7 +423,7 @@ pub struct UnableToRunDsymutil {
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_stripping_debu_info_failed)]
 #[note]
-pub struct StrippingDebuInfoFailed<'a> {
+pub struct StrippingDebugInfoFailed<'a> {
     pub util: &'a str,
     pub status: ExitStatus,
     pub output: String,
@@ -485,52 +485,28 @@ pub struct RlibArchiveBuildFailure {
 #[diag(codegen_ssa_option_gcc_only)]
 pub struct OptionGccOnly;
 
-pub struct ExtractBundledLibsError<'a> {
-    pub kind: ExtractBundledLibsErrorKind,
-    pub rlib: &'a Path,
-    pub error: String,
-}
+#[derive(Diagnostic)]
+pub enum ExtractBundledLibsError<'a> {
+    #[diag(codegen_ssa_extract_bundled_libs_open_file)]
+    OpenFile { rlib: &'a Path, error: String },
 
-pub enum ExtractBundledLibsErrorKind {
-    OpenFile,
-    MmapFile,
-    ParseArchive,
-    ReadEntry,
-    ArchiveMember,
-    ConvertName,
-    WriteFile,
-}
+    #[diag(codegen_ssa_extract_bundled_libs_mmap_file)]
+    MmapFile { rlib: &'a Path, error: String },
 
-impl IntoDiagnostic<'_, !> for ExtractBundledLibsError<'_> {
-    fn into_diagnostic(self, handler: &'_ Handler) -> DiagnosticBuilder<'_, !> {
-        let mut diag = match self.kind {
-            ExtractBundledLibsErrorKind::OpenFile => {
-                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_open_file)
-            }
-            ExtractBundledLibsErrorKind::MmapFile => {
-                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_mmap_file)
-            }
-            ExtractBundledLibsErrorKind::ParseArchive => {
-                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_parse_archive)
-            }
-            ExtractBundledLibsErrorKind::ReadEntry => {
-                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_read_entry)
-            }
-            ExtractBundledLibsErrorKind::ArchiveMember => {
-                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_archive_member)
-            }
-            ExtractBundledLibsErrorKind::ConvertName => {
-                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_convert_name)
-            }
-            ExtractBundledLibsErrorKind::WriteFile => {
-                handler.struct_fatal(fluent::codegen_ssa_extract_bundled_libs_write_file)
-            }
-        };
+    #[diag(codegen_ssa_extract_bundled_libs_parse_archive)]
+    ParseArchive { rlib: &'a Path, error: String },
 
-        diag.set_arg("rlib", self.rlib);
-        diag.set_arg("error", self.error);
-        diag
-    }
+    #[diag(codegen_ssa_extract_bundled_libs_read_entry)]
+    ReadEntry { rlib: &'a Path, error: String },
+
+    #[diag(codegen_ssa_extract_bundled_libs_archive_member)]
+    ArchiveMember { rlib: &'a Path, error: String },
+
+    #[diag(codegen_ssa_extract_bundled_libs_convert_name)]
+    ConvertName { rlib: &'a Path, error: String },
+
+    #[diag(codegen_ssa_extract_bundled_libs_write_file)]
+    WriteFile { rlib: &'a Path, error: String },
 }
 
 #[derive(Diagnostic)]

From 540c3f94d71879f413a151bc8c83c20c10b386dc Mon Sep 17 00:00:00 2001
From: Jhonny Bill Mena <jhonnybillm@gmail.com>
Date: Fri, 4 Nov 2022 01:16:16 -0400
Subject: [PATCH 5/5] UPDATE - accept dyn error and make Box<dyn error> conform
 to IntoDiagnosticArg

---
 .../rustc_codegen_ssa/src/back/archive.rs     | 29 +++++++++----------
 compiler/rustc_codegen_ssa/src/errors.rs      | 14 ++++-----
 compiler/rustc_errors/src/diagnostic_impls.rs |  1 +
 3 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 9113ddab048ab..18789d00fd3a4 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -35,30 +35,29 @@ pub trait ArchiveBuilderBuilder {
         outdir: &Path,
         bundled_lib_file_names: &FxHashSet<Symbol>,
     ) -> Result<(), ExtractBundledLibsError<'_>> {
-        let archive_map =
-            unsafe {
-                Mmap::map(File::open(rlib).map_err(|e| ExtractBundledLibsError::OpenFile {
-                    rlib,
-                    error: e.to_string(),
-                })?)
-                .map_err(|e| ExtractBundledLibsError::MmapFile { rlib, error: e.to_string() })?
-            };
+        let archive_map = unsafe {
+            Mmap::map(
+                File::open(rlib)
+                    .map_err(|e| ExtractBundledLibsError::OpenFile { rlib, error: Box::new(e) })?,
+            )
+            .map_err(|e| ExtractBundledLibsError::MmapFile { rlib, error: Box::new(e) })?
+        };
         let archive = ArchiveFile::parse(&*archive_map)
-            .map_err(|e| ExtractBundledLibsError::ParseArchive { rlib, error: e.to_string() })?;
+            .map_err(|e| ExtractBundledLibsError::ParseArchive { rlib, error: Box::new(e) })?;
 
         for entry in archive.members() {
             let entry = entry
-                .map_err(|e| ExtractBundledLibsError::ReadEntry { rlib, error: e.to_string() })?;
-            let data = entry.data(&*archive_map).map_err(|e| {
-                ExtractBundledLibsError::ArchiveMember { rlib, error: e.to_string() }
-            })?;
+                .map_err(|e| ExtractBundledLibsError::ReadEntry { rlib, error: Box::new(e) })?;
+            let data = entry
+                .data(&*archive_map)
+                .map_err(|e| ExtractBundledLibsError::ArchiveMember { rlib, error: Box::new(e) })?;
             let name = std::str::from_utf8(entry.name())
-                .map_err(|e| ExtractBundledLibsError::ConvertName { rlib, error: e.to_string() })?;
+                .map_err(|e| ExtractBundledLibsError::ConvertName { rlib, error: Box::new(e) })?;
             if !bundled_lib_file_names.contains(&Symbol::intern(name)) {
                 continue; // We need to extract only native libraries.
             }
             std::fs::write(&outdir.join(&name), data)
-                .map_err(|e| ExtractBundledLibsError::WriteFile { rlib, error: e.to_string() })?;
+                .map_err(|e| ExtractBundledLibsError::WriteFile { rlib, error: Box::new(e) })?;
         }
         Ok(())
     }
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 265f466f2ca37..36c94462b0b3e 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -488,25 +488,25 @@ pub struct OptionGccOnly;
 #[derive(Diagnostic)]
 pub enum ExtractBundledLibsError<'a> {
     #[diag(codegen_ssa_extract_bundled_libs_open_file)]
-    OpenFile { rlib: &'a Path, error: String },
+    OpenFile { rlib: &'a Path, error: Box<dyn std::error::Error> },
 
     #[diag(codegen_ssa_extract_bundled_libs_mmap_file)]
-    MmapFile { rlib: &'a Path, error: String },
+    MmapFile { rlib: &'a Path, error: Box<dyn std::error::Error> },
 
     #[diag(codegen_ssa_extract_bundled_libs_parse_archive)]
-    ParseArchive { rlib: &'a Path, error: String },
+    ParseArchive { rlib: &'a Path, error: Box<dyn std::error::Error> },
 
     #[diag(codegen_ssa_extract_bundled_libs_read_entry)]
-    ReadEntry { rlib: &'a Path, error: String },
+    ReadEntry { rlib: &'a Path, error: Box<dyn std::error::Error> },
 
     #[diag(codegen_ssa_extract_bundled_libs_archive_member)]
-    ArchiveMember { rlib: &'a Path, error: String },
+    ArchiveMember { rlib: &'a Path, error: Box<dyn std::error::Error> },
 
     #[diag(codegen_ssa_extract_bundled_libs_convert_name)]
-    ConvertName { rlib: &'a Path, error: String },
+    ConvertName { rlib: &'a Path, error: Box<dyn std::error::Error> },
 
     #[diag(codegen_ssa_extract_bundled_libs_write_file)]
-    WriteFile { rlib: &'a Path, error: String },
+    WriteFile { rlib: &'a Path, error: Box<dyn std::error::Error> },
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index 4f32e236b2dbb..83a3211c63b88 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -59,6 +59,7 @@ into_diagnostic_arg_using_display!(
     i128,
     u128,
     std::io::Error,
+    std::boxed::Box<dyn std::error::Error>,
     std::num::NonZeroU32,
     hir::Target,
     Edition,