Skip to content

Commit f3a841f

Browse files
committed
path-clarity: Document new relative paths variant
For the final Rust 2018 release, we can delete the section that doesn't apply, and change the various qualified references like "the relative paths variant of Rust 2018" to just "Rust 2018".
1 parent 64123a1 commit f3a841f

File tree

1 file changed

+151
-7
lines changed

1 file changed

+151
-7
lines changed

src/rust-2018/path-clarity.md

+151-7
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,23 @@ As such, the 2018 edition of Rust introduces a few new module system
1212
features, but they end up *simplifying* the module system, to make it more
1313
clear as to what is going on.
1414

15+
Note: During the 2018 edition preview, there are two variants of the module
16+
system under consideration, the "absolute use paths" variant and the "relative
17+
paths" variant. Most of these changes apply to both variants; the two variant
18+
sections call out the differences between the two. We encourage testing of the
19+
new "relative paths" variant introduced in edition preview 2. The release of
20+
the 2018 edition will use one of these two variants.
21+
1522
Here's a brief summary:
1623

1724
* `extern crate` is no longer needed
18-
* Absolute paths begin with a crate name, where the keyword `crate`
19-
refers to the current crate.
25+
* The `crate` keyword refers to the current crate.
26+
* Relative paths variant: Paths work uniformly in both `use` statements and in
27+
other code, both in the top-level module and in submodules, and may use
28+
either absolute paths or local names relative to the current module.
29+
* Absolute use paths variant: Paths in `use` statements are always absolute and
30+
begin with a crate name (or `crate`); paths in other code may use absolute
31+
paths or local names relative to the current module.
2032
* A `foo.rs` and `foo/` subdirectory may coexist; `mod.rs` is no longer needed
2133
when placing submodules in a subdirectory.
2234

@@ -60,9 +72,142 @@ keep doing what you were doing there as well.
6072
One other use for `extern crate` was to import macros; that's no longer needed.
6173
Check [the macro section](2018/transitioning/modules/macros.html) for more.
6274

63-
### Absolute paths begin with `crate` or the crate name
75+
### The `crate` keyword refers to the current crate.
76+
77+
In `use` statements and in other code, you can refer to the root of the current
78+
crate with the `crate::` prefix. For instance, `crate::foo::bar` will always
79+
refer to the name `bar` inside the module `foo`, from anywhere else in the same
80+
crate.
81+
82+
The prefix `::` previously referred to either the crate root or an external
83+
crate; it now unambiguously refers to an external crate. For instance,
84+
`::foo::bar` always refers to the name `bar` inside the external crate `foo`.
85+
86+
### Relative paths variant
87+
88+
The relative paths variant of Rust 2018 simplifies and unifies path handling
89+
compared to Rust 2015. In Rust 2015, paths work differently in use statements
90+
than they do elsewhere. In particular, paths in `use` statements would always
91+
start from the crate root, while paths in other code implicitly started from
92+
the current module. Those differences didn't have any effect in the top-level
93+
module, which meant that everything would seem straightforward until working on
94+
a project large enough to have submodules.
95+
96+
In the relative paths variant of Rust 2018, paths in `use` statements and in
97+
other code always work the same way, both in the top-level module and in any
98+
submodule. You can either use a relative path from the current module, an
99+
absolute path from the top of the current crate (starting with `crate::`), or
100+
an absolute path starting from an external crate name.
101+
102+
Code that looked like this:
103+
104+
```rust,ignore
105+
// Rust 2015
106+
107+
extern crate futures;
108+
109+
use futures::Future;
110+
111+
mod foo {
112+
struct Bar;
113+
}
114+
115+
use foo::Bar;
116+
117+
fn my_poll() -> futures::Poll { ... }
118+
119+
enum SomeEnum {
120+
V1(usize),
121+
V2(String),
122+
}
123+
124+
fn func() {
125+
let five = std::sync::Arc::new(5);
126+
use SomeEnum::*;
127+
match ... {
128+
V1(i) => { ... }
129+
V2(s) => { ... }
130+
}
131+
}
132+
```
133+
134+
will look exactly the same in Rust 2018, except that you can delete the `extern
135+
crate` line:
64136

65-
In Rust 2018, paths in `use` statements *must* begin with one of:
137+
```rust,ignore
138+
// Rust 2018 (relative paths variant)
139+
140+
use futures::Future;
141+
142+
mod foo {
143+
struct Bar;
144+
}
145+
146+
use foo::Bar;
147+
148+
fn my_poll() -> futures::Poll { ... }
149+
150+
enum SomeEnum {
151+
V1(usize),
152+
V2(String),
153+
}
154+
155+
fn func() {
156+
let five = std::sync::Arc::new(5);
157+
use SomeEnum::*;
158+
match ... {
159+
V1(i) => { ... }
160+
V2(s) => { ... }
161+
}
162+
}
163+
```
164+
165+
With Rust 2018, however, the same code will also work completely unmodified in
166+
a submodule:
167+
168+
```rust,ignore
169+
// Rust 2018 (relative paths variant)
170+
171+
mod submodule {
172+
use futures::Future;
173+
174+
mod foo {
175+
struct Bar;
176+
}
177+
178+
use foo::Bar;
179+
180+
fn my_poll() -> futures::Poll { ... }
181+
182+
enum SomeEnum {
183+
V1(usize),
184+
V2(String),
185+
}
186+
187+
fn func() {
188+
let five = std::sync::Arc::new(5);
189+
use SomeEnum::*;
190+
match ... {
191+
V1(i) => { ... }
192+
V2(s) => { ... }
193+
}
194+
}
195+
}
196+
```
197+
198+
This makes it easy to move code around in a project, and avoids introducing
199+
additional complexity to multi-module projects.
200+
201+
If a path is ambiguous, such as if you have an external crate and a local
202+
module or item with the same name, you'll get an error, and you'll need to
203+
either rename one of the conflicting names or explicitly disambiguate the path.
204+
To explicitly disambiguate a path, use `::name` for an external crate name, or
205+
`self::name` for a local module or item.
206+
207+
### Absolute use paths variant
208+
209+
In the absolute use paths variant of Rust 2018, paths in `use` statements
210+
*must* begin with one of:
66211

67212
- A crate name
68213
- `crate` for the current crate's root
@@ -88,7 +233,7 @@ use foo::Bar;
88233
Now looks like this:
89234

90235
```rust,ignore
91-
// Rust 2018
236+
// Rust 2018 (absolute use paths variant)
92237
93238
// 'futures' is the name of a crate
94239
use futures::Future;
@@ -142,7 +287,7 @@ it's fine in `main`, but it doesn't exist in the submodule at all.
142287
Let's look at how this change affects things:
143288

144289
```rust,ignore
145-
// Rust 2018
290+
// Rust 2018 (absolute use paths variant)
146291
147292
// no more `extern crate futures;`
148293
@@ -169,7 +314,6 @@ mod submodule {
169314

170315
Much more straightforward.
171316

172-
**Note**: an alternative syntax is also under consideration: writing `::some::Local` rather than `crate::some::Local`. If you have thoughts about this alternative, please leave a comment on [the tracking issue](https://github.com/rust-lang/rust/issues/44660) or start a thread on the [edition feedback category](https://internals.rust-lang.org/c/edition-2018-feedback).
173317

174318
### No more `mod.rs`
175319

0 commit comments

Comments
 (0)