Skip to content

Commit e06876f

Browse files
committed
refactor restrictions
1 parent 26a2657 commit e06876f

File tree

5 files changed

+61
-67
lines changed

5 files changed

+61
-67
lines changed

crates/compilers/src/compilers/multi.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,8 @@ pub struct MultiCompilerRestrictions {
138138
}
139139

140140
impl CompilerSettingsRestrictions for MultiCompilerRestrictions {
141-
fn merge(&mut self, other: Self) {
142-
self.solc.merge(other.solc);
143-
self.vyper.merge(other.vyper);
141+
fn merge(self, other: Self) -> Option<Self> {
142+
Some(Self { solc: self.solc.merge(other.solc)?, vyper: self.vyper.merge(other.vyper)? })
144143
}
145144
}
146145

crates/compilers/src/compilers/restrictions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use std::{
55

66
use semver::VersionReq;
77

8-
pub trait CompilerSettingsRestrictions: Debug + Sync + Send + Clone + Default {
9-
fn merge(&mut self, other: Self);
8+
pub trait CompilerSettingsRestrictions: Copy + Debug + Sync + Send + Clone + Default {
9+
fn merge(self, other: Self) -> Option<Self>;
1010
}
1111

1212
/// Combines [CompilerSettingsRestrictions] with a restrictions on compiler versions for a given

crates/compilers/src/compilers/solc/mod.rs

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use foundry_compilers_artifacts::{
88
error::SourceLocation,
99
output_selection::OutputSelection,
1010
remappings::Remapping,
11-
serde_helpers::display_from_str_opt,
1211
sources::{Source, Sources},
1312
Error, EvmVersion, Settings, Severity, SolcInput,
1413
};
@@ -191,70 +190,73 @@ impl DerefMut for SolcSettings {
191190
}
192191
}
193192

194-
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, Eq, PartialEq)]
195-
pub struct EvmVersionRestriction {
196-
#[serde(default, with = "display_from_str_opt", skip_serializing_if = "Option::is_none")]
197-
pub min_evm_version: Option<EvmVersion>,
198-
#[serde(default, with = "display_from_str_opt", skip_serializing_if = "Option::is_none")]
199-
pub max_evm_version: Option<EvmVersion>,
193+
#[derive(Debug, Clone, Copy, Eq, Default, PartialEq)]
194+
pub struct Restriction<V> {
195+
pub min: Option<V>,
196+
pub max: Option<V>,
200197
}
201198

202-
impl EvmVersionRestriction {
199+
impl<V: PartialEq + Ord + Copy> Restriction<V> {
203200
/// Returns true if the given version satisfies the restrictions
204201
///
205202
/// If given None, only returns true if no restrictions are set
206-
pub fn satisfies(&self, version: Option<EvmVersion>) -> bool {
207-
self.min_evm_version.map_or(true, |min| version.map_or(false, |v| v >= min))
208-
&& self.max_evm_version.map_or(true, |max| version.map_or(false, |v| v <= max))
209-
}
210-
211-
pub fn merge(&mut self, other: &Self) {
212-
let Self { min_evm_version, max_evm_version } = other;
213-
214-
if let Some(min_evm_version) = min_evm_version {
215-
if self.min_evm_version.map_or(true, |e| e < *min_evm_version) {
216-
self.min_evm_version.replace(*min_evm_version);
203+
pub fn satisfies(&self, value: Option<V>) -> bool {
204+
self.min.map_or(true, |min| value.map_or(false, |v| v >= min))
205+
&& self.max.map_or(true, |max| value.map_or(false, |v| v <= max))
206+
}
207+
208+
/// Combines two restrictions into a new one
209+
pub fn merge(self, other: Self) -> Option<Self> {
210+
let Self { mut min, mut max } = self;
211+
let Self { min: other_min, max: other_max } = other;
212+
213+
min = min.map_or(other_min, |this_min| {
214+
Some(other_min.map_or(this_min, |other_min| this_min.max(other_min)))
215+
});
216+
max = max.map_or(other_max, |this_max| {
217+
Some(other_max.map_or(this_max, |other_max| this_max.min(other_max)))
218+
});
219+
220+
if let (Some(min), Some(max)) = (min, max) {
221+
if min > max {
222+
return None;
217223
}
218224
}
219225

220-
if let Some(max_evm_version) = max_evm_version {
221-
if self.max_evm_version.map_or(true, |e| e > *max_evm_version) {
222-
self.max_evm_version.replace(*max_evm_version);
223-
}
226+
Some(Self { min, max })
227+
}
228+
229+
pub fn apply(&self, value: Option<V>) -> Option<V> {
230+
match (value, self.min, self.max) {
231+
(None, Some(min), _) => Some(min),
232+
(None, None, Some(max)) => Some(max),
233+
(Some(cur), Some(min), _) if cur < min => Some(min),
234+
(Some(cur), _, Some(max)) if cur > max => Some(max),
235+
_ => value,
224236
}
225237
}
226238
}
227239

228240
#[derive(Debug, Clone, Copy, Default)]
229241
pub struct SolcRestrictions {
230-
pub evm_version: EvmVersionRestriction,
242+
pub evm_version: Restriction<EvmVersion>,
231243
pub via_ir: Option<bool>,
232-
pub min_optimizer_runs: Option<usize>,
233-
pub max_optimizer_runs: Option<usize>,
244+
pub optimizer_runs: Restriction<usize>,
234245
}
235246

236247
impl CompilerSettingsRestrictions for SolcRestrictions {
237-
fn merge(&mut self, other: Self) {
238-
self.evm_version.merge(&other.evm_version);
239-
240-
// Preserve true
241-
if self.via_ir.map_or(true, |via_ir| !via_ir) {
242-
self.via_ir = other.via_ir;
243-
}
244-
245-
if self
246-
.min_optimizer_runs
247-
.map_or(true, |min| min < other.min_optimizer_runs.unwrap_or(usize::MAX))
248-
{
249-
self.min_optimizer_runs = other.min_optimizer_runs;
248+
fn merge(self, other: Self) -> Option<Self> {
249+
if let (Some(via_ir), Some(other_via_ir)) = (self.via_ir, other.via_ir) {
250+
if via_ir != other_via_ir {
251+
return None;
252+
}
250253
}
251254

252-
if self
253-
.max_optimizer_runs
254-
.map_or(true, |max| max > other.max_optimizer_runs.unwrap_or(usize::MIN))
255-
{
256-
self.max_optimizer_runs = other.max_optimizer_runs;
257-
}
255+
Some(Self {
256+
evm_version: self.evm_version.merge(other.evm_version)?,
257+
via_ir: self.via_ir.or(other.via_ir),
258+
optimizer_runs: self.optimizer_runs.merge(other.optimizer_runs)?,
259+
})
258260
}
259261
}
260262

@@ -324,16 +326,12 @@ impl CompilerSettings for SolcSettings {
324326
satisfies &= restrictions.evm_version.satisfies(self.evm_version);
325327
satisfies &=
326328
restrictions.via_ir.map_or(true, |via_ir| via_ir == self.via_ir.unwrap_or_default());
327-
satisfies &= restrictions
328-
.min_optimizer_runs
329-
.map_or(true, |min| self.optimizer.runs.map_or(false, |runs| runs >= min));
330-
satisfies &= restrictions
331-
.max_optimizer_runs
332-
.map_or(true, |max| self.optimizer.runs.map_or(false, |runs| runs <= max));
329+
satisfies &= restrictions.optimizer_runs.satisfies(self.optimizer.runs);
333330

334331
// Ensure that we either don't have min optimizer runs set or that the optimizer is enabled
335332
satisfies &= restrictions
336-
.min_optimizer_runs
333+
.optimizer_runs
334+
.min
337335
.map_or(true, |min| min == 0 || self.optimizer.enabled.unwrap_or_default());
338336

339337
satisfies

crates/compilers/src/compilers/vyper/settings.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@ use std::{collections::BTreeSet, path::PathBuf};
33
pub use crate::artifacts::vyper::VyperSettings;
44
use crate::{
55
compilers::{restrictions::CompilerSettingsRestrictions, CompilerSettings},
6-
solc::EvmVersionRestriction,
6+
solc::Restriction,
77
};
8-
use foundry_compilers_artifacts::output_selection::OutputSelection;
8+
use foundry_compilers_artifacts::{output_selection::OutputSelection, EvmVersion};
99

1010
#[derive(Clone, Copy, Debug, Default)]
1111
pub struct VyperRestrictions {
12-
pub evm_version: EvmVersionRestriction,
12+
pub evm_version: Restriction<EvmVersion>,
1313
}
1414

1515
impl CompilerSettingsRestrictions for VyperRestrictions {
16-
fn merge(&mut self, other: Self) {
17-
self.evm_version.merge(&other.evm_version);
16+
fn merge(self, other: Self) -> Option<Self> {
17+
Some(Self { evm_version: self.evm_version.merge(other.evm_version)? })
1818
}
1919
}
2020

crates/compilers/tests/project.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use foundry_compilers::{
1616
info::ContractInfo,
1717
multi::MultiCompilerRestrictions,
1818
project_util::*,
19-
solc::{EvmVersionRestriction, SolcRestrictions, SolcSettings},
19+
solc::{Restriction, SolcRestrictions, SolcSettings},
2020
take_solc_installer_lock, Artifact, ConfigurableArtifacts, ExtraOutputValues, Graph, Project,
2121
ProjectBuilder, ProjectCompileOutput, ProjectPathsConfig, RestrictionsWithVersion,
2222
TestFileFilter,
@@ -4073,10 +4073,7 @@ contract SimpleContract {}
40734073
let cancun_restriction = RestrictionsWithVersion {
40744074
restrictions: MultiCompilerRestrictions {
40754075
solc: SolcRestrictions {
4076-
evm_version: EvmVersionRestriction {
4077-
min_evm_version: Some(EvmVersion::Cancun),
4078-
..Default::default()
4079-
},
4076+
evm_version: Restriction { min: Some(EvmVersion::Cancun), ..Default::default() },
40804077
..Default::default()
40814078
},
40824079
..Default::default()

0 commit comments

Comments
 (0)