diff --git a/crates/compiler/src/lib.rs b/crates/compiler/src/lib.rs index b9608e0..5bef24e 100644 --- a/crates/compiler/src/lib.rs +++ b/crates/compiler/src/lib.rs @@ -7,7 +7,6 @@ use std::{ collections::HashMap, hash::Hash, path::{Path, PathBuf}, - sync::Arc, }; use alloy::json_abi::JsonAbi; @@ -29,7 +28,7 @@ pub mod revive_resolc; pub mod solc; /// A common interface for all supported Solidity compilers. -pub trait SolidityCompiler { +pub trait SolidityCompiler: Sized { /// Instantiates a new compiler object. /// /// Based on the given [`Arguments`] and [`VersionOrRequirement`] this function instantiates a @@ -38,7 +37,7 @@ pub trait SolidityCompiler { fn new( config: &Arguments, version: impl Into>, - ) -> impl Future>>; + ) -> impl Future>; /// Returns the version of the compiler. fn version(&self) -> &Version; diff --git a/crates/compiler/src/revive_resolc.rs b/crates/compiler/src/revive_resolc.rs index 7c0b9da..0a928af 100644 --- a/crates/compiler/src/revive_resolc.rs +++ b/crates/compiler/src/revive_resolc.rs @@ -26,11 +26,13 @@ use semver::Version; use tokio::{io::AsyncWriteExt, process::Command as AsyncCommand}; /// A wrapper around the `resolc` binary, emitting PVM-compatible bytecode. -#[derive(Debug)] -pub struct Resolc { - /// The internal solc compiler that the resolc compiler uses as a compiler frontend. - solc: Arc, +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Resolc(Arc); +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +struct ResolcInner { + /// The internal solc compiler that the resolc compiler uses as a compiler frontend. + solc: Solc, /// Path to the `resolc` executable resolc_path: PathBuf, } @@ -39,12 +41,11 @@ impl SolidityCompiler for Resolc { async fn new( config: &Arguments, version: impl Into>, - ) -> Result> { + ) -> Result { /// This is a cache of all of the resolc compiler objects. Since we do not currently support /// multiple resolc compiler versions, so our cache is just keyed by the solc compiler and /// its version to the resolc compiler. - static COMPILERS_CACHE: LazyLock, Arc>> = - LazyLock::new(Default::default); + static COMPILERS_CACHE: LazyLock> = LazyLock::new(Default::default); let solc = Solc::new(config, version) .await @@ -53,10 +54,10 @@ impl SolidityCompiler for Resolc { Ok(COMPILERS_CACHE .entry(solc.clone()) .or_insert_with(|| { - Arc::new(Self { + Self(Arc::new(ResolcInner { solc, resolc_path: config.resolc.clone(), - }) + })) }) .clone()) } @@ -64,11 +65,11 @@ impl SolidityCompiler for Resolc { fn version(&self) -> &Version { // We currently return the solc compiler version since we do not support multiple resolc // compiler versions. - self.solc.version() + self.0.solc.version() } fn path(&self) -> &std::path::Path { - &self.resolc_path + &self.0.resolc_path } #[tracing::instrument(level = "debug", ret)] @@ -133,7 +134,7 @@ impl SolidityCompiler for Resolc { }, }; - let mut command = AsyncCommand::new(&self.resolc_path); + let mut command = AsyncCommand::new(self.path()); command .stdin(Stdio::piped()) .stdout(Stdio::piped()) @@ -154,7 +155,7 @@ impl SolidityCompiler for Resolc { } let mut child = command .spawn() - .with_context(|| format!("Failed to spawn resolc at {}", self.resolc_path.display()))?; + .with_context(|| format!("Failed to spawn resolc at {}", self.path().display()))?; let stdin_pipe = child.stdin.as_mut().expect("stdin must be piped"); let serialized_input = serde_json::to_vec(&input) @@ -276,6 +277,6 @@ impl SolidityCompiler for Resolc { optimize_setting: ModeOptimizerSetting, pipeline: ModePipeline, ) -> bool { - pipeline == ModePipeline::ViaYulIR && self.solc.supports_mode(optimize_setting, pipeline) + pipeline == ModePipeline::ViaYulIR && self.0.solc.supports_mode(optimize_setting, pipeline) } } diff --git a/crates/compiler/src/solc.rs b/crates/compiler/src/solc.rs index ed016d9..d87f940 100644 --- a/crates/compiler/src/solc.rs +++ b/crates/compiler/src/solc.rs @@ -26,7 +26,10 @@ use semver::Version; use tokio::{io::AsyncWriteExt, process::Command as AsyncCommand}; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Solc { +pub struct Solc(Arc); + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +struct SolcInner { /// The path of the solidity compiler executable that this object uses. solc_path: PathBuf, /// The version of the solidity compiler executable that this object uses. @@ -37,12 +40,11 @@ impl SolidityCompiler for Solc { async fn new( config: &Arguments, version: impl Into>, - ) -> Result> { + ) -> Result { // This is a cache for the compiler objects so that whenever the same compiler version is // requested the same object is returned. We do this as we do not want to keep cloning the // compiler around. - static COMPILERS_CACHE: LazyLock>> = - LazyLock::new(Default::default); + static COMPILERS_CACHE: LazyLock> = LazyLock::new(Default::default); // We attempt to download the solc binary. Note the following: this call does the version // resolution for us. Therefore, even if the download didn't proceed, this function will @@ -56,20 +58,20 @@ impl SolidityCompiler for Solc { Ok(COMPILERS_CACHE .entry(version.clone()) .or_insert_with(|| { - Arc::new(Self { + Self(Arc::new(SolcInner { solc_path: path, solc_version: version, - }) + })) }) .clone()) } fn version(&self) -> &Version { - &self.solc_version + &self.0.solc_version } fn path(&self) -> &std::path::Path { - &self.solc_path + &self.0.solc_path } #[tracing::instrument(level = "debug", ret)] @@ -150,7 +152,7 @@ impl SolidityCompiler for Solc { }, }; - let mut command = AsyncCommand::new(&self.solc_path); + let mut command = AsyncCommand::new(self.path()); command .stdin(Stdio::piped()) .stdout(Stdio::piped()) @@ -171,7 +173,7 @@ impl SolidityCompiler for Solc { } let mut child = command .spawn() - .with_context(|| format!("Failed to spawn solc at {}", self.solc_path.display()))?; + .with_context(|| format!("Failed to spawn solc at {}", self.path().display()))?; let stdin = child.stdin.as_mut().expect("should be piped"); let serialized_input = serde_json::to_vec(&input) @@ -266,6 +268,6 @@ impl SolidityCompiler for Solc { impl Solc { fn compiler_supports_yul(&self) -> bool { const SOLC_VERSION_SUPPORTING_VIA_YUL_IR: Version = Version::new(0, 8, 13); - self.solc_version >= SOLC_VERSION_SUPPORTING_VIA_YUL_IR + self.version() >= &SOLC_VERSION_SUPPORTING_VIA_YUL_IR } } diff --git a/crates/compiler/tests/lib.rs b/crates/compiler/tests/lib.rs index 4ad657c..3e2af4f 100644 --- a/crates/compiler/tests/lib.rs +++ b/crates/compiler/tests/lib.rs @@ -19,7 +19,7 @@ async fn contracts_can_be_compiled_with_solc() { .unwrap() .with_source("./tests/assets/array_one_element/main.sol") .unwrap() - .try_build(solc.as_ref()) + .try_build(&solc) .await; // Assert @@ -60,7 +60,7 @@ async fn contracts_can_be_compiled_with_resolc() { .unwrap() .with_source("./tests/assets/array_one_element/main.sol") .unwrap() - .try_build(resolc.as_ref()) + .try_build(&resolc) .await; // Assert diff --git a/crates/core/src/main.rs b/crates/core/src/main.rs index 5ee0c8e..39bc258 100644 --- a/crates/core/src/main.rs +++ b/crates/core/src/main.rs @@ -514,7 +514,7 @@ where test.metadata_file_path, test.mode.clone(), None, - test.leader_compiler.as_ref(), + &test.leader_compiler, &leader_reporter, ), cached_compiler.compile_contracts::( @@ -522,7 +522,7 @@ where test.metadata_file_path, test.mode.clone(), None, - test.follower_compiler.as_ref(), + &test.follower_compiler, &follower_reporter ) ) @@ -667,7 +667,7 @@ where test.metadata_file_path, test.mode.clone(), leader_deployed_libraries.as_ref(), - test.leader_compiler.as_ref(), + &test.leader_compiler, &leader_reporter, ), cached_compiler.compile_contracts::( @@ -675,7 +675,7 @@ where test.metadata_file_path, test.mode.clone(), follower_deployed_libraries.as_ref(), - test.follower_compiler.as_ref(), + &test.follower_compiler, &follower_reporter ) ) @@ -737,8 +737,8 @@ struct Test<'a, L: Platform, F: Platform> { case: &'a Case, leader_node: &'a ::Blockchain, follower_node: &'a ::Blockchain, - leader_compiler: Arc, - follower_compiler: Arc, + leader_compiler: L::Compiler, + follower_compiler: F::Compiler, reporter: TestSpecificReporter, }