diff --git a/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunner/SharedEnumAttributes.swift b/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunner/SharedEnumAttributes.swift index 55558803..10e4b140 100644 --- a/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunner/SharedEnumAttributes.swift +++ b/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunner/SharedEnumAttributes.swift @@ -10,3 +10,7 @@ import Foundation func extern_swift_enum_rename(arg: EnumRename) -> EnumRename { arg } + +func swift_reflect_already_declared_enum(arg: AlreadyDeclaredEnumTest) -> AlreadyDeclaredEnumTest { + arg +} diff --git a/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunnerTests/SharedEnumAttributeTests.swift b/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunnerTests/SharedEnumAttributeTests.swift index 04d17a65..1126903f 100644 --- a/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunnerTests/SharedEnumAttributeTests.swift +++ b/SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunnerTests/SharedEnumAttributeTests.swift @@ -21,7 +21,7 @@ class SharedEnumAttributeTests: XCTestCase { } - /// Verify that we can call a function that uses a type that was already declared in a different bridge module. + /// Verify that we can call a rust function from swift that uses a type that was already declared in a different bridge module. func testSharedEnumAlreadyDeclared() throws { XCTAssertEqual( reflect_already_declared_enum( @@ -31,11 +31,16 @@ class SharedEnumAttributeTests: XCTestCase { ) } + /// Verify that we can call a swift function from rust that uses a type that was already declared in a different bridge module. + func testSharedEnumAlreadyDeclared() throws { + test_rust_calls_swift_already_declared() + } /// Verify that we can use the generated Debug impl. func testSharedEnumDeriveDebug() throws { let debugString = String(reflecting: DeriveDebugEnum.Variant) XCTAssertEqual(debugString, "Variant") } + } diff --git a/book/src/bridge-module/transparent-types/enums/README.md b/book/src/bridge-module/transparent-types/enums/README.md index 44dbd952..9d7f7f10 100644 --- a/book/src/bridge-module/transparent-types/enums/README.md +++ b/book/src/bridge-module/transparent-types/enums/README.md @@ -59,7 +59,7 @@ mod ffi_2 { // The `already_declared` indicates that instead of creating a new enum // we should use super::SomeTransparentEnum; #[swift_bridge(already_declared)] - enum SomeTransparentEnum; + enum SomeTransparentEnum {} extern "Rust" { fn some_function() -> SomeTransparentEnum; diff --git a/crates/swift-bridge-ir/src/bridged_type.rs b/crates/swift-bridge-ir/src/bridged_type.rs index e95b412c..6c6f73a7 100644 --- a/crates/swift-bridge-ir/src/bridged_type.rs +++ b/crates/swift-bridge-ir/src/bridged_type.rs @@ -902,14 +902,26 @@ impl BridgedType { }, BridgedType::Foreign(CustomBridgedType::Shared(SharedType::Struct(shared_struct))) => { let ty_name = &shared_struct.name; - quote! { - #ty_name + if shared_struct.already_declared { + quote! { + super::#ty_name + } + } else { + quote! { + #ty_name + } } } BridgedType::Foreign(CustomBridgedType::Shared(SharedType::Enum(shared_enum))) => { let enum_name = &shared_enum.name; - quote! { - #enum_name + if shared_enum.already_declared { + quote! { + super::#enum_name + } + } else { + quote! { + #enum_name + } } } } diff --git a/crates/swift-bridge-ir/src/codegen/codegen_tests/already_declared_attribute_codegen_tests.rs b/crates/swift-bridge-ir/src/codegen/codegen_tests/already_declared_attribute_codegen_tests.rs index 3d7a7d71..677c019d 100644 --- a/crates/swift-bridge-ir/src/codegen/codegen_tests/already_declared_attribute_codegen_tests.rs +++ b/crates/swift-bridge-ir/src/codegen/codegen_tests/already_declared_attribute_codegen_tests.rs @@ -110,16 +110,35 @@ mod already_declared_struct { struct FfiSomeType; extern "Rust" { - fn some_function(arg: FfiSomeType) -> FfiSomeType; + fn rust_some_function(arg: FfiSomeType) -> FfiSomeType; + } + + extern "Swift" { + fn swift_some_function(arg: FfiSomeType) -> FfiSomeType; } } } } fn expected_rust_tokens() -> ExpectedRustTokens { - ExpectedRustTokens::DoesNotContain(quote! { - struct FfiSomeType - }) + ExpectedRustTokens::ContainsManyAndDoesNotContainMany { + contains: vec![ + quote! { + pub extern "C" fn __swift_bridge__rust_some_function(arg: ::FfiRepr) -> ::FfiRepr { + super::rust_some_function(arg.into_rust_repr()).into_ffi_repr() + } + }, + quote! { + extern "C" { + #[link_name = "__swift_bridge__$swift_some_function"] + fn __swift_bridge__swift_some_function(arg: ::FfiRepr) -> ::FfiRepr; + } + }, + ], + does_not_contain: vec![quote! { + struct FfiSomeType + }], + } } fn expected_swift_code() -> ExpectedSwiftCode { @@ -129,7 +148,7 @@ mod already_declared_struct { fn expected_c_header() -> ExpectedCHeader { ExpectedCHeader::ExactAfterTrim( r#" -struct __swift_bridge__$FfiSomeType __swift_bridge__$some_function(struct __swift_bridge__$FfiSomeType arg); +struct __swift_bridge__$FfiSomeType __swift_bridge__$rust_some_function(struct __swift_bridge__$FfiSomeType arg); "#, ) } @@ -157,7 +176,11 @@ mod already_declared_enum { enum FfiSomeEnum {} extern "Rust" { - fn some_function(arg: FfiSomeEnum) -> FfiSomeEnum; + fn rust_some_function(arg: FfiSomeEnum) -> FfiSomeEnum; + } + + extern "Swift" { + fn swift_some_function(arg: FfiSomeEnum) -> FfiSomeEnum; } } } @@ -165,11 +188,19 @@ mod already_declared_enum { fn expected_rust_tokens() -> ExpectedRustTokens { ExpectedRustTokens::ContainsManyAndDoesNotContainMany { - contains: vec![quote! { - pub extern "C" fn __swift_bridge__some_function(arg: ::FfiRepr) -> ::FfiRepr { - super::some_function(arg.into_rust_repr()).into_ffi_repr() - } - }], + contains: vec![ + quote! { + pub extern "C" fn __swift_bridge__rust_some_function(arg: ::FfiRepr) -> ::FfiRepr { + super::rust_some_function(arg.into_rust_repr()).into_ffi_repr() + } + }, + quote! { + extern "C" { + #[link_name = "__swift_bridge__$swift_some_function"] + fn __swift_bridge__swift_some_function(arg: ::FfiRepr) -> ::FfiRepr; + } + }, + ], does_not_contain: vec![quote! { enum FfiSomeEnum }], @@ -183,7 +214,7 @@ mod already_declared_enum { fn expected_c_header() -> ExpectedCHeader { ExpectedCHeader::ExactAfterTrim( r#" -struct __swift_bridge__$FfiSomeEnum __swift_bridge__$some_function(struct __swift_bridge__$FfiSomeEnum arg); +struct __swift_bridge__$FfiSomeEnum __swift_bridge__$rust_some_function(struct __swift_bridge__$FfiSomeEnum arg); "#, ) } diff --git a/crates/swift-bridge-macro/src/lib.rs b/crates/swift-bridge-macro/src/lib.rs index c6bc1585..3d9f79f3 100644 --- a/crates/swift-bridge-macro/src/lib.rs +++ b/crates/swift-bridge-macro/src/lib.rs @@ -21,6 +21,7 @@ pub fn bridge( let tokens = quote! { #module }; + tokens.into() } diff --git a/crates/swift-integration-tests/src/enum_attributes/already_declared.rs b/crates/swift-integration-tests/src/enum_attributes/already_declared.rs index 11cadaa5..ae4a1c3f 100644 --- a/crates/swift-integration-tests/src/enum_attributes/already_declared.rs +++ b/crates/swift-integration-tests/src/enum_attributes/already_declared.rs @@ -16,10 +16,26 @@ mod ffi2 { enum AlreadyDeclaredEnumTest {} extern "Rust" { - fn reflect_already_declared_enum(arg: AlreadyDeclaredEnumTest) -> AlreadyDeclaredEnumTest; + fn rust_reflect_already_declared_enum( + arg: AlreadyDeclaredEnumTest, + ) -> AlreadyDeclaredEnumTest; + } + + extern "Rust" { + fn test_rust_calls_swift_already_declared(); + } + + extern "Swift" { + fn swift_reflect_already_declared_enum( + arg: AlreadyDeclaredEnumTest, + ) -> AlreadyDeclaredEnumTest; } } -fn reflect_already_declared_enum(arg: AlreadyDeclaredEnumTest) -> AlreadyDeclaredEnumTest { +fn rust_reflect_already_declared_enum(arg: AlreadyDeclaredEnumTest) -> AlreadyDeclaredEnumTest { arg } +fn test_rust_calls_swift_already_declared() { + let val = ffi2::swift_reflect_already_declared_enum(AlreadyDeclaredEnumTest::Variant); + assert!(matches!(val, AlreadyDeclaredEnumTest::Variant)); +} diff --git a/crates/swift-integration-tests/src/struct_attributes/already_declared.rs b/crates/swift-integration-tests/src/struct_attributes/already_declared.rs index ffcf0098..95e4ebf7 100644 --- a/crates/swift-integration-tests/src/struct_attributes/already_declared.rs +++ b/crates/swift-integration-tests/src/struct_attributes/already_declared.rs @@ -17,12 +17,20 @@ mod ffi2 { struct AlreadyDeclaredStructTest; extern "Rust" { - fn reflect_already_declared_struct( + fn rust_reflect_already_declared_struct( + arg: AlreadyDeclaredStructTest, + ) -> AlreadyDeclaredStructTest; + } + + extern "Swift" { + fn swift_reflect_already_declared_struct( arg: AlreadyDeclaredStructTest, ) -> AlreadyDeclaredStructTest; } } -fn reflect_already_declared_struct(arg: AlreadyDeclaredStructTest) -> AlreadyDeclaredStructTest { +fn rust_reflect_already_declared_struct( + arg: AlreadyDeclaredStructTest, +) -> AlreadyDeclaredStructTest { arg }