]> git.proxmox.com Git - rustc.git/blob - src/doc/edition-guide/src/rust-2018/module-system/path-clarity.md
New upstream version 1.52.0~beta.3+dfsg1
[rustc.git] / src / doc / edition-guide / src / rust-2018 / module-system / path-clarity.md
1 # Path clarity
2
3 ![Minimum Rust version: 1.31](https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg)
4
5 The module system is often one of the hardest things for people new to Rust. Everyone
6 has their own things that take time to master, of course, but there's a root
7 cause for why it's so confusing to many: while there are simple and
8 consistent rules defining the module system, their consequences can feel
9 inconsistent, counterintuitive and mysterious.
10
11 As such, the 2018 edition of Rust introduces a few new module system
12 features, but they end up *simplifying* the module system, to make it more
13 clear as to what is going on.
14
15 Here's a brief summary:
16
17 * `extern crate` is no longer needed in 99% of circumstances.
18 * The `crate` keyword refers to the current crate.
19 * Paths may start with a crate name, even within submodules.
20 * Paths starting with `::` must reference an external crate.
21 * A `foo.rs` and `foo/` subdirectory may coexist; `mod.rs` is no longer needed
22 when placing submodules in a subdirectory.
23 * Paths in `use` declarations work the same as other paths.
24
25 These may seem like arbitrary new rules when put this way, but the mental
26 model is now significantly simplified overall. Read on for more details!
27
28 ## More details
29
30 Let's talk about each new feature in turn.
31
32 ### No more `extern crate`
33
34 This one is quite straightforward: you no longer need to write `extern crate` to
35 import a crate into your project. Before:
36
37 ```rust,ignore
38 // Rust 2015
39
40 extern crate futures;
41
42 mod submodule {
43 use futures::Future;
44 }
45 ```
46
47 After:
48
49 ```rust,ignore
50 // Rust 2018
51
52 mod submodule {
53 use futures::Future;
54 }
55 ```
56
57 Now, to add a new crate to your project, you can add it to your `Cargo.toml`,
58 and then there is no step two. If you're not using Cargo, you already had to pass
59 `--extern` flags to give `rustc` the location of external crates, so you'd just
60 keep doing what you were doing there as well.
61
62 > One small note here: `cargo fix` will not currently automate this change. We may
63 > have it do this for you in the future.
64
65 #### An exception
66
67 There's one exception to this rule, and that's the "sysroot" crates. These are the
68 crates distributed with Rust itself.
69
70 Usually these are only needed in very specialized situations. Starting in
71 1.41, `rustc` accepts the `--extern=CRATE_NAME` flag which automatically adds
72 the given crate name in a way similar to `extern crate`. Build tools may use
73 this to inject sysroot crates into the crate's prelude. Cargo does not have a
74 general way to express this, though it uses it for `proc_macro` crates.
75
76 Some examples of needing to explicitly import sysroot crates are:
77
78 * [`std`]: Usually this is not neccesary, because `std` is automatically
79 imported unless the crate is marked with [`#![no_std]`][no_std].
80 * [`core`]: Usually this is not necessary, because `core` is automatically
81 imported, unless the crate is marked with [`#![no_core]`][no_core]. For
82 example, some of the internal crates used by the standard library itself
83 need this.
84 * [`proc_macro`]: This is automatically imported by Cargo if it is a
85 proc-macro crate starting in 1.42. `extern crate proc_macro;` would be
86 needed if you want to support older releases, or if using another build tool
87 that does not pass the appropriate `--extern` flags to `rustc`.
88 * [`alloc`]: Items in the `alloc` crate are usually accessed via re-exports in
89 the `std` crate. If you are working with a `no_std` crate that supports
90 allocation, then you may need to explicitly import `alloc`.
91 * [`test`]: This is only available on the [nightly channel], and is usually
92 only used for the unstable benchmark support.
93
94 [`alloc`]: ../../../alloc/index.html
95 [`core`]: ../../../core/index.html
96 [`proc_macro`]: ../../../proc_macro/index.html
97 [`std`]: ../../../std/index.html
98 [`test`]: ../../../test/index.html
99 [nightly channel]: ../../../book/appendix-07-nightly-rust.html
100 [no_core]: https://github.com/rust-lang/rust/issues/29639
101 [no_std]: ../../../reference/names/preludes.html#the-no_std-attribute
102
103 #### Macros
104
105 One other use for `extern crate` was to import macros; that's no longer needed.
106 Check [the macro section](../macros/macro-changes.md) for more.
107
108 #### Renaming crates
109
110 If you've been using `as` to rename your crate like this:
111
112 ```rust,ignore
113 extern crate futures as f;
114
115 use f::Future;
116 ```
117
118 then removing the `extern crate` line on its own won't work. You'll need to do this:
119
120 ```rust,ignore
121 use futures as f;
122
123 use self::f::Future;
124 ```
125
126 This change will need to happen in any module that uses `f`.
127
128 ### The `crate` keyword refers to the current crate
129
130 In `use` declarations and in other code, you can refer to the root of the
131 current crate with the `crate::` prefix. For instance, `crate::foo::bar` will
132 always refer to the name `bar` inside the module `foo`, from anywhere else in
133 the same crate.
134
135 The prefix `::` previously referred to either the crate root or an external
136 crate; it now unambiguously refers to an external crate. For instance,
137 `::foo::bar` always refers to the name `bar` inside the external crate `foo`.
138
139 ### Extern crate paths
140
141 Previously, using an external crate in a module without a `use` import
142 required a leading `::` on the path.
143
144 ```rust,ignore
145 // Rust 2015
146
147 extern crate chrono;
148
149 fn foo() {
150 // this works in the crate root
151 let x = chrono::Utc::now();
152 }
153
154 mod submodule {
155 fn function() {
156 // but in a submodule it requires a leading :: if not imported with `use`
157 let x = ::chrono::Utc::now();
158 }
159 }
160 ```
161
162 Now, extern crate names are in scope in the entire crate, including
163 submodules.
164
165 ```rust,ignore
166 // Rust 2018
167
168 fn foo() {
169 // this works in the crate root
170 let x = chrono::Utc::now();
171 }
172
173 mod submodule {
174 fn function() {
175 // crates may be referenced directly, even in submodules
176 let x = chrono::Utc::now();
177 }
178 }
179 ```
180
181 ### No more `mod.rs`
182
183 In Rust 2015, if you have a submodule:
184
185 ```rust,ignore
186 // This `mod` declaration looks for the `foo` module in
187 // `foo.rs` or `foo/mod.rs`.
188 mod foo;
189 ```
190
191 It can live in `foo.rs` or `foo/mod.rs`. If it has submodules of its own, it
192 *must* be `foo/mod.rs`. So a `bar` submodule of `foo` would live at
193 `foo/bar.rs`.
194
195 In Rust 2018 the restriction that a module with submodules must be named
196 `mod.rs` is lifted. `foo.rs` can just be `foo.rs`,
197 and the submodule is still `foo/bar.rs`. This eliminates the special
198 name, and if you have a bunch of files open in your editor, you can clearly
199 see their names, instead of having a bunch of tabs named `mod.rs`.
200
201 <table>
202 <thead>
203 <tr>
204 <th>Rust 2015</th>
205 <th>Rust 2018</th>
206 </tr>
207 </thead>
208 <tbody>
209 <tr>
210 <td>
211 <pre>
212 .
213 ├── lib.rs
214 └── foo/
215    ├── mod.rs
216    └── bar.rs
217 </pre>
218 </td>
219 <td>
220 <pre>
221 .
222 ├── lib.rs
223 ├── foo.rs
224 └── foo/
225    └── bar.rs
226 </pre>
227 </td>
228 </tr>
229 </tbody>
230 </table>
231
232 ### `use` paths
233
234 ![Minimum Rust version: 1.32](https://img.shields.io/badge/Minimum%20Rust%20Version-1.32-brightgreen.svg)
235
236 Rust 2018 simplifies and unifies path handling compared to Rust 2015. In Rust
237 2015, paths work differently in `use` declarations than they do elsewhere. In
238 particular, paths in `use` declarations would always start from the crate
239 root, while paths in other code implicitly started from the current scope.
240 Those differences didn't have any effect in the top-level module, which meant
241 that everything would seem straightforward until working on a project large
242 enough to have submodules.
243
244 In Rust 2018, paths in `use` declarations and in other code work the same way,
245 both in the top-level module and in any submodule. You can use a relative path
246 from the current scope, a path starting from an external crate name, or a path
247 starting with `crate`, `super`, or `self`.
248
249 Code that looked like this:
250
251 ```rust,ignore
252 // Rust 2015
253
254 extern crate futures;
255
256 use futures::Future;
257
258 mod foo {
259 pub struct Bar;
260 }
261
262 use foo::Bar;
263
264 fn my_poll() -> futures::Poll { ... }
265
266 enum SomeEnum {
267 V1(usize),
268 V2(String),
269 }
270
271 fn func() {
272 let five = std::sync::Arc::new(5);
273 use SomeEnum::*;
274 match ... {
275 V1(i) => { ... }
276 V2(s) => { ... }
277 }
278 }
279 ```
280
281 will look exactly the same in Rust 2018, except that you can delete the `extern
282 crate` line:
283
284 ```rust,ignore
285 // Rust 2018
286
287 use futures::Future;
288
289 mod foo {
290 pub struct Bar;
291 }
292
293 use foo::Bar;
294
295 fn my_poll() -> futures::Poll { ... }
296
297 enum SomeEnum {
298 V1(usize),
299 V2(String),
300 }
301
302 fn func() {
303 let five = std::sync::Arc::new(5);
304 use SomeEnum::*;
305 match ... {
306 V1(i) => { ... }
307 V2(s) => { ... }
308 }
309 }
310 ```
311
312 The same code will also work completely unmodified in a submodule:
313
314 ```rust,ignore
315 // Rust 2018
316
317 mod submodule {
318 use futures::Future;
319
320 mod foo {
321 pub struct Bar;
322 }
323
324 use foo::Bar;
325
326 fn my_poll() -> futures::Poll { ... }
327
328 enum SomeEnum {
329 V1(usize),
330 V2(String),
331 }
332
333 fn func() {
334 let five = std::sync::Arc::new(5);
335 use SomeEnum::*;
336 match ... {
337 V1(i) => { ... }
338 V2(s) => { ... }
339 }
340 }
341 }
342 ```
343
344 This makes it easy to move code around in a project, and avoids introducing
345 additional complexity to multi-module projects.
346
347 If a path is ambiguous, such as if you have an external crate and a local
348 module or item with the same name, you'll get an error, and you'll need to
349 either rename one of the conflicting names or explicitly disambiguate the path.
350 To explicitly disambiguate a path, use `::name` for an external crate name, or
351 `self::name` for a local module or item.