Question about Trait Syntax

I recently ran into a trait syntax that I don't think I have seen before:

trait T: E {
    // ....
}

where E is some other trait. What is the semantics of this syntax?

It means that every type which implements trait T must also implement trait E. In practical terms, it means that if you have a generic function fn example<A:T>(a:A) { ... }, then you are allowed to call methods defined by either T or E on the value a.

1 Like

It means E is a Supertrait of T (similar to superclasses in object oriented languages, except we're having traits here, and not classes, so there are differences, of course).

1 Like

Thank both of y'all for y'all's reply!

It's short syntax for trait T where Self: E {} which means if some type implements T, it also must implement E.

It does not add a subclassing relationship (at least not yet), so types like &dyn T remain incompatible with &dyn E.

2 Likes

Note that while this is technically true, supertrait bounds (i.e. bounds on Self) on a trait behave differently from e.g. bounds on parameters. When you have

trait Foo<T> where T: Bar { /* methods... */ }

then every time you use S: Foo<T>, you will need to put extra T: Bar bounds. OTOH,

trait Baz: Qux { /* methods... */ }

or

trait Baz where Self: Qux { /* methods... */ }

has the effect that when you use S: Baz, the S: Qux will be implied, and does not need to be written explicitly. E.g.

// doesn't work
fn f<S, T>()
where
    S: Foo<T>,
{}
// works
fn g<S, T>()
where
    S: Foo<T>,
    T: Bar,
{}

vs.

// works
fn h1<S>()
where
    S: Baz,
{}
// works, and equivalent to h1
fn h2<S>()
where
    S: Baz,
    S: Qux,
{}

(playground)

3 Likes

That'd require #![feature(trait_upcasting)], I assume?

Yes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.