I can't figure out how GitHub works, so can someone please commit the following RFC, thank you:
- Start Date: 2014-04-17 - RFC PR #: - Rust Issue #: # Summary Add the ability to specify that a type, which implements a certain trait, must have certain set of fields (data members) of certain types so that the trait may then use those expected fields in the methods it provides (has a default definition for). # Motivation This enables much more code re-use than traits currently do. This also provides what other languages call "multiple inheritance" without facing the so called "diamond problem". # Detailed design A trait may specify a set of expected fields. For each expected field the trait definition must provide a type and a unique name. When a type implements such a trait, it must specify which of its fields correspond with each of the trait's expected fields. The types of the fields must match with the types of the corresponding expected fields of the trait and no two fields of the type may map to the same expected field of the trait. The type implementing the trait may have more fields than there are expected fields in the trait, and the order of fields doesn't matter. The knowledge of which field each expected field corresponds to can then be used by the trait to locate and use the data it expects to find by adding the offset of the field to a pointer to the first byte of ```self``` and by re-interpreting the pointed-to data as the expected field's type. What follows next is an example code snippet where I present the syntax I propose for this feature. And after that I'll provide the (currently valid) Rust code which the first example would conceptually correspond with. Example 1: The proposed syntax ``` trait Unify<T: Clone> { Self { x: T, y: T } fn unify(&mut self) { self.y = self.x.clone(); } } struct Stuff { a: u32, b: u32 } impl Unify<u32> for Stuff { Stuff { x => a, y => b } } ``` Example 2: The code that corresponds with example 1 ``` use std::cast::transmute; trait Unify<T: Clone> { fn x_offset(&self) -> int; // This should be replaced with an associated constant once we get those fn y_offset(&self) -> int; // This should be replaced with an associated constant once we get those fn unify(&mut self) { unsafe { let self_x: *mut T = transmute::<*mut u8, *mut T>(transmute::<&mut Self, *mut u8>(self).offset(self.x_offset())); let self_y: *mut T = transmute::<*mut u8, *mut T>(transmute::<&mut Self, *mut u8>(self).offset(self.y_offset())); *self_y = (*self_x).clone(); } } } struct Stuff { a: u32, // is at offset 0 bytes b: u32 // is at offset 4 bytes } impl Unify<u32> for Stuff { fn x_offset(&self) -> int { 0 // The offset of field 'a' } fn y_offset(&self) -> int { 4 // The offset of field 'b' } } ``` # Alternatives Code re-use is possible also with macros, but this solution is much more elegant and may allow better opportunities for the compiler to reduce template code-bloat. # Unresolved questions The syntax is completely open to debate. _______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev