chinedufn / swift-bridge

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

Replace `args_into` function attribute with `into` argument attribute. #234

Open chinedufn opened 1 year ago

chinedufn commented 1 year ago

Right now users can use the args_into attribute on an extern "Rust" function in order to convert the type passed in from Swift into a different Rust type.

https://github.com/chinedufn/swift-bridge/blob/27246447b4ac741b8bf086d3dfca15b47558e44f/book/src/bridge-module/functions/README.md?plain=1#L107-L144

We want to instead use an attribute on the function's arguments, like we do for the #[swift_bridge(label = "...")] attribute.

https://github.com/chinedufn/swift-bridge/blob/27246447b4ac741b8bf086d3dfca15b47558e44f/book/src/bridge-module/functions/README.md?plain=1#L264-L290

So, we want to be able to write a bridge module that looks like this:

mod ffi {
    extern "Rust" {
        fn a_function(
            // Notice how we let Swift pass in a `u64` even though the function
            // takes a `u128`.
            #[swift_bridge(into)] some_arg: u64
        );
    }
}

// Notice how this takes a `u128` 
fn a_function(some_arg: u128) {
    // ...
}

This should largely come down to looking at the #[swift_bridge(label = "...")] implementation and doing the same thing for a new #[swift_bridge(into)] function argument attribute.

Potentially Helpful Resources

Argument labels implementation

Here's the PR that implemented the #[swift_bridge(label = "...")] function attribute:

https://github.com/chinedufn/swift-bridge/pull/156/files

Parsing

Here's where we currently parse the args_into attribute:

https://github.com/chinedufn/swift-bridge/blob/1b797f6595c9e45f30032db5a24403f746f5d1b0/crates/swift-bridge-ir/src/parse/parse_extern_mod/function_attributes.rs#L112-L120

Here's where we currently parse the label attribute:

https://github.com/chinedufn/swift-bridge/blob/3c0d00da33fdf19e201eb121c7e6e370897f8070/crates/swift-bridge-ir/src/parse/parse_extern_mod/argument_attributes.rs#L32-L40

https://github.com/chinedufn/swift-bridge/blob/3c0d00da33fdf19e201eb121c7e6e370897f8070/crates/swift-bridge-ir/src/parse/parse_extern_mod/argument_attributes.rs#L58-L80

Codegen Test

Here's the argument label codegen test:

https://github.com/chinedufn/swift-bridge/blob/3c0d00da33fdf19e201eb121c7e6e370897f8070/crates/swift-bridge-ir/src/codegen/codegen_tests/argument_label_codegen_tests.rs#L5-L7

Here's the current args_into codegen test:

https://github.com/chinedufn/swift-bridge/blob/c15ba303a2c33dc457ddc2078cd0f8dbdc8e96de/crates/swift-bridge-ir/src/codegen/codegen_tests/function_attribute_codegen_tests.rs#L5-L6

Integration test

Here's the argument label integration test:

https://github.com/chinedufn/swift-bridge/blob/3c0d00da33fdf19e201eb121c7e6e370897f8070/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunnerTests/ArgumentAttributesTest.swift#L16-L19

Here's the current args_into integration test:

https://github.com/chinedufn/swift-bridge/blob/56fbe5c92f12d25146d005e6d2ebdc17958c21be/crates/swift-integration-tests/src/function_attributes/args_into.rs#L13-L21