Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
1d289bf
Add support for calling async Swift functions from Rust
Choochmeque Nov 30, 2025
73b4d29
Support calling sync Swift throws functions from Rust with Result ret…
Choochmeque Dec 1, 2025
0b2d82d
Use distinct Ok/Err values in async Swift throws test
Choochmeque Dec 1, 2025
09faa51
Refactor Swift codegen to share code between sync and async functions
Choochmeque Dec 1, 2025
cb2dabb
Add documentation for calling async Swift functions from Rust
Choochmeque Dec 1, 2025
911cde7
Consolidate async Swift function format! calls into single template
Choochmeque Dec 1, 2025
b974e63
Remove unnecessary Option wrapper from SwiftAsyncCallback sender
Choochmeque Dec 1, 2025
b46fb5b
Document panic conditions for create_swift_async_call
Choochmeque Dec 1, 2025
8b86630
Add codegen test for async Swift Result functions with arguments
Choochmeque Dec 1, 2025
2380cea
Merge branch 'master' into extern-swift-throws-result
Choochmeque Dec 1, 2025
f5b0c63
Run 'cargo fmt'
Choochmeque Dec 1, 2025
995c929
Improve fatalError message to include expected error type
Choochmeque Dec 1, 2025
4146daa
Update trybuild expected output for newer Rust compiler
Choochmeque Dec 1, 2025
3c800e9
Merge branch 'master' into extern-swift-throws-result
Choochmeque Dec 1, 2025
396e2ac
Replace fatalError with typed throws compile-time check for extern Sw…
Choochmeque Dec 1, 2025
9949212
Merge branch 'master' into extern-swift-throws-result
Choochmeque Dec 1, 2025
56f5cc4
Replace fatalError with typed throws compile-time check for extern Sw…
Choochmeque Dec 1, 2025
8b74871
Add Xcode setup to CI for Swift 5.9+ typed throws support
Choochmeque Dec 1, 2025
79d1e73
Merge branch 'chinedufn:master' into master
Choochmeque Dec 1, 2025
992d7be
Merge branch 'master' into extern-swift-throws-result
Choochmeque Dec 2, 2025
31ea6b2
Remove unused _types parameter from is_custom_result_type
Choochmeque Dec 2, 2025
5290072
Set Xcode version via xcode-select
Choochmeque Dec 2, 2025
6733fbd
Support Result<(), E> for async extern Swift functions
Choochmeque Dec 2, 2025
2b97766
Support async methods with &self on extern "Swift" types
Choochmeque Dec 2, 2025
9a6d75c
Document Xcode version requirement for typed throws support
Choochmeque Dec 3, 2025
8508eb8
Add codegen test for extern Swift Result<(), OpaqueRustType>
Choochmeque Dec 3, 2025
2943938
Add integration tests for extern Swift sync Result type variants
Choochmeque Dec 3, 2025
1fe3d94
Add codegen test for extern Swift Result<Opaque, Opaque>
Choochmeque Dec 3, 2025
b72ae47
Add codegen test for extern Swift Result with arguments
Choochmeque Dec 3, 2025
5daeaa0
Rename TypePosition::SwiftCallsRustAsyncOnCompleteReturnTy to ResultF…
Choochmeque Dec 3, 2025
9abe35f
Merge branch 'extern-swift-throws-result' into extern-swift-async-res…
Choochmeque Dec 3, 2025
9612de8
Remove redundant type cast in sync extern Swift catch clause
Choochmeque Dec 3, 2025
d8115a2
Merge branch 'chinedufn:master' into master
Choochmeque Dec 5, 2025
0a4c873
Merge commit 'd8115a236dcb1130a37fde6d8cc6a5afcb8018bb' into extern-s…
Choochmeque Dec 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,57 @@ func swift_async_throws(succeed: Bool) async throws(SwiftAsyncError) -> UInt32 {
throw SwiftAsyncError.ErrorWithValue(456)
}
}

/// An async Swift function that throws but returns void (maps to Result<(), E> in Rust)
/// Uses typed throws (Swift 5.9+) to ensure compile-time verification of error type
func swift_async_throws_void(succeed: Bool) async throws(SwiftAsyncVoidError) {
try? await Task.sleep(nanoseconds: 1_000_000) // 1ms
if !succeed {
throw SwiftAsyncVoidError.ErrorWithValue(789)
}
// On success, just return (void)
}

// =============================================================================
// Async Swift class with methods that can be called from Rust
// =============================================================================

/// A Swift class with async methods for testing async method calls from Rust
class AsyncSwiftType {
private let value: UInt32

init(value: UInt32) {
self.value = value
}

/// Simple async method returning the stored value
func get_value() async -> UInt32 {
try? await Task.sleep(nanoseconds: 1_000_000) // 1ms
return value
}

/// Async method with an argument that adds to the stored value
func add_to_value(amount: UInt32) async -> UInt32 {
try? await Task.sleep(nanoseconds: 1_000_000) // 1ms
return value + amount
}

/// Async method that can throw an error (maps to Result<T, E> in Rust)
func maybe_get_value(succeed: Bool) async throws(SwiftAsyncMethodError) -> UInt32 {
try? await Task.sleep(nanoseconds: 1_000_000) // 1ms
if succeed {
return value
} else {
throw SwiftAsyncMethodError.ErrorWithValue(value)
}
}

/// Async method that throws but returns void (maps to Result<(), E> in Rust)
func maybe_succeed(succeed: Bool) async throws(SwiftAsyncMethodError) {
try? await Task.sleep(nanoseconds: 1_000_000) // 1ms
if !succeed {
throw SwiftAsyncMethodError.ErrorWithValue(555)
}
// On success, just return (void)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ extension AsyncResultErrEnum: Error {}
extension SwiftAsyncError: @unchecked Sendable {}
extension SwiftAsyncError: Error {}

extension SwiftAsyncVoidError: @unchecked Sendable {}
extension SwiftAsyncVoidError: Error {}

extension SwiftAsyncMethodError: @unchecked Sendable {}
extension SwiftAsyncMethodError: Error {}

// ============================================================================
// Sync Swift throwing functions (called from Rust)
// ============================================================================
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,5 +225,57 @@ class AsyncTests: XCTestCase {
let result = rust_calls_swift_async_throws_err()
XCTAssertEqual(result, 456)
}

/// Test that Rust can call an async Swift function that throws void (Result<(), E>) - success case
func testRustCallsSwiftAsyncThrowsVoidOk() throws {
let result = rust_calls_swift_async_throws_void_ok()
XCTAssertTrue(result)
}

/// Test that Rust can call an async Swift function that throws void (Result<(), E>) - error case
func testRustCallsSwiftAsyncThrowsVoidErr() throws {
let result = rust_calls_swift_async_throws_void_err()
XCTAssertEqual(result, 789)
}

// =========================================================================
// Tests for Rust calling async Swift methods with &self
// =========================================================================

/// Test that Rust can call an async Swift method that returns u32
func testRustCallsSwiftAsyncMethodReturnU32() throws {
let result = rust_calls_swift_async_method_return_u32()
XCTAssertEqual(result, 42)
}

/// Test that Rust can call an async Swift method with arguments
func testRustCallsSwiftAsyncMethodWithArgs() throws {
let result = rust_calls_swift_async_method_with_args()
XCTAssertEqual(result, 150) // 100 + 50
}

/// Test that Rust can call an async Swift method that throws - success case
func testRustCallsSwiftAsyncMethodThrowsOk() throws {
let result = rust_calls_swift_async_method_throws_ok()
XCTAssertEqual(result, 999)
}

/// Test that Rust can call an async Swift method that throws - error case
func testRustCallsSwiftAsyncMethodThrowsErr() throws {
let result = rust_calls_swift_async_method_throws_err()
XCTAssertEqual(result, 123) // The value stored in the object
}

/// Test that Rust can call an async Swift method that throws void (Result<(), E>) - success case
func testRustCallsSwiftAsyncMethodThrowsVoidOk() throws {
let result = rust_calls_swift_async_method_throws_void_ok()
XCTAssertTrue(result)
}

/// Test that Rust can call an async Swift method that throws void (Result<(), E>) - error case
func testRustCallsSwiftAsyncMethodThrowsVoidErr() throws {
let result = rust_calls_swift_async_method_throws_void_err()
XCTAssertEqual(result, 555)
}
}

Loading
Loading