Private type in bound of public method

All right, this one's a doozy. I'm trying to make evmap have sound aliasing of values. The linked PR has a lot more discussion around the exact safety requirements, but that's only somewhat orthogonal to this issue.

Essentially, I have a type, Aliased<T, D> that is basically a &T. I also have a that that holds a HashSet that in turns stores Aliased<T, SomeType>. SomeType is private and must remain private for soundness (so no #[doc(hidden)] tricks. And now, I want to provide an method for checking if a T is in the set, and I want to do so while providing the nice ergonomic of Borrow. So, I want to write:

pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
where
    Aliased<T, SomeType>: Borrow<Q>,
    Q: Eq + Hash,
{
    self.set.contains(value)
}

But, this won't work, since SomeType is now a private type in a public interface. Rats.

And so I turn to you smart people of Rust world. How can I do this without making SomeType public, given that I have no control over Borrow or HashSet? Do I just have to give up on the nice ergonomics and take a &T, or can we find some sneaky type system hack to make this work?

Can you make it pub in a non-pub module?

That's how I use a whole bunch of "private" traits as bounds in arraytools::ArrayTools - Rust ...

1 Like

Huh, I thought that only worked for traits. But if that works for concrete types, I think you may just be right. That was easier than expected! Will report back shortly.

I use pub trait in private mod "trait sealing" precisely to prevent "private exposed in public" errors as well.

That indeed seems to have done it! Surprisingly #[deny(unreachable_pub)] doesn't catch it in my particular code (though it works in simplified cases I've tried), but that's something for me to dig into on my own time. Thanks for the quick pointer!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.