Skip to content

Commit 3f1f74a

Browse files
committed
Fix "weird configurations" CI
1 parent ae13234 commit 3f1f74a

File tree

3 files changed

+60
-23
lines changed

3 files changed

+60
-23
lines changed

doc/src/codegen/v2/config.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,13 +546,16 @@ impl CodegenConfig {
546546
Self {
547547
target_lang: TargetLang::Rust,
548548
cabi_functions: CAbiFunctionMode::ExternalBindings {
549-
link_library: "azul_dll".into(),
549+
link_library: "azul".into(),
550550
},
551551
struct_mode: StructMode::Prefixed,
552552
trait_impl_mode: TraitImplMode::UsingCAPI,
553553
type_prefix: "Az".into(),
554554
module_wrapper: Some("dll".into()),
555-
imports: vec!["use core::ffi::c_void;".into()],
555+
imports: vec![
556+
"use core::ffi::c_void;".into(),
557+
"use core::ffi::c_int;".into(),
558+
],
556559
type_filter: None,
557560
type_exclude: BTreeSet::new(),
558561
indent: " ".into(),

doc/src/codegen/v2/lang_rust.rs

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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()

doc/src/codegen/v2/rust/dynamic_binding.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ impl RustDynamicGenerator {
161161
let full_name = format!("{}{}", name, generics);
162162

163163
// Clone trait - calls Az{Type}_clone
164-
if struct_def.traits.is_clone {
164+
// Only generate manual impl if Clone is NOT derived (to avoid conflict with #[derive(Clone)])
165+
if struct_def.traits.is_clone && !struct_def.traits.clone_is_derived {
165166
let clone_fn = format!("{}_clone", name);
166167
builder.line(&format!("impl{} Clone for {} {{", generics, full_name));
167168
builder.indent();
@@ -282,7 +283,8 @@ impl RustDynamicGenerator {
282283
};
283284
let full_name = format!("{}{}", name, generics);
284285

285-
if enum_def.traits.is_clone {
286+
// Clone trait - only generate manual impl if Clone is NOT derived
287+
if enum_def.traits.is_clone && !enum_def.traits.clone_is_derived {
286288
let clone_fn = format!("{}_clone", name);
287289
builder.line(&format!("impl{} Clone for {} {{", generics, full_name));
288290
builder.indent();

0 commit comments

Comments
 (0)