You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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".
Copy file name to clipboardExpand all lines: src/2018/transitioning/modules/path-clarity.md
+121-8
Original file line number
Diff line number
Diff line change
@@ -10,11 +10,23 @@ As such, the 2018 edition of Rust introduces a few new module system
10
10
features, but they end up *simplifying* the module system, to make it more
11
11
clear as to what is going on.
12
12
13
+
Note: During the 2018 edition preview, there are two variants of the module
14
+
system under consideration, the "absolute use paths" variant and the "relative
15
+
paths" variant. Most of these changes apply to both variants; the two variant
16
+
sections call out the differences between the two. We would encourage testing
17
+
of the new "relative paths" variant introduced in edition preview 2. The
18
+
release of the 2018 edition will use one of these two variants.
19
+
13
20
Here's a brief summary:
14
21
15
22
*`extern crate` is no longer needed
16
-
* Absolute paths begin with a crate name, where the keyword `crate`
17
-
refers to the current crate.
23
+
* The `crate` keyword refers to the current crate.
24
+
* Relative paths variant: Paths work uniformly in both `use` statements and in
25
+
other code, both in the top-level module and in submodules, and may use
26
+
either absolute paths or local names relative to the current module.
27
+
* Absolute use paths variant: Paths in `use` statements are always absolute and
28
+
begin with a crate name (or `crate`); paths in other code may use absolute
29
+
paths or local names relative to the current module.
18
30
* The `crate` keyword also acts as a visibility modifier, equivalent to today's `pub(crate)`.
19
31
* A `foo.rs` and `foo/` subdirectory may coexist; `mod.rs` is no longer needed
20
32
when placing submodules in a subdirectory.
@@ -59,9 +71,112 @@ keep doing what you were doing there as well.
59
71
One other use for `extern crate` was to import macros; that's no longer needed.
60
72
Check [the macro section](2018/transitioning/modules/macros.html) for more.
61
73
62
-
### Absolute paths begin with `crate` or the crate name
74
+
### The `crate` keyword refers to the current crate.
75
+
76
+
In `use` statements and in other code, you can refer to the root of the current
77
+
crate with the `crate::` prefix. For instance, `crate::foo::bar` will always
78
+
refer to the name `bar` inside the module `foo`, from anywhere else in the same
79
+
crate.
80
+
81
+
The prefix `::` previously referred to either the crate root or an external
82
+
crate; it now unambiguously refers to an external crate. For instance,
83
+
`::foo::bar` always refers to the name `bar` inside the external crate `foo`.
84
+
85
+
### Relative paths variant
86
+
87
+
The relative paths variant of Rust 2018 simplifies and unifies path handling
88
+
compared to Rust 2015. In Rust 2015, paths work differently in use statements
89
+
than they do elsewhere. In particular, paths in `use` statements would always
90
+
start from the crate root, while paths in other code implicitly started from
91
+
the current module. Those differences didn't have any effect in the top-level
92
+
module, which meant that everything would seem straightforward until working on
93
+
a project large enough to have submodules.
94
+
95
+
In the relative paths variant of Rust 2018, paths in `use` statements and in
96
+
other code always work the same way, both in the top-level module and in any
97
+
submodule. You can either use a relative path from the current module, an
98
+
absolute path from the top of the current crate (starting with `crate::`), or
99
+
an absolute path starting from an external crate name.
100
+
101
+
Code that looked like this:
102
+
103
+
```rust,ignore
104
+
// Rust 2015
105
+
106
+
extern crate futures;
107
+
108
+
use futures::Future;
109
+
110
+
mod foo {
111
+
struct Bar;
112
+
}
113
+
114
+
use foo::Bar;
115
+
116
+
fn my_poll() -> futures::Poll { ... }
117
+
118
+
fn func() {
119
+
let five = std::sync::Arc::new(5);
120
+
}
121
+
```
122
+
123
+
will look exactly the same in Rust 2018, except that you can delete the `extern
124
+
crate` line:
125
+
126
+
```rust,ignore
127
+
// Rust 2018 (relative paths variant)
128
+
129
+
use futures::Future;
130
+
131
+
mod foo {
132
+
struct Bar;
133
+
}
134
+
135
+
use foo::Bar;
136
+
137
+
fn my_poll() -> futures::Poll { ... }
138
+
139
+
fn func() {
140
+
let five = std::sync::Arc::new(5);
141
+
}
142
+
```
143
+
144
+
With Rust 2018, however, the same code will also work completely unmodified in
145
+
a submodule:
146
+
147
+
```rust,ignore
148
+
// Rust 2018 (relative paths variant)
149
+
150
+
mod submodule {
151
+
use futures::Future;
63
152
64
-
In Rust 2018, paths in `use` statements *must* begin with one of:
153
+
mod foo {
154
+
struct Bar;
155
+
}
156
+
157
+
use foo::Bar;
158
+
159
+
fn my_poll() -> futures::Poll { ... }
160
+
161
+
fn func() {
162
+
let five = std::sync::Arc::new(5);
163
+
}
164
+
}
165
+
```
166
+
167
+
This makes it easy to move code around in a project, and avoids introducing
168
+
additional complexity to multi-module projects.
169
+
170
+
If a path is ambiguous, such as if you have an external crate and a local
171
+
module or item with the same name, you'll get an error, and you'll need to
172
+
either rename one of the conflicting names or explicitly disambiguate the path.
173
+
To explicitly disambiguate a path, use `::name` for an external crate name, or
174
+
`self::name` for a local module or item.
175
+
176
+
### Absolute use paths variant
177
+
178
+
In the absolute use paths variant of Rust 2018, paths in `use` statements
179
+
*must* begin with one of:
65
180
66
181
- A crate name
67
182
-`crate` for the current crate's root
@@ -87,7 +202,7 @@ use foo::Bar;
87
202
Now looks like this:
88
203
89
204
```rust,ignore
90
-
// Rust 2018
205
+
// Rust 2018 (absolute use paths variant)
91
206
92
207
// 'futures' is the name of a crate
93
208
use futures::Future;
@@ -141,7 +256,7 @@ it's fine in `main`, but it doesn't exist in the submodule at all.
141
256
Let's look at how this change affects things:
142
257
143
258
```rust,ignore
144
-
// Rust 2018
259
+
// Rust 2018 (absolute use paths variant)
145
260
146
261
// no more `extern crate futures;`
147
262
@@ -168,8 +283,6 @@ mod submodule {
168
283
169
284
Much more straightforward.
170
285
171
-
**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).
172
-
173
286
### The `crate` visibility modifier
174
287
175
288
In Rust 2015, you can use `pub(crate)` to make something visible
0 commit comments