For example:
trait TraitX { }
trait TraitY { }
impl TraitX for TraitY { }
I figured it would mean the same as
impl<A: TraitY> TraitX for A { }
but the error message suggests otherwise:
$ rustc --version
rustc 0.12.0-nightly (a70a0374e 2014-10-01 21:27:19 +0000)
$ rustc test.rs
test.rs:3:17: 3:23 error: explicit lifetime bound required
test.rs:3 impl TraitX for TraitY { }
^~~~~~
Does impl TraitX for TraitY
(or some variant of it with an explicit lifetime) mean anything in Rust? If so, what is an example of its use?
Rust has changed a lot since this question was asked. While that syntax is currently* still supported, trait objects should now be designated with the keyword dyn
:
trait TraitX { }
trait TraitY { }
impl TraitX for dyn TraitY { }
This is entirely equivalent to the code in the question, but a bit more obvious about what it means: implement TraitX
for the trait object dyn TraitY
.
For example:
struct Thing;
impl TraitY for Thing {}
fn main() {
// Treat the &Thing as a dynamic object
let object: &dyn TraitY = &Thing;
// The TraitY object can still be used where a TraitX is expected
do_something(object);
}
fn do_something<T: TraitX + ?Sized>(t: &T) {
}
On the surface, as you mention, it seems similar to:
impl<A: TraitY> TraitX for A { }
This implements TraitX
for any concrete type that implements TraitY
, but does not include trait objects because Sized
is always an implicit bound on type parameters. But we can remove that limitation by explicitly opting out of the Sized
bound:
impl<A: TraitY + ?Sized> TraitX for A { }
This includes all concrete types that implement TraitY
, but now also includes dynamic TraitY
objects. For maximum flexibility, you should use this form instead of either of the alternatives above.
*"Currently" because future editions of Rust may require the keyword in these situations. At least, the default linter will disallow omitting it.