@@ -158,6 +158,25 @@ pub fn executor_derive(input: TokenStream) -> TokenStream {
158158 where_clause
159159 . predicates
160160 . push ( syn:: parse_quote! { #inner_ty: :: openvm_circuit:: arch:: Executor <F > } ) ;
161+
162+ // We use the macro's feature to decide whether to generate the impl or not. This avoids
163+ // the target crate needing the "tco" feature defined.
164+ #[ cfg( feature = "tco" ) ]
165+ let handler = quote ! {
166+ fn handler<Ctx >(
167+ & self ,
168+ pc: u32 ,
169+ inst: & :: openvm_circuit:: arch:: instructions:: instruction:: Instruction <F >,
170+ data: & mut [ u8 ] ,
171+ ) -> Result <:: openvm_circuit:: arch:: Handler <F , Ctx >, :: openvm_circuit:: arch:: StaticProgramError >
172+ where
173+ Ctx : :: openvm_circuit:: arch:: execution_mode:: ExecutionCtxTrait , {
174+ self . 0 . handler( pc, inst, data)
175+ }
176+ } ;
177+ #[ cfg( not( feature = "tco" ) ) ]
178+ let handler = quote ! { } ;
179+
161180 quote ! {
162181 impl #impl_generics :: openvm_circuit:: arch:: Executor <F > for #name #ty_generics #where_clause {
163182 #[ inline( always) ]
@@ -176,17 +195,7 @@ pub fn executor_derive(input: TokenStream) -> TokenStream {
176195 self . 0 . pre_compute( pc, inst, data)
177196 }
178197
179- #[ cfg( feature = "tco" ) ]
180- fn handler<Ctx >(
181- & self ,
182- pc: u32 ,
183- inst: & :: openvm_circuit:: arch:: instructions:: instruction:: Instruction <F >,
184- data: & mut [ u8 ] ,
185- ) -> Result <:: openvm_circuit:: arch:: Handler <F , Ctx >, :: openvm_circuit:: arch:: StaticProgramError >
186- where
187- Ctx : :: openvm_circuit:: arch:: execution_mode:: ExecutionCtxTrait , {
188- self . 0 . handler( pc, inst, data)
189- }
198+ #handler
190199 }
191200 }
192201 . into ( )
@@ -220,7 +229,7 @@ pub fn executor_derive(input: TokenStream) -> TokenStream {
220229 } ) ;
221230 // Use full path ::openvm_circuit... so it can be used either within or outside the vm
222231 // crate. Assume F is already generic of the field.
223- let ( pre_compute_size_arms, pre_compute_arms, handler_arms , where_predicates) : ( Vec < _ > , Vec < _ > , Vec < _ > , Vec < _ > ) = multiunzip ( variants. iter ( ) . map ( |( variant_name, field) | {
232+ let ( pre_compute_size_arms, pre_compute_arms, _handler_arms , where_predicates) : ( Vec < _ > , Vec < _ > , Vec < _ > , Vec < _ > ) = multiunzip ( variants. iter ( ) . map ( |( variant_name, field) | {
224233 let field_ty = & field. ty ;
225234 let pre_compute_size_arm = quote ! {
226235 #name:: #variant_name( x) => <#field_ty as :: openvm_circuit:: arch:: Executor <#first_ty_generic>>:: pre_compute_size( x)
@@ -240,6 +249,26 @@ pub fn executor_derive(input: TokenStream) -> TokenStream {
240249 for predicate in where_predicates {
241250 where_clause. predicates . push ( predicate) ;
242251 }
252+ // We use the macro's feature to decide whether to generate the impl or not. This avoids
253+ // the target crate needing the "tco" feature defined.
254+ #[ cfg( feature = "tco" ) ]
255+ let handler = quote ! {
256+ fn handler<Ctx >(
257+ & self ,
258+ pc: u32 ,
259+ instruction: & :: openvm_circuit:: arch:: instructions:: instruction:: Instruction <F >,
260+ data: & mut [ u8 ] ,
261+ ) -> Result <:: openvm_circuit:: arch:: Handler <F , Ctx >, :: openvm_circuit:: arch:: StaticProgramError >
262+ where
263+ Ctx : :: openvm_circuit:: arch:: execution_mode:: ExecutionCtxTrait , {
264+ match self {
265+ #( #_handler_arms, ) *
266+ }
267+ }
268+ } ;
269+ #[ cfg( not( feature = "tco" ) ) ]
270+ let handler = quote ! { } ;
271+
243272 // Don't use these ty_generics because it might have extra "F"
244273 let ( impl_generics, _, where_clause) = new_generics. split_for_impl ( ) ;
245274
@@ -266,19 +295,7 @@ pub fn executor_derive(input: TokenStream) -> TokenStream {
266295 }
267296 }
268297
269- #[ cfg( feature = "tco" ) ]
270- fn handler<Ctx >(
271- & self ,
272- pc: u32 ,
273- instruction: & :: openvm_circuit:: arch:: instructions:: instruction:: Instruction <F >,
274- data: & mut [ u8 ] ,
275- ) -> Result <:: openvm_circuit:: arch:: Handler <F , Ctx >, :: openvm_circuit:: arch:: StaticProgramError >
276- where
277- Ctx : :: openvm_circuit:: arch:: execution_mode:: ExecutionCtxTrait , {
278- match self {
279- #( #handler_arms, ) *
280- }
281- }
298+ #handler
282299 }
283300 }
284301 . into ( )
@@ -314,6 +331,26 @@ pub fn metered_executor_derive(input: TokenStream) -> TokenStream {
314331 where_clause
315332 . predicates
316333 . push ( syn:: parse_quote! { #inner_ty: :: openvm_circuit:: arch:: MeteredExecutor <F > } ) ;
334+
335+ // We use the macro's feature to decide whether to generate the impl or not. This avoids
336+ // the target crate needing the "tco" feature defined.
337+ #[ cfg( feature = "tco" ) ]
338+ let metered_handler = quote ! {
339+ fn metered_handler<Ctx >(
340+ & self ,
341+ chip_idx: usize ,
342+ pc: u32 ,
343+ inst: & :: openvm_circuit:: arch:: instructions:: instruction:: Instruction <F >,
344+ data: & mut [ u8 ] ,
345+ ) -> Result <:: openvm_circuit:: arch:: Handler <F , Ctx >, :: openvm_circuit:: arch:: StaticProgramError >
346+ where
347+ Ctx : :: openvm_circuit:: arch:: execution_mode:: MeteredExecutionCtxTrait , {
348+ self . 0 . metered_handler( chip_idx, pc, inst, data)
349+ }
350+ } ;
351+ #[ cfg( not( feature = "tco" ) ) ]
352+ let metered_handler = quote ! { } ;
353+
317354 quote ! {
318355 impl #impl_generics :: openvm_circuit:: arch:: MeteredExecutor <F > for #name #ty_generics #where_clause {
319356 #[ inline( always) ]
@@ -332,18 +369,7 @@ pub fn metered_executor_derive(input: TokenStream) -> TokenStream {
332369 Ctx : :: openvm_circuit:: arch:: execution_mode:: MeteredExecutionCtxTrait , {
333370 self . 0 . metered_pre_compute( chip_idx, pc, inst, data)
334371 }
335- #[ cfg( feature = "tco" ) ]
336- fn metered_handler<Ctx >(
337- & self ,
338- chip_idx: usize ,
339- pc: u32 ,
340- inst: & :: openvm_circuit:: arch:: instructions:: instruction:: Instruction <F >,
341- data: & mut [ u8 ] ,
342- ) -> Result <:: openvm_circuit:: arch:: Handler <F , Ctx >, :: openvm_circuit:: arch:: StaticProgramError >
343- where
344- Ctx : :: openvm_circuit:: arch:: execution_mode:: MeteredExecutionCtxTrait , {
345- self . 0 . metered_handler( chip_idx, pc, inst, data)
346- }
372+ #metered_handler
347373 }
348374 }
349375 . into ( )
@@ -377,7 +403,7 @@ pub fn metered_executor_derive(input: TokenStream) -> TokenStream {
377403 } ) ;
378404 // Use full path ::openvm_circuit... so it can be used either within or outside the vm
379405 // crate. Assume F is already generic of the field.
380- let ( pre_compute_size_arms, metered_pre_compute_arms, metered_handler_arms , where_predicates) : ( Vec < _ > , Vec < _ > , Vec < _ > , Vec < _ > ) = multiunzip ( variants. iter ( ) . map ( |( variant_name, field) | {
406+ let ( pre_compute_size_arms, metered_pre_compute_arms, _metered_handler_arms , where_predicates) : ( Vec < _ > , Vec < _ > , Vec < _ > , Vec < _ > ) = multiunzip ( variants. iter ( ) . map ( |( variant_name, field) | {
381407 let field_ty = & field. ty ;
382408 let pre_compute_size_arm = quote ! {
383409 #name:: #variant_name( x) => <#field_ty as :: openvm_circuit:: arch:: MeteredExecutor <#first_ty_generic>>:: metered_pre_compute_size( x)
@@ -400,6 +426,28 @@ pub fn metered_executor_derive(input: TokenStream) -> TokenStream {
400426 // Don't use these ty_generics because it might have extra "F"
401427 let ( impl_generics, _, where_clause) = new_generics. split_for_impl ( ) ;
402428
429+ // We use the macro's feature to decide whether to generate the impl or not. This avoids
430+ // the target crate needing the "tco" feature defined.
431+ #[ cfg( feature = "tco" ) ]
432+ let metered_handler = quote ! {
433+ fn metered_handler<Ctx >(
434+ & self ,
435+ chip_idx: usize ,
436+ pc: u32 ,
437+ instruction: & :: openvm_circuit:: arch:: instructions:: instruction:: Instruction <F >,
438+ data: & mut [ u8 ] ,
439+ ) -> Result <:: openvm_circuit:: arch:: Handler <F , Ctx >, :: openvm_circuit:: arch:: StaticProgramError >
440+ where
441+ Ctx : :: openvm_circuit:: arch:: execution_mode:: MeteredExecutionCtxTrait ,
442+ {
443+ match self {
444+ #( #_metered_handler_arms, ) *
445+ }
446+ }
447+ } ;
448+ #[ cfg( not( feature = "tco" ) ) ]
449+ let metered_handler = quote ! { } ;
450+
403451 quote ! {
404452 impl #impl_generics :: openvm_circuit:: arch:: MeteredExecutor <#first_ty_generic> for #name #ty_generics #where_clause {
405453 #[ inline( always) ]
@@ -424,20 +472,7 @@ pub fn metered_executor_derive(input: TokenStream) -> TokenStream {
424472 }
425473 }
426474
427- #[ cfg( feature = "tco" ) ]
428- fn metered_handler<Ctx >(
429- & self ,
430- chip_idx: usize ,
431- pc: u32 ,
432- instruction: & :: openvm_circuit:: arch:: instructions:: instruction:: Instruction <F >,
433- data: & mut [ u8 ] ,
434- ) -> Result <:: openvm_circuit:: arch:: Handler <F , Ctx >, :: openvm_circuit:: arch:: StaticProgramError >
435- where
436- Ctx : :: openvm_circuit:: arch:: execution_mode:: MeteredExecutionCtxTrait , {
437- match self {
438- #( #metered_handler_arms, ) *
439- }
440- }
475+ #metered_handler
441476 }
442477 }
443478 . into ( )
@@ -563,7 +598,12 @@ fn generate_config_traits_impl(name: &Ident, inner: &DataStruct) -> syn::Result<
563598 . iter ( )
564599 . filter ( |f| f. attrs . iter ( ) . any ( |attr| attr. path ( ) . is_ident ( "config" ) ) )
565600 . exactly_one ( )
566- . expect ( "Exactly one field must have the #[config] attribute" ) ;
601+ . map_err ( |_| {
602+ syn:: Error :: new (
603+ name. span ( ) ,
604+ "Exactly one field must have the #[config] attribute" ,
605+ )
606+ } ) ?;
567607 let ( source_name, source_name_upper) =
568608 gen_name_with_uppercase_idents ( source_field. ident . as_ref ( ) . unwrap ( ) ) ;
569609
0 commit comments