The orphan rule counts a trait's type arguments
An impl may be written with its trait, or where any of the types it joins is declared:
its type, then each of the trait’s arguments in order, stopping at a bare type parameter.
Chosen by the user on 2026-10-23. This widens D-0031, which said “with the trait or with
the type”.
D-0031 was decided before traits took type arguments (Mul<f32> came with §18.27), and the
checker compared only the trait’s module and the type’s. So the module declaring Vec2 could
not write impl ImplicitAs<Vec2> for rl::Vector2, a conversion into its own type, nor
impl Mul<Vec2> for f32, though both name its type. The user pointed out that the argument
is part of the trait being implemented, and asked how Rust treats it.
- Rust’s rule (chosen). Since Rust 1.41 (RFC 2451),
impl ForeignTrait<LocalType> for ForeignTypeis allowed. It stays coherent: two modules can only both write one implementation if each names the other’s type, which would make their dependencies a cycle, and §3.2 makes a cycle an error (DZ0006). - The uncovered-parameter limit, also Rust’s. A bare type parameter before the local
type ends the search:
impl<T> Pair<T, Mine> for TheirscoversPair<Yours, Mine>, which the module declaringYourscould also write without a cycle. - The old rule (rejected). It refused implementations that cannot collide, and with it
ImplicitAs(D-0089) could only convert from a module’s types, never into them.
Spec: §7.6.
