11# Path clarity
22
33![ Minimum Rust version: 1.31] ( https://img.shields.io/badge/Minimum%20Rust%20Version-1.31-brightgreen.svg )
4- ![ Minimum Rust version: nightly] ( https://img.shields.io/badge/Minimum%20Rust%20Version-nightly-red.svg ) for "uniform paths"
54
65The module system is often one of the hardest things for people new to Rust. Everyone
76has their own things that take time to master, of course, but there's a root
@@ -17,18 +16,15 @@ Here's a brief summary:
1716
1817* ` extern crate ` is no longer needed in 99% of circumstances.
1918* The ` crate ` keyword refers to the current crate.
20- * Absolute paths begin with a crate name, where the keyword ` crate `
21- 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.
2221* A ` foo.rs ` and ` foo/ ` subdirectory may coexist; ` mod.rs ` is no longer needed
2322 when placing submodules in a subdirectory.
23+ * Paths in ` use ` declarations work the same as other paths.
2424
2525These may seem like arbitrary new rules when put this way, but the mental
2626model is now significantly simplified overall. Read on for more details!
2727
28- > Additionally, in nightly, there's an additional possible tweak to paths
29- > called "Uniform paths". This is backwards compatible with the new path
30- > changes. Uniform paths have a dedicated section at the end of this guide.
31-
3228## More details
3329
3430Let's talk about each new feature in turn.
@@ -124,122 +120,55 @@ The prefix `::` previously referred to either the crate root or an external
124120crate; it now unambiguously refers to an external crate. For instance,
125121` ::foo::bar ` always refers to the name ` bar ` inside the external crate ` foo ` .
126122
127- ### Changes to paths
128-
129- In Rust 2018, paths in ` use ` declarations * must* begin with a crate name,
130- ` crate ` , ` self ` , or ` super ` .
123+ ### Extern crate paths
131124
132- Code that looked like this:
125+ Previously, using an external crate in a module without a ` use ` import
126+ required a leading ` :: ` on the path.
133127
134128``` rust,ignore
135129// Rust 2015
136130
137- extern crate futures ;
131+ extern crate chrono ;
138132
139- use futures::Future;
140-
141- mod foo {
142- pub struct Bar;
143- }
144-
145- use foo::Bar;
146- ```
147-
148- Now looks like this:
149-
150- ``` rust,ignore
151- // Rust 2018
152-
153- // 'futures' is the name of a crate
154- use futures::Future;
155-
156- mod foo {
157- pub struct Bar;
158- }
159-
160- // 'crate' means the current crate
161- use crate::foo::Bar;
162- ```
163-
164- In addition, all of these path forms are available outside of ` use `
165- declarations as well, which eliminates many sources of confusion. Consider
166- this code in Rust 2015:
167-
168- ``` rust,ignore
169- // Rust 2015
170-
171- extern crate futures;
172-
173- mod submodule {
174- // this works!
175- use futures::Future;
176-
177- // so why doesn't this work?
178- fn my_poll() -> futures::Poll { ... }
179- }
180-
181- fn main() {
182- // this works
183- let five = std::sync::Arc::new(5);
133+ fn foo() {
134+ // this works in the crate root
135+ let x = chrono::Utc::now();
184136}
185137
186138mod submodule {
187139 fn function() {
188- // ... so why doesn't this work
189- let five = std::sync::Arc::new(5 );
140+ // but in a submodule it requires a leading :: if not imported with `use`
141+ let x = ::chrono::Utc::now( );
190142 }
191143}
192144```
193145
194- > In real code, you couldn't repeat ` mod submodule ` , and ` function ` would be defined
195- > in the first ` mod ` block.
196-
197- In the ` futures ` example, the ` my_poll ` function signature is incorrect,
198- because ` submodule ` contains no items named ` futures ` ; that is, this path is
199- considered relative. ` use futures:: ` works even though a lone ` futures:: `
200- doesn't! With ` std ` it can be even more confusing, as you never wrote the
201- ` extern crate std; ` line at all. So why does it work in ` main ` but not in a
202- submodule? Same thing: it's a relative path because it's not in a ` use `
203- declaration. ` extern crate std; ` is inserted at the crate root, so it's fine
204- in ` main ` , but it doesn't exist in the submodule at all.
205-
206- Let's look at how this change affects things:
146+ Now, extern crate names are in scope in the entire crate, including
147+ submodules.
207148
208149``` rust,ignore
209150// Rust 2018
210151
211- // no more `extern crate futures;`
152+ fn foo() {
153+ // this works in the crate root
154+ let x = chrono::Utc::now();
155+ }
212156
213157mod submodule {
214- // 'futures' is the name of a crate, so this works
215- use futures::Future;
216-
217- // 'futures' is the name of a crate, so this works
218- fn my_poll<T, E>() -> futures::Poll {
219- unimplemented!()
220- }
221-
222158 fn function() {
223- // 'std' is the name of a crate, so this works
224- let five = std::sync::Arc::new(5 );
159+ // crates may be referenced directly, even in submodules
160+ let x = chrono::Utc::now( );
225161 }
226162}
227-
228- fn main() {
229- // 'std' is the name of a crate, so this works
230- let five = std::sync::Arc::new(5);
231- }
232163```
233164
234- Much more straightforward.
235-
236165### No more ` mod.rs `
237166
238167In Rust 2015, if you have a submodule:
239168
240169``` rust,ignore
241- /// foo.rs
242- /// or
170+ /// foo.rs
171+ /// or
243172/// foo/mod.rs
244173
245174mod foo;
@@ -249,10 +178,10 @@ It can live in `foo.rs` or `foo/mod.rs`. If it has submodules of its own, it
249178* must* be ` foo/mod.rs ` . So a ` bar ` submodule of ` foo ` would live at
250179` foo/bar.rs ` .
251180
252- In Rust 2018, ` mod.rs ` is no longer needed.
181+ In Rust 2018, ` mod.rs ` is no longer needed.
253182
254183``` rust,ignore
255- /// foo.rs
184+ /// foo.rs
256185/// foo/bar.rs
257186
258187mod foo;
@@ -266,23 +195,22 @@ and the submodule is still `foo/bar.rs`. This eliminates the special
266195name, and if you have a bunch of files open in your editor, you can clearly
267196see their names, instead of having a bunch of tabs named ` mod.rs ` .
268197
269- # Uniform paths
198+ ### ` use ` paths
270199
271- > Uniform paths are a nightly-only feature.
200+ ![ Minimum Rust version: 1.32 ] ( https://img.shields.io/badge/Minimum%20Rust%20Version-1.32-brightgreen.svg )
272201
273- The uniform paths variant of Rust 2018 simplifies and unifies path handling
274- compared to Rust 2015. In Rust 2015 , paths work differently in ` use `
275- declarations than they do elsewhere. In particular, paths in ` use `
276- declarations would always start from the crate root, while paths in other code
277- implicitly started from the current module. Those differences didn't have any
278- effect in the top-level module, which meant that everything would seem
279- straightforward until working on a project large enough to have submodules.
202+ Rust 2018 simplifies and unifies path handling compared to Rust 2015. In Rust
203+ 2015, paths work differently in ` use ` declarations than they do elsewhere. In
204+ particular, paths in ` use ` declarations would always start from the crate
205+ root, while paths in other code implicitly started from the current scope.
206+ Those differences didn't have any effect in the top-level module, which meant
207+ that everything would seem straightforward until working on a project large
208+ enough to have submodules.
280209
281- In the uniform paths variant of Rust 2018, paths in ` use ` declarations and in
282- other code always work the same way, both in the top-level module and in any
283- submodule. You can always use a relative path from the current module, a path
284- starting from an external crate name, or a path starting with ` crate ` , ` super ` ,
285- or ` self ` .
210+ In Rust 2018, paths in ` use ` declarations and in other code work the same way,
211+ both in the top-level module and in any submodule. You can use a relative path
212+ from the current scope, a path starting from an external crate name, or a path
213+ starting with ` crate ` , ` super ` , or ` self ` .
286214
287215Code that looked like this:
288216
@@ -320,7 +248,7 @@ will look exactly the same in Rust 2018, except that you can delete the `extern
320248crate` line:
321249
322250``` rust,ignore
323- // Rust 2018 (uniform paths variant)
251+ // Rust 2018
324252
325253use futures::Future;
326254
@@ -347,11 +275,10 @@ fn func() {
347275}
348276```
349277
350- With uniform paths, however, the same code will also work completely unmodified in
351- a submodule:
278+ The same code will also work completely unmodified in a submodule:
352279
353280``` rust,ignore
354- // Rust 2018 (uniform paths variant)
281+ // Rust 2018
355282
356283mod submodule {
357284 use futures::Future;
0 commit comments