From f3a841f65809c4d35d30a636390b118fa4c5d0fd Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 3 Aug 2018 13:50:26 -0700 Subject: [PATCH 1/5] 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". --- src/rust-2018/path-clarity.md | 158 ++++++++++++++++++++++++++++++++-- 1 file changed, 151 insertions(+), 7 deletions(-) diff --git a/src/rust-2018/path-clarity.md b/src/rust-2018/path-clarity.md index aa0eee26..dd376e28 100644 --- a/src/rust-2018/path-clarity.md +++ b/src/rust-2018/path-clarity.md @@ -12,11 +12,23 @@ As such, the 2018 edition of Rust introduces a few new module system features, but they end up *simplifying* the module system, to make it more clear as to what is going on. +Note: During the 2018 edition preview, there are two variants of the module +system under consideration, the "absolute use paths" variant and the "relative +paths" variant. Most of these changes apply to both variants; the two variant +sections call out the differences between the two. We encourage testing of the +new "relative paths" variant introduced in edition preview 2. The release of +the 2018 edition will use one of these two variants. + Here's a brief summary: * `extern crate` is no longer needed -* Absolute paths begin with a crate name, where the keyword `crate` - refers to the current crate. +* The `crate` keyword refers to the current crate. +* Relative paths variant: Paths work uniformly in both `use` statements and in + other code, both in the top-level module and in submodules, and may use + either absolute paths or local names relative to the current module. +* Absolute use paths variant: Paths in `use` statements are always absolute and + begin with a crate name (or `crate`); paths in other code may use absolute + paths or local names relative to the current module. * A `foo.rs` and `foo/` subdirectory may coexist; `mod.rs` is no longer needed when placing submodules in a subdirectory. @@ -60,9 +72,142 @@ keep doing what you were doing there as well. One other use for `extern crate` was to import macros; that's no longer needed. Check [the macro section](2018/transitioning/modules/macros.html) for more. -### Absolute paths begin with `crate` or the crate name +### The `crate` keyword refers to the current crate. + +In `use` statements and in other code, you can refer to the root of the current +crate with the `crate::` prefix. For instance, `crate::foo::bar` will always +refer to the name `bar` inside the module `foo`, from anywhere else in the same +crate. + +The prefix `::` previously referred to either the crate root or an external +crate; it now unambiguously refers to an external crate. For instance, +`::foo::bar` always refers to the name `bar` inside the external crate `foo`. + +### Relative paths variant + +The relative paths variant of Rust 2018 simplifies and unifies path handling +compared to Rust 2015. In Rust 2015, paths work differently in use statements +than they do elsewhere. In particular, paths in `use` statements would always +start from the crate root, while paths in other code implicitly started from +the current module. Those differences didn't have any effect in the top-level +module, which meant that everything would seem straightforward until working on +a project large enough to have submodules. + +In the relative paths variant of Rust 2018, paths in `use` statements and in +other code always work the same way, both in the top-level module and in any +submodule. You can either use a relative path from the current module, an +absolute path from the top of the current crate (starting with `crate::`), or +an absolute path starting from an external crate name. + +Code that looked like this: + +```rust,ignore +// Rust 2015 + +extern crate futures; + +use futures::Future; + +mod foo { + struct Bar; +} + +use foo::Bar; + +fn my_poll() -> futures::Poll { ... } + +enum SomeEnum { + V1(usize), + V2(String), +} + +fn func() { + let five = std::sync::Arc::new(5); + use SomeEnum::*; + match ... { + V1(i) => { ... } + V2(s) => { ... } + } +} +``` + +will look exactly the same in Rust 2018, except that you can delete the `extern +crate` line: -In Rust 2018, paths in `use` statements *must* begin with one of: +```rust,ignore +// Rust 2018 (relative paths variant) + +use futures::Future; + +mod foo { + struct Bar; +} + +use foo::Bar; + +fn my_poll() -> futures::Poll { ... } + +enum SomeEnum { + V1(usize), + V2(String), +} + +fn func() { + let five = std::sync::Arc::new(5); + use SomeEnum::*; + match ... { + V1(i) => { ... } + V2(s) => { ... } + } +} +``` + +With Rust 2018, however, the same code will also work completely unmodified in +a submodule: + +```rust,ignore +// Rust 2018 (relative paths variant) + +mod submodule { + use futures::Future; + + mod foo { + struct Bar; + } + + use foo::Bar; + + fn my_poll() -> futures::Poll { ... } + + enum SomeEnum { + V1(usize), + V2(String), + } + + fn func() { + let five = std::sync::Arc::new(5); + use SomeEnum::*; + match ... { + V1(i) => { ... } + V2(s) => { ... } + } + } +} +``` + +This makes it easy to move code around in a project, and avoids introducing +additional complexity to multi-module projects. + +If a path is ambiguous, such as if you have an external crate and a local +module or item with the same name, you'll get an error, and you'll need to +either rename one of the conflicting names or explicitly disambiguate the path. +To explicitly disambiguate a path, use `::name` for an external crate name, or +`self::name` for a local module or item. + +### Absolute use paths variant + +In the absolute use paths variant of Rust 2018, paths in `use` statements +*must* begin with one of: - A crate name - `crate` for the current crate's root @@ -88,7 +233,7 @@ use foo::Bar; Now looks like this: ```rust,ignore -// Rust 2018 +// Rust 2018 (absolute use paths variant) // 'futures' is the name of a crate use futures::Future; @@ -142,7 +287,7 @@ it's fine in `main`, but it doesn't exist in the submodule at all. Let's look at how this change affects things: ```rust,ignore -// Rust 2018 +// Rust 2018 (absolute use paths variant) // no more `extern crate futures;` @@ -169,7 +314,6 @@ mod submodule { Much more straightforward. -**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). ### No more `mod.rs` From f5b56499baf0264a1f0df371dd2de2a6ae8f3aa5 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 3 Aug 2018 14:54:38 -0700 Subject: [PATCH 2/5] path-clarity: Change "`use` statements" to "`use` declarations" --- src/rust-2018/path-clarity.md | 42 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/rust-2018/path-clarity.md b/src/rust-2018/path-clarity.md index dd376e28..3bdc3c8e 100644 --- a/src/rust-2018/path-clarity.md +++ b/src/rust-2018/path-clarity.md @@ -23,12 +23,12 @@ Here's a brief summary: * `extern crate` is no longer needed * The `crate` keyword refers to the current crate. -* Relative paths variant: Paths work uniformly in both `use` statements and in - other code, both in the top-level module and in submodules, and may use +* Relative paths variant: Paths work uniformly in both `use` declarations and + in other code, both in the top-level module and in submodules, and may use either absolute paths or local names relative to the current module. -* Absolute use paths variant: Paths in `use` statements are always absolute and - begin with a crate name (or `crate`); paths in other code may use absolute - paths or local names relative to the current module. +* Absolute use paths variant: Paths in `use` declarations are always absolute + and begin with a crate name (or `crate`); paths in other code may use + absolute paths or local names relative to the current module. * A `foo.rs` and `foo/` subdirectory may coexist; `mod.rs` is no longer needed when placing submodules in a subdirectory. @@ -74,10 +74,10 @@ Check [the macro section](2018/transitioning/modules/macros.html) for more. ### The `crate` keyword refers to the current crate. -In `use` statements and in other code, you can refer to the root of the current -crate with the `crate::` prefix. For instance, `crate::foo::bar` will always -refer to the name `bar` inside the module `foo`, from anywhere else in the same -crate. +In `use` declarations and in other code, you can refer to the root of the +current crate with the `crate::` prefix. For instance, `crate::foo::bar` will +always refer to the name `bar` inside the module `foo`, from anywhere else in +the same crate. The prefix `::` previously referred to either the crate root or an external crate; it now unambiguously refers to an external crate. For instance, @@ -86,14 +86,14 @@ crate; it now unambiguously refers to an external crate. For instance, ### Relative paths variant The relative paths variant of Rust 2018 simplifies and unifies path handling -compared to Rust 2015. In Rust 2015, paths work differently in use statements -than they do elsewhere. In particular, paths in `use` statements would always -start from the crate root, while paths in other code implicitly started from -the current module. Those differences didn't have any effect in the top-level -module, which meant that everything would seem straightforward until working on -a project large enough to have submodules. - -In the relative paths variant of Rust 2018, paths in `use` statements and in +compared to Rust 2015. In Rust 2015, paths work differently in `use` +declarations than they do elsewhere. In particular, paths in `use` +declarations would always start from the crate root, while paths in other code +implicitly started from the current module. Those differences didn't have any +effect in the top-level module, which meant that everything would seem +straightforward until working on a project large enough to have submodules. + +In the relative paths variant of Rust 2018, paths in `use` declarations and in other code always work the same way, both in the top-level module and in any submodule. You can either use a relative path from the current module, an absolute path from the top of the current crate (starting with `crate::`), or @@ -206,7 +206,7 @@ To explicitly disambiguate a path, use `::name` for an external crate name, or ### Absolute use paths variant -In the absolute use paths variant of Rust 2018, paths in `use` statements +In the absolute use paths variant of Rust 2018, paths in `use` declarations *must* begin with one of: - A crate name @@ -246,9 +246,9 @@ mod foo { use crate::foo::Bar; ``` -In addition, all of these path forms are available outside of `use` statements -as well, which eliminates many sources of confusion. Consider this code in Rust -2015: +In addition, all of these path forms are available outside of `use` +declarations as well, which eliminates many sources of confusion. Consider this +code in Rust 2015: ```rust,ignore // Rust 2015 From d1656812fab090ac38a65a678857ec3f15e0443e Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 3 Aug 2018 16:15:44 -0700 Subject: [PATCH 3/5] path-clarity: Fix visibility bug --- src/rust-2018/path-clarity.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rust-2018/path-clarity.md b/src/rust-2018/path-clarity.md index 3bdc3c8e..4e0cb042 100644 --- a/src/rust-2018/path-clarity.md +++ b/src/rust-2018/path-clarity.md @@ -109,7 +109,7 @@ extern crate futures; use futures::Future; mod foo { - struct Bar; + pub struct Bar; } use foo::Bar; @@ -140,7 +140,7 @@ crate` line: use futures::Future; mod foo { - struct Bar; + pub struct Bar; } use foo::Bar; @@ -172,7 +172,7 @@ mod submodule { use futures::Future; mod foo { - struct Bar; + pub struct Bar; } use foo::Bar; @@ -224,7 +224,7 @@ extern crate futures; use futures::Future; mod foo { - struct Bar; + pub struct Bar; } use foo::Bar; @@ -239,7 +239,7 @@ Now looks like this: use futures::Future; mod foo { - struct Bar; + pub struct Bar; } // 'crate' means the current crate From ae1e7da2c3c187a1bf41c44374f2362fe4832ecf Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 3 Aug 2018 16:16:17 -0700 Subject: [PATCH 4/5] path-clarity: Terminology change to avoid misusing "relative" and "absolute" Describe the new variant as "uniform paths", and the previous variant as "anchored use paths". These names both highlight the primary benefit of each variant, and avoid describing paths including "self" or "super" as "absolute". --- src/rust-2018/path-clarity.md | 58 ++++++++++++++++------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/src/rust-2018/path-clarity.md b/src/rust-2018/path-clarity.md index 4e0cb042..b402b0be 100644 --- a/src/rust-2018/path-clarity.md +++ b/src/rust-2018/path-clarity.md @@ -13,22 +13,23 @@ features, but they end up *simplifying* the module system, to make it more clear as to what is going on. Note: During the 2018 edition preview, there are two variants of the module -system under consideration, the "absolute use paths" variant and the "relative +system under consideration, the "uniform paths" variant and the "anchored use paths" variant. Most of these changes apply to both variants; the two variant sections call out the differences between the two. We encourage testing of the -new "relative paths" variant introduced in edition preview 2. The release of +new "uniform paths" variant introduced in edition preview 2. The release of the 2018 edition will use one of these two variants. Here's a brief summary: * `extern crate` is no longer needed * The `crate` keyword refers to the current crate. -* Relative paths variant: Paths work uniformly in both `use` declarations and - in other code, both in the top-level module and in submodules, and may use - either absolute paths or local names relative to the current module. -* Absolute use paths variant: Paths in `use` declarations are always absolute - and begin with a crate name (or `crate`); paths in other code may use - absolute paths or local names relative to the current module. +* Uniform paths variant: Paths work uniformly in both `use` declarations and in + other code. Paths work uniformly both in the top-level module and in + submodules. Any path may start with a crate, with `crate`, `super`, or + `self`, or with a local name relative to the current module. +* Anchored use paths variant: Paths in `use` declarations always start with a + crate name, or with `crate`, `super`, or `self`. Paths in code other than + `use` declarations may also start with names relative to the current module. * A `foo.rs` and `foo/` subdirectory may coexist; `mod.rs` is no longer needed when placing submodules in a subdirectory. @@ -83,9 +84,9 @@ The prefix `::` previously referred to either the crate root or an external crate; it now unambiguously refers to an external crate. For instance, `::foo::bar` always refers to the name `bar` inside the external crate `foo`. -### Relative paths variant +### Uniform paths variant -The relative paths variant of Rust 2018 simplifies and unifies path handling +The uniform paths variant of Rust 2018 simplifies and unifies path handling compared to Rust 2015. In Rust 2015, paths work differently in `use` declarations than they do elsewhere. In particular, paths in `use` declarations would always start from the crate root, while paths in other code @@ -93,11 +94,11 @@ implicitly started from the current module. Those differences didn't have any effect in the top-level module, which meant that everything would seem straightforward until working on a project large enough to have submodules. -In the relative paths variant of Rust 2018, paths in `use` declarations and in +In the uniform paths variant of Rust 2018, paths in `use` declarations and in other code always work the same way, both in the top-level module and in any -submodule. You can either use a relative path from the current module, an -absolute path from the top of the current crate (starting with `crate::`), or -an absolute path starting from an external crate name. +submodule. You can always use a relative path from the current module, a path +starting from an external crate name, or a path starting with `crate`, `super`, +or `self`. Code that looked like this: @@ -135,7 +136,7 @@ will look exactly the same in Rust 2018, except that you can delete the `extern crate` line: ```rust,ignore -// Rust 2018 (relative paths variant) +// Rust 2018 (uniform paths variant) use futures::Future; @@ -166,7 +167,7 @@ With Rust 2018, however, the same code will also work completely unmodified in a submodule: ```rust,ignore -// Rust 2018 (relative paths variant) +// Rust 2018 (uniform paths variant) mod submodule { use futures::Future; @@ -204,15 +205,10 @@ either rename one of the conflicting names or explicitly disambiguate the path. To explicitly disambiguate a path, use `::name` for an external crate name, or `self::name` for a local module or item. -### Absolute use paths variant +### Anchored use paths variant -In the absolute use paths variant of Rust 2018, paths in `use` declarations -*must* begin with one of: - -- A crate name -- `crate` for the current crate's root -- `self` for the current module's root -- `super` for the current module's parent +In the anchored use paths variant of Rust 2018, paths in `use` declarations +*must* begin with a crate name, `crate`, `self`, or `super`. Code that looked like this: @@ -233,7 +229,7 @@ use foo::Bar; Now looks like this: ```rust,ignore -// Rust 2018 (absolute use paths variant) +// Rust 2018 (anchored use paths variant) // 'futures' is the name of a crate use futures::Future; @@ -278,7 +274,7 @@ mod submodule { In the `futures` example, the `my_poll` function signature is incorrect, because `submodule` contains no items named `futures`; that is, this path is considered relative. But because -`use` is absolute, `use futures::` works even though a lone `futures::` doesn't! With `std` +`use` is anchored, `use futures::` works even though a lone `futures::` doesn't! With `std` it can be even more confusing, as you never wrote the `extern crate std;` line at all. So why does it work in `main` but not in a submodule? Same thing: it's a relative path because it's not in a `use` declaration. `extern crate std;` is inserted at the crate root, so @@ -287,26 +283,26 @@ it's fine in `main`, but it doesn't exist in the submodule at all. Let's look at how this change affects things: ```rust,ignore -// Rust 2018 (absolute use paths variant) +// Rust 2018 (anchored use paths variant) // no more `extern crate futures;` mod submodule { - // 'futures' is the name of a crate, so this is absolute and works + // 'futures' is the name of a crate, so this is anchored and works use futures::Future; - // 'futures' is the name of a crate, so this is absolute and works + // 'futures' is the name of a crate, so this is anchored and works fn my_poll() -> futures::Poll { ... } } fn main() { - // 'std' is the name of a crate, so this is absolute and works + // 'std' is the name of a crate, so this is anchored and works let five = std::sync::Arc::new(5); } mod submodule { fn function() { - // 'std' is the name of a crate, so this is absolute and works + // 'std' is the name of a crate, so this is anchored and works let five = std::sync::Arc::new(5); } } From 42654b6ea716eba11ed840c71e0fe10504adf9c3 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 3 Aug 2018 16:29:35 -0700 Subject: [PATCH 5/5] path-clarity: Clarify selection and stabilization plan --- src/rust-2018/path-clarity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust-2018/path-clarity.md b/src/rust-2018/path-clarity.md index b402b0be..cfe18f83 100644 --- a/src/rust-2018/path-clarity.md +++ b/src/rust-2018/path-clarity.md @@ -17,7 +17,7 @@ system under consideration, the "uniform paths" variant and the "anchored use paths" variant. Most of these changes apply to both variants; the two variant sections call out the differences between the two. We encourage testing of the new "uniform paths" variant introduced in edition preview 2. The release of -the 2018 edition will use one of these two variants. +Rust 2018 will stabilize one of these two variants and drop the other. Here's a brief summary: