Open madsmtm opened 1 year ago
Actually, creating news methods (i.e. not overriding) is safe (provided they are not special methods like retain
, or private underscored methods).
So perhaps we need a #[override]
attribute (that is checked at runtime), similar to Swift?
Okay so we have two cases that I see a solution to:
The hardest part here is overriding methods.
At the very least, it requires an #[override]
attribute, to also allow calling the super method safely: https://github.com/madsmtm/objc2/issues/455
But checking that the signatures are equal is difficult! Possibly we could do the following check in the type system: Self::Super::$method_name == Self::$method_name
? Though that won't work for overriding methods further up in the superclass hierarchy, and it would also fail for methods mentioning Self
.
Note that having matching method encodings is not enough to make overriding safe.
Another option is to have traits for each implementation, that the user can then select. So e.g.:
trait NSView_methods {
fn drawRect(&self, rect: NSRect);
}
// Usage
declare_class!(
struct MyView;
// unsafe impl ClassType ...
impl NSView_methods for MyView {
#[method(drawRect:)]
fn drawRect(&self, rect: NSRect) {
// Do drawing
}
}
);
Though this is just... Not very nice, and can be confusing to find the right trait for the methods you want (especially for NSView
, which has a lot of categories).
Though maybe the idea of specifying which class' method you're overriding is not a bad one? It would allow us to get the type from NSView::drawRect
directly, and maybe with a bit (read: a lot) of type system and macro trickery, we can compare the two methods anyhow? Though I'm doubtful it's going to be particularly stable, since we also want the user to be able to write fn drawRect(self: &MyView, rect: NSRect) { ... }
, which while a bit contrived, still needs to work.
Note that we're assuming the user uses the same method names as the superclass/protocol, which they don't necessarily have to, so we also need a way to verify that.
A nice thing about that though is that we could maybe avoid the need to specify a selector in declare_class!
? That would make it very "Rusty"!
It would be nice if
icrate
could mark certain protocols / methods as safe to override, such thatdeclare_class!
could (after checking that all types are the same) allow just doing:(Notice the lack of
unsafe impl
)