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+ * ` use ` declarations take [ uniform paths] ( #uniform-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,61 @@ 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;
138-
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
131+ extern crate chrono;
152132
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 }
143+
144+ // unlike expressions, `use` paths were allowed to reference crates directly
145+ use chrono::Local;
191146}
192147```
193148
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:
149+ Now, extern crate names are in scope in the entire crate, including
150+ submodules.
207151
208152``` rust,ignore
209153// Rust 2018
210154
211- // no more `extern crate futures;`
155+ fn foo() {
156+ // this works in the crate root
157+ let x = chrono::Utc::now();
158+ }
212159
213160mod 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-
222161 fn function() {
223- // 'std' is the name of a crate, so this works
224- let five = std::sync::Arc::new(5 );
162+ // crates may be referenced directly, even in submodules
163+ let x = chrono::Utc::now( );
225164 }
226- }
227165
228- fn main() {
229- // 'std' is the name of a crate, so this works
230- let five = std::sync::Arc::new(5);
166+ // `use` paths have the same path style
167+ use chrono::Local;
231168}
232169```
233170
234- Much more straightforward.
235-
236171### No more ` mod.rs `
237172
238173In Rust 2015, if you have a submodule:
239174
240175``` rust,ignore
241- /// foo.rs
242- /// or
176+ /// foo.rs
177+ /// or
243178/// foo/mod.rs
244179
245180mod foo;
@@ -249,10 +184,10 @@ It can live in `foo.rs` or `foo/mod.rs`. If it has submodules of its own, it
249184* must* be ` foo/mod.rs ` . So a ` bar ` submodule of ` foo ` would live at
250185` foo/bar.rs ` .
251186
252- In Rust 2018, ` mod.rs ` is no longer needed.
187+ In Rust 2018, ` mod.rs ` is no longer needed.
253188
254189``` rust,ignore
255- /// foo.rs
190+ /// foo.rs
256191/// foo/bar.rs
257192
258193mod foo;
@@ -268,21 +203,21 @@ see their names, instead of having a bunch of tabs named `mod.rs`.
268203
269204# Uniform paths
270205
271- > Uniform paths are a nightly-only feature.
206+ ![ Minimum Rust version: 1.32 ] ( https://img.shields.io/badge/Minimum%20Rust%20Version-1.32-brightgreen.svg )
272207
273208The uniform paths variant of Rust 2018 simplifies and unifies path handling
274209compared to Rust 2015. In Rust 2015, paths work differently in ` use `
275210declarations than they do elsewhere. In particular, paths in ` use `
276211declarations 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
212+ implicitly started from the current scope . Those differences didn't have any
278213effect in the top-level module, which meant that everything would seem
279214straightforward until working on a project large enough to have submodules.
280215
281216In 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 ` .
217+ other code almost always work the same way, both in the top-level module and
218+ in any submodule. You can use a relative path from the current scope , a path
219+ starting from an external crate name, or a path starting with ` crate ` ,
220+ ` super ` , or ` self ` .
286221
287222Code that looked like this:
288223
0 commit comments