From 2b9db57a2e441b8e61dff7b775aaa01d53334ec1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 3 Dec 2024 21:42:44 -0700 Subject: [PATCH] Implement `core::error::Error` on Rust 1.81+ (#747) This commit updates when the `Error` trait is implemented to account for how in Rust 1.81-and-prior the `Error` trait is always available, even in `core`. This is currently done with detection at build-time of the current Rust compiler version because the MSRV for this crate is below 1.81. In the future when the MSRV is increased, however, the build script can be deleted. --- Cargo.toml | 2 ++ build.rs | 27 +++++++++++++++++++++++++++ src/build/error.rs | 2 ++ src/read/mod.rs | 2 ++ src/write/mod.rs | 2 ++ 5 files changed, 35 insertions(+) create mode 100644 build.rs diff --git a/Cargo.toml b/Cargo.toml index a18b2b1a..e826f19a 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,8 @@ edition = "2018" keywords = ["object", "elf", "mach-o", "pe", "coff"] license = "Apache-2.0 OR MIT" repository = "https://github.com/gimli-rs/object" +# NB: if this number increases to 1.81-or-later delete the `build.rs` script +# as it's no longer necessary. rust-version = "1.65" description = "A unified interface for reading and writing object file formats." include = [ diff --git a/build.rs b/build.rs new file mode 100644 index 00000000..305853b5 --- /dev/null +++ b/build.rs @@ -0,0 +1,27 @@ +use std::process::Command; +use std::str; + +fn main() { + // Temporary check to see if the rustc version >= 1.81 in which case the + // `Error` trait is always available. This is temporary because in the + // future the MSRV of this crate will be beyond 1.81 in which case this + // build script can be deleted. + let minor = rustc_minor_version().unwrap_or(0); + if minor >= 81 { + println!("cargo:rustc-cfg=core_error"); + } + if minor >= 80 { + println!("cargo:rustc-check-cfg=cfg(core_error)"); + } +} + +fn rustc_minor_version() -> Option { + let rustc = std::env::var("RUSTC").unwrap(); + let output = Command::new(rustc).arg("--version").output().ok()?; + let version = str::from_utf8(&output.stdout).ok()?; + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + pieces.next()?.parse().ok() +} diff --git a/src/build/error.rs b/src/build/error.rs index 364aa2f9..1e56780e 100644 --- a/src/build/error.rs +++ b/src/build/error.rs @@ -24,6 +24,8 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl error::Error for Error {} +#[cfg(all(not(feature = "std"), core_error))] +impl core::error::Error for Error {} impl From for Error { fn from(error: read::Error) -> Error { diff --git a/src/read/mod.rs b/src/read/mod.rs index 74954476..469fab96 100644 --- a/src/read/mod.rs +++ b/src/read/mod.rs @@ -124,6 +124,8 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error {} +#[cfg(all(not(feature = "std"), core_error))] +impl core::error::Error for Error {} /// The result type used within the read module. pub type Result = result::Result; diff --git a/src/write/mod.rs b/src/write/mod.rs index 9a9f2ad6..b20c603d 100644 --- a/src/write/mod.rs +++ b/src/write/mod.rs @@ -60,6 +60,8 @@ impl fmt::Display for Error { #[cfg(feature = "std")] impl error::Error for Error {} +#[cfg(all(not(feature = "std"), core_error))] +impl core::error::Error for Error {} /// The result type used within the write module. pub type Result = result::Result;