diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 9a0c379b4e44d..95e72184ff037 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 c71d332475a5f..bad22ccb1fedd 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 6188094bbbdd4..1f577e9f3524f 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( ); 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 0000000000000..0ffe887202261 --- /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 3ef9a634e1857..ceebe4d417f7d 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; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl new file mode 100644 index 0000000000000..0d0388a039e2d --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -0,0 +1,119 @@ +codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error} + +codegen_ssa_version_script_write_failure = failed to write version script: {$error} + +codegen_ssa_symbol_file_write_failure = failed to write symbols file: {$error} + +codegen_ssa_ld64_unimplemented_modifier = `as-needed` modifier not implemented yet for ld64 + +codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker + +codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not implemented yet for L4Bender + +codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error} + +codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error} + +codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$error} + +codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced + +codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced + +codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error} + +codegen_ssa_incompatible_linking_modifiers = the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs + +codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error} + +codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions + +codegen_ssa_rlib_missing_format = could not find formats for rlibs + +codegen_ssa_rlib_only_rmeta_found = could not find rlib for: `{$crate_name}`, found rmeta (metadata) file + +codegen_ssa_rlib_not_found = could not find rlib for: `{$crate_name}` + +codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status} + +codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified + +codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link + +codegen_ssa_use_cargo_directive = 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) + +codegen_ssa_thorin_read_input_failure = failed to read input file + +codegen_ssa_thorin_parse_input_file_kind = failed to parse input file kind + +codegen_ssa_thorin_parse_input_object_file = failed to parse input object file + +codegen_ssa_thorin_parse_input_archive_file = failed to parse input archive file + +codegen_ssa_thorin_parse_archive_member = failed to parse archive member + +codegen_ssa_thorin_invalid_input_kind = input is not an archive or elf object + +codegen_ssa_thorin_decompress_data = failed to decompress compressed section + +codegen_ssa_thorin_section_without_name = section without name at offset {$offset} + +codegen_ssa_thorin_relocation_with_invalid_symbol = relocation with invalid symbol for section `{$section}` at offset {$offset} + +codegen_ssa_thorin_multiple_relocations = multiple relocations for section `{$section}` at offset {$offset} + +codegen_ssa_thorin_unsupported_relocation = unsupported relocation for section {$section} at offset {$offset} + +codegen_ssa_thorin_missing_dwo_name = missing path attribute to DWARF object ({$id}) + +codegen_ssa_thorin_no_compilation_units = input object has no compilation units + +codegen_ssa_thorin_no_die = no top-level debugging information entry in compilation/type unit + +codegen_ssa_thorin_top_level_die_not_unit = top-level debugging information entry is not a compilation/type unit + +codegen_ssa_thorin_missing_required_section = input object missing required section `{$section}` + +codegen_ssa_thorin_parse_unit_abbreviations = failed to parse unit abbreviations + +codegen_ssa_thorin_parse_unit_attribute = failed to parse unit attribute + +codegen_ssa_thorin_parse_unit_header = failed to parse unit header + +codegen_ssa_thorin_parse_unit = failed to parse unit + +codegen_ssa_thorin_incompatible_index_version = incompatible `{$section}` index version: found version {$actual}, expected version {$format} + +codegen_ssa_thorin_offset_at_index = read offset at index {$index} of `.debug_str_offsets.dwo` section + +codegen_ssa_thorin_str_at_offset = read string at offset {$offset} of `.debug_str.dwo` section + +codegen_ssa_thorin_parse_index = failed to parse `{$section}` index section + +codegen_ssa_thorin_unit_not_in_index = unit {$unit} from input package is not in its index + +codegen_ssa_thorin_row_not_in_index = row {$row} found in index's hash table not present in index + +codegen_ssa_thorin_section_not_in_row = section not found in unit's row in index + +codegen_ssa_thorin_empty_unit = unit {$unit} in input DWARF object with no data + +codegen_ssa_thorin_multiple_debug_info_section = multiple `.debug_info.dwo` sections + +codegen_ssa_thorin_multiple_debug_types_section = multiple `.debug_types.dwo` sections in a package + +codegen_ssa_thorin_not_split_unit = regular compilation unit in object (missing dwo identifier) + +codegen_ssa_thorin_duplicate_unit = duplicate split compilation unit ({$unit}) + +codegen_ssa_thorin_missing_referenced_unit = unit {$unit} referenced by executable was not found + +codegen_ssa_thorin_not_output_object_created = no output object was created from inputs + +codegen_ssa_thorin_mixed_input_encodings = input objects haved mixed encodings + +codegen_ssa_thorin_io = {$error} +codegen_ssa_thorin_object_read = {$error} +codegen_ssa_thorin_object_write = {$error} +codegen_ssa_thorin_gimli_read = {$error} +codegen_ssa_thorin_gimli_write = {$error} diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 18be60975e4eb..77f87d5b007e3 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -40,9 +40,10 @@ fluent_messages! { attr => "../locales/en-US/attr.ftl", borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", + codegen_gcc => "../locales/en-US/codegen_gcc.ftl", + codegen_ssa => "../locales/en-US/codegen_ssa.ftl", compiletest => "../locales/en-US/compiletest.ftl", const_eval => "../locales/en-US/const_eval.ftl", - codegen_gcc => "../locales/en-US/codegen_gcc.ftl", driver => "../locales/en-US/driver.ftl", expand => "../locales/en-US/expand.ftl", hir_analysis => "../locales/en-US/hir_analysis.ftl",