I got a brain wave today when I was reading this blog post, which briefly mentioned object safety in Rust and how Swift avoids that issue. Now that RFC 2027 has been implemented, if you enable the feature object_safe_for_dispatch
, dyn Trait
is always a well-formed type, it just doesn't implement Trait
if the trait isn't object-safe. Being object-safe really just means that the dyn Trait
type can't implement Trait
, because of one of the following reasons:
- the trait requires
Self: Sized
, whichdyn Trait
inherently is not, - the trait has an associated
const
, whichdyn Trait
couldn't provide a value for, or - the trait has one or more methods/associated functions that can't be implemented using dynamic dispatch. For example, there is no
self
argument, and therefore no vtable to do dynamic dispatch on; or the method returnsSelf
; or one of a few other reasons.
There might be another reason that I'm missing, but the main thing to notice here is that there might be some methods that can definitely be implemented using dynamic dispatch, even if the trait as a whole cannot. What if we took the subset of methods that are object-safe, and made them available as inherent methods?
Take for example this trait:
trait Trait {
// not object safe, because it has no `self` argument
fn static_method();
// this method is fine
fn call_static_method(&self) {
Self::static_method()
}
}
dyn Trait
can't provide an implementation of static_method
, and therefore can't implement Trait
. But it could still provide call_static_method
as an inherent method. It would be like the following code was added:
impl dyn Trait {
fn call_static_method(&self) {
/* compiler implemented */
}
}
Then you could do this, assuming i32
implements Trait
:
let bx = Box::new(6) as Box<dyn Trait>;
bx.call_static_method();
Note that the cast to Box<dyn Trait>
isn't allowed right now, even with #![feature(object_safe_for_dispatch)]
. I don't see any reason why you couldn't or shouldn't be able to do that though.
call_static_method
would be an inherent method on dyn Trait
, as well as on any dyn SubTrait
types where SubTrait
requires Self: Trait
. There's one complication I just thought of, though: what if SubTrait
also has a method named call_static_method
? Normally, you would disambiguate the two with <dyn SubTrait as Trait>::call_static_method
and <dyn SubTrait as SubTrait>::call_static_method
, but that doesn't work if they are both inherent methods on dyn SubTrait
. I guess it's an open question what to in that case.
What do you think? Are there any other complications that I'm missing?