rust-lang / rust-lang/rust-bindgen
[Objc] Objective-c category names are not unique and can cause duplicate names
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 5.3k
- Forks
- 829
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 15
Description
Found this today when using bindgen on AppKit. Looks like there's an NSImage category (with no name) created twice.
My example below uses nameless categories like AppKit does but you can also just give them names and it's the same bug. I'm pretty sure that this is bad practice from apple but it's still part of the objective-c grammar so I figure I'd write this ticket for the next person. It's unclear how common this issue is so it's possible that it's not worth fixing.
Input Objc Header
// bindgen-flags: --objc-extern-crate -- -x objective-c
// bindgen-osx-only
@interface NSImage
@end
@interface NSImage ()
@end
@interface NSImage ()
- (int*)foo;
@end
Bindgen Invocation
$ bindgen input.h input.h -- -x objective-c
Actual Results
/* automatically generated by rust-bindgen 0.55.1 */
use objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct NSImage(pub id);
impl std::ops::Deref for NSImage {
type Target = objc::runtime::Object;
fn deref(&self) -> &Self::Target {
unsafe { &*self.0 }
}
}
unsafe impl objc::Message for NSImage {}
impl NSImage {
pub fn alloc() -> Self {
Self(unsafe { msg_send!(objc::class!(NSImage), alloc) })
}
}
impl INSImage for NSImage {}
pub trait INSImage: Sized + std::ops::Deref {}
impl NSImage_ for NSImage {}
pub trait NSImage_: Sized + std::ops::Deref {}
impl NSImage_ for NSImage {}
pub trait NSImage_: Sized + std::ops::Deref {
unsafe fn foo(self) -> *mut ::std::os::raw::c_int
where
<Self as std::ops::Deref>::Target: objc::Message + Sized,
{
msg_send!(self, foo)
}
}
Expected Results
I'm not sure what to add but a suffix at the end like NSImage_2 would make it unique.
impl NSImage_ for NSImage {}
pub trait NSImage_: Sized + std::ops::Deref {}
impl NSImage_2 for NSImage {}
pub trait NSImage_2: Sized + std::ops::Deref {
unsafe fn foo(self) -> *mut ::std::os::raw::c_int
where
<Self as std::ops::Deref>::Target: objc::Message + Sized,
{
msg_send!(self, foo)
}
}
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 by reproducing the issue with the provided input.h and bindgen invocation, then trace Objective-C category handling and generated Rust trait naming. Done means repeated or named categories produce unique generated names, with a regression test covering the duplicate-category case.
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
- 42/100