Skip to content

Commit a2576a1

Browse files
committed
Update for uniform_path stabilization.
1 parent 94ae04d commit a2576a1

File tree

2 files changed

+37
-110
lines changed

2 files changed

+37
-110
lines changed

src/rust-2018/edition-changes.md

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,8 @@ the 2018 edition compared to the 2015 edition.
77
- [Non-lexical lifetimes] (future inclusion planned for 2015 edition)
88
- [At most once] `?` macro repetition operator.
99
- [Path changes]:
10-
- `use` declarations must begin with:
11-
- `crate` – refers to the current crate.
12-
- `self` – refers to the current module.
13-
- `super` – refers to the parent module.
14-
- An external crate name.
15-
- `::` – must be followed by an external crate name. This is required
16-
if an external crate has the same name as an in-scope item, to catch
17-
possible ambiguities with [uniform paths] (which is planned for
18-
inclusion soon [#55618]).
10+
- [Uniform paths] in `use` declarations.
11+
- Paths staring with `::` must be followed with an external crate.
1912
- Paths in `pub(in path)` visibility modifiers must start with `crate`,
2013
`self`, or `super`.
2114
- [Anonymous trait function parameters] are not allowed.
@@ -35,7 +28,6 @@ the 2018 edition compared to the 2015 edition.
3528
- `cargo install` for the current directory is no longer allowed, you must
3629
specify `cargo install --path .` to install the current package.
3730

38-
[#55618]: https://github.com/rust-lang/rust/issues/55618
3931
[Anonymous trait function parameters]: rust-2018/trait-system/no-anon-params.html
4032
[At most once]: rust-2018/macros/at-most-once.html
4133
[Non-lexical lifetimes]: rust-2018/ownership-and-lifetimes/non-lexical-lifetimes.html

src/rust-2018/module-system/path-clarity.md

Lines changed: 35 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
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

65
The module system is often one of the hardest things for people new to Rust. Everyone
76
has 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

2525
These may seem like arbitrary new rules when put this way, but the mental
2626
model 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

3430
Let's talk about each new feature in turn.
@@ -124,122 +120,61 @@ The prefix `::` previously referred to either the crate root or an external
124120
crate; 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
186138
mod 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
213160
mod 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

238173
In 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
245180
mod 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
258193
mod 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

273208
The uniform paths variant of Rust 2018 simplifies and unifies path handling
274209
compared to Rust 2015. In Rust 2015, paths work differently in `use`
275210
declarations than they do elsewhere. In particular, paths in `use`
276211
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
212+
implicitly started from the current scope. Those differences didn't have any
278213
effect in the top-level module, which meant that everything would seem
279214
straightforward until working on a project large enough to have submodules.
280215

281216
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`.
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

287222
Code that looked like this:
288223

0 commit comments

Comments
 (0)