]> git.proxmox.com Git - rustc.git/blob - src/doc/reference/src/visibility-and-privacy.md
New upstream version 1.55.0+dfsg1
[rustc.git] / src / doc / reference / src / visibility-and-privacy.md
1 # Visibility and Privacy
2
3 > **<sup>Syntax<sup>**\
4 > _Visibility_ :\
5 > &nbsp;&nbsp; &nbsp;&nbsp; `pub`\
6 > &nbsp;&nbsp; | `pub` `(` `crate` `)`\
7 > &nbsp;&nbsp; | `pub` `(` `self` `)`\
8 > &nbsp;&nbsp; | `pub` `(` `super` `)`\
9 > &nbsp;&nbsp; | `pub` `(` `in` [_SimplePath_] `)`
10
11 These two terms are often used interchangeably, and what they are attempting to
12 convey is the answer to the question "Can this item be used at this location?"
13
14 Rust's name resolution operates on a global hierarchy of namespaces. Each level
15 in the hierarchy can be thought of as some item. The items are one of those
16 mentioned above, but also include external crates. Declaring or defining a new
17 module can be thought of as inserting a new tree into the hierarchy at the
18 location of the definition.
19
20 To control whether interfaces can be used across modules, Rust checks each use
21 of an item to see whether it should be allowed or not. This is where privacy
22 warnings are generated, or otherwise "you used a private item of another module
23 and weren't allowed to."
24
25 By default, everything in Rust is *private*, with two exceptions: Associated
26 items in a `pub` Trait are public by default; Enum variants
27 in a `pub` enum are also public by default. When an item is declared as `pub`,
28 it can be thought of as being accessible to the outside world. For example:
29
30 ```rust
31 # fn main() {}
32 // Declare a private struct
33 struct Foo;
34
35 // Declare a public struct with a private field
36 pub struct Bar {
37 field: i32,
38 }
39
40 // Declare a public enum with two public variants
41 pub enum State {
42 PubliclyAccessibleState,
43 PubliclyAccessibleState2,
44 }
45 ```
46
47 With the notion of an item being either public or private, Rust allows item
48 accesses in two cases:
49
50 1. If an item is public, then it can be accessed externally from some module
51 `m` if you can access all the item's ancestor modules from `m`. You can
52 also potentially be able to name the item through re-exports. See below.
53 2. If an item is private, it may be accessed by the current module and its
54 descendants.
55
56 These two cases are surprisingly powerful for creating module hierarchies
57 exposing public APIs while hiding internal implementation details. To help
58 explain, here's a few use cases and what they would entail:
59
60 * A library developer needs to expose functionality to crates which link
61 against their library. As a consequence of the first case, this means that
62 anything which is usable externally must be `pub` from the root down to the
63 destination item. Any private item in the chain will disallow external
64 accesses.
65
66 * A crate needs a global available "helper module" to itself, but it doesn't
67 want to expose the helper module as a public API. To accomplish this, the
68 root of the crate's hierarchy would have a private module which then
69 internally has a "public API". Because the entire crate is a descendant of
70 the root, then the entire local crate can access this private module through
71 the second case.
72
73 * When writing unit tests for a module, it's often a common idiom to have an
74 immediate child of the module to-be-tested named `mod test`. This module
75 could access any items of the parent module through the second case, meaning
76 that internal implementation details could also be seamlessly tested from the
77 child module.
78
79 In the second case, it mentions that a private item "can be accessed" by the
80 current module and its descendants, but the exact meaning of accessing an item
81 depends on what the item is. Accessing a module, for example, would mean
82 looking inside of it (to import more items). On the other hand, accessing a
83 function would mean that it is invoked. Additionally, path expressions and
84 import statements are considered to access an item in the sense that the
85 import/expression is only valid if the destination is in the current visibility
86 scope.
87
88 Here's an example of a program which exemplifies the three cases outlined
89 above:
90
91 ```rust
92 // This module is private, meaning that no external crate can access this
93 // module. Because it is private at the root of this current crate, however, any
94 // module in the crate may access any publicly visible item in this module.
95 mod crate_helper_module {
96
97 // This function can be used by anything in the current crate
98 pub fn crate_helper() {}
99
100 // This function *cannot* be used by anything else in the crate. It is not
101 // publicly visible outside of the `crate_helper_module`, so only this
102 // current module and its descendants may access it.
103 fn implementation_detail() {}
104 }
105
106 // This function is "public to the root" meaning that it's available to external
107 // crates linking against this one.
108 pub fn public_api() {}
109
110 // Similarly to 'public_api', this module is public so external crates may look
111 // inside of it.
112 pub mod submodule {
113 use crate::crate_helper_module;
114
115 pub fn my_method() {
116 // Any item in the local crate may invoke the helper module's public
117 // interface through a combination of the two rules above.
118 crate_helper_module::crate_helper();
119 }
120
121 // This function is hidden to any module which is not a descendant of
122 // `submodule`
123 fn my_implementation() {}
124
125 #[cfg(test)]
126 mod test {
127
128 #[test]
129 fn test_my_implementation() {
130 // Because this module is a descendant of `submodule`, it's allowed
131 // to access private items inside of `submodule` without a privacy
132 // violation.
133 super::my_implementation();
134 }
135 }
136 }
137
138 # fn main() {}
139 ```
140
141 For a Rust program to pass the privacy checking pass, all paths must be valid
142 accesses given the two rules above. This includes all use statements,
143 expressions, types, etc.
144
145 ## `pub(in path)`, `pub(crate)`, `pub(super)`, and `pub(self)`
146
147 In addition to public and private, Rust allows users to declare an item as
148 visible only within a given scope. The rules for `pub` restrictions are as
149 follows:
150 - `pub(in path)` makes an item visible within the provided `path`. `path` must
151 be an ancestor module of the item whose visibility is being declared.
152 - `pub(crate)` makes an item visible within the current crate.
153 - `pub(super)` makes an item visible to the parent module. This is equivalent
154 to `pub(in super)`.
155 - `pub(self)` makes an item visible to the current module. This is equivalent
156 to `pub(in self)` or not using `pub` at all.
157
158 > **Edition Differences**: Starting with the 2018 edition, paths for
159 > `pub(in path)` must start with `crate`, `self`, or `super`. The 2015 edition
160 > may also use paths starting with `::` or modules from the crate root.
161
162 Here's an example:
163
164 ```rust,edition2015
165 pub mod outer_mod {
166 pub mod inner_mod {
167 // This function is visible within `outer_mod`
168 pub(in crate::outer_mod) fn outer_mod_visible_fn() {}
169 // Same as above, this is only valid in the 2015 edition.
170 pub(in outer_mod) fn outer_mod_visible_fn_2015() {}
171
172 // This function is visible to the entire crate
173 pub(crate) fn crate_visible_fn() {}
174
175 // This function is visible within `outer_mod`
176 pub(super) fn super_mod_visible_fn() {
177 // This function is visible since we're in the same `mod`
178 inner_mod_visible_fn();
179 }
180
181 // This function is visible only within `inner_mod`,
182 // which is the same as leaving it private.
183 pub(self) fn inner_mod_visible_fn() {}
184 }
185 pub fn foo() {
186 inner_mod::outer_mod_visible_fn();
187 inner_mod::crate_visible_fn();
188 inner_mod::super_mod_visible_fn();
189
190 // This function is no longer visible since we're outside of `inner_mod`
191 // Error! `inner_mod_visible_fn` is private
192 //inner_mod::inner_mod_visible_fn();
193 }
194 }
195
196 fn bar() {
197 // This function is still visible since we're in the same crate
198 outer_mod::inner_mod::crate_visible_fn();
199
200 // This function is no longer visible since we're outside of `outer_mod`
201 // Error! `super_mod_visible_fn` is private
202 //outer_mod::inner_mod::super_mod_visible_fn();
203
204 // This function is no longer visible since we're outside of `outer_mod`
205 // Error! `outer_mod_visible_fn` is private
206 //outer_mod::inner_mod::outer_mod_visible_fn();
207
208 outer_mod::foo();
209 }
210
211 fn main() { bar() }
212 ```
213
214 > **Note:** This syntax only adds another restriction to the visibility of an
215 > item. It does not guarantee that the item is visible within all parts of the
216 > specified scope. To access an item, all of its parent items up to the
217 > current scope must still be visible as well.
218
219 ## Re-exporting and Visibility
220
221 Rust allows publicly re-exporting items through a `pub use` directive. Because
222 this is a public directive, this allows the item to be used in the current
223 module through the rules above. It essentially allows public access into the
224 re-exported item. For example, this program is valid:
225
226 ```rust
227 pub use self::implementation::api;
228
229 mod implementation {
230 pub mod api {
231 pub fn f() {}
232 }
233 }
234
235 # fn main() {}
236 ```
237
238 This means that any external crate referencing `implementation::api::f` would
239 receive a privacy violation, while the path `api::f` would be allowed.
240
241 When re-exporting a private item, it can be thought of as allowing the "privacy
242 chain" being short-circuited through the reexport instead of passing through
243 the namespace hierarchy as it normally would.
244
245 [_SimplePath_]: paths.md#simple-paths