servo / core-foundation-rs

Rust bindings to Core Foundation and other low level libraries on Mac OS X and iOS
Other
1.02k stars 222 forks source link

Multiple definitions of `initWithFrame_` #177

Open bors-servo opened 6 years ago

bors-servo commented 6 years ago

Issue by jtomschroeder Thursday Feb 02, 2017 at 17:33 GMT Originally opened as https://github.com/servo/cocoa-rs/issues/154


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?

bors-servo commented 6 years ago

Comment by paulrouget Friday Feb 03, 2017 at 00:18 GMT


What about:

let text = NSTextField::initWithFrame_(NSTextField::alloc(nil), frame);
bors-servo commented 6 years ago

Comment by paulrouget Friday Feb 03, 2017 at 00:19 GMT


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

bors-servo commented 6 years ago

Comment by paulrouget Friday Feb 03, 2017 at 00:32 GMT


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.

bors-servo commented 6 years ago

Comment by jtomschroeder Friday Feb 03, 2017 at 00:40 GMT


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.

bors-servo commented 6 years ago

Comment by oluseyi Wednesday Mar 22, 2017 at 19:26 GMT


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 https://github.com/servo/cocoa-rs/issues/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 https://github.com/servo/cocoa-rs/issues/117 without waiting for specialization.