Comments (11)
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!() }
}
from swift-bridge.
Ah, it looks like we currently only test returning Option<T>
swift-bridge/crates/swift-integration-tests/src/option.rs
Lines 84 to 86 in dd5bef5
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.
from swift-bridge.
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()
}
}
from swift-bridge.
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!
from swift-bridge.
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
from swift-bridge.
Implementation would go here:
swift-bridge/crates/swift-bridge-ir/src/bridged_type/bridged_opaque_type.rs
Lines 287 to 293 in 4fbd30f
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.
from swift-bridge.
Alright pushed that up: #257
How do I run the full suite of tests?
EDIT: NVM, I see in the README - running now
from swift-bridge.
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
from swift-bridge.
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 swift-bridge.
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
from swift-bridge.
Thanks for reporting this issue and including clear details. Much appreciated.
I'll reply to any other questions here -> #257
from swift-bridge.
Related Issues (20)
- swift-bridge-build should not emit errors and instead let rustc show errors emitted by the procedural macro HOT 2
- Problem with x86_64-apple-ios-simulator HOT 2
- Add RustVec.intoArray() HOT 1
- SwiftData struct for translating Swift's Data class HOT 1
- extern Swift declaration not public HOT 12
- Support Box<FnOnce> in extern "Rust" HOT 3
- Xcode reports "Multiple commands produce '...DerivedData...Build/Products/Debug/include/module.modulemap'" HOT 4
- Clippy finds clippy::unnecessary-cast
- Getting these errors in my project HOT 1
- Add an additional XCode + Rust project option HOT 1
- Building for Release HOT 5
- #[swift_bridge::bridge] macro forces module to be private HOT 2
- warning: `extern` block uses type `RustString`, which is not FFI-safe HOT 4
- Book update: Xcode 15 (at least) requires a bridge in order to import into swift
- Cannot use two `#[swift_bridge(..)]` attributes on the same function
- Already_declared causes swift generation to never declare Class HOT 1
- Result returns translating incorrectly? HOT 3
- Is &Vec<T> supported? HOT 2
- Cannot for the life of me get Xcode + Cargo to work HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from swift-bridge.