Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document underscore imports. #492

Merged
merged 2 commits into from
Dec 30, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/items/extern-crates.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> **<sup>Syntax:<sup>**\
> _ExternCrate_ :\
> &nbsp;&nbsp; `extern` `crate` [IDENTIFIER]&nbsp;(`as` [IDENTIFIER])<sup>?</sup> `;`
> &nbsp;&nbsp; `extern` `crate` [IDENTIFIER]&nbsp;(`as` ( [IDENTIFIER] | `_` ) )<sup>?</sup> `;`

An _`extern crate` declaration_ specifies a dependency on an external crate.
The external crate is then bound into the declaring scope as the [identifier]
Expand Down Expand Up @@ -68,16 +68,24 @@ need for specifying `extern crate`.

<!--
Possible upcoming changes that will change this:

The `extern_crate_item_prelude` unstable feature allows `extern crate` to
update the extern prelude in certain situations, see
https://github.com/rust-lang/rust/pull/54658

Unstable `--extern proc_macro` flag that would force the crate into the
extern prelude.
https://github.com/rust-lang/rust/pull/54116
-->

## 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there somewhere to hyperlink "as usual" to?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. I added a link to where macro_use is described, but it is very brief. I actually just today learned about the macro-use prelude, and I'm not sure if it is wise to mention it here since it is not described anywhere.

In general I think it would be amazing to have good documentation on name resolution — something that explained the different namespaces, the different preludes, the precedence and order, macro resolution, maybe ribs?, etc. I added docs on "extern prelude", but I don't really understand these things. I think if I did understand them, my mental model of how Rust works would be substantially improved. I'm not even sure where to start learning it (is everything in librustc_resolve? and macros are mostly in libsyntax?). The current rustc-guide docs are kinda incomplete.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should have a Q&A session with @petrochenkov... =P

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/
Expand Down
46 changes: 39 additions & 7 deletions src/items/use-declarations.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
> _UseTree_ :\
> &nbsp;&nbsp; &nbsp;&nbsp; ([_SimplePath_]<sup>?</sup> `::`)<sup>?</sup> `*`\
> &nbsp;&nbsp; | ([_SimplePath_]<sup>?</sup> `::`)<sup>?</sup> `{` (_UseTree_ ( `,` _UseTree_ )<sup>\*</sup> `,`<sup>?</sup>)<sup>?</sup> `}`\
> &nbsp;&nbsp; | [_SimplePath_]&nbsp;( `as` [IDENTIFIER] )<sup>?</sup>
> &nbsp;&nbsp; | [_SimplePath_]&nbsp;( `as` ( [IDENTIFIER] | `_` ) )<sup>?</sup>

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
Expand All @@ -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
Expand Down Expand Up @@ -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:
>
Expand All @@ -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. <!-- uniform_paths future-proofing -->
Expand All @@ -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<T> 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();
}
```
Centril marked this conversation as resolved.
Show resolved Hide resolved

[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