diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index edd3dabbe..aeb86b8ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,11 +26,11 @@ jobs: fail-fast: false matrix: os: ["ubuntu-latest", "macos-latest", "windows-latest"] - rust: ["stable", "1.88"] + rust: ["stable", "1.93"] flags: ["", "--all-features"] exclude: # Skip because some features have higher MSRV. - - rust: "1.88" # MSRV + - rust: "1.93" # MSRV flags: "--all-features" steps: - uses: actions/checkout@v5 diff --git a/Cargo.toml b/Cargo.toml index feb3c3863..707058bbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,11 @@ [workspace] members = ["crates/artifacts/*", "crates/core", "crates/compilers"] -resolver = "2" +resolver = "3" [workspace.package] authors = ["Foundry Maintainers"] version = "0.19.14" -rust-version = "1.88" +rust-version = "1.93" readme = "README.md" license = "MIT OR Apache-2.0" repository = "https://github.com/foundry-rs/compilers" @@ -13,24 +13,30 @@ homepage = "https://github.com/foundry-rs/compilers" documentation = "https://docs.rs/foundry-compilers" description = "Utilities for working with EVM language compilers" keywords = ["foundry", "solidity", "solc", "ethereum", "ethers"] -edition = "2021" +edition = "2024" exclude = [".github/", "scripts/", "test-data/"] [workspace.lints.clippy] +borrow_as_ptr = "warn" +branches_sharing_code = "warn" +clear_with_drain = "warn" +cloned_instead_of_copied = "warn" +collection_is_never_read = "warn" dbg-macro = "warn" +explicit_iter_loop = "warn" manual-string-new = "warn" uninlined-format-args = "warn" use-self = "warn" redundant-clone = "warn" - -result-large-err = "allow" -large-enum-variant = "allow" +result_large_err = "allow" +large_enum_variant = "allow" [workspace.lints.rust] +redundant_imports = "warn" +redundant-lifetimes = "warn" rust-2018-idioms = "warn" -# unreachable-pub = "warn" unused-must-use = "warn" -redundant-lifetimes = "warn" +# unreachable-pub = "warn" [workspace.lints.rustdoc] all = "warn" diff --git a/clippy.toml b/clippy.toml index f3322b5fd..c5e04e2e3 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -msrv = "1.88" +msrv = "1.93" diff --git a/crates/artifacts/solc/src/ast/lowfidelity.rs b/crates/artifacts/solc/src/ast/lowfidelity.rs index 57e1c2746..2a9f987c2 100644 --- a/crates/artifacts/solc/src/ast/lowfidelity.rs +++ b/crates/artifacts/solc/src/ast/lowfidelity.rs @@ -1,7 +1,7 @@ //! Bindings for solc's `ast` output field use crate::serde_helpers; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde::{Deserialize, Serialize, de::DeserializeOwned}; use std::{collections::BTreeMap, fmt, fmt::Write, str::FromStr}; /// Represents the AST field in the solc output diff --git a/crates/artifacts/solc/src/bytecode.rs b/crates/artifacts/solc/src/bytecode.rs index 5866dcdf6..7e0a18a31 100644 --- a/crates/artifacts/solc/src/bytecode.rs +++ b/crates/artifacts/solc/src/bytecode.rs @@ -1,11 +1,10 @@ //! Bytecode related types. use crate::{ - serde_helpers, + FunctionDebugData, GeneratedSource, Offsets, serde_helpers, sourcemap::{self, SourceMap, SyntaxError}, - FunctionDebugData, GeneratedSource, Offsets, }; -use alloy_primitives::{hex, Address, Bytes}; +use alloy_primitives::{Address, Bytes, hex}; use foundry_compilers_core::utils; use serde::{Deserialize, Serialize, Serializer}; use std::collections::BTreeMap; @@ -286,10 +285,10 @@ impl BytecodeObject { /// /// Returns the string if it is a valid pub fn resolve(&mut self) -> Option<&Bytes> { - if let Self::Unlinked(unlinked) = self { - if let Ok(linked) = hex::decode(unlinked) { - *self = Self::Bytecode(linked.into()); - } + if let Self::Unlinked(unlinked) = self + && let Ok(linked) = hex::decode(unlinked) + { + *self = Self::Bytecode(linked.into()); } self.as_bytes() } diff --git a/crates/artifacts/solc/src/configurable.rs b/crates/artifacts/solc/src/configurable.rs index 4a24a8352..75dcabf9a 100644 --- a/crates/artifacts/solc/src/configurable.rs +++ b/crates/artifacts/solc/src/configurable.rs @@ -74,10 +74,10 @@ impl ConfigurableContractArtifact { links.extend(bcode.link_references.clone()); } - if let Some(d_bcode) = &self.deployed_bytecode { - if let Some(bcode) = &d_bcode.bytecode { - links.extend(bcode.link_references.clone()); - } + if let Some(d_bcode) = &self.deployed_bytecode + && let Some(bcode) = &d_bcode.bytecode + { + links.extend(bcode.link_references.clone()); } links } diff --git a/crates/artifacts/solc/src/contract.rs b/crates/artifacts/solc/src/contract.rs index 7101b84df..b3f5fd7c5 100644 --- a/crates/artifacts/solc/src/contract.rs +++ b/crates/artifacts/solc/src/contract.rs @@ -1,10 +1,11 @@ //! Contract related types. use crate::{ + DevDoc, Evm, Ewasm, LosslessMetadata, Offsets, StorageLayout, UserDoc, bytecode::{ Bytecode, BytecodeObject, CompactBytecode, CompactDeployedBytecode, DeployedBytecode, }, - serde_helpers, DevDoc, Evm, Ewasm, LosslessMetadata, Offsets, StorageLayout, UserDoc, + serde_helpers, }; use alloy_json_abi::JsonAbi; use alloy_primitives::Bytes; @@ -101,10 +102,10 @@ impl ContractBytecode { links.extend(bcode.link_references.clone()); } - if let Some(d_bcode) = &self.deployed_bytecode { - if let Some(bcode) = &d_bcode.bytecode { - links.extend(bcode.link_references.clone()); - } + if let Some(d_bcode) = &self.deployed_bytecode + && let Some(bcode) = &d_bcode.bytecode + { + links.extend(bcode.link_references.clone()); } links } @@ -146,10 +147,10 @@ impl CompactContractBytecode { links.extend(bcode.link_references.clone()); } - if let Some(d_bcode) = &self.deployed_bytecode { - if let Some(bcode) = &d_bcode.bytecode { - links.extend(bcode.link_references.clone()); - } + if let Some(d_bcode) = &self.deployed_bytecode + && let Some(bcode) = &d_bcode.bytecode + { + links.extend(bcode.link_references.clone()); } links } diff --git a/crates/artifacts/solc/src/lib.rs b/crates/artifacts/solc/src/lib.rs index d2672a3e4..bbf4f17d5 100644 --- a/crates/artifacts/solc/src/lib.rs +++ b/crates/artifacts/solc/src/lib.rs @@ -8,7 +8,7 @@ extern crate tracing; use semver::Version; -use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Visitor}; use std::{ collections::{BTreeMap, HashSet}, fmt, @@ -37,9 +37,8 @@ use crate::output_selection::{ContractOutputSelection, OutputSelection}; use foundry_compilers_core::{ error::SolcError, utils::{ - strip_prefix_owned, BERLIN_SOLC, BYZANTIUM_SOLC, CANCUN_SOLC, CONSTANTINOPLE_SOLC, - ISTANBUL_SOLC, LONDON_SOLC, OSAKA_SOLC, PARIS_SOLC, PETERSBURG_SOLC, PRAGUE_SOLC, - SHANGHAI_SOLC, + BERLIN_SOLC, BYZANTIUM_SOLC, CANCUN_SOLC, CONSTANTINOPLE_SOLC, ISTANBUL_SOLC, LONDON_SOLC, + OSAKA_SOLC, PARIS_SOLC, PETERSBURG_SOLC, PRAGUE_SOLC, SHANGHAI_SOLC, strip_prefix_owned, }, }; pub use serde_helpers::{deserialize_bytes, deserialize_opt_bytes}; @@ -341,11 +340,11 @@ impl Settings { meta.cbor_metadata = None; } - if let Some(model_checker) = &mut self.model_checker { - if let Some(solvers) = &mut model_checker.solvers { - // elf solver introduced in 0.8.18 - solvers.retain(|solver| *solver != ModelCheckerSolver::Eld); - } + if let Some(model_checker) = &mut self.model_checker + && let Some(solvers) = &mut model_checker.solvers + { + // elf solver introduced in 0.8.18 + solvers.retain(|solver| *solver != ModelCheckerSolver::Eld); } } @@ -394,7 +393,7 @@ impl Settings { /// Inserts the value for all files and contracts /// /// ``` - /// use foundry_compilers_artifacts_solc::{output_selection::ContractOutputSelection, Settings}; + /// use foundry_compilers_artifacts_solc::{Settings, output_selection::ContractOutputSelection}; /// let mut selection = Settings::default(); /// selection.push_output_selection(ContractOutputSelection::Metadata); /// ``` @@ -1857,7 +1856,7 @@ mod tests { object.object } - let bytecode = "6060604052341561000f57600080fd5b60f48061001d6000396000f300606060405260043610603e5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166326121ff081146043575b600080fd5b3415604d57600080fd5b60536055565b005b73__lib2.sol:L____________________________6326121ff06040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b151560b357600080fd5b6102c65a03f4151560c357600080fd5b5050505600a165627a7a723058207979b30bd4a07c77b02774a511f2a1dd04d7e5d65b5c2735b5fc96ad61d43ae40029"; + let bytecode = "6060604052341561000f57600080fd5b60f48061001d6000396000f300606060405260043610603e5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166326121ff081146043575b600080fd5b3415604d57600080fd5b60536055565b005b73__lib2.sol:L____________________________6326121ff06040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160006040518083038186803b151560b357600080fd5b6102c65a03f4151560c357600080fd5b5050505600a165627a7a723058207979b30bd4a07c77b02774a511f2a1dd04d7e5d65b5c2735b5fc96ad61d43ae40029"; let mut object = parse_bytecode(bytecode); assert!(object.is_unlinked()); @@ -2201,7 +2200,10 @@ mod tests { let value: serde_json::Value = serde_json::from_str(s).unwrap(); let c: Contract = serde_json::from_value(value).unwrap(); - assert_eq!(c.metadata.as_ref().unwrap().raw_metadata, "{\"compiler\":{\"version\":\"0.4.18+commit.9cf6e910\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"newOwner\":\"The address to transfer ownership to.\"}}},\"title\":\"Ownable\"},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"src/Contract.sol\":\"Ownable\"},\"libraries\":{},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[\":src/=src/\"]},\"sources\":{\"src/Contract.sol\":{\"keccak256\":\"0x3e0d611f53491f313ae035797ed7ecfd1dfd8db8fef8f82737e6f0cd86d71de7\",\"urls\":[\"bzzr://9c33025fa9d1b8389e4c7c9534a1d70fad91c6c2ad70eb5e4b7dc3a701a5f892\"]}},\"version\":1}"); + assert_eq!( + c.metadata.as_ref().unwrap().raw_metadata, + "{\"compiler\":{\"version\":\"0.4.18+commit.9cf6e910\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"newOwner\":\"The address to transfer ownership to.\"}}},\"title\":\"Ownable\"},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"src/Contract.sol\":\"Ownable\"},\"libraries\":{},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[\":src/=src/\"]},\"sources\":{\"src/Contract.sol\":{\"keccak256\":\"0x3e0d611f53491f313ae035797ed7ecfd1dfd8db8fef8f82737e6f0cd86d71de7\",\"urls\":[\"bzzr://9c33025fa9d1b8389e4c7c9534a1d70fad91c6c2ad70eb5e4b7dc3a701a5f892\"]}},\"version\":1}" + ); let value = serde_json::to_string(&c).unwrap(); assert_eq!(s, value); diff --git a/crates/artifacts/solc/src/output_selection.rs b/crates/artifacts/solc/src/output_selection.rs index 0ca81a76e..cf96ec5eb 100644 --- a/crates/artifacts/solc/src/output_selection.rs +++ b/crates/artifacts/solc/src/output_selection.rs @@ -1,6 +1,6 @@ //! Bindings for standard json output selection. -use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer, ser::SerializeMap}; use std::{collections::BTreeMap, fmt, str::FromStr}; /// Represents the desired outputs based on a File `(file -> (contract -> [outputs]))` @@ -169,7 +169,7 @@ impl Serialize for OutputSelection { } let mut map = serializer.serialize_map(Some(self.0.len()))?; - for (file, selection) in self.0.iter() { + for (file, selection) in &self.0 { if selection.is_empty() { map.serialize_entry(file, &EmptyFileOutput {})?; } else { diff --git a/crates/artifacts/solc/src/remappings/find.rs b/crates/artifacts/solc/src/remappings/find.rs index f24f9f6f8..5a8dbcb16 100644 --- a/crates/artifacts/solc/src/remappings/find.rs +++ b/crates/artifacts/solc/src/remappings/find.rs @@ -2,7 +2,7 @@ use super::Remapping; use foundry_compilers_core::utils; use rayon::prelude::*; use std::{ - collections::{btree_map::Entry, BTreeMap, HashSet}, + collections::{BTreeMap, HashSet, btree_map::Entry}, fs::FileType, path::{Path, PathBuf}, sync::Mutex, @@ -325,19 +325,17 @@ fn find_remapping_candidates( // ├── dep/node_modules // ├── symlink to `my-package` // ``` - if path_is_symlink { - if let Ok(target) = utils::canonicalize(&subdir) { - if !visited_symlink_dirs.lock().unwrap().insert(target.clone()) { - // short-circuiting if we've already visited the symlink - return Vec::new(); - } - // the symlink points to a parent dir of the current window - if open.components().count() > target.components().count() - && utils::common_ancestor(open, &target).is_some() - { - // short-circuiting - return Vec::new(); - } + if path_is_symlink && let Ok(target) = utils::canonicalize(&subdir) { + if !visited_symlink_dirs.lock().unwrap().insert(target.clone()) { + // short-circuiting if we've already visited the symlink + return Vec::new(); + } + // the symlink points to a parent dir of the current window + if open.components().count() > target.components().count() + && utils::common_ancestor(open, &target).is_some() + { + // short-circuiting + return Vec::new(); } } @@ -449,11 +447,7 @@ fn dir_distance(root: &Path, current: &Path) -> usize { if root == current { return 0; } - if let Ok(rem) = current.strip_prefix(root) { - rem.components().count() - } else { - 0 - } + if let Ok(rem) = current.strip_prefix(root) { rem.components().count() } else { 0 } } /// This finds the next window between `root` and `current` @@ -511,11 +505,14 @@ mod tests { "/var/folders/l5/lprhf87s6xv8djgd017f0b2h0000gn/T/lib.Z6ODLZJQeJQa/repo1/lib", ); let b = Path::new( - "/var/folders/l5/lprhf87s6xv8djgd017f0b2h0000gn/T/lib.Z6ODLZJQeJQa/repo1/lib/ds-test/src" + "/var/folders/l5/lprhf87s6xv8djgd017f0b2h0000gn/T/lib.Z6ODLZJQeJQa/repo1/lib/ds-test/src", + ); + assert_eq!( + next_nested_window(a, b), + Path::new( + "/var/folders/l5/lprhf87s6xv8djgd017f0b2h0000gn/T/lib.Z6ODLZJQeJQa/repo1/lib/ds-test" + ) ); - assert_eq!(next_nested_window(a, b),Path::new( - "/var/folders/l5/lprhf87s6xv8djgd017f0b2h0000gn/T/lib.Z6ODLZJQeJQa/repo1/lib/ds-test" - )); } #[test] diff --git a/crates/artifacts/solc/src/serde_helpers.rs b/crates/artifacts/solc/src/serde_helpers.rs index 73526a956..783a393b6 100644 --- a/crates/artifacts/solc/src/serde_helpers.rs +++ b/crates/artifacts/solc/src/serde_helpers.rs @@ -28,8 +28,8 @@ where pub mod json_string_opt { use serde::{ - de::{self, DeserializeOwned}, Deserialize, Deserializer, Serialize, Serializer, + de::{self, DeserializeOwned}, }; pub fn serialize(value: &Option, serializer: S) -> Result @@ -64,8 +64,8 @@ pub mod json_string_opt { /// deserializes empty json object `{}` as `None` pub mod empty_json_object_opt { use serde::{ - de::{self, DeserializeOwned}, Deserialize, Deserializer, Serialize, Serializer, + de::{self, DeserializeOwned}, }; pub fn serialize(value: &Option, serializer: S) -> Result @@ -117,16 +117,12 @@ pub mod string_bytes { D: Deserializer<'de>, { let value = String::deserialize(deserializer)?; - if let Some(rem) = value.strip_prefix("0x") { - Ok(rem.to_string()) - } else { - Ok(value) - } + if let Some(rem) = value.strip_prefix("0x") { Ok(rem.to_string()) } else { Ok(value) } } } pub mod display_from_str_opt { - use serde::{de, Deserialize, Deserializer, Serializer}; + use serde::{Deserialize, Deserializer, Serializer, de}; use std::{fmt, str::FromStr}; pub fn serialize(value: &Option, serializer: S) -> Result @@ -156,7 +152,7 @@ pub mod display_from_str_opt { } pub mod display_from_str { - use serde::{de, Deserialize, Deserializer, Serializer}; + use serde::{Deserialize, Deserializer, Serializer, de}; use std::{fmt, str::FromStr}; pub fn serialize(value: &T, serializer: S) -> Result @@ -179,7 +175,7 @@ pub mod display_from_str { /// (De)serialize vec of tuples as map pub mod tuple_vec_map { - use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize, Serializer}; + use serde::{Deserialize, Deserializer, Serialize, Serializer, de::DeserializeOwned}; pub fn serialize(data: &[(K, V)], serializer: S) -> Result where diff --git a/crates/artifacts/solc/src/sourcemap.rs b/crates/artifacts/solc/src/sourcemap.rs index 39fd60bfd..088584594 100644 --- a/crates/artifacts/solc/src/sourcemap.rs +++ b/crates/artifacts/solc/src/sourcemap.rs @@ -130,7 +130,7 @@ impl<'input> Lexer<'input> { fn number(&mut self, start: usize, mut end: usize) -> Token<'input> { loop { - if let Some((_, ch)) = self.chars.peek().cloned() { + if let Some((_, ch)) = self.chars.peek().copied() { if !ch.is_ascii_digit() { break; } @@ -238,11 +238,7 @@ impl SourceElement { /// This case is represented as a `None` value. #[inline] pub fn index(&self) -> Option { - if self.index == -1 { - None - } else { - Some(self.index as u32) - } + if self.index == -1 { None } else { Some(self.index as u32) } } /// The source index. @@ -594,7 +590,9 @@ mod tests { if s != input { return Err(SyntaxError::new( None, - format!("mismatched output:\n actual: {s:?}\n expected: {input:?}\n sm: {sm:#?}"), + format!( + "mismatched output:\n actual: {s:?}\n expected: {input:?}\n sm: {sm:#?}" + ), )); } Ok(sm) diff --git a/crates/artifacts/solc/src/sources.rs b/crates/artifacts/solc/src/sources.rs index 2b929ad7a..1b3b24243 100644 --- a/crates/artifacts/solc/src/sources.rs +++ b/crates/artifacts/solc/src/sources.rs @@ -157,12 +157,11 @@ impl Source { // see also // check if there exists a file with different case #[cfg(feature = "walkdir")] - if !exists { - if let Some(existing_file) = + if !exists + && let Some(existing_file) = foundry_compilers_core::utils::find_case_sensitive_existing_file(file) - { - return SolcError::ResolveCaseSensitiveFileName { error: err, existing_file }; - } + { + return SolcError::ResolveCaseSensitiveFileName { error: err, existing_file }; } SolcError::Resolve(err) diff --git a/crates/artifacts/vyper/src/input.rs b/crates/artifacts/vyper/src/input.rs index 6e18f1dfb..d6fff1a38 100644 --- a/crates/artifacts/vyper/src/input.rs +++ b/crates/artifacts/vyper/src/input.rs @@ -65,7 +65,6 @@ impl VyperInput { #[cfg(test)] mod tests { use super::*; - use crate::VyperSettings; use foundry_compilers_artifacts_solc::EvmVersion; #[test] diff --git a/crates/artifacts/vyper/src/settings.rs b/crates/artifacts/vyper/src/settings.rs index f162d2871..4e8c09f22 100644 --- a/crates/artifacts/vyper/src/settings.rs +++ b/crates/artifacts/vyper/src/settings.rs @@ -1,5 +1,5 @@ use foundry_compilers_artifacts_solc::{ - output_selection::OutputSelection, serde_helpers, EvmVersion, + EvmVersion, output_selection::OutputSelection, serde_helpers, }; use semver::Version; use serde::{Deserialize, Serialize}; diff --git a/crates/compilers/src/artifact_output/configurable.rs b/crates/compilers/src/artifact_output/configurable.rs index 1968b777d..15de58e7b 100644 --- a/crates/compilers/src/artifact_output/configurable.rs +++ b/crates/compilers/src/artifact_output/configurable.rs @@ -9,20 +9,20 @@ //! addition to that some output values can also be emitted as standalone files. use crate::{ - sources::VersionedSourceFile, Artifact, ArtifactFile, ArtifactOutput, SolcConfig, SolcError, - SourceFile, + Artifact, ArtifactFile, ArtifactOutput, SolcConfig, SolcError, SourceFile, + sources::VersionedSourceFile, }; use alloy_json_abi::JsonAbi; use alloy_primitives::hex; use foundry_compilers_artifacts::{ + BytecodeObject, ConfigurableContractArtifact, Evm, Ewasm, GeneratedSource, LosslessMetadata, + Metadata, Settings, bytecode::{CompactBytecode, CompactDeployedBytecode}, contract::Contract, output_selection::{ BytecodeOutputSelection, ContractOutputSelection, DeployedBytecodeOutputSelection, EvmOutputSelection, EwasmOutputSelection, }, - BytecodeObject, ConfigurableContractArtifact, Evm, Ewasm, GeneratedSource, LosslessMetadata, - Metadata, Settings, }; use foundry_compilers_core::utils; use std::{fs, path::Path}; @@ -177,7 +177,7 @@ impl ArtifactOutput for ConfigurableArtifacts { contracts: &crate::VersionedContracts, artifacts: &crate::Artifacts, ) -> Result<(), SolcError> { - for (file, contracts) in contracts.as_ref().iter() { + for (file, contracts) in contracts.as_ref() { for (name, versioned_contracts) in contracts { for contract in versioned_contracts { if let Some(artifact) = artifacts.find_artifact_with_profile( @@ -237,11 +237,11 @@ impl ArtifactOutput for ConfigurableArtifacts { ir_optimized_ast, } = contract; - if self.additional_values.metadata || self.additional_files.metadata { - if let Some(LosslessMetadata { raw_metadata, metadata }) = metadata { - artifact_raw_metadata = Some(raw_metadata); - artifact_metadata = Some(metadata); - } + if (self.additional_values.metadata || self.additional_files.metadata) + && let Some(LosslessMetadata { raw_metadata, metadata }) = metadata + { + artifact_raw_metadata = Some(raw_metadata); + artifact_metadata = Some(metadata); } if self.additional_values.userdoc { artifact_userdoc = Some(userdoc); @@ -681,33 +681,33 @@ impl ExtraOutputFiles { } fn process_abi(&self, abi: Option<&JsonAbi>, file: &Path) -> Result<(), SolcError> { - if self.abi { - if let Some(abi) = abi { - let file = file.with_extension("abi.json"); - fs::write(&file, serde_json::to_string_pretty(abi)?) - .map_err(|err| SolcError::io(err, file))? - } + if self.abi + && let Some(abi) = abi + { + let file = file.with_extension("abi.json"); + fs::write(&file, serde_json::to_string_pretty(abi)?) + .map_err(|err| SolcError::io(err, file))? } Ok(()) } fn process_metadata(&self, metadata: Option<&Metadata>, file: &Path) -> Result<(), SolcError> { - if self.metadata { - if let Some(metadata) = metadata { - let file = file.with_extension("metadata.json"); - fs::write(&file, serde_json::to_string_pretty(metadata)?) - .map_err(|err| SolcError::io(err, file))? - } + if self.metadata + && let Some(metadata) = metadata + { + let file = file.with_extension("metadata.json"); + fs::write(&file, serde_json::to_string_pretty(metadata)?) + .map_err(|err| SolcError::io(err, file))? } Ok(()) } fn process_ir(&self, ir: Option<&str>, file: &Path) -> Result<(), SolcError> { - if self.ir { - if let Some(ir) = ir { - let file = file.with_extension("ir"); - fs::write(&file, ir).map_err(|err| SolcError::io(err, file))? - } + if self.ir + && let Some(ir) = ir + { + let file = file.with_extension("ir"); + fs::write(&file, ir).map_err(|err| SolcError::io(err, file))? } Ok(()) } @@ -717,32 +717,32 @@ impl ExtraOutputFiles { ir_optimized: Option<&str>, file: &Path, ) -> Result<(), SolcError> { - if self.ir_optimized { - if let Some(ir_optimized) = ir_optimized { - let file = file.with_extension("iropt"); - fs::write(&file, ir_optimized).map_err(|err| SolcError::io(err, file))? - } + if self.ir_optimized + && let Some(ir_optimized) = ir_optimized + { + let file = file.with_extension("iropt"); + fs::write(&file, ir_optimized).map_err(|err| SolcError::io(err, file))? } Ok(()) } fn process_ewasm(&self, ewasm: Option<&Ewasm>, file: &Path) -> Result<(), SolcError> { - if self.ewasm { - if let Some(ewasm) = ewasm { - let file = file.with_extension("ewasm"); - fs::write(&file, serde_json::to_vec_pretty(ewasm)?) - .map_err(|err| SolcError::io(err, file))?; - } + if self.ewasm + && let Some(ewasm) = ewasm + { + let file = file.with_extension("ewasm"); + fs::write(&file, serde_json::to_vec_pretty(ewasm)?) + .map_err(|err| SolcError::io(err, file))?; } Ok(()) } fn process_assembly(&self, asm: Option<&str>, file: &Path) -> Result<(), SolcError> { - if self.assembly { - if let Some(asm) = asm { - let file = file.with_extension("asm"); - fs::write(&file, asm).map_err(|err| SolcError::io(err, file))? - } + if self.assembly + && let Some(asm) = asm + { + let file = file.with_extension("asm"); + fs::write(&file, asm).map_err(|err| SolcError::io(err, file))? } Ok(()) } @@ -752,11 +752,11 @@ impl ExtraOutputFiles { asm: Option, file: &Path, ) -> Result<(), SolcError> { - if self.legacy_assembly { - if let Some(legacy_asm) = asm { - let file = file.with_extension("legacyAssembly.json"); - fs::write(&file, format!("{legacy_asm}")).map_err(|err| SolcError::io(err, file))? - } + if self.legacy_assembly + && let Some(legacy_asm) = asm + { + let file = file.with_extension("legacyAssembly.json"); + fs::write(&file, format!("{legacy_asm}")).map_err(|err| SolcError::io(err, file))? } Ok(()) } @@ -766,22 +766,22 @@ impl ExtraOutputFiles { generated_sources: Option<&Vec>, file: &Path, ) -> Result<(), SolcError> { - if self.generated_sources { - if let Some(generated_sources) = generated_sources { - let file = file.with_extension("gensources"); - fs::write(&file, serde_json::to_vec_pretty(generated_sources)?) - .map_err(|err| SolcError::io(err, file))?; - } + if self.generated_sources + && let Some(generated_sources) = generated_sources + { + let file = file.with_extension("gensources"); + fs::write(&file, serde_json::to_vec_pretty(generated_sources)?) + .map_err(|err| SolcError::io(err, file))?; } Ok(()) } fn process_source_map(&self, source_map: Option<&str>, file: &Path) -> Result<(), SolcError> { - if self.source_map { - if let Some(source_map) = source_map { - let file = file.with_extension("sourcemap"); - fs::write(&file, source_map).map_err(|err| SolcError::io(err, file))? - } + if self.source_map + && let Some(source_map) = source_map + { + let file = file.with_extension("sourcemap"); + fs::write(&file, source_map).map_err(|err| SolcError::io(err, file))? } Ok(()) } @@ -791,12 +791,12 @@ impl ExtraOutputFiles { bytecode: Option<&BytecodeObject>, file: &Path, ) -> Result<(), SolcError> { - if self.bytecode { - if let Some(bytecode) = bytecode { - let code = hex::encode(bytecode.as_ref()); - let file = file.with_extension("bin"); - fs::write(&file, code).map_err(|err| SolcError::io(err, file))? - } + if self.bytecode + && let Some(bytecode) = bytecode + { + let code = hex::encode(bytecode.as_ref()); + let file = file.with_extension("bin"); + fs::write(&file, code).map_err(|err| SolcError::io(err, file))? } Ok(()) } @@ -806,12 +806,12 @@ impl ExtraOutputFiles { deployed: Option<&BytecodeObject>, file: &Path, ) -> Result<(), SolcError> { - if self.deployed_bytecode { - if let Some(deployed) = deployed { - let code = hex::encode(deployed.as_ref()); - let file = file.with_extension("deployed-bin"); - fs::write(&file, code).map_err(|err| SolcError::io(err, file))? - } + if self.deployed_bytecode + && let Some(deployed) = deployed + { + let code = hex::encode(deployed.as_ref()); + let file = file.with_extension("deployed-bin"); + fs::write(&file, code).map_err(|err| SolcError::io(err, file))? } Ok(()) } diff --git a/crates/compilers/src/artifact_output/hh.rs b/crates/compilers/src/artifact_output/hh.rs index 8c85cf2df..2029eaba8 100644 --- a/crates/compilers/src/artifact_output/hh.rs +++ b/crates/compilers/src/artifact_output/hh.rs @@ -1,7 +1,7 @@ -use crate::{output::sources::VersionedSourceFile, ArtifactOutput}; +use crate::{ArtifactOutput, output::sources::VersionedSourceFile}; use foundry_compilers_artifacts::{ - hh::{HardhatArtifact, HH_ARTIFACT_VERSION}, Contract, SourceFile, + hh::{HH_ARTIFACT_VERSION, HardhatArtifact}, }; use std::path::Path; diff --git a/crates/compilers/src/artifact_output/mod.rs b/crates/compilers/src/artifact_output/mod.rs index b07994134..3ea7efb23 100644 --- a/crates/compilers/src/artifact_output/mod.rs +++ b/crates/compilers/src/artifact_output/mod.rs @@ -3,10 +3,10 @@ use alloy_json_abi::JsonAbi; use alloy_primitives::Bytes; use foundry_compilers_artifacts::{ - hh::HardhatArtifact, - sourcemap::{SourceMap, SyntaxError}, BytecodeObject, CompactBytecode, CompactContract, CompactContractBytecode, CompactContractBytecodeCow, CompactDeployedBytecode, Contract, FileToContractsMap, SourceFile, + hh::HardhatArtifact, + sourcemap::{SourceMap, SyntaxError}, }; use foundry_compilers_core::{ error::{Result, SolcError, SolcIoError}, @@ -14,10 +14,10 @@ use foundry_compilers_core::{ }; use path_slash::PathBufExt; use semver::Version; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde::{Deserialize, Serialize, de::DeserializeOwned}; use std::{ borrow::Cow, - collections::{btree_map::BTreeMap, HashMap, HashSet}, + collections::{HashMap, HashSet, btree_map::BTreeMap}, ffi::OsString, fmt, fs, hash::Hash, @@ -32,12 +32,12 @@ mod hh; pub use hh::*; use crate::{ + CompilerContract, ProjectPathsConfig, cache::{CachedArtifacts, CompilerCache}, output::{ contracts::VersionedContracts, sources::{VersionedSourceFile, VersionedSourceFiles}, }, - CompilerContract, ProjectPathsConfig, }; /// Represents unique artifact metadata for identifying artifacts on output @@ -952,7 +952,7 @@ pub trait ArtifactOutput { // this is unfortunately necessary, so we can "mock" `Artifacts` for solidity files without // any contract definition, which are not included in the `CompilerOutput` but we want to // create Artifacts for them regardless - for (file, sources) in sources.as_ref().iter() { + for (file, sources) in sources.as_ref() { let unique_versions = sources.iter().map(|s| &s.version).collect::>(); let unique_profiles = sources.iter().map(|s| &s.profile).collect::>(); for source in sources { @@ -968,38 +968,36 @@ pub trait ArtifactOutput { } // we use file and file stem - if let Some(name) = Path::new(file).file_stem().and_then(|stem| stem.to_str()) { - if let Some(artifact) = + if let Some(name) = Path::new(file).file_stem().and_then(|stem| stem.to_str()) + && let Some(artifact) = self.standalone_source_file_to_artifact(file, source) - { - let artifact_path = Self::get_artifact_path( - &ctx, - &taken_paths_lowercase, - file, - name, - &layout.artifacts, - &source.version, - &source.profile, - unique_versions.len() > 1, - unique_profiles.len() > 1, - ); - - taken_paths_lowercase - .insert(artifact_path.to_slash_lossy().to_lowercase()); - - artifacts - .entry(file.clone()) - .or_default() - .entry(name.to_string()) - .or_default() - .push(ArtifactFile { - artifact, - file: artifact_path, - version: source.version.clone(), - build_id: source.build_id.clone(), - profile: source.profile.clone(), - }); - } + { + let artifact_path = Self::get_artifact_path( + &ctx, + &taken_paths_lowercase, + file, + name, + &layout.artifacts, + &source.version, + &source.profile, + unique_versions.len() > 1, + unique_profiles.len() > 1, + ); + + taken_paths_lowercase.insert(artifact_path.to_slash_lossy().to_lowercase()); + + artifacts + .entry(file.clone()) + .or_default() + .entry(name.to_string()) + .or_default() + .push(ArtifactFile { + artifact, + file: artifact_path, + version: source.version.clone(), + build_id: source.build_id.clone(), + profile: source.profile.clone(), + }); } } } @@ -1188,7 +1186,6 @@ impl ArtifactOutput for MinimalCombinedArtifactsHardhatFallback { #[cfg(test)] mod tests { use super::*; - use std::collections::BTreeMap; #[test] fn is_artifact() { @@ -1238,7 +1235,9 @@ mod tests { let mut already_taken = HashSet::new(); let file = "/Users/carter/dev/goldfinch/mono/packages/protocol/test/forge/mainnet/utils/BaseMainnetForkingTest.t.sol"; - let conflict = PathBuf::from("/Users/carter/dev/goldfinch/mono/packages/protocol/artifacts/BaseMainnetForkingTest.t.sol/BaseMainnetForkingTest.json"); + let conflict = PathBuf::from( + "/Users/carter/dev/goldfinch/mono/packages/protocol/artifacts/BaseMainnetForkingTest.t.sol/BaseMainnetForkingTest.json", + ); already_taken.insert("/Users/carter/dev/goldfinch/mono/packages/protocol/artifacts/BaseMainnetForkingTest.t.sol/BaseMainnetForkingTest.json".into()); let alternative = ConfigurableArtifacts::conflict_free_output_file( @@ -1248,7 +1247,10 @@ mod tests { "/Users/carter/dev/goldfinch/mono/packages/protocol/artifacts".as_ref(), ); - assert_eq!(alternative.to_slash_lossy(), "/Users/carter/dev/goldfinch/mono/packages/protocol/artifacts/utils/BaseMainnetForkingTest.t.sol/BaseMainnetForkingTest.json"); + assert_eq!( + alternative.to_slash_lossy(), + "/Users/carter/dev/goldfinch/mono/packages/protocol/artifacts/utils/BaseMainnetForkingTest.t.sol/BaseMainnetForkingTest.json" + ); } fn assert_artifact() {} diff --git a/crates/compilers/src/buildinfo.rs b/crates/compilers/src/buildinfo.rs index cce159193..5404b6fef 100644 --- a/crates/compilers/src/buildinfo.rs +++ b/crates/compilers/src/buildinfo.rs @@ -5,7 +5,7 @@ use crate::compilers::{ }; use foundry_compilers_core::{error::Result, utils}; use semver::Version; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde::{Deserialize, Serialize, de::DeserializeOwned}; use std::{ collections::{BTreeMap, HashSet}, path::{Path, PathBuf}, @@ -50,7 +50,7 @@ impl BuildContext { let mut source_id_to_path = BTreeMap::new(); let input_sources = input.sources().map(|(path, _)| path).collect::>(); - for (path, source) in output.sources.iter() { + for (path, source) in &output.sources { if input_sources.contains(path.as_path()) { source_id_to_path.insert(source.id, path.to_path_buf()); } @@ -121,8 +121,7 @@ impl RawBuildInfo { mod tests { use super::*; use crate::compilers::solc::SolcVersionedInput; - use foundry_compilers_artifacts::{sources::Source, Contract, Error, SolcLanguage, Sources}; - use std::path::PathBuf; + use foundry_compilers_artifacts::{Contract, Error, SolcLanguage, Sources, sources::Source}; #[test] fn build_info_serde() { diff --git a/crates/compilers/src/cache.rs b/crates/compilers/src/cache.rs index 5c70fd71a..a5d194182 100644 --- a/crates/compilers/src/cache.rs +++ b/crates/compilers/src/cache.rs @@ -1,25 +1,25 @@ //! Support for compiling contracts. use crate::{ + ArtifactFile, ArtifactOutput, Artifacts, ArtifactsMap, Graph, OutputContext, Project, + ProjectPaths, ProjectPathsConfig, SourceCompilationKind, SourceParser, buildinfo::RawBuildInfo, compilers::{Compiler, CompilerSettings, Language}, output::Builds, resolver::GraphEdges, - ArtifactFile, ArtifactOutput, Artifacts, ArtifactsMap, Graph, OutputContext, Project, - ProjectPaths, ProjectPathsConfig, SourceCompilationKind, SourceParser, }; use foundry_compilers_artifacts::{ - sources::{Source, Sources}, Settings, + sources::{Source, Sources}, }; use foundry_compilers_core::{ error::{Result, SolcError}, utils::{self, strip_prefix}, }; use semver::Version; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde::{Deserialize, Serialize, de::DeserializeOwned}; use std::{ - collections::{btree_map::BTreeMap, hash_map, BTreeSet, HashMap, HashSet}, + collections::{BTreeSet, HashMap, HashSet, btree_map::BTreeMap, hash_map}, fs, path::{Path, PathBuf}, time::{Duration, UNIX_EPOCH}, @@ -112,7 +112,7 @@ impl CompilerCache { /// /// # Examples /// ```no_run - /// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project}; + /// use foundry_compilers::{Project, cache::CompilerCache, solc::SolcSettings}; /// /// let project = Project::builder().build(Default::default())?; /// let mut cache = CompilerCache::::read(project.cache_path())?; @@ -136,7 +136,7 @@ impl CompilerCache { /// /// # Examples /// ```no_run - /// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project}; + /// use foundry_compilers::{Project, cache::CompilerCache, solc::SolcSettings}; /// /// let project = Project::builder().build(Default::default())?; /// let cache: CompilerCache = CompilerCache::read_joined(&project.paths)?; @@ -245,7 +245,7 @@ impl CompilerCache { /// # Examples /// ```no_run /// use foundry_compilers::{ - /// artifacts::contract::CompactContract, cache::CompilerCache, solc::SolcSettings, Project, + /// Project, artifacts::contract::CompactContract, cache::CompilerCache, solc::SolcSettings, /// }; /// /// let project = Project::builder().build(Default::default())?; @@ -269,7 +269,7 @@ impl CompilerCache { /// /// # Examples /// ```no_run - /// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project}; + /// use foundry_compilers::{Project, cache::CompilerCache, solc::SolcSettings}; /// /// let project = Project::builder().build(Default::default())?; /// let cache: CompilerCache = CompilerCache::read_joined(&project.paths)?; @@ -287,7 +287,7 @@ impl CompilerCache { /// # Examples /// ```no_run /// use foundry_compilers::{ - /// artifacts::contract::CompactContract, cache::CompilerCache, solc::SolcSettings, Project, + /// Project, artifacts::contract::CompactContract, cache::CompilerCache, solc::SolcSettings, /// }; /// /// let project = Project::builder().build(Default::default())?; @@ -317,8 +317,8 @@ impl CompilerCache { /// # Examples /// ```no_run /// use foundry_compilers::{ - /// artifacts::contract::CompactContractBytecode, cache::CompilerCache, solc::SolcSettings, - /// Project, + /// Project, artifacts::contract::CompactContractBytecode, cache::CompilerCache, + /// solc::SolcSettings, /// }; /// /// let project = Project::builder().build(Default::default())?; @@ -506,7 +506,7 @@ impl CacheEntry { &self, ) -> Result>>> { let mut artifacts = BTreeMap::new(); - for (artifact_name, versioned_files) in self.artifacts.iter() { + for (artifact_name, versioned_files) in &self.artifacts { let mut files = Vec::with_capacity(versioned_files.len()); for (version, cached_artifact) in versioned_files { for (profile, cached_artifact) in cached_artifact { @@ -880,7 +880,7 @@ impl, C: Compiler> if !self.cache.preprocessed { // Perform DFS to find direct/indirect importers of dirty files. - for file in self.dirty_sources.clone().iter() { + for file in &self.dirty_sources.clone() { populate_dirty_files(file, &mut self.dirty_sources, &edges); } } else { @@ -1060,13 +1060,14 @@ impl<'a, T: ArtifactOutput, C: Compiler> // the currently configured paths let paths = project.paths.paths_relative(); - if !invalidate_cache && project.cache_path().exists() { - if let Ok(cache) = CompilerCache::read_joined(&project.paths) { - if cache.paths == paths && preprocessed == cache.preprocessed { - // unchanged project paths and same preprocess cache option - return cache; - } - } + if !invalidate_cache + && project.cache_path().exists() + && let Ok(cache) = CompilerCache::read_joined(&project.paths) + && cache.paths == paths + && preprocessed == cache.preprocessed + { + // unchanged project paths and same preprocess cache option + return cache; } trace!(invalidate_cache, "cache invalidated"); @@ -1289,10 +1290,10 @@ impl<'a, T: ArtifactOutput, C: Compiler> /// Marks the cached entry as seen by the compiler, if it's cached. pub fn compiler_seen(&mut self, file: &Path) { - if let ArtifactsCache::Cached(cache) = self { - if let Some(entry) = cache.cache.entry_mut(file) { - entry.seen_by_compiler = true; - } + if let ArtifactsCache::Cached(cache) = self + && let Some(entry) = cache.cache.entry_mut(file) + { + entry.seen_by_compiler = true; } } } diff --git a/crates/compilers/src/compile/output/contracts.rs b/crates/compilers/src/compile/output/contracts.rs index 9717b857d..81c4d118b 100644 --- a/crates/compilers/src/compile/output/contracts.rs +++ b/crates/compilers/src/compile/output/contracts.rs @@ -1,4 +1,4 @@ -use crate::{compilers::CompilerContract, ArtifactId}; +use crate::{ArtifactId, compilers::CompilerContract}; use foundry_compilers_artifacts::{ CompactContractBytecode, CompactContractRef, FileToContractsMap, }; @@ -53,7 +53,7 @@ where /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let output = project.compile()?.into_output(); @@ -70,7 +70,7 @@ where /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let output = project.compile()?.into_output(); @@ -92,7 +92,7 @@ where /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let (_, mut contracts) = project.compile()?.into_output().split(); @@ -118,7 +118,7 @@ where /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let (_, mut contracts) = project.compile()?.into_output().split(); diff --git a/crates/compilers/src/compile/output/mod.rs b/crates/compilers/src/compile/output/mod.rs index 4761afbf6..2dbf55564 100644 --- a/crates/compilers/src/compile/output/mod.rs +++ b/crates/compilers/src/compile/output/mod.rs @@ -15,12 +15,12 @@ use std::{ use yansi::Paint; use crate::{ + Artifact, ArtifactId, ArtifactOutput, Artifacts, ConfigurableArtifacts, buildinfo::{BuildContext, RawBuildInfo}, compilers::{ - multi::MultiCompiler, CompilationError, Compiler, CompilerContract, CompilerOutput, + CompilationError, Compiler, CompilerContract, CompilerOutput, multi::MultiCompiler, }, resolver::GraphEdges, - Artifact, ArtifactId, ArtifactOutput, Artifacts, ConfigurableArtifacts, }; pub mod contracts; @@ -131,7 +131,7 @@ impl, C: Compiler> /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::ConfigurableContractArtifact, ArtifactId, Project}; + /// use foundry_compilers::{ArtifactId, Project, artifacts::ConfigurableContractArtifact}; /// use std::collections::btree_map::BTreeMap; /// /// let project = Project::builder().build(Default::default())?; @@ -149,7 +149,7 @@ impl, C: Compiler> /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::ConfigurableContractArtifact, Project}; + /// use foundry_compilers::{Project, artifacts::ConfigurableContractArtifact}; /// use std::collections::btree_map::BTreeMap; /// /// let project = Project::builder().build(Default::default())?; @@ -166,7 +166,7 @@ impl, C: Compiler> /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::ConfigurableContractArtifact, Project}; + /// use foundry_compilers::{Project, artifacts::ConfigurableContractArtifact}; /// use semver::Version; /// use std::collections::btree_map::BTreeMap; /// @@ -208,7 +208,7 @@ impl, C: Compiler> /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::ConfigurableContractArtifact, Project}; + /// use foundry_compilers::{Project, artifacts::ConfigurableContractArtifact}; /// use std::{collections::btree_map::BTreeMap, path::PathBuf}; /// /// let project = Project::builder().build(Default::default())?; @@ -268,7 +268,7 @@ impl, C: Compiler> /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::contract::Contract, Project}; + /// use foundry_compilers::{Project, artifacts::contract::Contract}; /// use std::collections::btree_map::BTreeMap; /// /// let project = Project::builder().build(Default::default())?; @@ -342,7 +342,7 @@ impl, C: Compiler> /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, info::ContractInfo, Project}; + /// use foundry_compilers::{Project, artifacts::*, info::ContractInfo}; /// /// let project = Project::builder().build(Default::default())?; /// let output = project.compile()?; @@ -363,7 +363,7 @@ impl, C: Compiler> /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let output = project.compile()?; @@ -389,7 +389,7 @@ impl, C: Compiler> /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let output = project.compile()?; @@ -407,7 +407,7 @@ impl, C: Compiler> /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let mut output = project.compile()?; @@ -430,7 +430,7 @@ impl, C: Compiler> /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, info::ContractInfo, Project}; + /// use foundry_compilers::{Project, artifacts::*, info::ContractInfo}; /// /// let project = Project::builder().build(Default::default())?; /// let mut output = project.compile()?; @@ -456,8 +456,8 @@ impl, C: Compiler> /// # Examples /// ```no_run /// use foundry_compilers::{ - /// artifacts::contract::CompactContractBytecode, contracts::ArtifactContracts, ArtifactId, - /// Project, + /// ArtifactId, Project, artifacts::contract::CompactContractBytecode, + /// contracts::ArtifactContracts, /// }; /// use std::collections::btree_map::BTreeMap; /// @@ -657,7 +657,7 @@ impl AggregatedCompilerOutput { /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let output = project.compile()?.into_output(); @@ -672,7 +672,7 @@ impl AggregatedCompilerOutput { /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let mut output = project.compile()?.into_output(); @@ -687,7 +687,7 @@ impl AggregatedCompilerOutput { /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let mut output = project.compile()?.into_output(); @@ -706,7 +706,7 @@ impl AggregatedCompilerOutput { /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, info::ContractInfo, Project}; + /// use foundry_compilers::{Project, artifacts::*, info::ContractInfo}; /// /// let project = Project::builder().build(Default::default())?; /// let mut output = project.compile()?.into_output(); @@ -769,7 +769,7 @@ impl AggregatedCompilerOutput { /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let output = project.compile()?.into_output(); diff --git a/crates/compilers/src/compile/output/sources.rs b/crates/compilers/src/compile/output/sources.rs index 063c09b92..4a4d9aecd 100644 --- a/crates/compilers/src/compile/output/sources.rs +++ b/crates/compilers/src/compile/output/sources.rs @@ -57,7 +57,7 @@ impl VersionedSourceFiles { /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let output = project.compile()?.into_output(); @@ -72,11 +72,7 @@ impl VersionedSourceFiles { pub fn find_file_and_version(&self, path: &Path, version: &Version) -> Option<&SourceFile> { self.0.get(path).and_then(|contracts| { contracts.iter().find_map(|source| { - if source.version == *version { - Some(&source.source_file) - } else { - None - } + if source.version == *version { Some(&source.source_file) } else { None } }) }) } @@ -85,7 +81,7 @@ impl VersionedSourceFiles { /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let output = project.compile()?.into_output(); @@ -108,7 +104,7 @@ impl VersionedSourceFiles { /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let (mut sources, _) = project.compile()?.into_output().split(); @@ -117,11 +113,7 @@ impl VersionedSourceFiles { /// ``` pub fn remove_by_path(&mut self, path: &Path) -> Option { self.0.get_mut(path).and_then(|all_sources| { - if !all_sources.is_empty() { - Some(all_sources.remove(0).source_file) - } else { - None - } + if !all_sources.is_empty() { Some(all_sources.remove(0).source_file) } else { None } }) } @@ -129,7 +121,7 @@ impl VersionedSourceFiles { /// /// # Examples /// ```no_run - /// use foundry_compilers::{artifacts::*, Project}; + /// use foundry_compilers::{Project, artifacts::*}; /// /// let project = Project::builder().build(Default::default())?; /// let (mut sources, _) = project.compile()?.into_output().split(); diff --git a/crates/compilers/src/compile/project.rs b/crates/compilers/src/compile/project.rs index a79f16be8..1496b22e4 100644 --- a/crates/compilers/src/compile/project.rs +++ b/crates/compilers/src/compile/project.rs @@ -101,6 +101,8 @@ //! solc with only these dirty files instead of the entire source set. use crate::{ + ArtifactOutput, CompilerSettings, Graph, Project, ProjectCompileOutput, ProjectPathsConfig, + Sources, artifact_output::Artifacts, buildinfo::RawBuildInfo, cache::ArtifactsCache, @@ -109,8 +111,6 @@ use crate::{ output::{AggregatedCompilerOutput, Builds}, report, resolver::{GraphEdges, ResolvedSources}, - ArtifactOutput, CompilerSettings, Graph, Project, ProjectCompileOutput, ProjectPathsConfig, - Sources, }; use foundry_compilers_core::error::Result; use rayon::prelude::*; @@ -647,8 +647,8 @@ mod tests { use foundry_compilers_artifacts::output_selection::ContractOutputSelection; use crate::{ - compilers::multi::MultiCompiler, project_util::TempProject, ConfigurableArtifacts, - MinimalCombinedArtifacts, ProjectPathsConfig, + ConfigurableArtifacts, MinimalCombinedArtifacts, compilers::multi::MultiCompiler, + project_util::TempProject, }; use super::*; diff --git a/crates/compilers/src/compilers/mod.rs b/crates/compilers/src/compilers/mod.rs index ea9db512a..858ba4947 100644 --- a/crates/compilers/src/compilers/mod.rs +++ b/crates/compilers/src/compilers/mod.rs @@ -1,20 +1,20 @@ -use crate::{resolver::Node, ProjectPathsConfig}; +use crate::{ProjectPathsConfig, resolver::Node}; use alloy_json_abi::JsonAbi; use core::fmt; use foundry_compilers_artifacts::{ + BytecodeObject, CompactContractRef, Contract, FileToContractsMap, Severity, SourceFile, error::SourceLocation, output_selection::OutputSelection, remappings::Remapping, sources::{Source, Sources}, - BytecodeObject, CompactContractRef, Contract, FileToContractsMap, Severity, SourceFile, }; use foundry_compilers_core::error::Result; use rayon::prelude::*; use semver::{Version, VersionReq}; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde::{Deserialize, Serialize, de::DeserializeOwned}; use std::{ borrow::Cow, - collections::{hash_map::Entry, BTreeMap, BTreeSet, HashMap, HashSet}, + collections::{BTreeMap, BTreeSet, HashMap, HashSet, hash_map::Entry}, fmt::{Debug, Display}, hash::Hash, path::{Path, PathBuf}, @@ -338,11 +338,7 @@ impl CompilerContract for Contract { self.abi.as_ref() } fn bin_ref(&self) -> Option<&BytecodeObject> { - if let Some(ref evm) = self.evm { - evm.bytecode.as_ref().map(|c| &c.object) - } else { - None - } + if let Some(ref evm) = self.evm { evm.bytecode.as_ref().map(|c| &c.object) } else { None } } fn bin_runtime_ref(&self) -> Option<&BytecodeObject> { if let Some(ref evm) = self.evm { diff --git a/crates/compilers/src/compilers/multi.rs b/crates/compilers/src/compilers/multi.rs index 85cb80334..fe6a75071 100644 --- a/crates/compilers/src/compilers/multi.rs +++ b/crates/compilers/src/compilers/multi.rs @@ -1,27 +1,27 @@ use super::{ + CompilationError, Compiler, CompilerInput, CompilerOutput, CompilerSettings, CompilerVersion, + Language, ParsedSource, restrictions::CompilerSettingsRestrictions, - solc::{SolcCompiler, SolcSettings, SolcVersionedInput, SOLC_EXTENSIONS}, + solc::{SOLC_EXTENSIONS, SolcCompiler, SolcSettings, SolcVersionedInput}, vyper::{ - input::VyperVersionedInput, parser::VyperParsedSource, Vyper, VyperLanguage, - VYPER_EXTENSIONS, + VYPER_EXTENSIONS, Vyper, VyperLanguage, input::VyperVersionedInput, + parser::VyperParsedSource, }, - CompilationError, Compiler, CompilerInput, CompilerOutput, CompilerSettings, CompilerVersion, - Language, ParsedSource, }; use crate::{ + SourceParser, artifacts::vyper::{VyperCompilationError, VyperSettings}, parser::VyperParser, resolver::parse::{SolData, SolParser}, settings::VyperRestrictions, solc::SolcRestrictions, - SourceParser, }; use foundry_compilers_artifacts::{ + Contract, Error, Severity, SolcLanguage, error::SourceLocation, output_selection::OutputSelection, remappings::Remapping, sources::{Source, Sources}, - Contract, Error, Severity, SolcLanguage, }; use foundry_compilers_core::error::{Result, SolcError}; use semver::Version; diff --git a/crates/compilers/src/compilers/solc/compiler.rs b/crates/compilers/src/compilers/solc/compiler.rs index 7b23ac27e..fe8165ccc 100644 --- a/crates/compilers/src/compilers/solc/compiler.rs +++ b/crates/compilers/src/compilers/solc/compiler.rs @@ -1,12 +1,12 @@ use crate::resolver::parse::SolData; -use foundry_compilers_artifacts::{sources::Source, CompilerOutput, SolcInput}; +use foundry_compilers_artifacts::{CompilerOutput, SolcInput, sources::Source}; use foundry_compilers_core::{ error::{Result, SolcError}, utils::{SUPPORTS_BASE_PATH, SUPPORTS_INCLUDE_PATH}, }; use itertools::Itertools; use semver::{Version, VersionReq}; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde::{Deserialize, Serialize, de::DeserializeOwned}; use std::{ collections::BTreeSet, io::{self, Write}, @@ -616,11 +616,7 @@ impl Solc { } fn compile_output(output: Output) -> Result> { - if output.status.success() { - Ok(output.stdout) - } else { - Err(SolcError::solc_output(&output)) - } + if output.status.success() { Ok(output.stdout) } else { Err(SolcError::solc_output(&output)) } } fn version_from_output(output: Output) -> Result { @@ -647,7 +643,7 @@ impl AsRef for Solc { #[cfg(feature = "svm-solc")] mod tests { use super::*; - use crate::{resolver::parse::SolData, Artifact}; + use crate::Artifact; #[test] fn test_version_parse() { diff --git a/crates/compilers/src/compilers/solc/mod.rs b/crates/compilers/src/compilers/solc/mod.rs index 4176a0905..4b2cd1ddb 100644 --- a/crates/compilers/src/compilers/solc/mod.rs +++ b/crates/compilers/src/compilers/solc/mod.rs @@ -1,20 +1,20 @@ use super::{ - restrictions::CompilerSettingsRestrictions, CompilationError, Compiler, CompilerInput, - CompilerOutput, CompilerSettings, CompilerVersion, Language, ParsedSource, + CompilationError, Compiler, CompilerInput, CompilerOutput, CompilerSettings, CompilerVersion, + Language, ParsedSource, restrictions::CompilerSettingsRestrictions, }; use crate::{ + SourceParser, resolver::{ - parse::{SolData, SolParser}, Node, + parse::{SolData, SolParser}, }, - SourceParser, }; use foundry_compilers_artifacts::{ + BytecodeHash, Contract, Error, EvmVersion, Settings, Severity, SolcInput, error::SourceLocation, output_selection::OutputSelection, remappings::Remapping, sources::{Source, Sources}, - BytecodeHash, Contract, Error, EvmVersion, Settings, Severity, SolcInput, }; use foundry_compilers_core::error::{Result, SolcError, SolcIoError}; use rayon::prelude::*; @@ -30,7 +30,7 @@ use std::{ pub use foundry_compilers_artifacts::SolcLanguage; mod compiler; -pub use compiler::{Solc, SOLC_EXTENSIONS}; +pub use compiler::{SOLC_EXTENSIONS, Solc}; #[derive(Clone, Debug)] #[cfg_attr(feature = "svm-solc", derive(Default))] @@ -159,11 +159,7 @@ impl CompilerInput for SolcVersionedInput { fn compiler_name(&self) -> Cow<'static, str> { // Detect Solar from version build metadata (e.g., "0.8.28+commit.xxx.solar.0.1.8") - if self.version.build.as_str().contains("solar") { - "Solar".into() - } else { - "Solc".into() - } + if self.version.build.as_str().contains("solar") { "Solar".into() } else { "Solc".into() } } fn strip_prefix(&mut self, base: &Path) { @@ -236,10 +232,10 @@ impl Restriction { Some(other_max.map_or(this_max, |other_max| this_max.min(other_max))) }); - if let (Some(min), Some(max)) = (min, max) { - if min > max { - return None; - } + if let (Some(min), Some(max)) = (min, max) + && min > max + { + return None; } Some(Self { min, max }) @@ -267,18 +263,17 @@ pub struct SolcRestrictions { impl CompilerSettingsRestrictions for SolcRestrictions { fn merge(self, other: Self) -> Option { - if let (Some(via_ir), Some(other_via_ir)) = (self.via_ir, other.via_ir) { - if via_ir != other_via_ir { - return None; - } + if let (Some(via_ir), Some(other_via_ir)) = (self.via_ir, other.via_ir) + && via_ir != other_via_ir + { + return None; } if let (Some(bytecode_hash), Some(other_bytecode_hash)) = (self.bytecode_hash, other.bytecode_hash) + && bytecode_hash != other_bytecode_hash { - if bytecode_hash != other_bytecode_hash { - return None; - } + return None; } Some(Self { @@ -450,14 +445,13 @@ impl SourceParser for SolParser { // Set error on the first successful source, if any. This doesn't really have to be // exact, as long as at least one source has an error set it should be enough. - if let Some(Err(diag)) = compiler.sess().emitted_errors() { - if let Some(idx) = nodes + if let Some(Err(diag)) = compiler.sess().emitted_errors() + && let Some(idx) = nodes .iter() .position(|node| node.data.parse_result.is_ok()) .or_else(|| nodes.first().map(|_| 0)) - { - nodes[idx].data.parse_result = Err(diag.to_string()); - } + { + nodes[idx].data.parse_result = Err(diag.to_string()); } for node in nodes.iter() { @@ -486,11 +480,7 @@ impl ParsedSource for SolData { } fn language(&self) -> Self::Language { - if self.is_yul { - SolcLanguage::Yul - } else { - SolcLanguage::Solidity - } + if self.is_yul { SolcLanguage::Yul } else { SolcLanguage::Solidity } } fn resolve_imports( @@ -539,12 +529,12 @@ mod tests { use semver::Version; use crate::{ + AggregatedCompilerOutput, buildinfo::RawBuildInfo, compilers::{ - solc::{SolcCompiler, SolcVersionedInput}, CompilerInput, + solc::{SolcCompiler, SolcVersionedInput}, }, - AggregatedCompilerOutput, }; #[test] diff --git a/crates/compilers/src/compilers/vyper/error.rs b/crates/compilers/src/compilers/vyper/error.rs index 91644b064..d42e2bb23 100644 --- a/crates/compilers/src/compilers/vyper/error.rs +++ b/crates/compilers/src/compilers/vyper/error.rs @@ -1,5 +1,5 @@ use crate::{artifacts::vyper::VyperCompilationError, compilers::CompilationError}; -use foundry_compilers_artifacts::{error::SourceLocation, Severity}; +use foundry_compilers_artifacts::{Severity, error::SourceLocation}; impl CompilationError for VyperCompilationError { fn is_warning(&self) -> bool { diff --git a/crates/compilers/src/compilers/vyper/mod.rs b/crates/compilers/src/compilers/vyper/mod.rs index 88034cb0a..8db5e3b00 100644 --- a/crates/compilers/src/compilers/vyper/mod.rs +++ b/crates/compilers/src/compilers/vyper/mod.rs @@ -3,10 +3,10 @@ use super::{Compiler, CompilerOutput, Language}; pub use crate::artifacts::vyper::{VyperCompilationError, VyperInput, VyperOutput, VyperSettings}; use crate::parser::VyperParser; use core::fmt; -use foundry_compilers_artifacts::{sources::Source, Contract}; +use foundry_compilers_artifacts::{Contract, sources::Source}; use foundry_compilers_core::error::{Result, SolcError}; use semver::Version; -use serde::{de::DeserializeOwned, Serialize}; +use serde::{Serialize, de::DeserializeOwned}; use std::{ io::{self, Write}, path::{Path, PathBuf}, @@ -108,11 +108,11 @@ impl Vyper { /// /// ```no_run /// use foundry_compilers::{ + /// Vyper, /// artifacts::{ - /// vyper::{VyperInput, VyperSettings}, /// Source, + /// vyper::{VyperInput, VyperSettings}, /// }, - /// Vyper, /// }; /// use std::path::Path; /// diff --git a/crates/compilers/src/compilers/vyper/parser.rs b/crates/compilers/src/compilers/vyper/parser.rs index d3602b077..79e3a93fc 100644 --- a/crates/compilers/src/compilers/vyper/parser.rs +++ b/crates/compilers/src/compilers/vyper/parser.rs @@ -1,11 +1,11 @@ use super::VyperLanguage; use crate::{ - compilers::{vyper::VYPER_EXTENSIONS, ParsedSource}, ProjectPathsConfig, SourceParser, + compilers::{ParsedSource, vyper::VYPER_EXTENSIONS}, }; use foundry_compilers_core::{ error::{Result, SolcError}, - utils::{capture_outer_and_inner, RE_VYPER_VERSION}, + utils::{RE_VYPER_VERSION, capture_outer_and_inner}, }; use semver::VersionReq; use std::{ @@ -13,10 +13,10 @@ use std::{ path::{Path, PathBuf}, }; use winnow::{ + ModalResult, Parser, ascii::space1, combinator::{alt, opt, preceded}, token::{take_till, take_while}, - ModalResult, Parser, }; #[derive(Clone, Debug, PartialEq)] @@ -193,7 +193,7 @@ fn parse_import(input: &mut &str) -> ModalResult { #[cfg(test)] mod tests { - use super::{parse_import, VyperImport}; + use super::{VyperImport, parse_import}; use winnow::Parser; #[test] diff --git a/crates/compilers/src/compilers/vyper/settings.rs b/crates/compilers/src/compilers/vyper/settings.rs index 0a4b0f5c3..8db223c26 100644 --- a/crates/compilers/src/compilers/vyper/settings.rs +++ b/crates/compilers/src/compilers/vyper/settings.rs @@ -2,10 +2,10 @@ use std::{collections::BTreeSet, path::PathBuf}; pub use crate::artifacts::vyper::VyperSettings; use crate::{ - compilers::{restrictions::CompilerSettingsRestrictions, CompilerSettings}, + compilers::{CompilerSettings, restrictions::CompilerSettingsRestrictions}, solc::Restriction, }; -use foundry_compilers_artifacts::{output_selection::OutputSelection, EvmVersion}; +use foundry_compilers_artifacts::{EvmVersion, output_selection::OutputSelection}; #[derive(Clone, Copy, Debug, Default)] pub struct VyperRestrictions { diff --git a/crates/compilers/src/config.rs b/crates/compilers/src/config.rs index b73be1576..e4adb02b8 100644 --- a/crates/compilers/src/config.rs +++ b/crates/compilers/src/config.rs @@ -1,15 +1,15 @@ use crate::{ + Graph, cache::SOLIDITY_FILES_CACHE_FILENAME, - compilers::{multi::MultiCompilerLanguage, Language}, + compilers::{Language, multi::MultiCompilerLanguage}, flatten::{collect_ordered_deps, combine_version_pragmas}, - resolver::{parse::SolParser, SolImportAlias}, - Graph, + resolver::{SolImportAlias, parse::SolParser}, }; use foundry_compilers_artifacts::{ + Libraries, Settings, SolcLanguage, output_selection::ContractOutputSelection, remappings::Remapping, sources::{Source, Sources}, - Libraries, Settings, SolcLanguage, }; use foundry_compilers_core::{ error::{Result, SolcError, SolcIoError}, @@ -130,7 +130,7 @@ impl ProjectPathsConfig { let mut result = String::new(); - for path in ordered_deps.iter() { + for path in &ordered_deps { let node_id = *graph.files().get(path).ok_or_else(|| { SolcError::msg(format!("cannot resolve file at {}", path.display())) })?; @@ -424,21 +424,20 @@ impl ProjectPathsConfig { // absolute paths in solidity are a thing for example `import // "src/interfaces/IConfig.sol"` which could either point to `cwd + // src/interfaces/IConfig.sol`, or make use of a remapping (`src/=....`) - if let Some(lib) = self.find_library_ancestor(cwd) { - if let Some((include_path, import)) = + if let Some(lib) = self.find_library_ancestor(cwd) + && let Some((include_path, import)) = utils::resolve_absolute_library(lib, cwd, import) - { - // track the path for this absolute import inside a nested library - include_paths.insert(include_path); - return Ok(import); - } + { + // track the path for this absolute import inside a nested library + include_paths.insert(include_path); + return Ok(import); } // also try to resolve absolute imports from the project paths for path in [&self.root, &self.sources, &self.tests, &self.scripts] { - if cwd.starts_with(path) { - if let Ok(import) = utils::normalize_solidity_import_path(path, import) { - return Ok(import); - } + if cwd.starts_with(path) + && let Ok(import) = utils::normalize_solidity_import_path(path, import) + { + return Ok(import); } } } @@ -518,11 +517,7 @@ impl ProjectPathsConfig { .iter() .filter(|r| { // only check remappings that are either global or for `cwd` - if let Some(ctx) = r.context.as_ref() { - cwd.starts_with(ctx) - } else { - true - } + if let Some(ctx) = r.context.as_ref() { cwd.starts_with(ctx) } else { true } }) .find_map(|r| { import.strip_prefix(&r.name).ok().map(|stripped_import| { @@ -536,10 +531,11 @@ impl ProjectPathsConfig { // we handle the edge case where the path of a remapping ends with "contracts" // (`/=.../contracts`) and the stripped import also starts with // `contracts` - if let Ok(adjusted_import) = stripped_import.strip_prefix("contracts/") { - if r.path.ends_with("contracts/") && !self.root.join(&lib_path).exists() { - return Path::new(&r.path).join(adjusted_import); - } + if let Ok(adjusted_import) = stripped_import.strip_prefix("contracts/") + && r.path.ends_with("contracts/") + && !self.root.join(&lib_path).exists() + { + return Path::new(&r.path).join(adjusted_import); } lib_path }) @@ -579,10 +575,10 @@ impl ProjectPathsConfig { // Check if any remapping matches this path for r in &self.remappings { // Check context - if let Some(ctx) = r.context.as_ref() { - if !cwd_relative.starts_with(ctx) { - continue; - } + if let Some(ctx) = r.context.as_ref() + && !cwd_relative.starts_with(ctx) + { + continue; } // Check if the relative path starts with the remapping name @@ -1254,16 +1250,18 @@ mod tests { }); // Test that single file import / remapping resolves to file. - assert!(config - .resolve_import_and_include_paths( - &config.sources, - Path::new("@my-lib/B.sol"), - &mut Default::default(), - ) - .unwrap() - .to_str() - .unwrap() - .ends_with("my-lib/B.sol")); + assert!( + config + .resolve_import_and_include_paths( + &config.sources, + Path::new("@my-lib/B.sol"), + &mut Default::default(), + ) + .unwrap() + .to_str() + .unwrap() + .ends_with("my-lib/B.sol") + ); } #[test] diff --git a/crates/compilers/src/filter.rs b/crates/compilers/src/filter.rs index 573c848be..11f9b6ef5 100644 --- a/crates/compilers/src/filter.rs +++ b/crates/compilers/src/filter.rs @@ -1,9 +1,9 @@ //! Types to apply filter to input types use crate::{ - compilers::{multi::MultiCompilerParsedSource, CompilerSettings, ParsedSource}, - resolver::{parse::SolData, GraphEdges}, SourceParser, Sources, + compilers::{CompilerSettings, ParsedSource, multi::MultiCompilerParsedSource}, + resolver::{GraphEdges, parse::SolData}, }; use foundry_compilers_artifacts::output_selection::OutputSelection; use std::{ @@ -111,10 +111,10 @@ impl<'a> SparseOutputFilter<'a> { .dirty_files() .flat_map(|file| { // If we have a custom filter and file does not match, we skip it. - if let Self::Custom(f) = self { - if !f.is_match(file) { - return vec![]; - } + if let Self::Custom(f) = self + && !f.is_match(file) + { + return vec![]; } // Collect compilation dependencies for sources needing compilation. diff --git a/crates/compilers/src/flatten.rs b/crates/compilers/src/flatten.rs index 5ec755d0c..388a0a0da 100644 --- a/crates/compilers/src/flatten.rs +++ b/crates/compilers/src/flatten.rs @@ -1,16 +1,14 @@ use crate::{ + ArtifactOutput, CompilerSettings, Graph, Project, ProjectPathsConfig, SourceParser, Updates, apply_updates, compilers::{Compiler, ParsedSource}, filter::MaybeSolData, resolver::parse::SolData, - ArtifactOutput, CompilerSettings, Graph, Project, ProjectPathsConfig, SourceParser, Updates, }; use foundry_compilers_artifacts::{ ast::{visitor::Visitor, *}, output_selection::OutputSelection, - solc::ExternalInlineAssemblyReference, sources::{Source, Sources}, - ContractDefinitionPart, SourceUnit, SourceUnitPart, }; use foundry_compilers_core::{ error::{Result, SolcError}, @@ -80,19 +78,19 @@ impl Visitor for ReferencesCollector { } fn visit_member_access(&mut self, access: &MemberAccess) { - if let Some(referenced_declaration) = access.referenced_declaration { - if let (Some(src_start), Some(src_length)) = (access.src.start, access.src.length) { - let name_length = access.member_name.len(); - // Accessed member name is in the last name.len() symbols of the expression. - let start = src_start + src_length - name_length; - let end = start + name_length; - - self.references.entry(referenced_declaration).or_default().insert(ItemLocation { - start, - end, - path: self.path.to_path_buf(), - }); - } + if let Some(referenced_declaration) = access.referenced_declaration + && let (Some(src_start), Some(src_length)) = (access.src.start, access.src.length) + { + let name_length = access.member_name.len(); + // Accessed member name is in the last name.len() symbols of the expression. + let start = src_start + src_length - name_length; + let end = start + name_length; + + self.references.entry(referenced_declaration).or_default().insert(ItemLocation { + start, + end, + path: self.path.to_path_buf(), + }); } } @@ -101,11 +99,11 @@ impl Visitor for ReferencesCollector { // If suffix is used in assembly reference (e.g. value.slot), it will be included into src. // However, we are only interested in the referenced name, thus we strip . part. - if let Some(suffix) = &reference.suffix { - if let Some(len) = src.length.as_mut() { - let suffix_len = suffix.to_string().len(); - *len -= suffix_len + 1; - } + if let Some(suffix) = &reference.suffix + && let Some(len) = src.length.as_mut() + { + let suffix_len = suffix.to_string().len(); + *len -= suffix_len + 1; } self.process_referenced_declaration(reference.declaration as isize, &src); @@ -229,10 +227,10 @@ impl Flattener { // Convert all ASTs from artifacts to strongly typed ASTs let mut asts: Vec<(PathBuf, SourceUnit)> = Vec::new(); for (path, ast) in output.sources.0.iter().filter_map(|(path, files)| { - if let Some(ast) = files.first().and_then(|source| source.source_file.ast.as_ref()) { - if sources.contains_key(path) { - return Some((path, ast)); - } + if let Some(ast) = files.first().and_then(|source| source.source_file.ast.as_ref()) + && sources.contains_key(path) + { + return Some((path, ast)); } None }) { @@ -452,11 +450,7 @@ impl Flattener { .iter() .filter_map( |(name, ids)| { - if !ids.is_empty() { - Some((name.as_str(), ids[0])) - } else { - None - } + if !ids.is_empty() { Some((name.as_str(), ids[0])) } else { None } }, ) .collect::>(); diff --git a/crates/compilers/src/lib.rs b/crates/compilers/src/lib.rs index 6fdfedea4..a38d60e65 100644 --- a/crates/compilers/src/lib.rs +++ b/crates/compilers/src/lib.rs @@ -56,8 +56,8 @@ use compilers::multi::MultiCompiler; use foundry_compilers_artifacts::{ output_selection::OutputSelection, solc::{ - sources::{Source, SourceCompilationKind, Sources}, Severity, SourceFile, StandardJsonCompilerInput, + sources::{Source, SourceCompilationKind, Sources}, }, }; use foundry_compilers_core::error::{Result, SolcError, SolcIoError}; @@ -65,8 +65,8 @@ use output::sources::{VersionedSourceFile, VersionedSourceFiles}; use project::ProjectCompiler; use semver::Version; use solar::parse::{ - interface::{diagnostics::EmittedDiagnostics, source_map::FileName, Session}, Parser, + interface::{Session, diagnostics::EmittedDiagnostics, source_map::FileName}, }; use solc::SolcSettings; use std::{ @@ -149,7 +149,7 @@ impl Project { /// /// or use the builder directly: /// ```no_run - /// use foundry_compilers::{multi::MultiCompiler, ConfigurableArtifacts, ProjectBuilder}; + /// use foundry_compilers::{ConfigurableArtifacts, ProjectBuilder, multi::MultiCompiler}; /// /// let config = ProjectBuilder::::default().build(Default::default())?; /// # Ok::<(), Box>(()) @@ -969,7 +969,7 @@ pub(crate) fn parse_one_source( mod tests { use super::*; use foundry_compilers_artifacts::Remapping; - use foundry_compilers_core::utils::{self, mkdir_or_touch, tempdir}; + use foundry_compilers_core::utils::{mkdir_or_touch, tempdir}; #[test] #[cfg_attr(windows, ignore = "<0.7 solc is flaky")] diff --git a/crates/compilers/src/project_util/mock.rs b/crates/compilers/src/project_util/mock.rs index 0964cb769..19aee12c8 100644 --- a/crates/compilers/src/project_util/mock.rs +++ b/crates/compilers/src/project_util/mock.rs @@ -2,7 +2,7 @@ use foundry_compilers_artifacts::Remapping; use foundry_compilers_core::error::{Result, SolcError}; -use rand::{seq::SliceRandom, Rng}; +use rand::{Rng, seq::SliceRandom}; use serde::{Deserialize, Serialize}; use std::{ collections::{BTreeSet, HashMap, HashSet, VecDeque}, @@ -10,8 +10,8 @@ use std::{ }; use crate::{ - compilers::Language, multi::MultiCompilerParser, resolver::GraphEdges, Graph, - ProjectPathsConfig, SourceParser, + Graph, ProjectPathsConfig, SourceParser, compilers::Language, multi::MultiCompilerParser, + resolver::GraphEdges, }; /// Represents the layout of a project @@ -112,7 +112,7 @@ impl MockProjectGenerator { paths: &ProjectPathsConfig, version: &str, ) -> Result<()> { - for file in self.inner.files.iter() { + for file in &self.inner.files { let imports = self.get_imports(file.id); let content = file.mock_content(version, imports.join("\n").as_str()); super::create_contract_file(&file.target_path(self, paths), content)?; @@ -125,7 +125,7 @@ impl MockProjectGenerator { let file = &self.inner.files[file]; let mut imports = Vec::with_capacity(file.imports.len()); - for import in file.imports.iter() { + for import in &file.imports { match *import { MockImport::Internal(f) => { imports.push(format!("import \"./{}.sol\";", self.inner.files[f].name)); @@ -243,7 +243,7 @@ impl MockProjectGenerator { let mut rng = rand::rng(); let n = self.inner.files.len(); - for file in self.inner.files.iter_mut() { + for file in &mut self.inner.files { let throw = rng.random_range(0..n); if throw == 0 { // 1 in n chance that the file will be empty diff --git a/crates/compilers/src/project_util/mod.rs b/crates/compilers/src/project_util/mod.rs index 6473dc62c..277450cc7 100644 --- a/crates/compilers/src/project_util/mod.rs +++ b/crates/compilers/src/project_util/mod.rs @@ -1,15 +1,15 @@ //! Utilities for mocking project workspaces. use crate::{ + Artifact, ArtifactOutput, Artifacts, ConfigurableArtifacts, HardhatArtifacts, PathStyle, + Project, ProjectBuilder, ProjectCompileOutput, ProjectPathsConfig, cache::CompilerCache, compilers::{ - multi::{MultiCompiler, MultiCompilerSettings}, Compiler, + multi::{MultiCompiler, MultiCompilerSettings}, }, config::ProjectPathsConfigBuilder, solc::SolcSettings, - Artifact, ArtifactOutput, Artifacts, ConfigurableArtifacts, HardhatArtifacts, PathStyle, - Project, ProjectBuilder, ProjectCompileOutput, ProjectPathsConfig, }; use foundry_compilers_artifacts::{ConfigurableContractArtifact, Remapping, Settings}; use foundry_compilers_core::{ @@ -41,9 +41,8 @@ pub struct TempProject< inner: Project, } -impl< - T: ArtifactOutput::CompilerContract> + Default, - > TempProject +impl::CompilerContract> + Default> + TempProject { /// Creates a new temp project using the provided paths and artifacts handler. /// sets the project root to a temp dir @@ -70,9 +69,8 @@ impl< } } -impl< - T: ArtifactOutput::CompilerContract> + Default, - > TempProject +impl::CompilerContract> + Default> + TempProject { /// Creates a new temp project for the given `PathStyle` #[cfg(feature = "svm-solc")] @@ -85,9 +83,8 @@ impl< } } -impl< - T: ArtifactOutput::CompilerContract> + Default, - > fmt::Debug for TempProject +impl::CompilerContract> + Default> + fmt::Debug for TempProject { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TempProject").field("paths", &self.inner.paths).finish() @@ -128,10 +125,8 @@ impl TempProject { } } -impl< - C: Compiler + Default, - T: ArtifactOutput + Default, - > TempProject +impl + Default> + TempProject { /// Wraps an existing project in a temp dir. pub fn from_project(inner: Project) -> std::result::Result { @@ -374,8 +369,8 @@ contract {name} {{}} } /// Populate the project with mock files - pub fn mock(&self, gen: &MockProjectGenerator, version: &str) -> Result<()> { - gen.write_to(self.paths(), version) + pub fn mock(&self, generator: &MockProjectGenerator, version: &str) -> Result<()> { + generator.write_to(self.paths(), version) } /// Compiles the project and ensures that the output does not contain errors @@ -477,9 +472,9 @@ impl TempProject { /// Create a new temporary project and populate it with mock files. pub fn mocked(settings: &MockProjectSettings, version: &str) -> Result { let mut tmp = Self::dapptools()?; - let gen = MockProjectGenerator::new(settings); - tmp.mock(&gen, version)?; - let remappings = gen.remappings_at(tmp.root()); + let generator = MockProjectGenerator::new(settings); + tmp.mock(&generator, version)?; + let remappings = generator.remappings_at(tmp.root()); tmp.paths_mut().remappings.extend(remappings); Ok(tmp) } @@ -490,9 +485,8 @@ impl TempProject { } } -impl< - T: ArtifactOutput::CompilerContract> + Default, - > AsRef> for TempProject +impl::CompilerContract> + Default> + AsRef> for TempProject { fn as_ref(&self) -> &Project { self.project() diff --git a/crates/compilers/src/report/compiler.rs b/crates/compilers/src/report/compiler.rs index 59307a9a4..4c862a603 100644 --- a/crates/compilers/src/report/compiler.rs +++ b/crates/compilers/src/report/compiler.rs @@ -20,8 +20,7 @@ use std::{env, path::PathBuf, str::FromStr}; /// /// ```no_run /// use foundry_compilers::report::SolcCompilerIoReporter; -/// std::env::set_var("foundry_compilers_LOG", "in=in.json,out=out.json"); -/// let rep = SolcCompilerIoReporter::from_default_env(); +/// let rep = SolcCompilerIoReporter::new("in=in.json,out=out.json"); /// ``` #[derive(Clone, Debug, Default)] pub struct SolcCompilerIoReporter { @@ -198,14 +197,16 @@ mod tests { fn can_init_reporter_from_env() { let rep = SolcCompilerIoReporter::from_default_env(); assert!(rep.target.is_none()); - std::env::set_var("foundry_compilers_LOG", "in=in.json,out=out.json"); + // SAFETY: This test is not run in parallel with other tests that depend on this env var. + unsafe { std::env::set_var("foundry_compilers_LOG", "in=in.json,out=out.json") }; let rep = SolcCompilerIoReporter::from_default_env(); assert!(rep.target.is_some()); assert_eq!( rep.target.unwrap(), Target { dest_input: "in.json".into(), dest_output: "out.json".into() } ); - std::env::remove_var("foundry_compilers_LOG"); + // SAFETY: This test is not run in parallel with other tests that depend on this env var. + unsafe { std::env::remove_var("foundry_compilers_LOG") }; } #[test] diff --git a/crates/compilers/src/report/mod.rs b/crates/compilers/src/report/mod.rs index 6557f2342..81ccdbfd4 100644 --- a/crates/compilers/src/report/mod.rs +++ b/crates/compilers/src/report/mod.rs @@ -26,8 +26,8 @@ use std::{ path::{Path, PathBuf}, ptr::NonNull, sync::{ - atomic::{AtomicBool, AtomicUsize, Ordering}, Arc, + atomic::{AtomicBool, AtomicUsize, Ordering}, }, time::Duration, }; @@ -148,11 +148,7 @@ pub trait Reporter: 'static + std::fmt::Debug { /// with the provided `TypeId`. Failure to ensure this will result in /// undefined behaviour, so implementing `downcast_raw` is unsafe. unsafe fn downcast_raw(&self, id: TypeId) -> Option> { - if id == TypeId::of::() { - Some(NonNull::from(self).cast()) - } else { - None - } + if id == TypeId::of::() { Some(NonNull::from(self).cast()) } else { None } } } @@ -378,10 +374,10 @@ impl Reporter for BasicStdoutReporter { /// /// Non-`BrokenPipe` errors still panic, matching the prior `println!` behavior. fn write_line(mut writer: impl io::Write, args: fmt::Arguments<'_>) { - if let Err(err) = writeln!(writer, "{args}") { - if err.kind() != io::ErrorKind::BrokenPipe { - panic!("failed to write reporter output: {err}"); - } + if let Err(err) = writeln!(writer, "{args}") + && err.kind() != io::ErrorKind::BrokenPipe + { + panic!("failed to write reporter output: {err}"); } } diff --git a/crates/compilers/src/resolver/mod.rs b/crates/compilers/src/resolver/mod.rs index 0f16b9870..2d14bf8e5 100644 --- a/crates/compilers/src/resolver/mod.rs +++ b/crates/compilers/src/resolver/mod.rs @@ -46,10 +46,10 @@ //! which is defined on a per source file basis. use crate::{ + ArtifactOutput, CompilerSettings, Project, ProjectPathsConfig, SourceParser, compilers::{Compiler, CompilerVersion, ParsedSource}, project::VersionedSources, resolver::parse::SolParser, - ArtifactOutput, CompilerSettings, Project, ProjectPathsConfig, SourceParser, }; use core::fmt; use foundry_compilers_artifacts::sources::{Source, Sources}; @@ -69,7 +69,7 @@ pub mod parse; mod tree; pub use parse::SolImportAlias; -pub use tree::{print, Charset, TreeOptions}; +pub use tree::{Charset, TreeOptions, print}; /// Container for result of version and profile resolution of sources contained in [`Graph`]. #[derive(Debug)] @@ -468,7 +468,7 @@ impl Graph

{ // Build `rev_edges` for (idx, edges) in edges.iter().enumerate() { - for &edge in edges.iter() { + for &edge in edges { rev_edges[edge].push(idx); } } @@ -710,7 +710,7 @@ impl Graph

{ let nodes: Vec<_> = self.node_ids(idx).collect(); let mut failed_node_idx = None; - for node in nodes.iter() { + for node in &nodes { if let Some(req) = self.version_requirement(*node, project) { candidates.retain(|v| req.matches(v.as_ref())); @@ -782,7 +782,7 @@ impl Graph

{ let nodes: Vec<_> = self.node_ids(idx).collect(); let mut failed_node_idx = None; - for node in nodes.iter() { + for node in &nodes { if let Some(req) = project.restrictions.get(&self.node(*node).path) { candidates.retain(|(_, (_, settings))| settings.satisfies_restrictions(&**req)); if candidates.is_empty() { @@ -811,22 +811,16 @@ impl Graph

{ // iterate over all the nodes once again and find the one incompatible for node in &nodes { - if let Some(req) = project.restrictions.get(&self.node(*node).path) { - if !all_profiles + if let Some(req) = project.restrictions.get(&self.node(*node).path) + && !all_profiles .iter() .any(|(_, (_, settings))| settings.satisfies_restrictions(&**req)) - { - let mut msg = "Found incompatible settings restrictions:\n".white().to_string(); + { + let mut msg = "Found incompatible settings restrictions:\n".white().to_string(); - self.format_imports_list( - idx, - [*node, failed_node_idx].into(), - project, - &mut msg, - ) + self.format_imports_list(idx, [*node, failed_node_idx].into(), project, &mut msg) .unwrap(); - return Err(msg); - } + return Err(msg); } } @@ -1281,7 +1275,7 @@ src/Dapp.t.sol >=0.6.6 #[test] #[cfg(feature = "svm-solc")] fn test_print_unresolved() { - use crate::{solc::SolcCompiler, ProjectBuilder}; + use crate::{ProjectBuilder, solc::SolcCompiler}; let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../test-data/incompatible-pragmas"); diff --git a/crates/compilers/src/resolver/parse.rs b/crates/compilers/src/resolver/parse.rs index 2fc5a597a..b2556cb20 100644 --- a/crates/compilers/src/resolver/parse.rs +++ b/crates/compilers/src/resolver/parse.rs @@ -74,13 +74,9 @@ impl interface::source_map::FileLoader for FileLoader { } fn load_file(&self, path: &Path) -> std::io::Result { - interface::source_map::RealFileLoader.load_file(path).map(|s| { - if s.contains('\r') { - s.replace('\r', "") - } else { - s - } - }) + interface::source_map::RealFileLoader + .load_file(path) + .map(|s| if s.contains('\r') { s.replace('\r', "") } else { s }) } fn load_binary_file(&self, path: &Path) -> std::io::Result> { diff --git a/crates/compilers/tests/mocked.rs b/crates/compilers/tests/mocked.rs index 34cf80279..4f315b834 100644 --- a/crates/compilers/tests/mocked.rs +++ b/crates/compilers/tests/mocked.rs @@ -3,8 +3,8 @@ use foundry_compilers::{ compilers::multi::MultiCompiler, project_util::{ - mock::{MockProjectGenerator, MockProjectSettings, MockProjectSkeleton}, TempProject, + mock::{MockProjectGenerator, MockProjectSettings, MockProjectSkeleton}, }, }; use foundry_compilers_core::error::Result; @@ -34,17 +34,17 @@ fn run_mock( f: impl FnOnce(&mut TempProject, &MockProjectGenerator) -> Result<()>, ) -> TempProject { let MockSettings { settings, version } = settings.into(); - let gen = MockProjectGenerator::new(&settings); + let generator = MockProjectGenerator::new(&settings); let mut project = TempProject::dapptools().unwrap(); - let remappings = gen.remappings_at(project.root()); + let remappings = generator.remappings_at(project.root()); project.paths_mut().remappings.extend(remappings); - project.mock(&gen, version).unwrap(); + project.mock(&generator, version).unwrap(); - if let Err(err) = f(&mut project, &gen) { + if let Err(err) = f(&mut project, &generator) { panic!( "mock failed: `{}` with mock settings:\n {}", err, - serde_json::to_string(&gen).unwrap() + serde_json::to_string(&generator).unwrap() ); } @@ -83,10 +83,14 @@ fn can_compile_mocked_large() { #[test] fn can_compile_mocked_modified() { - run_mock(MockProjectSettings::random(), |project, gen| { + run_mock(MockProjectSettings::random(), |project, generator| { project.ensure_no_errors_recompile_unchanged()?; // modify a random file - gen.modify_file(gen.used_file_ids().count() / 2, project.paths(), DEFAULT_VERSION)?; + generator.modify_file( + generator.used_file_ids().count() / 2, + project.paths(), + DEFAULT_VERSION, + )?; project.ensure_changed()?; project.artifacts_snapshot()?.assert_artifacts_essentials_present(); Ok(()) @@ -95,11 +99,11 @@ fn can_compile_mocked_modified() { #[test] fn can_compile_mocked_modified_all() { - run_mock(MockProjectSettings::random(), |project, gen| { + run_mock(MockProjectSettings::random(), |project, generator| { project.ensure_no_errors_recompile_unchanged()?; // modify a random file - for id in gen.used_file_ids() { - gen.modify_file(id, project.paths(), DEFAULT_VERSION)?; + for id in generator.used_file_ids() { + generator.modify_file(id, project.paths(), DEFAULT_VERSION)?; project.ensure_changed()?; project.artifacts_snapshot()?.assert_artifacts_essentials_present(); } @@ -112,10 +116,11 @@ fn can_compile_mocked_modified_all() { fn can_compile_skeleton() { let mut project = TempProject::::dapptools().unwrap(); let s = r#"{"files":[{"id":0,"name":"SourceFile0","imports":[{"External":[0,1]},{"External":[3,4]}],"lib_id":null,"emit_artifacts":true},{"id":1,"name":"SourceFile1","imports":[],"lib_id":0,"emit_artifacts":true},{"id":2,"name":"SourceFile2","imports":[],"lib_id":1,"emit_artifacts":true},{"id":3,"name":"SourceFile3","imports":[],"lib_id":2,"emit_artifacts":true},{"id":4,"name":"SourceFile4","imports":[],"lib_id":3,"emit_artifacts":true}],"libraries":[{"name":"Lib0","id":0,"offset":1,"num_files":1},{"name":"Lib1","id":1,"offset":2,"num_files":1},{"name":"Lib2","id":2,"offset":3,"num_files":1},{"name":"Lib3","id":3,"offset":4,"num_files":1}]}"#; - let gen: MockProjectGenerator = serde_json::from_str::(s).unwrap().into(); - let remappings = gen.remappings_at(project.root()); + let generator: MockProjectGenerator = + serde_json::from_str::(s).unwrap().into(); + let remappings = generator.remappings_at(project.root()); project.paths_mut().remappings.extend(remappings); - project.mock(&gen, DEFAULT_VERSION).unwrap(); + project.mock(&generator, DEFAULT_VERSION).unwrap(); // mattsse: helper to show what's being generated // gen.write_to(&foundry_compilers::ProjectPathsConfig::dapptools("./skeleton").unwrap(), @@ -124,8 +129,8 @@ fn can_compile_skeleton() { let compiled = project.compile().unwrap(); compiled.assert_success(); assert!(!compiled.is_unchanged()); - for id in gen.used_file_ids() { - gen.modify_file(id, project.paths(), DEFAULT_VERSION).unwrap(); + for id in generator.used_file_ids() { + generator.modify_file(id, project.paths(), DEFAULT_VERSION).unwrap(); project.ensure_changed().unwrap(); project.artifacts_snapshot().unwrap().assert_artifacts_essentials_present(); } diff --git a/crates/compilers/tests/project.rs b/crates/compilers/tests/project.rs index 1a2075fd7..4ab56f484 100644 --- a/crates/compilers/tests/project.rs +++ b/crates/compilers/tests/project.rs @@ -2,13 +2,16 @@ use alloy_primitives::{Address, Bytes}; use foundry_compilers::{ + Artifact, ConfigurableArtifacts, ExtraOutputFiles, ExtraOutputValues, Graph, Project, + ProjectBuilder, ProjectCompileOutput, ProjectPathsConfig, RestrictionsWithVersion, + TestFileFilter, buildinfo::BuildInfo, cache::{CompilerCache, SOLIDITY_FILES_CACHE_FILENAME}, compilers::{ + CompilerOutput, multi::{MultiCompiler, MultiCompilerLanguage, MultiCompilerSettings}, solc::{Solc, SolcCompiler, SolcLanguage}, vyper::{Vyper, VyperLanguage, VyperSettings}, - CompilerOutput, }, flatten::Flattener, info::ContractInfo, @@ -16,18 +19,16 @@ use foundry_compilers::{ project::{Preprocessor, ProjectCompiler}, project_util::*, solc::{Restriction, SolcRestrictions, SolcSettings}, - take_solc_installer_lock, Artifact, ConfigurableArtifacts, ExtraOutputFiles, ExtraOutputValues, - Graph, Project, ProjectBuilder, ProjectCompileOutput, ProjectPathsConfig, - RestrictionsWithVersion, TestFileFilter, + take_solc_installer_lock, }; use foundry_compilers_artifacts::{ - output_selection::OutputSelection, remappings::Remapping, BytecodeHash, Contract, DevDoc, - Error, ErrorDoc, EventDoc, EvmVersion, Libraries, MethodDoc, ModelCheckerEngine::CHC, - ModelCheckerSettings, Settings, Severity, SolcInput, UserDoc, UserDocNotice, + BytecodeHash, Contract, DevDoc, Error, ErrorDoc, EventDoc, EvmVersion, Libraries, MethodDoc, + ModelCheckerEngine::CHC, ModelCheckerSettings, Settings, Severity, SolcInput, UserDoc, + UserDocNotice, output_selection::OutputSelection, remappings::Remapping, }; use foundry_compilers_core::{ error::SolcError, - utils::{self, canonicalize, RuntimeOrHandle}, + utils::{self, RuntimeOrHandle, canonicalize}, }; use semver::Version; use similar_asserts::assert_eq; @@ -36,11 +37,11 @@ use std::{ env, fs::{self}, io, - path::{Path, PathBuf, MAIN_SEPARATOR}, + path::{MAIN_SEPARATOR, Path, PathBuf}, str::FromStr, sync::LazyLock, }; -use svm::{platform, Platform}; +use svm::{Platform, platform}; pub static VYPER: LazyLock = LazyLock::new(|| { RuntimeOrHandle::new().block_on(async { @@ -2184,7 +2185,12 @@ fn can_detect_invalid_version() { let out = tmp.compile().unwrap_err(); match out { SolcError::Message(err) => { - assert_eq!(err, format!("Encountered invalid solc version in src{MAIN_SEPARATOR}A.sol: No solc version exists that matches the version requirement: ^0.100.10")); + assert_eq!( + err, + format!( + "Encountered invalid solc version in src{MAIN_SEPARATOR}A.sol: No solc version exists that matches the version requirement: ^0.100.10" + ) + ); } _ => { unreachable!() diff --git a/crates/core/src/error.rs b/crates/core/src/error.rs index eab098142..385f6035a 100644 --- a/crates/core/src/error.rs +++ b/crates/core/src/error.rs @@ -52,7 +52,9 @@ pub enum SolcError { /// Failed to resolve a file #[error("failed to resolve file: {0}; check configured remappings")] Resolve(SolcIoError), - #[error("file cannot be resolved due to mismatch of file name case: {error}.\nFound existing file: {existing_file:?}\nPlease check the case of the import.")] + #[error( + "file cannot be resolved due to mismatch of file name case: {error}.\nFound existing file: {existing_file:?}\nPlease check the case of the import." + )] ResolveCaseSensitiveFileName { error: SolcIoError, existing_file: PathBuf }, #[error( "{0}\n\t\ diff --git a/crates/core/src/utils/mod.rs b/crates/core/src/utils/mod.rs index 09a0ad876..99d01ced8 100644 --- a/crates/core/src/utils/mod.rs +++ b/crates/core/src/utils/mod.rs @@ -4,7 +4,7 @@ use crate::error::{SolcError, SolcIoError}; use alloy_primitives::{hex, keccak256}; use cfg_if::cfg_if; use semver::{Version, VersionReq}; -use serde::{de::DeserializeOwned, Serialize}; +use serde::{Serialize, de::DeserializeOwned}; use std::{ fs, io::Write, @@ -392,11 +392,7 @@ pub fn common_ancestor(a: &Path, b: &Path) -> Option { break; } } - if found { - Some(ret) - } else { - None - } + if found { Some(ret) } else { None } } /// Returns the right subpath in a dir @@ -517,7 +513,7 @@ pub fn mkdir_or_touch(tmp: &std::path::Path, paths: &[&str]) { #[cfg(test)] mod tests { pub use super::*; - pub use std::fs::{create_dir_all, File}; + pub use std::fs::{File, create_dir_all}; #[test] fn can_create_parent_dirs_with_ext() {