From 569c3a18aa53feb1ac784d0b10f9351bb1293489 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 29 Nov 2024 15:37:46 +0100 Subject: [PATCH 1/3] meta: add note about grammar,spelling prs (#228) --- CONTRIBUTING.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 602193f0..4755f50a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -74,6 +74,7 @@ cases should be limited, as much as possible, to using only Foundry Compilers AP See [How to create a Minimal, Complete, and Verifiable example][mcve]. [mcve]: https://stackoverflow.com/help/mcve + [template]: .github/PULL_REQUEST_TEMPLATE.md ### Triaging a Bug Report @@ -120,6 +121,11 @@ commit signing. This option allows us to make small changes to your PR to bring it in line with these standards. It helps us get your PR in faster, and with less work from you. +### Contributions Related to Spelling and Grammar + +At this time, we will not be accepting contributions that only fix spelling or grammatical errors in documentation, code +or elsewhere. + ### Cargo Commands This section lists some commonly needed commands. @@ -304,5 +310,7 @@ the commit log, or by using an `Author: ` meta-data tag in the commit. _Adapted from the [Tokio contributing guide]_. [hiding-a-comment]: https://help.github.com/articles/managing-disruptive-comments/#hiding-a-comment + [documentation test]: https://doc.rust-lang.org/rustdoc/documentation-tests.html + [Tokio contributing guide]: https://github.com/tokio-rs/tokio/blob/master/CONTRIBUTING.md From 9589a49f07cd790f7572b91c6699ac20d4fa52ba Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 29 Nov 2024 21:58:15 +0100 Subject: [PATCH 2/3] fix: add fallback parser for contract names (#229) Fixes after bump https://github.com/foundry-rs/foundry/issues/9433 --- Cargo.toml | 3 +-- crates/compilers/Cargo.toml | 2 -- .../compilers/src/compilers/solc/compiler.rs | 4 ++-- crates/compilers/src/resolver/parse.rs | 23 +++++++++++++++++++ crates/compilers/tests/project.rs | 4 ++-- crates/core/Cargo.toml | 1 - crates/core/src/utils.rs | 7 +++++- 7 files changed, 34 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b5d90c47..5b787913 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,6 @@ cfg-if = "1.0" dunce = "1.0" md-5 = "0.10" memmap2 = "0.9" -once_cell = "1.19" path-slash = "0.2" rayon = "1.8" regex = "1.10" @@ -54,7 +53,7 @@ similar-asserts = "1" solar-parse = { version = "=0.1.0", default-features = false } svm = { package = "svm-rs", version = "0.5", default-features = false } tempfile = "3.9" -thiserror = "1" +thiserror = "2" tracing = "0.1" walkdir = "2.5" yansi = "1.0" diff --git a/crates/compilers/Cargo.toml b/crates/compilers/Cargo.toml index 3d7f6339..5da761c1 100644 --- a/crates/compilers/Cargo.toml +++ b/crates/compilers/Cargo.toml @@ -29,7 +29,6 @@ thiserror.workspace = true path-slash.workspace = true yansi.workspace = true solar-parse.workspace = true -once_cell = { workspace = true, optional = true } futures-util = { workspace = true, optional = true } tokio = { workspace = true, optional = true } @@ -85,7 +84,6 @@ svm-solc = [ "dep:svm-builds", "dep:sha2", "foundry-compilers-core/svm-solc", - "dep:once_cell", ] # Utilities for creating and testing project workspaces. project-util = [ diff --git a/crates/compilers/src/compilers/solc/compiler.rs b/crates/compilers/src/compilers/solc/compiler.rs index aefcc629..86e7fb51 100644 --- a/crates/compilers/src/compilers/solc/compiler.rs +++ b/crates/compilers/src/compilers/solc/compiler.rs @@ -45,8 +45,8 @@ macro_rules! take_solc_installer_lock { /// we should download. /// The boolean value marks whether there was an error accessing the release list #[cfg(feature = "svm-solc")] -pub static RELEASES: once_cell::sync::Lazy<(svm::Releases, Vec, bool)> = - once_cell::sync::Lazy::new(|| { +pub static RELEASES: std::sync::LazyLock<(svm::Releases, Vec, bool)> = + std::sync::LazyLock::new(|| { match serde_json::from_str::(svm_builds::RELEASE_LIST_JSON) { Ok(releases) => { let sorted_versions = releases.clone().into_versions(); diff --git a/crates/compilers/src/resolver/parse.rs b/crates/compilers/src/resolver/parse.rs index 3bb4f1be..d4e27090 100644 --- a/crates/compilers/src/resolver/parse.rs +++ b/crates/compilers/src/resolver/parse.rs @@ -133,6 +133,11 @@ impl SolData { if imports.is_empty() { imports = capture_imports(content); } + if contract_names.is_empty() { + utils::RE_CONTRACT_NAMES.captures_iter(content).for_each(|cap| { + contract_names.push(cap[1].to_owned()); + }); + } } let license = content.lines().next().and_then(|line| { utils::capture_outer_and_inner( @@ -313,6 +318,12 @@ mod tests { assert_eq!(data.version_req, version_req.map(|v| v.parse().unwrap()), "src:\n{src}"); } + #[track_caller] + fn assert_contract_names(names: &[&str], src: &str) { + let data = SolData::parse(src, "test.sol".as_ref()); + assert_eq!(data.contract_names, names, "src:\n{src}"); + } + #[test] fn soldata_parsing() { assert_version(None, ""); @@ -332,6 +343,18 @@ contract BugReport { } "#, ); + + assert_contract_names( + &["A", "B69$_", "C_", "$D"], + r#" + contract A {} +library B69$_ {} +abstract contract C_ {} interface $D {} + +uint constant x = .1e10; +uint constant y = .1 ether; + "#, + ); } #[test] diff --git a/crates/compilers/tests/project.rs b/crates/compilers/tests/project.rs index 8bb36917..1f9af8d8 100644 --- a/crates/compilers/tests/project.rs +++ b/crates/compilers/tests/project.rs @@ -30,7 +30,6 @@ use foundry_compilers_core::{ error::SolcError, utils::{self, canonicalize, RuntimeOrHandle}, }; -use once_cell::sync::Lazy; use semver::Version; use similar_asserts::assert_eq; use std::{ @@ -39,10 +38,11 @@ use std::{ io, path::{Path, PathBuf, MAIN_SEPARATOR}, str::FromStr, + sync::LazyLock, }; use svm::{platform, Platform}; -pub static VYPER: Lazy = Lazy::new(|| { +pub static VYPER: LazyLock = LazyLock::new(|| { RuntimeOrHandle::new().block_on(async { #[cfg(target_family = "unix")] use std::{fs::Permissions, os::unix::fs::PermissionsExt}; diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index d132dedc..09512aaa 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -18,7 +18,6 @@ workspace = true alloy-primitives.workspace = true cfg-if.workspace = true dunce.workspace = true -once_cell.workspace = true path-slash.workspace = true regex.workspace = true semver.workspace = true diff --git a/crates/core/src/utils.rs b/crates/core/src/utils.rs index 62441497..4a591527 100644 --- a/crates/core/src/utils.rs +++ b/crates/core/src/utils.rs @@ -3,7 +3,6 @@ use crate::error::{SolcError, SolcIoError}; use alloy_primitives::{hex, keccak256}; use cfg_if::cfg_if; -use once_cell::sync::Lazy; use regex::{Match, Regex}; use semver::{Version, VersionReq}; use serde::{de::DeserializeOwned, Serialize}; @@ -13,6 +12,7 @@ use std::{ io::Write, ops::Range, path::{Component, Path, PathBuf}, + sync::LazyLock as Lazy, }; use walkdir::WalkDir; @@ -46,6 +46,11 @@ pub static RE_THREE_OR_MORE_NEWLINES: Lazy = Lazy::new(|| Regex::new("\n{ pub static RE_VYPER_VERSION: Lazy = Lazy::new(|| Regex::new(r"#(?:pragma version|@version)\s+(?P.+)").unwrap()); +/// A regex that matches the contract names in a Solidity file. +pub static RE_CONTRACT_NAMES: Lazy = Lazy::new(|| { + Regex::new(r"\b(?:contract|library|abstract\s+contract|interface)\s+([\w$]+)").unwrap() +}); + /// Extensions acceptable by solc compiler. pub const SOLC_EXTENSIONS: &[&str] = &["sol", "yul"]; From a1ce2b434b4560b15b20483850727e8128a59375 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 2 Dec 2024 17:31:45 +0200 Subject: [PATCH 3/3] chore: bump MSRV to 1.83 (#230) --- .github/workflows/ci.yml | 12 +++++------- Cargo.toml | 2 +- README.md | 2 +- clippy.toml | 2 +- crates/artifacts/solc/src/error.rs | 8 +++++--- crates/artifacts/solc/src/lib.rs | 4 ++-- crates/artifacts/solc/src/output_selection.rs | 4 ++-- crates/artifacts/vyper/src/input.rs | 2 +- crates/compilers/src/cache.rs | 6 ++---- crates/compilers/src/compile/output/mod.rs | 2 +- crates/compilers/src/compilers/solc/mod.rs | 6 +++--- crates/compilers/src/filter.rs | 2 +- crates/compilers/src/lib.rs | 2 +- crates/compilers/src/resolver/parse.rs | 2 +- 14 files changed, 27 insertions(+), 29 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 641342f9..e8710d01 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,15 +21,17 @@ jobs: fail-fast: false matrix: os: ["ubuntu-latest", "macos-latest", "windows-latest"] - rust: ["stable", "1.70"] + rust: ["stable", "1.83"] flags: ["", "--all-features"] exclude: # Skip because some features have higher MSRV. - - rust: "1.70" # MSRV + - rust: "1.83" # MSRV flags: "--all-features" steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} - name: Install test binaries shell: bash run: ./.github/scripts/install_test_binaries.sh @@ -38,11 +40,7 @@ jobs: - uses: Swatinem/rust-cache@v2 with: cache-on-failure: true - - name: build - if: matrix.rust == '1.70' # MSRV - run: cargo build --workspace ${{ matrix.flags }} - name: test - if: matrix.rust != '1.70' # MSRV shell: bash run: cargo nextest run ${{ matrix.flags }} --retries 2 diff --git a/Cargo.toml b/Cargo.toml index 5b787913..d40d4d9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ resolver = "2" [workspace.package] authors = ["Foundry Maintainers"] version = "0.12.3" -rust-version = "1.70" +rust-version = "1.83" readme = "README.md" license = "MIT OR Apache-2.0" repository = "https://github.com/foundry-rs/compilers" diff --git a/README.md b/README.md index 88cb13f5..70e1f88f 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ When updating this, also update: Foundry Compilers will keep a rolling MSRV (minimum supported rust version) policy of **at least** 6 months. When increasing the MSRV, the new Rust version must have been -released at least six months ago. The current MSRV is 1.70.0. +released at least six months ago. The current MSRV is 1.83.0. Note that the MSRV is not increased automatically, and only as part of a minor release. diff --git a/clippy.toml b/clippy.toml index 5d37e5d8..f234c901 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -msrv = "1.70" +msrv = "1.83" diff --git a/crates/artifacts/solc/src/error.rs b/crates/artifacts/solc/src/error.rs index bdde31d0..78453cd6 100644 --- a/crates/artifacts/solc/src/error.rs +++ b/crates/artifacts/solc/src/error.rs @@ -150,9 +150,11 @@ impl fmt::Display for Error { // unless it also contains a source location, in which case the entire error message is an // old style error message, like: // path/to/file:line:column: ErrorType: message - if lines.clone().next().map_or(false, |l| { - l.contains(short_msg) && l.bytes().filter(|b| *b == b':').count() < 3 - }) { + if lines + .clone() + .next() + .is_some_and(|l| l.contains(short_msg) && l.bytes().filter(|b| *b == b':').count() < 3) + { let _ = lines.next(); } diff --git a/crates/artifacts/solc/src/lib.rs b/crates/artifacts/solc/src/lib.rs index a04da256..6437181d 100644 --- a/crates/artifacts/solc/src/lib.rs +++ b/crates/artifacts/solc/src/lib.rs @@ -110,9 +110,9 @@ impl SolcInput { let mut yul_sources = Sources::new(); for (file, source) in sources { - if file.extension().map_or(false, |e| e == "yul") { + if file.extension().is_some_and(|e| e == "yul") { yul_sources.insert(file, source); - } else if file.extension().map_or(false, |e| e == "sol") { + } else if file.extension().is_some_and(|e| e == "sol") { solidity_sources.insert(file, source); } } diff --git a/crates/artifacts/solc/src/output_selection.rs b/crates/artifacts/solc/src/output_selection.rs index e39e28d0..99beb3e0 100644 --- a/crates/artifacts/solc/src/output_selection.rs +++ b/crates/artifacts/solc/src/output_selection.rs @@ -149,9 +149,9 @@ impl OutputSelection { /// TODO: correctly process wildcard keys to reduce false negatives pub fn is_subset_of(&self, other: &Self) -> bool { self.0.iter().all(|(file, selection)| { - other.0.get(file).map_or(false, |other_selection| { + other.0.get(file).is_some_and(|other_selection| { selection.iter().all(|(contract, outputs)| { - other_selection.get(contract).map_or(false, |other_outputs| { + other_selection.get(contract).is_some_and(|other_outputs| { outputs.iter().all(|output| other_outputs.contains(output)) }) }) diff --git a/crates/artifacts/vyper/src/input.rs b/crates/artifacts/vyper/src/input.rs index 7b99b79a..9b1b17d7 100644 --- a/crates/artifacts/vyper/src/input.rs +++ b/crates/artifacts/vyper/src/input.rs @@ -22,7 +22,7 @@ impl VyperInput { let mut interfaces = Sources::new(); for (path, content) in sources { - if path.extension().map_or(false, |ext| ext == VYPER_INTERFACE_EXTENSION) { + if path.extension().is_some_and(|ext| ext == VYPER_INTERFACE_EXTENSION) { // Interface .vyi files should be removed from the output selection. settings.output_selection.0.remove(path.to_string_lossy().as_ref()); interfaces.insert(path, content); diff --git a/crates/compilers/src/cache.rs b/crates/compilers/src/cache.rs index 21a738d7..17777e66 100644 --- a/crates/compilers/src/cache.rs +++ b/crates/compilers/src/cache.rs @@ -616,7 +616,7 @@ impl GroupedSources { /// Returns true if the file was included with the given version. pub fn contains(&self, file: &Path, version: &Version) -> bool { - self.inner.get(file).map_or(false, |versions| versions.contains(version)) + self.inner.get(file).is_some_and(|versions| versions.contains(version)) } } @@ -783,9 +783,7 @@ impl ArtifactsCacheInner<'_, T, C> { let mut dirty_profiles = HashSet::new(); for (profile, settings) in &self.cache.profiles { - if !existing_profiles - .get(profile.as_str()) - .map_or(false, |p| p.can_use_cached(settings)) + if !existing_profiles.get(profile.as_str()).is_some_and(|p| p.can_use_cached(settings)) { trace!("dirty profile: {}", profile); dirty_profiles.insert(profile.clone()); diff --git a/crates/compilers/src/compile/output/mod.rs b/crates/compilers/src/compile/output/mod.rs index 4c2eb9c4..193ef1dd 100644 --- a/crates/compilers/src/compile/output/mod.rs +++ b/crates/compilers/src/compile/output/mod.rs @@ -872,7 +872,7 @@ impl AggregatedCompilerOutput { self.contracts.contracts_with_files().filter(|(path, _, _)| *path == contract_path).any( |(_, _, contract)| { - contract.abi.as_ref().map_or(false, |abi| abi.functions.contains_key("IS_TEST")) + contract.abi.as_ref().is_some_and(|abi| abi.functions.contains_key("IS_TEST")) }, ) } diff --git a/crates/compilers/src/compilers/solc/mod.rs b/crates/compilers/src/compilers/solc/mod.rs index d3aebcd6..218d51cc 100644 --- a/crates/compilers/src/compilers/solc/mod.rs +++ b/crates/compilers/src/compilers/solc/mod.rs @@ -201,8 +201,8 @@ impl Restriction { /// /// If given None, only returns true if no restrictions are set pub fn satisfies(&self, value: Option) -> bool { - self.min.map_or(true, |min| value.map_or(false, |v| v >= min)) - && self.max.map_or(true, |max| value.map_or(false, |v| v <= max)) + self.min.is_none_or(|min| value.is_some_and(|v| v >= min)) + && self.max.is_none_or(|max| value.is_some_and(|v| v <= max)) } /// Combines two restrictions into a new one @@ -346,7 +346,7 @@ impl CompilerSettings for SolcSettings { // Ensure that we either don't have min optimizer runs set or that the optimizer is enabled satisfies &= optimizer_runs .min - .map_or(true, |min| min == 0 || self.optimizer.enabled.unwrap_or_default()); + .is_none_or(|min| min == 0 || self.optimizer.enabled.unwrap_or_default()); satisfies } diff --git a/crates/compilers/src/filter.rs b/crates/compilers/src/filter.rs index 9038e50c..119d9674 100644 --- a/crates/compilers/src/filter.rs +++ b/crates/compilers/src/filter.rs @@ -142,7 +142,7 @@ impl<'a> SparseOutputFilter<'a> { .collect(); // Remove clean sources, those will be read from cache. - full_compilation.retain(|file| sources.0.get(file).map_or(false, |s| s.is_dirty())); + full_compilation.retain(|file| sources.0.get(file).is_some_and(|s| s.is_dirty())); settings.update_output_selection(|selection| { trace!( diff --git a/crates/compilers/src/lib.rs b/crates/compilers/src/lib.rs index 26f1c085..d273cbe8 100644 --- a/crates/compilers/src/lib.rs +++ b/crates/compilers/src/lib.rs @@ -403,7 +403,7 @@ impl Project { { let mut contracts = self.collect_contract_names()?; - if contracts.get(target_name).map_or(true, |paths| paths.is_empty()) { + if contracts.get(target_name).is_none_or(|paths| paths.is_empty()) { return Err(SolcError::msg(format!("No contract found with the name `{target_name}`"))); } let mut paths = contracts.remove(target_name).unwrap(); diff --git a/crates/compilers/src/resolver/parse.rs b/crates/compilers/src/resolver/parse.rs index d4e27090..adaf96d3 100644 --- a/crates/compilers/src/resolver/parse.rs +++ b/crates/compilers/src/resolver/parse.rs @@ -45,7 +45,7 @@ impl SolData { /// This will attempt to parse the solidity AST and extract the imports and version pragma. If /// parsing fails, we'll fall back to extract that info via regex pub fn parse(content: &str, file: &Path) -> Self { - let is_yul = file.extension().map_or(false, |ext| ext == "yul"); + let is_yul = file.extension().is_some_and(|ext| ext == "yul"); let mut version = None; let mut experimental = None; let mut imports = Vec::>::new();