It seems the argument on single-inheritance hinges on the following use
case:
struct Foo { foo: int }
struct Bar : Foo { bar: bar }
fn main() {
let myFoos = [Foo{ foo: 1 } as ~Foo, Bar{ foo: Foo{foo: 1}, bar: 2} as
~Foo];
for myFoo in myFoos.iter() {
myFoo.foo; // Fixed offset access
}
}
If I understand correctly, this member access is vital for Servo.
At the same time, I (and I think others) would like to see some form of a
flexible implementation reuse for traits, with the understanding the
invoking trait methods incurs the cost of a virtual function anyway.
I think it is "obvious" that the same mechanism can't do both. So how about
a compromise? There would be two mechanisms, but we'll make them play nice
with each other.
Mechanism #1: Struct-traits.
Mechanism #3: Anonymous fields.
struct Foo { foo: int }
// Note: Use "Foo" as a trait.
// Any type implementing "Foo" has a publicly-reachable "Foo" member at
offset 0.
// The trait "Foo" allows constant-offset access to all the "Foo" data
members.
fn use_foo<T: Foo>(ptr: &T) -> int {
ptr.foo // Fixed offset
}
// By construction, Bar implements the Foo struct-trait
struct Bar {
Foo;
bar: int;
}
(It is also possible to add a new syntax "struct Bar : Foo { bar int }", if
this is seen as clearer, but IMO it isn't really needed).
// Baz also implements Foo by construction.
struct Baz {
Bar;
baz: int;
}
// Qux doesn't implement Foo.
struct Qux {
qux: int,
Foo
}
As for non-struct traits, anonymous fields would provide a default
implementation. That is, suppose that:
impl Trait for Foo { ... }
Then one would be need to write (explicitly!):
impl Trait for Bar {} // Just use the default from Foo
Or:
impl Trait for Bar { ... override some of the methods ... };
(I think it is a bad idea to have traits be implemented implicitly just
because one anonymous field implements them; IMVHO an explicit "impl Trait
for Container" is a "very good idea").
This way you can have your cake and eat it 2. I think it is pretty clean -
traits do arbitrary mixin things with virtual-function cost (_with_
implementation reuse); And there's a "by definition single inheritance"
special access-my-data-members-at-fixed-offset trait whose existence does
not impact the power of the normal mixin traits in any way.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev