`dyn Trait` syntax in unexpected position

I’ve run into compiler warnings suggesting dyn Trait syntax in locations (1) that are accepted by the compiler but I didn’t expect and can’t find documentation for the semantics or (2) that are invalid.

1

Playground link

Making the suggested change is accepted, but I didn’t find docs in the dyn trait RFC discussion that make explicit what impl B for dyn A means – does this require that A be object safe?

2

I don’t have a working playground example for this yet, but I have a project that suggests putting dyn in the trait definition, which is invalid. I suspect this is macro-related and will file a bug if I can get a small reproduction:

warning: trait objects without an explicit `dyn` are deprecated
   --> src/datatype/interface.rs:137:11
    |
137 | pub trait CustomProductionPolicyController {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn CustomProductionPolicyController`

According to 1) - are you sure you know what are you doing here? In general writing:

impl Trait for OtherTrait {}

Doesn’t mean "implement Trait for any type implementing OtherTrait" but “implement Trait for any fat-pointer to OtherTrait”, and this is deprecated syntax (the dyn word should be added before OtherTrait). This is important difference - first one is universal, the second one works only for fat pointers. If you meant the first, you should write:

impl<T: OtherTrait> Trait for T {}

The problem is, that it disallows later specialized definitions of Trait for types implementing OtherTrait without specializations (which is unstable feature for now AFAIK).

3 Likes

To avoid loss of generality, you can even add a ?Sized “unbound” on the generic:

impl<T : ?Sized> Trait for T
where
    T : OtherTrait,
{
    // ...
}
1 Like

:man_facepalming: Yeah, not enough coffee yet. Makes perfect sense. Was working backwards from the legitimate error in (2) and didn’t stop to think what I was writing.