chinedufn / swift-bridge

swift-bridge facilitates Rust and Swift interop.
https://chinedufn.github.io/swift-bridge
Apache License 2.0
847 stars 62 forks source link

Stop using a custom FFI representation for unit/empty shared structs #14

Open chinedufn opened 2 years ago

chinedufn commented 2 years ago

Right now if you define a shared struct

#[swift_bridge::bridge]
mod ffi {
    struct SomeStruct;
}

We generate an FFI representation that looks something like this:

#[repr(C)]
struct __swift_bridge__SomeStruct {
    _private_: u8,
}

impl swift_bridge::SharedStruct for SomeStruct {
    type FfiRepr = __swift_bridge__SomeStruct;
}

When passing SomeStruct across the FFI boundary, we create and pass a __swift_bridge__SomeStruct.

This is unnecessary since we control both sides of the FFI boundary.

For example ... say you have

#[swift_bridge::bridge]
mod ffi {
    struct SomeStruct;

    extern "Rust" {
        fn reflect(arg: SomeStruct, num: u8) -> SomeStruct;
    }
}

We should generate things like:

// Notice how the FFI function doesn't take a `SomeStruct` argument.
pub extern "C" fn __swift_bridge__reflect(num: u8) {
    super::reflect(SomeStruct, num)
}

The same idea would go for function return types.

Benefits

chinedufn commented 1 year ago

We can add a BridgeableType.has_exactly_one_representation() -> bool method so that our logic works for all types that fit this pattern.


We can add tests to confirm that we elide FFI arguments / return values when there is exactly one representation.

chinedufn commented 1 year ago

Closed via #178

chinedufn commented 1 year ago

Still to stop generating the FFI #[repr(C)] representation when struct is empty. Then we can close this.