@@ -192,7 +192,7 @@ impl LanguageGenerator for RustGenerator {
192192 if skip_trait_functions && func. kind . is_trait_function ( ) {
193193 continue ;
194194 }
195- self . generate_function_declaration ( & mut builder, func, config) ;
195+ self . generate_function_declaration ( & mut builder, func, ir , config) ;
196196 }
197197
198198 builder. dedent ( ) ;
@@ -725,7 +725,7 @@ impl RustGenerator {
725725
726726 // into_option() - converts to std Option<T>
727727 builder. line ( & format ! (
728- "/// Converts to a Rust `Option<{}>`." ,
728+ "/// Converts to a Rust `Option<{}>`, consuming self ." ,
729729 prefixed_inner
730730 ) ) ;
731731 builder. line ( "#[inline]" ) ;
@@ -734,9 +734,15 @@ impl RustGenerator {
734734 prefixed_inner
735735 ) ) ;
736736 builder. indent ( ) ;
737- builder. line ( "match self {" ) ;
737+ builder. line ( "match & self {" ) ;
738738 builder. indent ( ) ;
739- builder. line ( & format ! ( "{}::Some(v) => Some(v)," , prefixed_name) ) ;
739+ builder. line ( & format ! ( "{}::Some(val) => {{" , prefixed_name) ) ;
740+ builder. indent ( ) ;
741+ builder. line ( "let v = unsafe { core::ptr::read(val) };" ) ;
742+ builder. line ( "core::mem::forget(self);" ) ;
743+ builder. line ( "Some(v)" ) ;
744+ builder. dedent ( ) ;
745+ builder. line ( "}" ) ;
740746 builder. line ( & format ! ( "{}::None => None," , prefixed_name) ) ;
741747 builder. dedent ( ) ;
742748 builder. line ( "}" ) ;
@@ -1478,10 +1484,9 @@ impl RustGenerator {
14781484 // Check if this type is a callback wrapper
14791485 // If so, accept the CallbackType (fn pointer) and pass it directly
14801486 // (The C-ABI function now accepts CallbackType directly, not the wrapper struct)
1481- // BUT: Don't apply this transformation when we're in a method of the callback wrapper itself
1482- // (e.g., deep_copy on IFrameCallback should take &IFrameCallback, not IFrameCallbackType)
1483- // ALSO: Don't apply for EnumVariantConstructor - enum variants need exact types
1484- // (e.g., OptionCallback::Some needs Callback, not CallbackType)
1487+ // BUT: Don't apply this transformation when:
1488+ // - we're in a method of the callback wrapper itself (e.g., deep_copy on IFrameCallback)
1489+ // - this is an EnumVariantConstructor (e.g., OptionCallback::Some needs Callback, not CallbackType)
14851490 let is_method_of_this_callback = arg. type_name == func. class_name ;
14861491 let is_enum_variant_constructor =
14871492 matches ! ( func. kind, FunctionKind :: EnumVariantConstructor ) ;
@@ -1492,7 +1497,7 @@ impl RustGenerator {
14921497 {
14931498 let fn_ptr_type = config. apply_prefix ( callback_type_name) ;
14941499 args. push ( format ! ( "{}: {}" , arg. name, fn_ptr_type) ) ;
1495- // Pass the callback type directly to the C-ABI function
1500+ // The C-ABI function now expects the fn pointer type directly
14961501 call_args. push ( arg. name . clone ( ) ) ;
14971502 continue ;
14981503 }
@@ -1780,11 +1785,18 @@ impl RustGenerator {
17801785
17811786 // Copy is a marker trait that cannot be implemented manually or via transmute
17821787 // If the source type explicitly derives Copy, we must derive it here too
1788+ // Note: Copy requires Clone, so Copy types must also derive Clone
17831789 if struct_def. traits . is_copy {
17841790 builder. line ( "#[derive(Copy)]" ) ;
17851791 }
1786- // Only derive Clone if it was explicitly in the derive list (not custom_impls)
1787- if struct_def. traits . clone_is_derived {
1792+ // Derive Clone if:
1793+ // 1. The type is Copy (Copy requires Clone as supertrait), OR
1794+ // 2. clone_is_derived is true AND we're NOT using C-API trait impls
1795+ // When using UsingCAPI for non-Copy types, Clone is implemented via C-ABI function calls
1796+ let clone_via_capi = matches ! ( config. trait_impl_mode, TraitImplMode :: UsingCAPI ) ;
1797+ let need_derive_clone = struct_def. traits . is_copy
1798+ || ( struct_def. traits . clone_is_derived && !clone_via_capi) ;
1799+ if need_derive_clone {
17881800 builder. line ( "#[derive(Clone)]" ) ;
17891801 }
17901802
@@ -1844,11 +1856,18 @@ impl RustGenerator {
18441856
18451857 // Copy is a marker trait that cannot be implemented manually or via transmute
18461858 // If the source type explicitly derives Copy, we must derive it here too
1859+ // Note: Copy requires Clone, so Copy types must also derive Clone
18471860 if enum_def. traits . is_copy {
18481861 builder. line ( "#[derive(Copy)]" ) ;
18491862 }
1850- // Only derive Clone if it was explicitly in the derive list (not custom_impls)
1851- if enum_def. traits . clone_is_derived {
1863+ // Derive Clone if:
1864+ // 1. The type is Copy (Copy requires Clone as supertrait), OR
1865+ // 2. clone_is_derived is true AND we're NOT using C-API trait impls
1866+ // When using UsingCAPI for non-Copy types, Clone is implemented via C-ABI function calls
1867+ let clone_via_capi = matches ! ( config. trait_impl_mode, TraitImplMode :: UsingCAPI ) ;
1868+ let need_derive_clone = enum_def. traits . is_copy
1869+ || ( enum_def. traits . clone_is_derived && !clone_via_capi) ;
1870+ if need_derive_clone {
18521871 builder. line ( "#[derive(Clone)]" ) ;
18531872 }
18541873
@@ -2286,11 +2305,10 @@ impl RustGenerator {
22862305 builder. line ( "#[no_mangle]" ) ;
22872306 }
22882307
2289- // Only apply callback wrapper substitution for API functions (Constructor, Method, etc.)
2290- // NOT for trait functions (Delete, DeepCopy, PartialEq, etc.) which operate on the
2291- // callback wrapper struct itself
2292- // NOT for EnumVariantConstructor because enum variants need the exact type (e.g.,
2293- // OptionCallback::Some needs Callback, not CallbackType)
2308+ // Apply callback wrapper substitution for API functions (Constructor, Method, etc.)
2309+ // NOT for trait functions (Delete, DeepCopy, etc.) which operate on the callback wrapper itself
2310+ // NOT for EnumVariantConstructor - enum variants like OptionCallback::Some need exact types
2311+ // for easier C code generation
22942312 let should_substitute_callbacks = matches ! (
22952313 func. kind,
22962314 FunctionKind :: Constructor
@@ -2599,9 +2617,23 @@ impl RustGenerator {
25992617 & self ,
26002618 builder : & mut CodeBuilder ,
26012619 func : & FunctionDef ,
2620+ ir : & CodegenIR ,
26022621 config : & CodegenConfig ,
26032622 ) {
2604- let args = self . format_function_args ( func, config) ;
2623+ // Use format_function_args_for_cabi for API functions (substitutes callback wrappers with fn pointers)
2624+ // Use format_function_args for EnumVariantConstructor (keeps Callback structs for easier C code)
2625+ let should_substitute_callbacks = matches ! (
2626+ func. kind,
2627+ FunctionKind :: Constructor
2628+ | FunctionKind :: StaticMethod
2629+ | FunctionKind :: Method
2630+ | FunctionKind :: MethodMut
2631+ ) ;
2632+ let args = if should_substitute_callbacks {
2633+ self . format_function_args_for_cabi ( func, ir, config)
2634+ } else {
2635+ self . format_function_args ( func, config)
2636+ } ;
26052637 let return_str = func
26062638 . return_type
26072639 . as_ref ( )
0 commit comments