-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support returning Result<(), OpaqueRust> from Rust functions #180
Support returning Result<(), OpaqueRust> from Rust functions #180
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is AWESOME work, thanks.
Left some minor comments then we can merge this.
If you don't mind, how did you figure out where/how to implement this?
I'm asking because the goal is to make it easier for folks to contribute, so I'm curious about how hard or easy it was to make your first contribution?
Cheers and thanks!
crates/swift-bridge-ir/src/codegen/codegen_tests/result_codegen_tests.rs
Outdated
Show resolved
Hide resolved
SwiftRustIntegrationTestRunner/SwiftRustIntegrationTestRunnerTests/ResultTests.swift
Show resolved
Hide resolved
@jfaust mind updating your PR body to include a bridge module that illustrates what this PR enables? Here are some other PRs to use as inspiration: The example will get used in our release notes, and also makes old PRs that much more useful (in case we want to link someone to another PR that implemented something similar). |
@chinedufn happy to make these changes, though it may take me a couple days to get to them. Honestly making the changes was fairly straightforward - I found I was testing it all using my codebase, so once it was working I found the rust & swift I'm guessing this was probably one of the easier changes to make as a first-time contributor.
Thanks for building/maintaining this project! |
@chinedufn I think I've resolved all your comments. Let me know if there's anything else to do! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!! Once tests are passing we can merge!
@@ -58,10 +58,11 @@ pub(crate) trait BridgeableType: Debug { | |||
!self.is_built_in_type() | |||
} | |||
|
|||
/// Whether or not this type can be encoded to exactly one representation. | |||
/// Whether or not this type can be encoded to exactly one representation,; | |||
/// and therefore can be encoded with zero bytes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice
@chinedufn I'm not sure why the Swift tests aren't compiling - they work fine on my machine with Xcode 14.2. Do you know what version of xcode is in use in the Action? |
I see this in the CI output
So I'm assuming we're on 13.2.1 in CI. I'm seeing this as the error:
Hmm... |
I'm on public func rust_func_return_result_null_opaque_rust(_ succeed: Bool) throws -> () {
try { let val = __swift_bridge__$rust_func_return_result_null_opaque_rust(succeed); if val.is_ok { return () } else { throw ResultTestOpaqueRustType(ptr: val.err!) } }()
} |
Hmm.. so this fails to compile: func foo() {
{ let foo = 5; return () }()
} But this compiles successfully: func foo() {
{ let foo = 5; return }()
} |
Ok, looks like it's possible to add an explicit signature at the beginning of the closure. For example, this compiles: struct MyStruct {}
func foo() {
{ () -> () in let foo = 5; return () }()
}
func bar() {
{ () -> MyStruct in let foo = 5; return MyStruct() }()
} So our options (assuming we want to continue to support Xcode 13) are to either:
I would have assumed that having explicit types always leads to better compile times, but I did some quick googling (only looked at one result) and found that using explicit types was slower in the one link that I read (did not verify results myself, did not do thorough research, this post is two years old) https://forums.swift.org/t/regarding-swift-type-inference-compile-time-performance/49748/16 So... for now I like option 1 or 2. Option 2 boils down to: let mut maybe_closure_type = "";
// There is a Swift compiler bug in Xcode 13 where using an explicit `()` here somehow leads
// the Swift compiler to a compile time error:
// "Unable to infer complex closure return type; add explicit type to disambiguate"
//
// It's asking us to add a `{ () -> () in .. }` explicit type to the beginning of our closure.
//
// We can remove this if statement whenever we stop supporting Xcode 13;
if self.is_null() {
maybe_closure_type = " () -> () in "
}
format!("try {{{maybe_closure_type} let val = {expression}; if val.is_ok {{ return {ok} }} else {{ throw {err} }} }}()") On line 176 in |
Adds partial support for #177 - supports returning
Result<(), OpaqueRust>
but not passing as an arg.The change to
examples/rust-binary-calls-swift-package/build.rs
was to support xcode not existing in the default location (I use thexcodes
tool).This PR also supports empty types, based on @chinedufn's recommendation.
This enables the following: