While pub(crate) is currently not used often, in the future it will be - possibly even more often than pub.
To illustrate this, consider the following hypothetical channel implemented as a library:
pub struct Channel<T> { inner: queue::Queue<T> }
impl<T> Channel<T> {
pub fn send(&self, msg: T) { self.inner.push(msg); }
pub fn recv(&self) -> Option<T> { self.inner.pop() }
}
mod queue {
pub struct Queue<T> { ... }
impl<T> Queue<T> {
pub fn push(&self, value: T) { ... }
pub fn pop(&self) -> Option<T> { ... }
}
}
Everything in module queue is declared pub, but it doesn’t have to be. We could’ve used pub(crate) as well. More importantly, note that structure Queue and its methods are not really public - they’re only visible to the parent module.
Now, this example is pretty simple, but when reading a big codebase with a lot of modules, structs, and functions, it can be frustratingly difficult to figure out whether pub struct Queue is visible to other crates or not. Therefore we’ve decided to have two kinds of pub: visible to other crates (pub) and visible within this crate (crate).
To improve code readability, we should’ve ideally written the previous example like this:
pub struct Channel<T> { inner: queue::Queue<T> }
impl<T> Channel<T> {
pub fn send(&self, msg: T) { self.inner.push(msg); }
pub fn recv(&self) -> Option<T> { self.inner.pop() }
}
mod queue {
pub(crate) struct Queue<T> { ... }
impl<T> Queue<T> {
pub(crate) fn push(&self, value: T) { ... }
pub(crate) fn pop(&self) -> Option<T> { ... }
}
}
This is much better. Now it’s perfectly clear that Queue is only an implementation detail of this crate, and definitely not something visible to other crates. Maybe this example is not particularly convincing because it’s very small, but I’ve personally found the overuse of pub to be a serious problem.
Anyways, nobody is going to write pub(crate) in this situation because pub is simply easier to type. So we want to make it easy to type code that will be more readable, hence why we’re introducing the crate modifier. It should be used very liberally.
As far as I’m concerned, crate as a visibility modifier cannot come soon enough. 