| use std::ffi::{CString, c_uint}; | |
| use std::path::Path; | |
| use rustc_data_structures::small_c_str::SmallCStr; | |
| use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level, format_diag_message, msg}; | |
| use rustc_macros::Diagnostic; | |
| use rustc_span::Span; | |
| #[derive(Diagnostic)] | |
| #[diag("symbol `{$symbol_name}` is already defined")] | |
| pub(crate) struct SymbolAlreadyDefined<'a> { | |
| #[primary_span] | |
| pub span: Span, | |
| pub symbol_name: &'a str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`-Zsanitizer=memtag` requires `-Ctarget-feature=+mte`")] | |
| pub(crate) struct SanitizerMemtagRequiresMte; | |
| pub(crate) struct ParseTargetMachineConfig<'a>(pub LlvmError<'a>); | |
| impl Diagnostic<'_> for ParseTargetMachineConfig<'_> { | |
| fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_> { | |
| // Reuse the formatted primary message from `LlvmError` without emitting it. | |
| let diag = self.0.into_diag(dcx, level); | |
| let (message, _) = diag.messages.first().expect("`LlvmError` with no message"); | |
| let message = format_diag_message(message, &diag.args).into_owned(); | |
| diag.cancel(); | |
| Diag::new( | |
| dcx, | |
| level, | |
| msg!("failed to parse target machine config to target machine: {$error}"), | |
| ) | |
| .with_arg("error", message) | |
| } | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("failed to load our autodiff backend: {$err}")] | |
| pub(crate) struct AutoDiffComponentUnavailable { | |
| pub err: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("autodiff backend not found in the sysroot: {$err}")] | |
| #[note("it will be distributed via rustup in the future")] | |
| pub(crate) struct AutoDiffComponentMissing { | |
| pub err: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("using the autodiff feature requires setting `lto=\"fat\"` in your Cargo.toml")] | |
| pub(crate) struct AutoDiffWithoutLto; | |
| #[derive(Diagnostic)] | |
| #[diag("using the autodiff feature requires -Z autodiff=Enable")] | |
| pub(crate) struct AutoDiffWithoutEnable; | |
| #[derive(Diagnostic)] | |
| #[diag("failed to load our rust offload backend: {$err}")] | |
| pub(crate) struct RustOffloadComponentUnavailable { | |
| pub err: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("rust offload backend not found in the sysroot: {$err}")] | |
| #[note("it will be distributed via rustup in the future")] | |
| pub(crate) struct RustOffloadComponentMissing { | |
| pub err: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "using the offload feature requires -Z offload=<Device or Host=/absolute/path/to/device.bin>" | |
| )] | |
| pub(crate) struct OffloadWithoutEnable; | |
| #[derive(Diagnostic)] | |
| #[diag("using the offload feature requires -C lto=fat")] | |
| pub(crate) struct OffloadWithoutFatLTO; | |
| #[derive(Diagnostic)] | |
| #[diag("using the `-Z offload=Host=/absolute/path/to/device.bin` flag requires an absolute path")] | |
| pub(crate) struct OffloadWithoutAbsPath; | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "using the `-Z offload=Host=/absolute/path/to/device.bin` flag must point to a `device.bin` file" | |
| )] | |
| pub(crate) struct OffloadWrongFileName; | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "the given path/file to `device.bin` does not exist. Did you forget to run the device compilation first?" | |
| )] | |
| pub(crate) struct OffloadNonexistingPath; | |
| #[derive(Diagnostic)] | |
| #[diag("call to BundleImages failed, `device.bin` was not created")] | |
| pub(crate) struct OffloadBundleImagesFailed; | |
| #[derive(Diagnostic)] | |
| #[diag("call to WrapImages failed, device image was not wrapped into the host module")] | |
| pub(crate) struct OffloadWrapImagesFailed; | |
| #[derive(Diagnostic)] | |
| #[diag("failed to get bitcode from object file for LTO ({$err})")] | |
| pub(crate) struct LtoBitcodeFromRlib { | |
| pub err: String, | |
| } | |
| #[derive(Diagnostic)] | |
| pub(crate) enum LlvmError<'a> { | |
| #[diag("could not write output to {$path}")] | |
| WriteOutput { path: &'a Path }, | |
| #[diag("could not create LLVM TargetMachine for triple: {$triple}")] | |
| CreateTargetMachine { triple: SmallCStr }, | |
| #[diag("could not create LLVM MCSubtargetInfo for triple: {$triple}")] | |
| CreateMCSubtargetInfo { triple: SmallCStr }, | |
| #[diag("failed to run LLVM passes")] | |
| RunLlvmPasses, | |
| #[diag("failed to write LLVM IR to {$path}")] | |
| WriteIr { path: &'a Path }, | |
| #[diag("failed to prepare thin LTO context")] | |
| PrepareThinLtoContext, | |
| #[diag("failed to load bitcode of module \"{$name}\"")] | |
| LoadBitcode { name: CString }, | |
| #[diag("error while writing ThinLTO key data: {$err}")] | |
| WriteThinLtoKey { err: std::io::Error }, | |
| #[diag("failed to prepare thin LTO module")] | |
| PrepareThinLtoModule, | |
| #[diag("failed to parse bitcode for LTO module")] | |
| ParseBitcode, | |
| } | |
| pub(crate) struct WithLlvmError<'a>(pub LlvmError<'a>, pub String); | |
| impl Diagnostic<'_> for WithLlvmError<'_> { | |
| fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_> { | |
| use LlvmError::*; | |
| let msg_with_llvm_err = match &self.0 { | |
| WriteOutput { .. } => msg!("could not write output to {$path}: {$llvm_err}"), | |
| CreateTargetMachine { .. } => { | |
| msg!("could not create LLVM TargetMachine for triple: {$triple}: {$llvm_err}") | |
| } | |
| CreateMCSubtargetInfo { .. } => { | |
| msg!("could not create LLVM MCSubtargetInfo for triple: {$triple}: {$llvm_err}") | |
| } | |
| RunLlvmPasses => msg!("failed to run LLVM passes: {$llvm_err}"), | |
| WriteIr { .. } => msg!("failed to write LLVM IR to {$path}: {$llvm_err}"), | |
| PrepareThinLtoContext => { | |
| msg!("failed to prepare thin LTO context: {$llvm_err}") | |
| } | |
| LoadBitcode { .. } => { | |
| msg!("failed to load bitcode of module \"{$name}\": {$llvm_err}") | |
| } | |
| WriteThinLtoKey { .. } => { | |
| msg!("error while writing ThinLTO key data: {$err}: {$llvm_err}") | |
| } | |
| PrepareThinLtoModule => { | |
| msg!("failed to prepare thin LTO module: {$llvm_err}") | |
| } | |
| ParseBitcode => msg!("failed to parse bitcode for LTO module: {$llvm_err}"), | |
| }; | |
| self.0 | |
| .into_diag(dcx, level) | |
| .with_primary_message(msg_with_llvm_err) | |
| .with_arg("llvm_err", self.1) | |
| } | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("{$filename}:{$line}:{$column} {$pass_name} ({$kind}): {$message}")] | |
| pub(crate) struct FromLlvmOptimizationDiag<'a> { | |
| pub filename: &'a str, | |
| pub line: std::ffi::c_uint, | |
| pub column: std::ffi::c_uint, | |
| pub pass_name: &'a str, | |
| pub kind: &'a str, | |
| pub message: &'a str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("{$message}")] | |
| pub(crate) struct FromLlvmDiag { | |
| pub message: String, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("failed to write bytecode to {$path}: {$err}")] | |
| pub(crate) struct WriteBytecode<'a> { | |
| pub path: &'a Path, | |
| pub err: std::io::Error, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("failed to copy bitcode to object file: {$err}")] | |
| pub(crate) struct CopyBitcode { | |
| pub err: std::io::Error, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "unsupported debuginfo compression algorithm {$algorithm} - will fall back to uncompressed debuginfo" | |
| )] | |
| pub(crate) struct UnsupportedCompression { | |
| pub algorithm: &'static str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "data-layout for target `{$rustc_target}`, `{$rustc_layout}`, differs from LLVM target's `{$llvm_target}` default layout, `{$llvm_layout}`" | |
| )] | |
| pub(crate) struct MismatchedDataLayout<'a> { | |
| pub rustc_target: &'a str, | |
| pub rustc_layout: &'a str, | |
| pub llvm_target: &'a str, | |
| pub llvm_layout: &'a str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture")] | |
| pub(crate) struct FixedX18InvalidArch<'a> { | |
| pub arch: &'a str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("`-Zpacked-stack` is incompatible with `backchain` target feature")] | |
| #[note( | |
| "enabling both `-Zpacked-stack` and the `backchain` target feature is incompatible with the default s390x ABI. Switch to s390x-unknown-none-softfloat if you need both attributes" | |
| )] | |
| pub(crate) struct PackedStackBackchainNeedsSoftfloat; | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "intrinsic signature mismatch for `{$name}`: expected signature `{$llvm_fn_ty}`, found `{$rust_fn_ty}`" | |
| )] | |
| pub(crate) struct IntrinsicSignatureMismatch<'a> { | |
| pub name: &'a str, | |
| pub llvm_fn_ty: &'a str, | |
| pub rust_fn_ty: &'a str, | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("unknown LLVM intrinsic `{$name}`")] | |
| pub(crate) struct UnknownIntrinsic<'a> { | |
| pub name: &'a str, | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("intrinsic `{$name}` cannot be used with target arch `{$target_arch}`")] | |
| pub(crate) struct IntrinsicWrongArch<'a> { | |
| pub name: &'a str, | |
| pub target_arch: &'a str, | |
| #[primary_span] | |
| pub span: Span, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag("ignoring feature with missing prefix in `-Zllvm-target-feature`: `{$feature}`")] | |
| #[note("features must begin with a `+` to enable or `-` to disable it")] | |
| pub(crate) struct UnknownLlvmTargetFeaturePrefix<'a> { | |
| pub feature: &'a str, | |
| } | |
| #[derive(Diagnostic)] | |
| #[diag( | |
| "LLVM version mismatch: this compiler was built for LLVM {$expected_version}, but LLVM {$llvm_major}.{$llvm_minor}.{$llvm_patch} was found{$dll_loc}" | |
| )] | |
| pub(crate) struct LlvmVersionMismatch<'a> { | |
| pub expected_version: c_uint, | |
| pub llvm_major: c_uint, | |
| pub llvm_minor: c_uint, | |
| pub llvm_patch: c_uint, | |
| pub dll_loc: &'a str, | |
| } |