From e5392f6cb6905230001167620bcd3fa5667caab0 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 30 Dec 2018 11:55:09 -0800 Subject: [PATCH 1/2] Document underscore imports. --- src/items/extern-crates.md | 14 ++++++++--- src/items/use-declarations.md | 46 +++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/items/extern-crates.md b/src/items/extern-crates.md index 078cc7b5e..a3e9b43d9 100644 --- a/src/items/extern-crates.md +++ b/src/items/extern-crates.md @@ -2,7 +2,7 @@ > **Syntax:**\ > _ExternCrate_ :\ ->    `extern` `crate` [IDENTIFIER] (`as` [IDENTIFIER])? `;` +>    `extern` `crate` [IDENTIFIER] (`as` ( [IDENTIFIER] | `_` ) )? `;` An _`extern crate` declaration_ specifies a dependency on an external crate. The external crate is then bound into the declaring scope as the [identifier] @@ -68,16 +68,24 @@ need for specifying `extern crate`. +## Underscore Imports + +An external crate dependency can be declared without binding its name in scope +by using an underscore with the form `extern crate foo as _`. This may be +useful for crates that only need to be linked, but are never referenced, and +will avoid being reported as unused. + +The `#[macro_use]` attribute will work as usual and import the macro names +into the macro-use prelude. + [IDENTIFIER]: identifiers.html [RFC 940]: https://github.com/rust-lang/rfcs/blob/master/text/0940-hyphens-considered-harmful.md [`alloc`]: https://doc.rust-lang.org/alloc/ diff --git a/src/items/use-declarations.md b/src/items/use-declarations.md index 49287dbdb..fc3e62f70 100644 --- a/src/items/use-declarations.md +++ b/src/items/use-declarations.md @@ -7,7 +7,7 @@ > _UseTree_ :\ >       ([_SimplePath_]? `::`)? `*`\ >    | ([_SimplePath_]? `::`)? `{` (_UseTree_ ( `,` _UseTree_ )\* `,`?)? `}`\ ->    | [_SimplePath_] ( `as` [IDENTIFIER] )? +>    | [_SimplePath_] ( `as` ( [IDENTIFIER] | `_` ) )? A _use declaration_ creates one or more local name bindings synonymous with some other [path]. Usually a `use` declaration is used to shorten the path @@ -18,10 +18,6 @@ and [blocks], usually at the top. [modules]: items/modules.html [blocks]: expressions/block-expr.html -> **Note**: Unlike in many languages, `use` declarations in Rust do *not* -> declare linkage dependency with external crates. Rather, [`extern crate` -> declarations](items/extern-crates.html) declare linkage dependencies. - Use declarations support a number of convenient shortcuts: * Simultaneously binding a list of paths with a common prefix, using the @@ -124,7 +120,7 @@ mod foo { fn main() {} ``` -> **Edition Differences**: In the 2015 Edition, `use` paths also allow +> **Edition Differences**: In the 2015 edition, `use` paths also allow > accessing items in the crate root. Using the example above, the following > `use` paths work in 2015 but not 2018: > @@ -133,7 +129,13 @@ fn main() {} > use ::foo::baz::foobaz; > ``` > -> In the 2018 Edition, if an in-scope item has the same name as an external +> The 2015 edition does not allow use declarations to reference the [extern +> prelude]. Thus [`extern crate`] declarations are still required in 2015 to +> reference an external crate in a use declaration. Beginning with the 2018 +> edition, use declarations can specify an external crate dependency the same +> way `extern crate` can. +> +> In the 2018 edition, if an in-scope item has the same name as an external > crate, then `use` of that crate name requires a leading `::` to > unambiguously select the crate name. This is to retain compatibility with > potential future changes. @@ -149,7 +151,37 @@ fn main() {} > # fn main() {} > ``` +## Underscore Imports + +Items can be imported without binding to a name by using an underscore with +the form `use path as _`. This is particularly useful to import a trait so +that its methods may be used without importing the trait's symbol, for example +if the trait's symbol may conflict with another symbol. Another example is to +link an external crate without importing its name. + +Asterisk glob imports will import items imported with `_` in their unnameable +form. + +```rust +mod foo { + pub trait Zoo { + fn zoo(&self) {} + } + + impl Zoo for T {} +} + +use self::foo::Zoo as _; +struct Zoo; // Underscore import avoids name conflict with this item. + +fn main() { + let z = Zoo; + z.zoo(); +} +``` [IDENTIFIER]: identifiers.html [_SimplePath_]: paths.html#simple-paths +[`extern crate`]: items/extern-crates.html +[extern prelude]: items/extern-crates.html#extern-prelude [path qualifiers]: paths.html#path-qualifiers From c205ae622ec22861eb02d37e11bd8130808c45ab Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 30 Dec 2018 15:30:21 -0800 Subject: [PATCH 2/2] Address review comments. --- src/items/extern-crates.md | 3 ++- src/items/use-declarations.md | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/items/extern-crates.md b/src/items/extern-crates.md index a3e9b43d9..3c61ce220 100644 --- a/src/items/extern-crates.md +++ b/src/items/extern-crates.md @@ -83,11 +83,12 @@ by using an underscore with the form `extern crate foo as _`. This may be useful for crates that only need to be linked, but are never referenced, and will avoid being reported as unused. -The `#[macro_use]` attribute will work as usual and import the macro names +The [`#[macro_use]` attribute] will work as usual and import the macro names into the macro-use prelude. [IDENTIFIER]: identifiers.html [RFC 940]: https://github.com/rust-lang/rfcs/blob/master/text/0940-hyphens-considered-harmful.md +[`#[macro_use]` attribute]: attributes.html#macro-related-attributes [`alloc`]: https://doc.rust-lang.org/alloc/ [`crate::`]: paths.html#crate [`proc_macro`]: https://doc.rust-lang.org/proc_macro/ diff --git a/src/items/use-declarations.md b/src/items/use-declarations.md index fc3e62f70..264d52a54 100644 --- a/src/items/use-declarations.md +++ b/src/items/use-declarations.md @@ -180,6 +180,21 @@ fn main() { } ``` +The unique, unnameable symbols are created after macro expansion so that +macros may safely emit multiple references to `_` imports. For example, the +following should not produce an error: + +```rust +macro_rules! m { + ($item: item) => { $item $item } +} + +m!(use std as _;); +// This expands to: +// use std as _; +// use std as _; +``` + [IDENTIFIER]: identifiers.html [_SimplePath_]: paths.html#simple-paths [`extern crate`]: items/extern-crates.html