I'll start right away with an example. Consider this crate that could
have been written using the old privacy rules:
pub mod mod_a
{
pub struct S { priv m: int; }
impl S
{
pub fn pub_api(&self) -> int { self.m }
}
mod internal
{
use super::S;
impl S
{
/* This one doesn't actually work due to bugs */
pub fn crate_api_1() -> S { S{m: 0} }
}
pub fn crate_api_2() -> S { S{m: 0} }
}
}
Under the old privacy rules, items were accessible within a crate if
they were pub'd, regardless of the intervening privacy. Note that
crate_api_1() and crate_api_2() can only be used within the crate. Under
the new privacy rules, this sort of looks like this:
mod internal
{
pub struct S { priv m: int; }
impl S
{
pub fn pub_api(&self) -> int { self.m }
}
pub fn crate_api_2() -> S { S{m: 0} }
}
pub mod mod_a
{
pub use internal::S;
}
The general idea is that you have a top-level, private module which
contains the crate-scoped API. Note that I don't think you can even
write crate_api_1 anymore. Also note how the public API moved inside the
internal module: in fact, pretty much everything is now placed inside
it, and the public API is now re-exported elsewhere (reminiscent of the
old export lists). If you weren't planning to have crate-local API, then
you'd really have to restructure your code to support it... so much so,
that it might be prudent to code as if you had crate-scoped API even if
you don't (yet).
Is my analysis incorrect? Is there a way to write crate_api_1 (i.e. a
crate-scoped method) ? Is there a way to avoid moving the entire code
base inside the 'internal' mod?
One last note... since the new privacy rules don't mention crates, this
problem becomes a bit more general, i.e. it's very tricky to isolate a
particular API to a sub-tree of modules. I feel like it's almost simpler
to just make everything public and rely on documentation or place
everything in a single module.
-SL
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev