I have a public trait called Foo
, and a secret type SecretFoo
which is not public. I want to all my functions return a Arc<dyn Foo>
without exposing SecretFoo
, but when I wrote something complicated, I don't know to do it (hide the SecretFoo
):
pub trait Foo {}
struct SecretFoo {}
impl Foo for SecretFoo {}
pub trait Bar {
type Foo;
}
pub struct Baz {}
impl Bar for Baz {
type Foo = Arc<dyn Foo>;
}
pub fn test<T: Bar>() -> T::Foo {
Arc::new(SecretFoo {})
}
This will not compile because compiler don't know how to convert Arc<SecretFoo>
to T::Foo
:
error[E0308]: mismatched types
--> src/main.rs:21:5
|
20 | pub fn test<T: Bar>() -> T::Foo {
| ------ expected `<T as Bar>::Foo` because of return type
21 | Arc::new(SecretFoo {})
| ^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found struct `Arc`
|
= note: expected associated type `<T as Bar>::Foo`
found struct `Arc<SecretFoo>`
help: consider constraining the associated type `<T as Bar>::Foo` to `Arc<SecretFoo>`
|
20 | pub fn test<T: Bar<Foo = Arc<SecretFoo>>>() -> T::Foo {
| ++++++++++++++++++++++
I don't want to follow the suggestion from the compiler, because it will expose the SecretFoo
to the public, any other way to do this?
P.S. Currently, I can leave my SecretFoo
to private but using the suggestion, but the compiler will warn me:
warning: private type `SecretFoo` in public interface (error E0446)
--> src/main.rs:20:1
|
20 | pub fn test<T: Bar<Foo = Arc<SecretFoo>>>() -> T::Foo {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
= note: `#[warn(private_in_public)]` on by default
warning: 1 warning emitted
Finished dev [unoptimized + debuginfo] target(s) in 0.63s
Process finished with exit code 0
P.P.S: It indeed not necessary to make SecretFoo
as private, I can leave it to the public, but I don't want the user who use my crate get confused with too many types that he doesn't need to know at all.