William Taylor
William Taylor

Reputation: 629

Private trait in public interface when blanket implement public trait to private trait

Currently, I'm trying to blanket implement a public trait on any struct that implement a private trail, but i get compiler warning: private trait `mod_b::PrivateTrait` in public interface (error E0445) Is there anyway to fix this?

main.rs:

trait PublicTrait {}

mod mod_b
{
    use PublicTrait;
    trait PrivateTrait {}

    impl<T: PrivateTrait> PublicTrait for T {}
}

pub fn main ()
{
}

Upvotes: 4

Views: 1772

Answers (2)

tjb1982
tjb1982

Reputation: 2259

I accomplished this two ways: with a private fn outside of the trait in the same module (like you might do in JavaScript); and with a private trait and pub trait in the same module. In both cases, the solution involved implementing a generic and using the Sized constraint.

Private fn:

pub trait MyPublicTrait: Sized {
    fn get_msg(&self) -> &str { "Hello from" }

    fn do_something(&self) {
        do_something_impl(self);
    }
}

fn do_something_impl<T>(a: &T)
    where T: MyPublicTrait
{
    println!("{} private fn", a.get_msg());
}

Private trait:

trait MyPrivateTrait {
    fn do_something_impl(&self);
}

pub trait MyPublicTrait: Sized {
    fn get_msg(&self) -> &str { "Hello from" }

    fn do_something(&self) {
        self.do_something_impl();
    }
}

impl<T: MyPublicTrait> MyPrivateTrait for T {
    fn do_something_impl(&self) {
        println!("{} private trait", self.get_msg());
    }
}

The second one seemed confusing to me at first, because MyPublicTrait is using do_something_impl before it "knows" that Self will always implement MyPrivateTrait. But apparently the compiler knows what we're trying to say: that do_something_impl is always there for any MyPublicTrait because MyPrivateTrait is implemented for all T: MyPublicTrait. And vice versa, get_msg is available for MyPrivateTrait because any T will always be a MyPublicTrait.

And from the perspective of calling code outside of this module, the methods declared in MyPrivateTrait will never be available because you can't use a private trait.

Upvotes: 1

Neeraj
Neeraj

Reputation: 174

You need to make the PrivateTrait public

trait PublicTrait {}

mod mod_b {
    use crate::PublicTrait;
    pub trait PrivateTrait {}

    impl<T: PrivateTrait> PublicTrait for T {}
}

fn test<T: PublicTrait>(_: T){
    println!("public")
}

struct Private;
impl mod_b::PrivateTrait for Private {}

pub fn main() {
    test(Private);
}

Or to keep PrivateTrait private in mod_b

trait PublicTrait {}

mod mod_b {
    use crate::PublicTrait;
    trait PrivateTrait {}

    impl<T: PublicTrait> PrivateTrait for T {}
}

fn main() {}

Upvotes: 3

Related Questions