diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-10-11 18:59:48 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-11 18:59:48 +0200 |
| commit | 24722e8d5bba76eeaa8006d568658fbd92fd402c (patch) | |
| tree | 9ccb5fe117f856777a8135c1be5a3823ed448df1 /compiler/rustc_codegen_ssa/src | |
| parent | d10b47ef69a36590a04c76e8868093d251adfec6 (diff) | |
| parent | 13d4f27c829a332f50a2109647f3b16bce119b8d (diff) | |
| download | rust-24722e8d5bba76eeaa8006d568658fbd92fd402c.tar.gz rust-24722e8d5bba76eeaa8006d568658fbd92fd402c.zip | |
Rollup merge of #102612 - JhonnyBillM:migrate-codegen-ssa-to-diagnostics-structs, r=davidtwco
Migrate `codegen_ssa` to diagnostics structs - [Part 1] Initial migration of `codegen_ssa`. Going to split this crate migration in at least two PRs in order to avoid a huge PR and to quick off some questions around: 1. Translating messages from "external" crates. 2. Interfacing with OS messages. 3. Adding UI tests while migrating diagnostics. _See comments below._
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/link.rs | 82 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/linker.rs | 34 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/back/write.rs | 34 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/errors.rs | 353 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/lib.rs | 2 |
5 files changed, 414 insertions, 91 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 9a0c379b4e4..95e72184ff0 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -31,7 +31,9 @@ use super::command::Command; use super::linker::{self, Linker}; use super::metadata::{create_rmeta_file, MetadataPosition}; use super::rpath::{self, RPathConfig}; -use crate::{looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo, NativeLib}; +use crate::{ + errors, looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo, NativeLib, +}; use cc::windows_registry; use regex::Regex; @@ -93,7 +95,7 @@ pub fn link_binary<'a>( let tmpdir = TempFileBuilder::new() .prefix("rustc") .tempdir() - .unwrap_or_else(|err| sess.fatal(&format!("couldn't create a temp dir: {}", err))); + .unwrap_or_else(|error| sess.emit_fatal(errors::CreateTempDir { error })); let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps); let out_filename = out_filename( sess, @@ -208,7 +210,7 @@ pub fn link_binary<'a>( pub fn each_linked_rlib( info: &CrateInfo, f: &mut dyn FnMut(CrateNum, &Path), -) -> Result<(), String> { +) -> Result<(), errors::LinkRlibError> { let crates = info.used_crates.iter(); let mut fmts = None; for (ty, list) in info.dependency_formats.iter() { @@ -224,26 +226,23 @@ pub fn each_linked_rlib( } } let Some(fmts) = fmts else { - return Err("could not find formats for rlibs".to_string()); + return Err(errors::LinkRlibError::MissingFormat); }; for &cnum in crates { match fmts.get(cnum.as_usize() - 1) { Some(&Linkage::NotLinked | &Linkage::IncludedFromDylib) => continue, Some(_) => {} - None => return Err("could not find formats for rlibs".to_string()), + None => return Err(errors::LinkRlibError::MissingFormat), } - let name = info.crate_name[&cnum]; + let crate_name = info.crate_name[&cnum]; let used_crate_source = &info.used_crate_source[&cnum]; if let Some((path, _)) = &used_crate_source.rlib { f(cnum, &path); } else { if used_crate_source.rmeta.is_some() { - return Err(format!( - "could not find rlib for: `{}`, found rmeta (metadata) file", - name - )); + return Err(errors::LinkRlibError::OnlyRmetaFound { crate_name }); } else { - return Err(format!("could not find rlib for: `{}`", name)); + return Err(errors::LinkRlibError::NotFound { crate_name }); } } } @@ -340,10 +339,7 @@ fn link_rlib<'a>( // -whole-archive and it isn't clear how we can currently handle such a // situation correctly. // See https://github.com/rust-lang/rust/issues/88085#issuecomment-901050897 - sess.err( - "the linking modifiers `+bundle` and `+whole-archive` are not compatible \ - with each other when generating rlibs", - ); + sess.emit_err(errors::IncompatibleLinkingModifiers); } NativeLibKind::Static { bundle: None | Some(true), .. } => {} NativeLibKind::Static { bundle: Some(false), .. } @@ -365,12 +361,8 @@ fn link_rlib<'a>( )); continue; } - ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|e| { - sess.fatal(&format!( - "failed to add native library {}: {}", - location.to_string_lossy(), - e - )); + ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|error| { + sess.emit_fatal(errors::AddNativeLibrary { library_path: location, error }); }); } } @@ -385,8 +377,8 @@ fn link_rlib<'a>( tmpdir.as_ref(), ); - ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|e| { - sess.fatal(&format!("failed to add native library {}: {}", output_path.display(), e)); + ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| { + sess.emit_fatal(errors::AddNativeLibrary { library_path: output_path, error }); }); } @@ -451,14 +443,11 @@ fn collate_raw_dylibs( // FIXME: when we add support for ordinals, figure out if we need to do anything // if we have two DllImport values with the same name but different ordinals. if import.calling_convention != old_import.calling_convention { - sess.span_err( - import.span, - &format!( - "multiple declarations of external function `{}` from \ - library `{}` have different calling conventions", - import.name, name, - ), - ); + sess.emit_err(errors::MultipleExternalFuncDecl { + span: import.span, + function: import.name, + library_name: &name, + }); } } } @@ -560,7 +549,7 @@ fn link_staticlib<'a>( all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned()); }); if let Err(e) = res { - sess.fatal(&e); + sess.emit_fatal(e); } ab.build(out_filename); @@ -673,9 +662,7 @@ fn link_dwarf_object<'a>( }) { Ok(()) => {} Err(e) => { - sess.struct_err("linking dwarf objects with thorin failed") - .note(&format!("{:?}", e)) - .emit(); + sess.emit_err(errors::ThorinErrorWrapper(e)); sess.abort_if_errors(); } } @@ -879,23 +866,14 @@ fn link_natively<'a>( let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); let escaped_output = escape_string(&output); - let mut err = sess.struct_err(&format!( - "linking with `{}` failed: {}", - linker_path.display(), - prog.status - )); - err.note(&format!("{:?}", &cmd)).note(&escaped_output); - if escaped_output.contains("undefined reference to") { - err.help( - "some `extern` functions couldn't be found; some native libraries may \ - need to be installed or have their path specified", - ); - err.note("use the `-l` flag to specify native libraries to link"); - err.note("use the `cargo:rustc-link-lib` directive to specify the native \ - libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)"); - } - err.emit(); - + // FIXME: Add UI tests for this error. + let err = errors::LinkingFailed { + linker_path: &linker_path, + exit_status: prog.status, + command: &cmd, + escaped_output: &escaped_output, + }; + sess.diagnostic().emit_err(err); // If MSVC's `link.exe` was expected but the return code // is not a Microsoft LNK error then suggest a way to fix or // install the Visual Studio build tools. diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index c71d332475a..bad22ccb1fe 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1,5 +1,6 @@ use super::command::Command; use super::symbol_export; +use crate::errors; use rustc_span::symbol::sym; use std::ffi::{OsStr, OsString}; @@ -434,11 +435,11 @@ impl<'a> Linker for GccLinker<'a> { // FIXME(81490): ld64 doesn't support these flags but macOS 11 // has -needed-l{} / -needed_library {} // but we have no way to detect that here. - self.sess.warn("`as-needed` modifier not implemented yet for ld64"); + self.sess.emit_warning(errors::Ld64UnimplementedModifier); } else if self.is_gnu && !self.sess.target.is_like_windows { self.linker_arg("--no-as-needed"); } else { - self.sess.warn("`as-needed` modifier not supported for current linker"); + self.sess.emit_warning(errors::LinkerUnsupportedModifier); } } self.hint_dynamic(); @@ -492,7 +493,7 @@ impl<'a> Linker for GccLinker<'a> { // FIXME(81490): ld64 as of macOS 11 supports the -needed_framework // flag but we have no way to detect that here. // self.cmd.arg("-needed_framework").arg(framework); - self.sess.warn("`as-needed` modifier not implemented yet for ld64"); + self.sess.emit_warning(errors::Ld64UnimplementedModifier); } self.cmd.arg("-framework").arg(framework); } @@ -665,8 +666,8 @@ impl<'a> Linker for GccLinker<'a> { writeln!(f, "_{}", sym)?; } }; - if let Err(e) = res { - self.sess.fatal(&format!("failed to write lib.def file: {}", e)); + if let Err(error) = res { + self.sess.emit_fatal(errors::LibDefWriteFailure { error }); } } else if is_windows { let res: io::Result<()> = try { @@ -680,8 +681,8 @@ impl<'a> Linker for GccLinker<'a> { writeln!(f, " {}", symbol)?; } }; - if let Err(e) = res { - self.sess.fatal(&format!("failed to write list.def file: {}", e)); + if let Err(error) = res { + self.sess.emit_fatal(errors::LibDefWriteFailure { error }); } } else { // Write an LD version script @@ -697,8 +698,8 @@ impl<'a> Linker for GccLinker<'a> { } writeln!(f, "\n local:\n *;\n}};")?; }; - if let Err(e) = res { - self.sess.fatal(&format!("failed to write version script: {}", e)); + if let Err(error) = res { + self.sess.emit_fatal(errors::VersionScriptWriteFailure { error }); } } @@ -915,9 +916,8 @@ impl<'a> Linker for MsvcLinker<'a> { self.cmd.arg(arg); } } - Err(err) => { - self.sess - .warn(&format!("error enumerating natvis directory: {}", err)); + Err(error) => { + self.sess.emit_warning(errors::NoNatvisDirectory { error }); } } } @@ -971,8 +971,8 @@ impl<'a> Linker for MsvcLinker<'a> { writeln!(f, " {}", symbol)?; } }; - if let Err(e) = res { - self.sess.fatal(&format!("failed to write lib.def file: {}", e)); + if let Err(error) = res { + self.sess.emit_fatal(errors::LibDefWriteFailure { error }); } let mut arg = OsString::from("/DEF:"); arg.push(path); @@ -1435,7 +1435,7 @@ impl<'a> Linker for L4Bender<'a> { fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) { // ToDo, not implemented, copy from GCC - self.sess.warn("exporting symbols not implemented yet for L4Bender"); + self.sess.emit_warning(errors::L4BenderExportingSymbolsUnimplemented); return; } @@ -1727,8 +1727,8 @@ impl<'a> Linker for BpfLinker<'a> { writeln!(f, "{}", sym)?; } }; - if let Err(e) = res { - self.sess.fatal(&format!("failed to write symbols file: {}", e)); + if let Err(error) = res { + self.sess.emit_fatal(errors::SymbolFileWriteFailure { error }); } else { self.cmd.arg("--export-symbols").arg(&path); } diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 6188094bbbd..1f577e9f352 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -2,11 +2,11 @@ use super::link::{self, ensure_removed}; use super::lto::{self, SerializedModule}; use super::symbol_export::symbol_name_for_instance_in_crate; +use crate::errors; +use crate::traits::*; use crate::{ CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, }; - -use crate::traits::*; use jobserver::{Acquired, Client}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::memmap::Mmap; @@ -530,7 +530,7 @@ fn produce_final_output_artifacts( // Produce final compile outputs. let copy_gracefully = |from: &Path, to: &Path| { if let Err(e) = fs::copy(from, to) { - sess.err(&format!("could not copy {:?} to {:?}: {}", from, to, e)); + sess.emit_err(errors::CopyPath::new(from, to, e)); } }; @@ -546,7 +546,7 @@ fn produce_final_output_artifacts( ensure_removed(sess.diagnostic(), &path); } } else { - let ext = crate_output + let extension = crate_output .temp_path(output_type, None) .extension() .unwrap() @@ -557,19 +557,11 @@ fn produce_final_output_artifacts( if crate_output.outputs.contains_key(&output_type) { // 2) Multiple codegen units, with `--emit foo=some_name`. We have // no good solution for this case, so warn the user. - sess.warn(&format!( - "ignoring emit path because multiple .{} files \ - were produced", - ext - )); + sess.emit_warning(errors::IgnoringEmitPath { extension }); } else if crate_output.single_output_file.is_some() { // 3) Multiple codegen units, with `-o some_name`. We have // no good solution for this case, so warn the user. - sess.warn(&format!( - "ignoring -o because multiple .{} files \ - were produced", - ext - )); + sess.emit_warning(errors::IgnoringOutput { extension }); } else { // 4) Multiple codegen units, but no explicit name. We // just leave the `foo.0.x` files in place. @@ -880,14 +872,12 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( ); match link_or_copy(&source_file, &output_path) { Ok(_) => Some(output_path), - Err(err) => { - let diag_handler = cgcx.create_diag_handler(); - diag_handler.err(&format!( - "unable to copy {} to {}: {}", - source_file.display(), - output_path.display(), - err - )); + Err(error) => { + cgcx.create_diag_handler().emit_err(errors::CopyPathBuf { + source_file, + output_path, + error, + }); None } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs new file mode 100644 index 00000000000..0ffe8872022 --- /dev/null +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -0,0 +1,353 @@ +//! Errors emitted by codegen_ssa + +use crate::back::command::Command; +use rustc_errors::{ + fluent, DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, + IntoDiagnosticArg, +}; +use rustc_macros::Diagnostic; +use rustc_span::{Span, Symbol}; +use std::borrow::Cow; +use std::io::Error; +use std::path::{Path, PathBuf}; +use std::process::ExitStatus; + +#[derive(Diagnostic)] +#[diag(codegen_ssa::lib_def_write_failure)] +pub struct LibDefWriteFailure { + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::version_script_write_failure)] +pub struct VersionScriptWriteFailure { + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::symbol_file_write_failure)] +pub struct SymbolFileWriteFailure { + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::ld64_unimplemented_modifier)] +pub struct Ld64UnimplementedModifier; + +#[derive(Diagnostic)] +#[diag(codegen_ssa::linker_unsupported_modifier)] +pub struct LinkerUnsupportedModifier; + +#[derive(Diagnostic)] +#[diag(codegen_ssa::L4Bender_exporting_symbols_unimplemented)] +pub struct L4BenderExportingSymbolsUnimplemented; + +#[derive(Diagnostic)] +#[diag(codegen_ssa::no_natvis_directory)] +pub struct NoNatvisDirectory { + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::copy_path_buf)] +pub struct CopyPathBuf { + pub source_file: PathBuf, + pub output_path: PathBuf, + pub error: Error, +} + +// Reports Paths using `Debug` implementation rather than Path's `Display` implementation. +#[derive(Diagnostic)] +#[diag(codegen_ssa::copy_path)] +pub struct CopyPath<'a> { + from: DebugArgPath<'a>, + to: DebugArgPath<'a>, + error: Error, +} + +impl<'a> CopyPath<'a> { + pub fn new(from: &'a Path, to: &'a Path, error: Error) -> CopyPath<'a> { + CopyPath { from: DebugArgPath(from), to: DebugArgPath(to), error } + } +} + +struct DebugArgPath<'a>(pub &'a Path); + +impl IntoDiagnosticArg for DebugArgPath<'_> { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self.0))) + } +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::ignoring_emit_path)] +pub struct IgnoringEmitPath { + pub extension: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::ignoring_output)] +pub struct IgnoringOutput { + pub extension: String, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::create_temp_dir)] +pub struct CreateTempDir { + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::incompatible_linking_modifiers)] +pub struct IncompatibleLinkingModifiers; + +#[derive(Diagnostic)] +#[diag(codegen_ssa::add_native_library)] +pub struct AddNativeLibrary { + pub library_path: PathBuf, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::multiple_external_func_decl)] +pub struct MultipleExternalFuncDecl<'a> { + #[primary_span] + pub span: Span, + pub function: Symbol, + pub library_name: &'a str, +} + +#[derive(Diagnostic)] +pub enum LinkRlibError { + #[diag(codegen_ssa::rlib_missing_format)] + MissingFormat, + + #[diag(codegen_ssa::rlib_only_rmeta_found)] + OnlyRmetaFound { crate_name: Symbol }, + + #[diag(codegen_ssa::rlib_not_found)] + NotFound { crate_name: Symbol }, +} + +pub struct ThorinErrorWrapper(pub thorin::Error); + +impl IntoDiagnostic<'_> for ThorinErrorWrapper { + fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag; + match self.0 { + thorin::Error::ReadInput(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_read_input_failure); + diag + } + thorin::Error::ParseFileKind(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_input_file_kind); + diag + } + thorin::Error::ParseObjectFile(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_input_object_file); + diag + } + thorin::Error::ParseArchiveFile(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_input_archive_file); + diag + } + thorin::Error::ParseArchiveMember(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_archive_member); + diag + } + thorin::Error::InvalidInputKind => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_invalid_input_kind); + diag + } + thorin::Error::DecompressData(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_decompress_data); + diag + } + thorin::Error::NamelessSection(_, offset) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_section_without_name); + diag.set_arg("offset", format!("0x{:08x}", offset)); + diag + } + thorin::Error::RelocationWithInvalidSymbol(section, offset) => { + diag = + handler.struct_err(fluent::codegen_ssa::thorin_relocation_with_invalid_symbol); + diag.set_arg("section", section); + diag.set_arg("offset", format!("0x{:08x}", offset)); + diag + } + thorin::Error::MultipleRelocations(section, offset) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_multiple_relocations); + diag.set_arg("section", section); + diag.set_arg("offset", format!("0x{:08x}", offset)); + diag + } + thorin::Error::UnsupportedRelocation(section, offset) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_unsupported_relocation); + diag.set_arg("section", section); + diag.set_arg("offset", format!("0x{:08x}", offset)); + diag + } + thorin::Error::MissingDwoName(id) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_missing_dwo_name); + diag.set_arg("id", format!("0x{:08x}", id)); + diag + } + thorin::Error::NoCompilationUnits => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_no_compilation_units); + diag + } + thorin::Error::NoDie => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_no_die); + diag + } + thorin::Error::TopLevelDieNotUnit => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_top_level_die_not_unit); + diag + } + thorin::Error::MissingRequiredSection(section) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_missing_required_section); + diag.set_arg("section", section); + diag + } + thorin::Error::ParseUnitAbbreviations(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_unit_abbreviations); + diag + } + thorin::Error::ParseUnitAttribute(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_unit_attribute); + diag + } + thorin::Error::ParseUnitHeader(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_unit_header); + diag + } + thorin::Error::ParseUnit(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_unit); + diag + } + thorin::Error::IncompatibleIndexVersion(section, format, actual) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_incompatible_index_version); + diag.set_arg("section", section); + diag.set_arg("actual", actual); + diag.set_arg("format", format); + diag + } + thorin::Error::OffsetAtIndex(_, index) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_offset_at_index); + diag.set_arg("index", index); + diag + } + thorin::Error::StrAtOffset(_, offset) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_str_at_offset); + diag.set_arg("offset", format!("0x{:08x}", offset)); + diag + } + thorin::Error::ParseIndex(_, section) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_index); + diag.set_arg("section", section); + diag + } + thorin::Error::UnitNotInIndex(unit) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_unit_not_in_index); + diag.set_arg("unit", format!("0x{:08x}", unit)); + diag + } + thorin::Error::RowNotInIndex(_, row) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_row_not_in_index); + diag.set_arg("row", row); + diag + } + thorin::Error::SectionNotInRow => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_section_not_in_row); + diag + } + thorin::Error::EmptyUnit(unit) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_empty_unit); + diag.set_arg("unit", format!("0x{:08x}", unit)); + diag + } + thorin::Error::MultipleDebugInfoSection => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_multiple_debug_info_section); + diag + } + thorin::Error::MultipleDebugTypesSection => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_multiple_debug_types_section); + diag + } + thorin::Error::NotSplitUnit => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_not_split_unit); + diag + } + thorin::Error::DuplicateUnit(unit) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_duplicate_unit); + diag.set_arg("unit", format!("0x{:08x}", unit)); + diag + } + thorin::Error::MissingReferencedUnit(unit) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_missing_referenced_unit); + diag.set_arg("unit", format!("0x{:08x}", unit)); + diag + } + thorin::Error::NoOutputObjectCreated => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_not_output_object_created); + diag + } + thorin::Error::MixedInputEncodings => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_mixed_input_encodings); + diag + } + thorin::Error::Io(e) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_io); + diag.set_arg("error", format!("{e}")); + diag + } + thorin::Error::ObjectRead(e) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_object_read); + diag.set_arg("error", format!("{e}")); + diag + } + thorin::Error::ObjectWrite(e) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_object_write); + diag.set_arg("error", format!("{e}")); + diag + } + thorin::Error::GimliRead(e) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_gimli_read); + diag.set_arg("error", format!("{e}")); + diag + } + thorin::Error::GimliWrite(e) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_gimli_write); + diag.set_arg("error", format!("{e}")); + diag + } + _ => unimplemented!("Untranslated thorin error"), + } + } +} + +pub struct LinkingFailed<'a> { + pub linker_path: &'a PathBuf, + pub exit_status: ExitStatus, + pub command: &'a Command, + pub escaped_output: &'a str, +} + +impl IntoDiagnostic<'_> for LinkingFailed<'_> { + fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag = handler.struct_err(fluent::codegen_ssa::linking_failed); + diag.set_arg("linker_path", format!("{}", self.linker_path.display())); + diag.set_arg("exit_status", format!("{}", self.exit_status)); + + diag.note(format!("{:?}", self.command)).note(self.escaped_output); + + // Trying to match an error from OS linkers + // which by now we have no way to translate. + if self.escaped_output.contains("undefined reference to") { + diag.note(fluent::codegen_ssa::extern_funcs_not_found) + .note(fluent::codegen_ssa::specify_libraries_to_link) + .note(fluent::codegen_ssa::use_cargo_directive); + } + diag + } +} diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 3ef9a634e18..ceebe4d417f 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -6,6 +6,7 @@ #![feature(strict_provenance)] #![feature(int_roundings)] #![feature(if_let_guard)] +#![feature(never_type)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] @@ -43,6 +44,7 @@ pub mod base; pub mod common; pub mod coverageinfo; pub mod debuginfo; +pub mod errors; pub mod glue; pub mod meth; pub mod mir; |
