From reddit.
The trait definition entirely determines the signatures of impl'd methods, and so the signature is known without examining the function body, e.g.
trait Foo<T> { fn bar(&self, x: T, y: Self, z: ~str) -> bool; }
impl Foo<int> for f64 {
fn bar(&self, x: int, y: f64, z: ~str) -> bool { ... }
}
// could be
impl Foo<int> for f64 {
fn bar(&self, x, y, z) { ... }
}
(Or something like fn bar(&self, x: _, y: _, z: _) -> _ { ... } to make it obvious that a inferred/blank type is being used.)
I'm personally ambivalent on this; it may result in
- some tooling being harder to write,
- confusing error messages,
- code that subtly changes behaviour if an upstream trait changes method definitions slightly, but the method body uses that argument in a way that is satisfied by both the old and new types. e.g.
TreeMap<uint, T> becoming ~[T]: they both have a methods called insert and remove with the same signature, but they have different performance and semantics. (WIth explicit signatures, the downstream code would stop compiling, rather than changing behaviour.)
From reddit.
The trait definition entirely determines the signatures of impl'd methods, and so the signature is known without examining the function body, e.g.
(Or something like
fn bar(&self, x: _, y: _, z: _) -> _ { ... }to make it obvious that a inferred/blank type is being used.)I'm personally ambivalent on this; it may result in
TreeMap<uint, T>becoming~[T]: they both have a methods calledinsertandremovewith the same signature, but they have different performance and semantics. (WIth explicit signatures, the downstream code would stop compiling, rather than changing behaviour.)