@@ -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 ) ]
229241pub 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
236247impl 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
0 commit comments