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

Imports #129

Merged
merged 1 commit into from May 10, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
128 changes: 127 additions & 1 deletion guide/items.md
Expand Up @@ -433,4 +433,130 @@ before:

When writing extern items (such as `extern "C" fn`), always be explicit about
the ABI. For example, write `extern "C" fn foo ...`, not `extern fn foo ...`, or
`extern "C" { ... }.
`extern "C" { ... }`.


### Imports (`use` statements)

If an import can be formatted on one line, do so. There should be no spaces
around braces.

```rust
use a::b::c;
use a::b::d::*;
use a::b::{foo, bar, baz};
```


#### Large list imports

Prefer to use multiple imports rather than a multi-line import. However, tools
Copy link
Member

Choose a reason for hiding this comment

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

What does prefer mean here, if tools aren't supposed to enforce it? I thought the focus of these RFCs was to determine how Rust formatting tools behaved.

Copy link
Member Author

Choose a reason for hiding this comment

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

That is the focus, but we have also given advice in some cases for humans to follow where tools can't reformat

Copy link
Member

Choose a reason for hiding this comment

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

Sounds good! Thanks for the explanation.

should not split imports by default (they may offer this as an option).

If an import does require multiple lines, then break after the opening brace
Copy link
Member

Choose a reason for hiding this comment

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

What determines "does require multiple lines"? in my proposal on #24, I suggested that nested imports should be broken out into their own line if they contain multiple path segments, e.g.:

// Do this
use foo::{
   bar, bal,
   baz::buz,
   bla::{blue, red},
};

// Not this
use foo::{bar, bal, baz::buz, bla::{blue, red}};

Copy link
Member

Choose a reason for hiding this comment

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

Reasonable point, and I agree.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, this was my intention; I'll clarify.

and before the closing brace, use a trailing comma, and block indent the names.


```rust
// Prefer
foo::{long, list, of, imports};
foo::{more, imports};

// If necessary
foo::{
long, list, of, imports, more,
imports, // Note trailing comma
};
```


#### Ordering of imports

A *group* of imports is a set of imports on the same or sequential lines. One or
more blank lines or other items (e.g., a function) separate groups of imports.

Within a group of imports, imports must be sorted ascii-betically. Groups of
imports must not be merged or re-ordered.


E.g., input:

```rust
use d;
use c;

use b;
use a;
```

output:

```rust
use c;
use d;

use a;
use b;
```

Because of `macro_use`, attributes must also start a new group and prevent
re-ordering.

Note that tools which only have access to syntax (such as Rustfmt) cannot tell
which imports are from an external crate or the std lib, etc.


#### Ordering list import

Names in a list import must be sorted ascii-betically, but with `self` and
`super` first, and groups and glob imports last. This applies recursively. For
example, `a::*` comes before `b::a` but `a::b` comes before `a::*`. E.g.,
`use foo::bar::{a, b::c, b::d, b::d::{x, y, z}, b::{self, r, s}};`.


#### Normalisation

Tools must make the following normalisations:

* `use a::self;` -> `use a;`
* `use a::{};` ->
* `use a::{b};` -> `use a::b;`

And must apply these recursively.

Tools must not otherwise merge or un-merge import lists or adjust glob imports
(without an explicit option).


#### Nested imports

If there are any nested imports in a list import, then use the multi-line form,
even if the import fits on one line. Each nested import must be on its own line,
but non-nested imports must be grouped on as few lines as possible.

For example,

```rust
use a::b::{
x, y, z,
w::{...},
u::{...},
};
```


#### Merging/un-merging imports

An example:

```rust
// Un-merged
use a::b;
use a::c::d;

// Merged
use a::{b, c::d};
```

Tools must not merge or un-merge imports by default. They may offer merging or
un-merging as an option.