rust-lang / rust-lang/rust-bindgen
Objective-c categories aren't included in inheritance traits and impl blocks
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 5.3k
- Forks
- 829
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 15
Description
Objective-c categories are a way of extending a given objective-c class. It almost feels like categories are used to organize various sections of their codebase. As a result, there are a lot of categories in the apple frameworks.
In #1750 I added better inheritance support for the binding generation but didn't add the impl blocks for the traits generated from the Objective-c categories.
It's unclear to me how to best implement this because a given class has no reference to the classes it implements. The only reference to the classes are from the categories to the classes they extend.
Input C/C++ Header
// bindgen-flags: --objc-extern-crate -- -x objective-c
// bindgen-osx-only
@interface Foo
-(void)method;
@end
@interface Foo (BarCategory)
-(void)categoryMethod;
@end
@interface Bar: Foo
@end
Bindgen Invocation
$ bindgen input.h --objc-extern-crate -- -x objective-c
Actual Results
/* automatically generated by rust-bindgen */
#![allow(
dead_code,
non_snake_case,
non_camel_case_types,
non_upper_case_globals
)]
#![cfg(target_os = "macos")]
#[macro_use]
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Foo(pub id);
impl std::ops::Deref for Foo {
type Target = objc::runtime::Object;
fn deref(&self) -> &Self::Target {
unsafe { &*self.0 }
}
}
unsafe impl objc::Message for Foo {}
impl Foo {
pub fn alloc() -> Self {
Self(unsafe { msg_send!(objc::class!(Foo), alloc) })
}
}
impl IFoo for Foo {}
pub trait IFoo: Sized + std::ops::Deref {
unsafe fn method(self)
where
<Self as std::ops::Deref>::Target: objc::Message + Sized,
{
msg_send!(self, method)
}
}
impl Foo_BarCategory for Foo {}
pub trait Foo_BarCategory: Sized + std::ops::Deref {
unsafe fn categoryMethod(self)
where
<Self as std::ops::Deref>::Target: objc::Message + Sized,
{
msg_send!(self, categoryMethod)
}
}
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct Bar(pub id);
impl std::ops::Deref for Bar {
type Target = objc::runtime::Object;
fn deref(&self) -> &Self::Target {
unsafe { &*self.0 }
}
}
unsafe impl objc::Message for Bar {}
impl Bar {
pub fn alloc() -> Self {
Self(unsafe { msg_send!(objc::class!(Bar), alloc) })
}
}
impl IFoo for Bar {}
impl IBar for Bar {}
pub trait IBar: Sized + std::ops::Deref {}
Expected Results
impl Foo_BarCategory for Bar {} is missing and should be something like the following:
...
impl IFoo for Bar {}
impl IBar for Bar {}
impl Foo_BarCategory for Bar {}
pub trait IBar: Sized + std::ops::Deref {}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the Objective-C inheritance and category binding-generation paths described in the issue, using the supplied header and bindgen invocation as the reproduction case. Verify that a subclass receives the category trait implementation, with impl Foo_BarCategory for Bar {} appearing in the generated Rust output alongside the existing trait implementations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- objective-c, rust
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100