servo/cocoa-rs

Multiple definitions of `initWithFrame_`

Opened this issue · 5 comments

I get the following error when attempting to call initWithFrame_:

error[E0034]: multiple applicable items in scope
  --> src/lib.rs:63:52
   |
63 |                 let text = NSTextField::alloc(nil).initWithFrame_(frame);
   |                                                    ^^^^^^^^^^^^^^ multiple `initWithFrame_` found
   |
   = note: candidate #1 is defined in an impl of the trait `cocoa::appkit::NSView` for the type `*mut objc::runtime::Object`
   = note: candidate #2 is defined in an impl of the trait `cocoa::appkit::NSTextField` for the type `*mut objc::runtime::Object`

Because NSView is implemented for id, are the other definitions of initWithFrame_ redundant? If so, can they be removed?

What about:

let text = NSTextField::initWithFrame_(NSTextField::alloc(nil), frame);

But yeah, maybe we can remove NSTextField::initWithFrame_.

In the case of NSTextField, initWithFrame is: https://developer.apple.com/reference/appkit/nscontrol/1428900-initwithframe?language=objc

In the case of NSView, initWithFrame is: https://developer.apple.com/reference/appkit/nsview/1483458-initwithframe?language=objc

Not sure what is the proper way to deal with that.

Sure, I did something similar:

use cocoa::appkit::NSView;
cocoa::appkit::NSTextField::alloc(nil).initWithFrame_(frame);

It looks like initWithFrame_ is also defined for NSButton and NSTabView.

It's interesting that the AppKit docs define it for both NSView and NSTextField. In my mind, it's more or less inheritance with NSTextField overriding NSView's implementation. It does seem tricky to represent in a rusty way.

The root issue here is that cocoa-rs exports all NSObject-derived types as id, and all individual classes are implemented as traits against that same id struct. At the very least, newtypes might help with disambiguating (see #117), but then you run into problems with subtypes not inheriting base type implementations.

sorbet-cocoa is one WIP crate that tries to solve this conclusively, but it's dependent on the still-not-production-ready specialization features in rustc nightly (see here: https://kylewlacy.github.io/posts/cocoa-apps-in-rust-eventually/).

In any case, it'll be interesting to see what can be done to resolve this and #117 without waiting for specialization.