I think you are right about that, but that requires a language change. The Idea in the topic was just about a small change of a thing in libstd.
But you are right. We need to be able to use private traits like that, it solves another problem: “overloading”.
pub trait AcceptableType {
...
}
impl Foo {
pub fn new_from<T: AcceptableType>(init: T) -> Self { .. }
}
There are two choices here: AcceptableType is a regular, open trait, and users may usefully impl it for their own types sometimes. The other simpler choice is to make it a closed/private trait.
The closed/private trait is simpler: less public API surface area. I can change the AcceptableType’s methods when refactoring my library. All I used the trait for was for user-facing constructor overload anyway.
Using unsafe trait is not even a solution there – the public trait adds methods to the types it is implemented for. I don’t want that with a closed trait, I don’t want that just because the trait is part of the public API, that its internals and its methods are available to library users. I want that to be an encapsulated detail in my API. All I wanted was overloading of new_from.