@@ -13265,6 +13265,50 @@ class RustCompiler extends GenericCompiler<RustFile, RustFile, RustExpr, RustFil
1326513265 });
1326613266 }
1326713267
13268+ /**
13269+ Wraps a required trait-object handle when its destination admits null.
13270+
13271+ Why
13272+ - Haxe types an optional interface parameter as `Null<Interface>`, while a required
13273+ interface argument remains the same non-null interface at the call site.
13274+ - Rust represents those values differently: the required value is an `Arc<dyn Trait>`
13275+ and the nullable destination is `HxDynRef<dyn Trait>`.
13276+
13277+ What
13278+ - Converts the already type-checked required interface value into the nullable carrier.
13279+ - Leaves concrete-class upcasts to the existing conversion below.
13280+
13281+ How
13282+ - Detects only the closed `Arc<dyn Trait>` to `HxDynRef<dyn Trait>` representation edge,
13283+ requires structurally equal trait-object inner types, and constructs the nullable wrapper
13284+ directly around the compiled value. Interface-inheritance upcasts remain unadmitted.
13285+ **/
13286+ var requiredTraitSource = unwrapMetaParen(valueExpr);
13287+ while (true) {
13288+ switch (requiredTraitSource.expr) {
13289+ case TCast(inner, _):
13290+ requiredTraitSource = unwrapMetaParen(inner);
13291+ continue;
13292+ case _:
13293+ }
13294+ break;
13295+ }
13296+ var requiredTraitSourceType = switch (requiredTraitSource.expr) {
13297+ case TLocal(variable): variable.t;
13298+ case _: requiredTraitSource.t;
13299+ };
13300+ var requiredTraitSourceRust = toRustType(requiredTraitSourceType, requiredTraitSource.pos);
13301+ var requiredTraitExpectedInner = rustTypeSingleGenericArgument(expectedRust);
13302+ var requiredTraitSourceInner = rustTypeSingleGenericArgument(requiredTraitSourceRust);
13303+ if (rustTypeIsDynRefCarrier(expectedRust)
13304+ && rustTypeContainsTraitObject(expectedRust)
13305+ && rustTypeIsRcTraitObject(requiredTraitSourceRust)
13306+ && requiredTraitExpectedInner != null
13307+ && requiredTraitSourceInner != null
13308+ && rustTypesEqual(requiredTraitExpectedInner, requiredTraitSourceInner)) {
13309+ return ECall(rustDynRefMemberExpr("new"), [compiled]);
13310+ }
13311+
1326813312 // `Null<T>` (Option<T>) used where a non-null `T` is expected.
1326913313 //
1327013314 // Haxe allows this implicitly in many places (especially in upstream stdlib for "dynamic-ish"
0 commit comments