Closed PrismaPhonic closed 8 months ago
Nevermind. I see that you addressed this in your comment.
Does the implementation of User::current_program_ref
return Option<Program>
(notice the missing &
)?
If so, you'll want something like:
#[swift_bridge::bridge]
mod ffi {
extern "Rust" {
type User;
type Program;
#[swift_bridge(return_with = Option::as_ref)]
fn current_program_ref(self: &User) -> Option<&Program>;
}
}
// Assuming: your code looks like:
impl User {
fn current_program_ref(&self) -> Option<Program> { unimplemented!() }
}
Ah, it looks like we currently only test returning Option<T>
I'd be happy to provide instructions on how to add support for returning Option<&T>
. Would boil down to adding a new test case next to each of the ones linked above.
Look like this:
#[export_name = "__swift_bridge__$User$current_program_ref"]
pub extern "C" fn __swift_bridge__User_current_program_ref(
this: *mut super::User,
) -> *mut super::Program {
if let Some(val) = (unsafe { &*this }).current_program_ref() {
Box::into_raw(Box::new(val))
} else {
std::ptr::null_mut()
}
}
Should be:
#[export_name = "__swift_bridge__$User$current_program_ref"]
pub extern "C" fn __swift_bridge__User_current_program_ref(
this: *mut super::User,
) -> *const super::Program {
if let Some(val) = (unsafe { &*this }).current_program_ref() {
val as *const super::Program
} else {
std::ptr::null()
}
}
I was about to say - I just found from experimenting some more that it appears the issue lies in the ref being nested inside the Option. Wow, you're fast!
I can add the new test cases but I would imagine you would be faster at the actual implementation :-P but if you can give instructions for where the translation is happening I can give it a shot
Implementation would go here:
Can replace the linked code with:
let ty = &self.ty;
if self.reference {
quote! {
if let Some(val) = #expression {
val as *const super::#ty
} else {
std::ptr::null()
}
}
} else {
quote! {
if let Some(val) = #expression {
Box::into_raw(Box::new(val))
} else {
std::ptr::null_mut()
}
}
}
Please don't hesitate to let me know if you have any questions.
Alright pushed that up: https://github.com/chinedufn/swift-bridge/pull/257
How do I run the full suite of tests?
EDIT: NVM, I see in the README - running now
Hmm, I seem to be hitting this:
error[E0308]: mismatched types
--> crates/swift-integration-tests/src/option.rs:3:1
|
3 | #[swift_bridge::bridge]
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `&OptTestOpaqueRustType`, found `OptTestOpaqueRustType`
Not sure if it's obvious to you from looking at the PR I linked. I would try cargo expand
but in this case it expands so much I have trouble finding the relevant code.
Edit: I would guess it probably has something to do with my addition of this:
fn rust_reflect_option_ref_opaque_rust_type(
arg: Option<&OptTestOpaqueRustType>,
) -> Option<&OptTestOpaqueRustType> {
arg
}
And then my import for generation:
fn rust_reflect_option_ref_opaque_rust_type(
arg: Option<&OptTestOpaqueRustType>,
) -> Option<&OptTestOpaqueRustType>;
But I'm not sure why this alone would produce this error as it seems like an extremely simple function and a very simple declaration in the extern "Rust" block
May have found it. I think I needed to also change fn to_ffi_compatible_option_rust_type()
in bridged_opaque_type.rs
to check the reference as well, and conditionally return either *const
or *mut
but now I'm getting this:
error[E0308]: mismatched types
--> crates/swift-integration-tests/src/option.rs:89:13
|
3 | #[swift_bridge::bridge]
| ----------------------- arguments to this function are incorrect
...
89 | arg: Option<&OptTestOpaqueRustType>,
| ^^^ types differ in mutability
|
= note: expected raw pointer `*mut _`
found raw pointer `*const OptTestOpaqueRustType`
It seems that the pointer it found is the type we want - I'm not sure why it expects *mut
from cargo expand it looks like the generated code for the test now:
#[export_name = "__swift_bridge__$rust_reflect_option_ref_opaque_rust_type"]
pub extern "C" fn __swift_bridge__rust_reflect_option_ref_opaque_rust_type(
arg: *const super::OptTestOpaqueRustTypeRef,
) -> *const super::OptTestOpaqueRustTypeRef {
if let Some(val) = super::rust_reflect_option_ref_opaque_rust_type(
if arg.is_null() { None } else { Some(unsafe { *Box::from_raw(arg) }) },
) {
val as *const super::OptTestOpaqueRustTypeRef
} else {
std::ptr::null()
}
}
It seems to have an issue with from_raw()
getting called. I can see that Box::from_raw expects a *mut
but I'm not sure what the correct replacement would be here
Thanks for reporting this issue and including clear details. Much appreciated.
I'll reply to any other questions here -> https://github.com/chinedufn/swift-bridge/pull/257
I'm having an issue where I can't seem to return refs of custom types. Here's the code:
The above models the function signature from
User
that I'm copying. (I have other methods that are working that omitted for brevity).This is the generated code for this method:
The rest of the code generated relevant to the
Program
type:and the error: