This is somewhat of a haphazard pre-RFC because it’s really just a collection of paper-cuts.
Motivation
- This would allow private trait helper methods.
- This would allow non-overridable methods on traits.
- This would allow (some) generic trait methods to be called on trait objects. Really, all the
map
,fold
, etc. functions onIterator
should be implemented this way but it might be a bit late to change that.
Specifically motivated by: https://users.rust-lang.org/t/dynamic-dispatch-and-sized-trait/2918
Design (ish)
Basically, fix the following 4 comments (if possible).
trait Test {
fn call_test(&self) {
// 1. Complains about missing test method. This should (be made to) work.
self.priv_test(0);
// 2. Complains that Self isn't Sized. Is there any reason this can't work?
(self as &Test).priv_test(0);
}
}
// 3. I shouldn't need to specify this lifetime but, if I don't, `&something as &Test`
// complains about `something` not having a static lifetime (because this defaults to
// `impl Test + 'static`). As far as I can tell, this case isn't specified in any of
// the object lifetime bounds RFCs.
impl<'a> Test + 'a {
fn priv_test<A>(&self, a: A) { }
pub fn pub_test<A>(&self, a: A) { }
}
struct MyStruct;
impl Test for MyStruct { }
fn main() {
let s = MyStruct;
// 4. It should be possible to call this method directly.
s.pub_test(0);
}
Drawbacks
Dynamic dispatch. The trait methods rely on dynamic dispatch so calls back into the trait would be somewhat slower in a naive implementation. However, it should be possible to optimize this when the receiver’s type is actually known.