Search code examples
rusttraitsorphan

Why is implementing an external trait using my type as a parameter for an external type legal?


I am modifying some code to depend on rand version 0.5. At first, I was worried how I would enable generating random values of my own types with Standard, but I found out this is legal:

impl ::rand::distributions::Distribution<MyType> for ::rand::distributions::Standard {
    // ...
}

Why is it legal? I thought implementing an external trait for an external type is illegal.


Solution

  • The entire purpose of these rules (called the orphan rules or coherence rules) is to avoid having any conflicting implementations for a given trait/type combination. Since Rust 1.0, it is believed that it would not be in line with a language striving for solid stability to be "willy-nilly" about who is allowed to implement a trait for a type.

    A very common example of this particular type of implementation is From:

    impl From<MyType> for i32 {
        // ...
    }
    

    By parameterizing the trait with a local type, there's still no ambiguity about who is implementing the trait. One way of thinking about it would be treating Distribution as not a trait but a trait constructor 1. Each instance of Distribution creates a new trait, one that's custom-made for the case.

    See also:

    1 — This isn't true, but it's a reasonable analogy.