@@ -1501,6 +1501,171 @@ is `extern "abi" fn(A1, ..., An) -> R`,
15011501where ` A1...An ` are the declared types of its arguments
15021502and ` R ` is the decalred return type.
15031503
1504+ ## Visibility and Privacy
1505+
1506+ These two terms are often used interchangeably, and what they are attempting to
1507+ convey is the answer to the question "Can this item be used at this location?"
1508+
1509+ Rust's name resolution operates on a global hierarchy of namespaces. Each level
1510+ in the hierarchy can be thought of as some item. The items are one of those
1511+ mentioned above, but also include external crates. Declaring or defining a new
1512+ module can be thought of as inserting a new tree into the hierarchy at the
1513+ location of the definition.
1514+
1515+ To control whether interfaces can be used across modules, Rust checks each use
1516+ of an item to see whether it should be allowed or not. This is where privacy
1517+ warnings are generated, or otherwise "you used a private item of another module
1518+ and weren't allowed to."
1519+
1520+ By default, everything in rust is * private* , with two exceptions. The first
1521+ exception is that struct fields are public by default (but the struct itself is
1522+ still private by default), and the remaining exception is that enum variants in
1523+ a ` pub ` enum are the default visibility of the enum container itself.. You are
1524+ allowed to alter this default visibility with the ` pub ` keyword (or ` priv `
1525+ keyword for struct fields and enum variants). When an item is declared as ` pub ` ,
1526+ it can be thought of as being accessible to the outside world. For example:
1527+
1528+ ~~~
1529+ // Declare a private struct
1530+ struct Foo;
1531+
1532+ // Declare a public struct with a private field
1533+ pub struct Bar {
1534+ priv field: int
1535+ }
1536+
1537+ // Declare a public enum with public and private variants
1538+ pub enum State {
1539+ PubliclyAccessibleState,
1540+ priv PrivatelyAccessibleState
1541+ }
1542+ ~~~
1543+
1544+ With the notion of an item being either public or private, Rust allows item
1545+ accesses in two cases:
1546+
1547+ 1 . If an item is public, then it can be used externally through any of its
1548+ public ancestors.
1549+ 2 . If an item is private, it may be accessed by the current module and its
1550+ descendants.
1551+
1552+ These two cases are surprisingly powerful for creating module hierarchies
1553+ exposing public APIs while hiding internal implementation details. To help
1554+ explain, here's a few use cases and what they would entail.
1555+
1556+ * A library developer needs to expose functionality to crates which link against
1557+ their library. As a consequence of the first case, this means that anything
1558+ which is usable externally must be ` pub ` from the root down to the destination
1559+ item. Any private item in the chain will disallow external accesses.
1560+
1561+ * A crate needs a global available "helper module" to itself, but it doesn't
1562+ want to expose the helper module as a public API. To accomplish this, the root
1563+ of the crate's hierarchy would have a private module which then internally has
1564+ a "public api". Because the entire crate is an ancestor of the root, then the
1565+ entire local crate can access this private module through the second case.
1566+
1567+ * When writing unit tests for a module, it's often a common idiom to have an
1568+ immediate child of the module to-be-tested named ` mod test ` . This module could
1569+ access any items of the parent module through the second case, meaning that
1570+ internal implementation details could also be seamlessly tested from the child
1571+ module.
1572+
1573+ In the second case, it mentions that a private item "can be accessed" by the
1574+ current module and its descendants, but the exact meaning of accessing an item
1575+ depends on what the item is. Accessing a module, for example, would mean looking
1576+ inside of it (to import more items). On the other hand, accessing a function
1577+ would mean that it is invoked.
1578+
1579+ Here's an example of a program which exemplifies the three cases outlined above.
1580+
1581+ ~~~
1582+ // This module is private, meaning that no external crate can access this
1583+ // module. Because it is private at the root of this current crate, however, any
1584+ // module in the crate may access any publicly visible item in this module.
1585+ mod crate_helper_module {
1586+
1587+ // This function can be used by anything in the current crate
1588+ pub fn crate_helper() {}
1589+
1590+ // This function *cannot* be used by anything else in the crate. It is not
1591+ // publicly visible outside of the `crate_helper_module`, so only this
1592+ // current module and its descendants may access it.
1593+ fn implementation_detail() {}
1594+ }
1595+
1596+ // This function is "public to the root" meaning that it's available to external
1597+ // crates linking against this one.
1598+ pub fn public_api() {}
1599+
1600+ // Similarly to 'public_api', this module is public so external crates may look
1601+ // inside of it.
1602+ pub mod submodule {
1603+ use crate_helper_module;
1604+
1605+ pub fn my_method() {
1606+ // Any item in the local crate may invoke the helper module's public
1607+ // interface through a combination of the two rules above.
1608+ crate_helper_module::crate_helper();
1609+ }
1610+
1611+ // This function is hidden to any module which is not a descendant of
1612+ // `submodule`
1613+ fn my_implementation() {}
1614+
1615+ #[cfg(test)]
1616+ mod test {
1617+
1618+ #[test]
1619+ fn test_my_implementation() {
1620+ // Because this module is a descendant of `submodule`, it's allowed
1621+ // to access private items inside of `submodule` without a privacy
1622+ // violation.
1623+ super::my_implementation();
1624+ }
1625+ }
1626+ }
1627+
1628+ # fn main() {}
1629+ ~~~
1630+
1631+ For a rust program to pass the privacy checking pass, all paths must be valid
1632+ accesses given the two rules above. This includes all use statements,
1633+ expressions, types, etc.
1634+
1635+ ### Re-exporting and Visibility
1636+
1637+ Rust allows publicly re-exporting items through a ` pub use ` directive. Because
1638+ this is a public directive, this allows the item to be used in the current
1639+ module through the rules above. It essentially allows public access into the
1640+ re-exported item. For example, this program is valid:
1641+
1642+ ~~~
1643+ pub use api = self::implementation;
1644+
1645+ mod implementation {
1646+ pub fn f() {}
1647+ }
1648+
1649+ # fn main() {}
1650+ ~~~
1651+
1652+ This means that any external crate referencing ` implementation::f ` would receive
1653+ a privacy violation, while the path ` api::f ` would be allowed.
1654+
1655+ When re-exporting a private item, it can be thought of as allowing the "privacy
1656+ chain" being short-circuited through the reexport instead of passing through the
1657+ namespace hierarchy as it normally would.
1658+
1659+ ### Glob imports and Visibility
1660+
1661+ Currently glob imports are considered an "experimental" language feature. For
1662+ sanity purpose along with helping the implementation, glob imports will only
1663+ import public items from their destination, not private items.
1664+
1665+ > ** Note:** This is subject to change, glob exports may be removed entirely or
1666+ > they could possibly import private items for a privacy error to later be
1667+ > issued if the item is used.
1668+
15041669## Attributes
15051670
15061671~~~~~~~~ {.ebnf .gram}
0 commit comments