@@ -21,7 +21,7 @@ use crate::kani_middle::reachability::CallGraph;
2121use crate :: kani_middle:: transform:: body:: CheckType ;
2222use crate :: kani_middle:: transform:: check_uninit:: { DelayedUbPass , UninitPass } ;
2323use crate :: kani_middle:: transform:: check_values:: ValidValuePass ;
24- use crate :: kani_middle:: transform:: clone:: ClonableTransformPass ;
24+ use crate :: kani_middle:: transform:: clone:: { ClonableGlobalPass , ClonableTransformPass } ;
2525use crate :: kani_middle:: transform:: contracts:: { AnyModifiesPass , FunctionWithContractPass } ;
2626use crate :: kani_middle:: transform:: kani_intrinsics:: IntrinsicGeneratorPass ;
2727use crate :: kani_middle:: transform:: loop_contracts:: LoopContractPass ;
@@ -211,10 +211,11 @@ enum TransformationResult {
211211 NotModified ,
212212}
213213
214+ #[ derive( Clone ) ]
214215pub struct GlobalPasses {
215216 /// The passes that operate on the whole codegen unit, they run after all previous passes are
216217 /// done.
217- global_passes : Vec < Box < dyn GlobalPass > > ,
218+ global_passes : Vec < Box < dyn ClonableGlobalPass > > ,
218219}
219220
220221impl GlobalPasses {
@@ -232,7 +233,7 @@ impl GlobalPasses {
232233 global_passes
233234 }
234235
235- fn add_global_pass < P : GlobalPass + ' static > ( & mut self , query_db : & QueryDb , pass : P ) {
236+ fn add_global_pass < P : ClonableGlobalPass + ' static > ( & mut self , query_db : & QueryDb , pass : P ) {
236237 if pass. is_enabled ( query_db) {
237238 self . global_passes . push ( Box :: new ( pass) )
238239 }
@@ -269,32 +270,49 @@ mod clone {
269270 //! we set both up to have blanket implementations for all `T: TransformPass + Clone`, the compiler pieces them together properly
270271 //! and we can implement `Clone` directly using the pair!
271272
272- use crate :: kani_middle:: transform:: TransformPass ;
273+ /// Builds a new dyn compatible wrapper trait that's essentially equivalent to extending
274+ /// `$extends` with `Clone`. Requires an ident for an intermediate trait for avoiding cycles
275+ /// in the implementation.
276+ macro_rules! implement_clone {
277+ ( $new_trait_name: ident, $intermediate_trait_name: ident, $extends: path) => {
278+ #[ allow( private_interfaces) ]
279+ pub ( crate ) trait $new_trait_name: $extends {
280+ fn clone_there( & self ) -> Box <dyn $intermediate_trait_name>;
281+ }
273282
274- /// A wrapper trait essentially equivalent to `TransformPass + Clone`
275- pub ( crate ) trait ClonableTransformPass : TransformPass {
276- fn clone_there ( & self ) -> Box < dyn CloneBackIntoPass > ;
277- }
283+ impl Clone for Box <dyn $new_trait_name> {
284+ fn clone( & self ) -> Self {
285+ self . clone_there( ) . clone_back( )
286+ }
287+ }
278288
279- impl Clone for Box < dyn ClonableTransformPass > {
280- fn clone ( & self ) -> Self {
281- self . clone_there ( ) . clone_back ( )
282- }
283- }
289+ #[ allow( private_interfaces) ]
290+ impl <T : $extends + Clone + ' static > $new_trait_name for T {
291+ fn clone_there( & self ) -> Box <dyn $intermediate_trait_name> {
292+ Box :: new( self . clone( ) )
293+ }
294+ }
284295
285- impl < T : TransformPass + Clone + ' static > ClonableTransformPass for T {
286- fn clone_there ( & self ) -> Box < dyn CloneBackIntoPass > {
287- Box :: new ( self . clone ( ) )
288- }
289- }
296+ trait $intermediate_trait_name {
297+ fn clone_back( & self ) -> Box <dyn $new_trait_name>;
298+ }
290299
291- pub ( crate ) trait CloneBackIntoPass {
292- fn clone_back ( & self ) -> Box < dyn ClonableTransformPass > ;
300+ impl <T : $extends + Clone + ' static > $intermediate_trait_name for T {
301+ fn clone_back( & self ) -> Box <dyn $new_trait_name> {
302+ Box :: new( self . clone( ) )
303+ }
304+ }
305+ } ;
293306 }
294307
295- impl < T : TransformPass + Clone + ' static > CloneBackIntoPass for T {
296- fn clone_back ( & self ) -> Box < dyn ClonableTransformPass > {
297- Box :: new ( self . clone ( ) )
298- }
299- }
308+ implement_clone ! (
309+ ClonableTransformPass ,
310+ ClonableTransformPassMid ,
311+ crate :: kani_middle:: transform:: TransformPass
312+ ) ;
313+ implement_clone ! (
314+ ClonableGlobalPass ,
315+ ClonableGlobalPassMid ,
316+ crate :: kani_middle:: transform:: GlobalPass
317+ ) ;
300318}
0 commit comments