User extensions problems with orphan-rule
⚓ Rust 📅 2025-06-10 👤 surdeus 👁️ 12To simplify i'll present a minimized version of my problem, for detail see here:
The detailed problem (click for more details)What I want
I'm writing a crate that contains:
pub trait TraitA {}
pub struct StructA<T>(T);
And I would like the user to be able to write:
pub struct MyLocalType;
impl TraitA for StructA<MyLocalType> {}
Why I want it
In this case, StructA is a helper struct I provide to help implement another trait.
While we can write the following blanket implementation, I want the user to be able to specialise it.
impl<T> TraitA for StructA<T> {}
In our concrete example, the specialisation allows a x5 in performance.
The problem
The says that the orphan rule doesn't allow this:
error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
--> test_orphan/src/lib.rs:2:1
|
51 | impl<'a> TraitA for StructA<MyLocalType> {
| ^^^^^^^^^^^^^^^^^^^-------------------------------
| |
| `StructA` is not defined in the current crate
|
= note: impl doesn't have any local type before any uncovered type parameters
= note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
= note: define and implement a trait or new type instead
Why it happens
Looking at the rust reference I see the orphan rules defined as:
Given
impl<P1..=Pn> Trait<T1..=Tn> for T0, animplis valid only if at least one of the following is true:
Traitis a local trait- All of
- At least one of the types
T0..=Tnmust be a local type. LetTibe the first such type.- No uncovered type parameters
P1..=Pnmay appear inT0..Ti(excludingTi)
Here the problem is that T0, which in my case is StructA<MyLocalType>, is not a LocalType, as they are defined as:
LocalType
A struct, enum, or union which was defined in the current crate. This is not affected by applied type arguments. struct Foo is considered local, but Vec is not. LocalType is local. Type aliases do not affect locality.
Questions
1 - What's the reason why ForeignType<LocalType> is not local?
2 - What can I do to allow the user to write their specialised impl in an ergonomic way? I'd rather avoid having to write a new-type that wraps StructA<MyLocalType> and having to forward all traits
6 posts - 5 participants
🏷️ rust_feed