Skip to content

Commit

Permalink
Fix returning Result<Vec<>, ...> from Rust (#218)
Browse files Browse the repository at this point in the history
Fixes #217 

This supports bridges of the form:
```rust
#[swift_bridge::bridge]
mod ffi {
    extern "Rust" {
        type OpaqueRust;
        fn rust_func_return_result_of_vec_u32() -> Result<Vec<u32>, OpaqueRust>;
        fn rust_func_return_result_of_vec_opaque(
        ) -> Result<Vec<OpaqueRust>, OpaqueRust>;
    }
}

fn rust_func_return_result_of_vec_u32() -> Result<Vec<u32>, OpaqueRust> {
    Ok(vec![0, 1, 2])
}

fn rust_func_return_result_of_vec_opaque(
) -> Result<Vec<OpaqueRust>, OpaqueRust> {
    Ok(vec![
        OpaqueRust::new(...),
        OpaqueRust::new(...),
        OpaqueRust::new(...),
    ])
}
```
  • Loading branch information
jfaust authored May 4, 2023
1 parent 852ece7 commit de05902
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,21 @@ class ResultTests: XCTestCase {
}
}
}

/// Verify that we can receive a Result<Vec<>, OpaqueRust> from Rust
func testSwiftCallRustResultVecUInt32Rust() throws {
let vec = try! rust_func_return_result_of_vec_u32()
XCTAssertEqual(vec.len(), 3)
for (i, value) in vec.enumerated() {
XCTAssertEqual(UInt32(i), value)
}
}

func testSwiftCallRustResultVecOpaqueRust() throws {
let vec = try! rust_func_return_result_of_vec_opaque()
XCTAssertEqual(vec.len(), 3)
for (i, value) in vec.enumerated() {
XCTAssertEqual(UInt32(i), value.val())
}
}
}
1 change: 1 addition & 0 deletions crates/swift-bridge-ir/src/bridged_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ impl BridgeableType for BridgedType {

fn is_passed_via_pointer(&self) -> bool {
match self {
BridgedType::StdLib(StdLibType::Vec(_)) => true,
BridgedType::StdLib(_) => false,
BridgedType::Foreign(_) => false,
BridgedType::Bridgeable(ty) => ty.is_passed_via_pointer(),
Expand Down
19 changes: 19 additions & 0 deletions crates/swift-integration-tests/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ mod ffi {
fn same_custom_result_returned_twice_second() -> Result<SameEnum, SameEnum>;
}

extern "Rust" {
fn rust_func_return_result_of_vec_u32() -> Result<Vec<u32>, ResultTestOpaqueRustType>;
fn rust_func_return_result_of_vec_opaque(
) -> Result<Vec<ResultTestOpaqueRustType>, ResultTestOpaqueRustType>;
}

extern "Rust" {
fn rust_func_return_result_tuple_transparent_enum(
succeed: bool,
Expand Down Expand Up @@ -182,6 +188,19 @@ fn same_custom_result_returned_twice_second() -> Result<ffi::SameEnum, ffi::Same
todo!()
}

fn rust_func_return_result_of_vec_u32() -> Result<Vec<u32>, ResultTestOpaqueRustType> {
Ok(vec![0, 1, 2])
}

fn rust_func_return_result_of_vec_opaque(
) -> Result<Vec<ResultTestOpaqueRustType>, ResultTestOpaqueRustType> {
Ok(vec![
ResultTestOpaqueRustType::new(0),
ResultTestOpaqueRustType::new(1),
ResultTestOpaqueRustType::new(2),
])
}

fn rust_func_return_result_tuple_transparent_enum(
succeed: bool,
) -> Result<(i32, ResultTestOpaqueRustType, String), ffi::ResultTransparentEnum> {
Expand Down

0 comments on commit de05902

Please sign in to comment.