From a88d44f2f90d85156bc78bffc5e2df4e33d77431 Mon Sep 17 00:00:00 2001 From: EFanZh Date: Sun, 7 Feb 2021 23:13:04 +0800 Subject: [PATCH 1/5] Prevent calling `rustc_version::version_meta()` multiple times The custom `ArcError` maybe removed once Rust 1.51 released: https://doc.rust-lang.org/nightly/std/error/trait.Error.html#impl-Error-33. --- Cargo.toml | 1 + src/lib.rs | 9 +++++---- src/rustc.rs | 41 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8e52d80..d91c1d0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ version = "0.3.3" [dependencies] cargo_metadata = "0.11" clap = "2.33" +lazy_static = "1.4" regex = "1.3" rustc-cfg = "0.4" rustc-demangle = "0.1" diff --git a/src/lib.rs b/src/lib.rs index 17e540a..11bf5dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ #![deny(warnings)] +use std::borrow::Cow; use std::io::{self, BufReader, Write}; use std::path::{Component, Path}; use std::process::{Command, Stdio}; @@ -61,10 +62,10 @@ impl Context { // TODO: How will custom profiles impact this? if path == "debug" || path == "release" { // Looks like this artifact was built for the host. - rustc_version::version_meta()?.host + Cow::Borrowed(rustc::version_meta()?.host.as_str()) } else { // The artifact - path.to_string() + Cow::Owned(path.to_string()) } } else { unreachable!(); @@ -76,7 +77,7 @@ impl Context { /// Get a context structure from a provided target flag, used when cargo /// was not used to build the binary. fn from_flag(metadata: Metadata, target_flag: Option<&str>) -> Result { - let host_target_name = rustc_version::version_meta()?.host; + let host_target_name = rustc::version_meta()?.host.as_str(); // Get the "default" target override in .cargo/config. let mut config_target_name = None; @@ -93,7 +94,7 @@ impl Context { // Find the actual target. let target_name = target_flag .or(config_target_name) - .unwrap_or(&host_target_name); + .unwrap_or(host_target_name); Self::from_target_name(target_name) } diff --git a/src/rustc.rs b/src/rustc.rs index 2797b60..ac4ffd8 100644 --- a/src/rustc.rs +++ b/src/rustc.rs @@ -1,8 +1,47 @@ use std::env; +use std::error::Error; +use std::fmt::{self, Debug, Display, Formatter}; use std::path::PathBuf; use std::process::Command; +use std::sync::Arc; use anyhow::Result; +use rustc_version::VersionMeta; + +struct ArcError(Arc); + +impl Debug for ArcError { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Debug::fmt(&self.0, f) + } +} + +impl Display for ArcError { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + Display::fmt(&self.0, f) + } +} + +impl Error for ArcError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + self.0.source() + } +} + +impl Clone for ArcError { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +lazy_static::lazy_static! { + static ref VERSION_META: Result> = + rustc_version::version_meta().map_err(|error| ArcError(Arc::new(error))); +} + +pub fn version_meta() -> Result<&'static VersionMeta> { + VERSION_META.as_ref().map_err(|error| error.clone().into()) +} pub fn sysroot() -> Result { let rustc = env::var_os("RUSTC").unwrap_or_else(|| "rustc".into()); @@ -17,7 +56,7 @@ pub fn rustlib() -> Result { let mut pathbuf = PathBuf::from(sysroot); pathbuf.push("lib"); pathbuf.push("rustlib"); - pathbuf.push(rustc_version::version_meta()?.host); // TODO: Prevent calling rustc_version::version_meta() multiple times + pathbuf.push(&version_meta()?.host); pathbuf.push("bin"); Ok(pathbuf) } From 29aeb2fc5c1b45f776f351d62d87e48b41edeee7 Mon Sep 17 00:00:00 2001 From: EFanZh Date: Mon, 8 Feb 2021 09:10:24 +0800 Subject: [PATCH 2/5] No need to use `Arc` --- src/rustc.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/rustc.rs b/src/rustc.rs index ac4ffd8..412da61 100644 --- a/src/rustc.rs +++ b/src/rustc.rs @@ -3,44 +3,44 @@ use std::error::Error; use std::fmt::{self, Debug, Display, Formatter}; use std::path::PathBuf; use std::process::Command; -use std::sync::Arc; use anyhow::Result; use rustc_version::VersionMeta; -struct ArcError(Arc); +struct RefError<'a, T>(&'a T); -impl Debug for ArcError { +impl<'a, T: Debug> Debug for RefError<'a, T> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - Debug::fmt(&self.0, f) + Debug::fmt(self.0, f) } } -impl Display for ArcError { +impl<'a, T: Display> Display for RefError<'a, T> { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - Display::fmt(&self.0, f) + Display::fmt(self.0, f) } } -impl Error for ArcError { +impl<'a, T: Error> Error for RefError<'a, T> { fn source(&self) -> Option<&(dyn Error + 'static)> { self.0.source() } } -impl Clone for ArcError { +impl<'a, T> Clone for RefError<'a, T> { fn clone(&self) -> Self { - Self(self.0.clone()) + Self(self.0) } } lazy_static::lazy_static! { - static ref VERSION_META: Result> = - rustc_version::version_meta().map_err(|error| ArcError(Arc::new(error))); + static ref VERSION_META: Result = rustc_version::version_meta(); } pub fn version_meta() -> Result<&'static VersionMeta> { - VERSION_META.as_ref().map_err(|error| error.clone().into()) + VERSION_META + .as_ref() + .map_err(|error| RefError(error).into()) } pub fn sysroot() -> Result { From ea81e6daf33bb0d7507f15124cd3c649edc8facb Mon Sep 17 00:00:00 2001 From: EFanZh Date: Mon, 8 Feb 2021 09:14:00 +0800 Subject: [PATCH 3/5] No need to implement `Clone` now --- src/rustc.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/rustc.rs b/src/rustc.rs index 412da61..b3c1e93 100644 --- a/src/rustc.rs +++ b/src/rustc.rs @@ -27,12 +27,6 @@ impl<'a, T: Error> Error for RefError<'a, T> { } } -impl<'a, T> Clone for RefError<'a, T> { - fn clone(&self) -> Self { - Self(self.0) - } -} - lazy_static::lazy_static! { static ref VERSION_META: Result = rustc_version::version_meta(); } From 5e2e97c7a0c464bd68ec35134013798e369165f7 Mon Sep 17 00:00:00 2001 From: EFanZh Date: Mon, 8 Feb 2021 09:17:59 +0800 Subject: [PATCH 4/5] Avoid create new `String`s --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 11bf5dc..554c26e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,7 +65,7 @@ impl Context { Cow::Borrowed(rustc::version_meta()?.host.as_str()) } else { // The artifact - Cow::Owned(path.to_string()) + path } } else { unreachable!(); From ab6b4a107518d12b1863268fe0981b49425b0e2e Mon Sep 17 00:00:00 2001 From: EFanZh Date: Mon, 8 Feb 2021 09:20:04 +0800 Subject: [PATCH 5/5] Use `Into::into` for type conversion --- src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 554c26e..c338fa4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ #![deny(warnings)] -use std::borrow::Cow; use std::io::{self, BufReader, Write}; use std::path::{Component, Path}; use std::process::{Command, Stdio}; @@ -62,7 +61,7 @@ impl Context { // TODO: How will custom profiles impact this? if path == "debug" || path == "release" { // Looks like this artifact was built for the host. - Cow::Borrowed(rustc::version_meta()?.host.as_str()) + rustc::version_meta()?.host.as_str().into() } else { // The artifact path