-
Notifications
You must be signed in to change notification settings - Fork 57
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
Adding a method isn't ergonomic #12
Comments
Would this work? add_method(sel!(setFoo:), my_obj_set_foo as extern fn(_)) |
Unfortunately not, the compiler doesn't seem to be able to tell what we mean by that cast. Gives an error like:
|
This is probably its own issue, but why does this implement Encoding... modified_fun as extern fn(&mut Object, Sel, &'static mut Object) ... when this doesn't? fun as extern fn(&mut Object, Sel, &mut Object) |
@quadrupleslap ... huh, that's very weird. I was able to repro with this error message:
I thought maybe that the implementation of |
I'm actually having a tough time with this. Very new to ObjC, just trying to knock together a Rust binding for a small MacOS API surface I need for my crate so I can avoid ObjC entirely. I'm trying to implement a callback for this delegate and stay as close to ObjC as I can (I.e. minimal use of cocoa and other crates, which don't implement this API anyway.) I have:
That gives me:
I've looked at the definition of Anyway, not sure where else to turn for help with this, but having spent 6 hours trying to figure out how to match this delegate selector to a method and failing does suggest that method definition could be a bit more ergonomic. :) Otherwise, thanks for creating this. Didn't take me very long to call into MacOS ObjC APIs without knowing a whole lot about them, and I'm hopeful that this delegate issue is the last I'll face with ObjC interop for this particular task (though maybe that's a bit naive of me. :) |
I cracked it with some help. The second |
Support architectures with pointer width 16
So the issue is... Quite complex, and honestly feels more like a bug in the compiler (though I'm not really qualified to state that). In short, it's because our implementation of See this playground link, and the Rust tracking issue rust-lang/rust#56105. To make this concrete, I'll try to answer some of the questions that has been raised here:
This won't work because methods have more than one argument, but you're only specifying one with But even if you specified the correct number of arguments (
These two snippets desugar to: modified_fun as for<'a> extern "C" fn(&'a mut Object, Sel, &'static mut Object)
fun as for<'a, b> extern "C" fn(&'a mut Object, Sel, &'b mut Object) And only the first one matches our implementation of
You can fix this by doing: decl.add_method(
sel!(speechSynthesizer:didFinishSpeaking:),
speech_synthesizer_did_finish_speaking
as extern "C" fn(&Object, Sel, _, BOOL),
) But your solution with |
Previously, the receiver's lifetime was higher-ranked, while the rest of the arguments weren't, which meant that: - Their type could not be inferred like the other arguments - Having a return type with a lifetime bound to the receiver was impossible Fixes upstream SSheldon/rust-objc#12, at least as far as possible right now. This is a breaking change, and is unfortunately difficult for users to know how to fix, not really sure how to improve that situation?
Adding a method to a
ClassDecl
isn't ergonomic because you need to cast the function to a function pointer, like so:This is a bummer because you need to repeat the types that you've already specified.
This wasn't always the case for Rust, but this behavior changed in rust-lang/rust#19891. rust-lang/rust#21086 was opened about this, but was closed as expected behavior.
The text was updated successfully, but these errors were encountered: