Reputation: 1296
The following code does not compile:
pub(crate) trait Private {}
pub trait Public {}
impl<T: Private> Public for T {}
The error is:
error[E0445]: private trait `Private` in public interface
--> src/main.rs:7:1
|
3 | pub(crate) trait Private {}
| ------------------------ `Private` declared as private
...
7 | impl<T: Private> Public for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
I don't understand why the Private trait is considered leaked in this situation.
The linked error explanation lists similar examples which do leak a private trait by using it in a trait bound. However, those examples are different because the trait bounds are something external crates can use.
For example, I can see why this is considered to leak the Private trait:
pub trait Public : Private {} // error: private trait in public interface
Here, external crates would be required to implement the Private trait (which they can't do) to implement the Public trait (which they can).
My first example is different in that external crates don't need to know anything about the Private trait – so I'm confused.
Where are the rules of leaking documented? What does leaking a private trait really mean?
Why does my example fail to compile? Is there a reason for guarding against such an impl
?
Upvotes: 2
Views: 1219
Reputation: 1296
As @eggyal explained in the comments, even though users of Public
don't need to know anything about the Private
trait, it is still leaked through the documentation, which must include the head of the impl
block to communicate which types implement Public
.
The workaround is to mark the Private
trait as pub
. It may still be hidden away in a private mod
if you wish to keep it effectively private.
mod hidden {
pub trait Private {}
}
pub(crate) use hidden::Private;
pub trait Public {}
impl<T: Private> Public for T {}
Upvotes: 2