Skip to content
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

Replace ResultVoidAndPtr with pointer #184

Merged

Conversation

NiwakaDev
Copy link
Collaborator

@NiwakaDev NiwakaDev commented Mar 5, 2023

This PR replaces ResultVoidAndPtr with a pointer. Note that this PR doesn't affect the user experience at all.

related to #183.

For example, the following bridge module:

#[swift_bridge::bridge]
mod ffi {
    extern "Rust" {
        type SomeType;

        fn some_function () -> Result<(), SomeType>;
    }
}

Will now generate the following foreign function interface:

#[export_name = "__swift_bridge__$some_function"]
pub extern "C" fn __swift_bridge__some_function() -> *mut super::SomeType {
    match super::some_function() {
        Ok(ok) => std::ptr::null_mut(),
        Err(err) => Box::into_raw(Box::new({
            let val: super::SomeType = err;
            val
        })) as *mut super::SomeType
    }
}

Copy link
Owner

@chinedufn chinedufn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!!

Left some minor feedback then after that this looks good to me.

Thanks!

if self.is_custom_result_type() {
let ty = format_ident!("{}", self.c_struct_name());
return quote! {
#ty
};
}

if self.ok_ty.can_be_encoded_with_zero_bytes() {
let err_ty = self.err_ty.to_rust_type_path(types);
Copy link
Owner

@chinedufn chinedufn Mar 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want return self.err_ty.to_ffi_compatible_rust_type(swift_bridge_path, types);

.convert_ffi_expression_to_swift_type("val.ok_or_err!", type_pos, types);
let err =
self.err_ty
.convert_ffi_expression_to_swift_type("val.ok_or_err!", type_pos, types);

// There is a Swift compiler bug in Xcode 13 where using an explicit `()` here somehow leads
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to move the comment since we moved the code that it was on

@@ -430,15 +424,16 @@ impl BuiltInResult {
if !self.is_custom_result_type() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we delete this panic since we already have extensive testing for this case

Copy link
Owner

@chinedufn chinedufn Mar 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can rename the method from c_struct_name to custom_c_struct_name to make it more clear that this is only used for custom results.

@@ -430,15 +424,16 @@ impl BuiltInResult {
if !self.is_custom_result_type() {
panic!("Should not be called when this type is not a custom result type.")
}

let ok = &self.ok_ty;
let err = &self.err_ty;

if ok.can_be_encoded_with_zero_bytes() && err.is_passed_via_pointer() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we delete this panic since we already have extensive testing for this case

let ok = &self.ok_ty;
let err = &self.err_ty;

if ok.can_be_encoded_with_zero_bytes() && err.is_passed_via_pointer() {
return "ResultVoidAndPtr".to_string();
panic!("Should not be called when this type is a ResultVoidAndPtr")
}

if ok.is_passed_via_pointer() && err.can_be_encoded_with_zero_bytes() {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we delete this panic since we already have extensive testing for this case

@@ -44,12 +44,3 @@ pub struct ResultPtrAndPtr {
pub is_ok: bool,
pub ok_or_err: *mut std::ffi::c_void,
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to also delete the C support

pub const C_RESULT_VOID_SUPPORT: &'static str = r#"
struct __private__ResultVoidAndPtr { bool is_ok; void* err; };
"#;

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c_header += "\n";
c_header += &C_RESULT_VOID_SUPPORT;

@chinedufn
Copy link
Owner

chinedufn commented Mar 5, 2023

Mind updating the PR body with a visual indication of what this does?

For example, a simple bridge module and the corresponding generated Rust extern "C" fn.

Here's an example (you don't need to do a write up like that PR has, just some quick example code is fine) #178


Reasons:

  • Your example code will get included in the commit message when I rebase the PR, so the commit message will be of higher quality
  • If someone is ever implementing a similar optimization we can link them to this PR and they can quickly get a sense of what it's doing

In general, if a PR touches our code generation then the PR body should visually illustrate the change. Doesn't need to be anything long or fancy. Just a simple bridge module and any relevant generated code is fine.

@NiwakaDev
Copy link
Collaborator Author

Addressed your review. Please let me know if any omissions or errors.

@NiwakaDev NiwakaDev changed the title Replace ResultVoidAndPtr with pointer Replace ResultVoidAndPtr with pointer Mar 5, 2023
@@ -232,6 +234,20 @@ impl BuiltInResult {
TypePosition::SwiftCallsRustAsyncOnCompleteReturnTy => todo!(),
};
}

// There is a Swift compiler bug in Xcode 13 where using an explicit `()` here somehow leads
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to go above if self.ok_ty.is_null() like it was before

let err_ty = self.err_ty.to_rust_type_path(types);
let err_ty = self
.err_ty
.to_ffi_compatible_rust_type(swift_bridge_path, types);
return quote! {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to quote!

@@ -36,7 +34,6 @@ pub(super) fn write_core_swift_and_c(out_dir: &Path) {
c_header += "\n";
c_header += &C_RESULT_SUPPORT;
c_header += "\n";
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can remove this new line

@NiwakaDev
Copy link
Collaborator Author

Done. But, there might be any omissions or errors.

@chinedufn
Copy link
Owner

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants