-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RFC: Nested groups in imports #2128
Merged
Merged
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
- Feature Name: use_nested_groups | ||
- Start Date: 2017-08-25 | ||
- RFC PR: (leave this empty) | ||
- Rust Issue: (leave this empty) | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
Permit nested `{}` groups in imports. | ||
Permit `*` in `{}` groups in imports. | ||
|
||
```rust | ||
use syntax::{ | ||
tokenstream::TokenTree, // >1 segments | ||
ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}, // nested braces | ||
ext::build::AstBuilder, | ||
ext::quote::rt::Span, | ||
}; | ||
|
||
use syntax::ast::{self, *}; // * in braces | ||
|
||
use rustc::mir::{*, transform::{MirPass, MirSource}}; // both * and nested braces | ||
``` | ||
|
||
# Motivation | ||
[motivation]: #motivation | ||
|
||
The motivation is ergonomics. | ||
Prefixes are often shared among imports, especially if many imports | ||
import names from the same crate. With this nested grouping it's more often | ||
possible to merge common import prefixes and write them once instead of writing | ||
them multiple times. | ||
|
||
# Guide-level explanation | ||
[guide-level-explanation]: #guide-level-explanation | ||
|
||
Several `use` items with common prefix can be merged into one `use` item, | ||
in which the prefix is written once and all the suffixes are listed inside | ||
curly braces `{}`. | ||
All kinds of suffixes can be listed inside curly braces, including globs `*` and | ||
"subtrees" with their own curly braces. | ||
|
||
```rust | ||
// BEFORE | ||
use syntax::tokenstream::TokenTree; | ||
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}; | ||
use syntax::ext::build::AstBuilder, | ||
use syntax::ext::quote::rt::Span, | ||
|
||
use syntax::ast; | ||
use syntax::ast::*; | ||
|
||
use rustc::mir::*; | ||
use rustc::transform::{MirPass, MirSource}; | ||
|
||
// AFTER | ||
use syntax::{ | ||
// paths with >1 segments are permitted inside braces | ||
tokenstream::TokenTree, | ||
// nested braces are permitted as well | ||
ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}, | ||
ext::build::AstBuilder, | ||
ext::quote::rt::Span, | ||
}; | ||
|
||
// `*` can be listed in braces too | ||
use syntax::ast::{self, *}; | ||
|
||
// both `*` and nested braces | ||
use rustc::mir::{*, transform::{MirPass, MirSource}}; | ||
``` | ||
|
||
A `use` item with merged prefixes behaves identically to several `use` items | ||
with all the prefixes "unmerged". | ||
|
||
# Reference-level explanation | ||
[reference-level-explanation]: #reference-level-explanation | ||
|
||
Syntax: | ||
``` | ||
IMPORT = ATTRS VISIBILITY `use` [`::`] IMPORT_TREE `;` | ||
|
||
IMPORT_TREE = `*` | | ||
REL_MOD_PATH `::` `*` | | ||
`{` IMPORT_TREE_LIST `}` | | ||
REL_MOD_PATH `::` `{` IMPORT_TREE_LIST `}` | | ||
REL_MOD_PATH [`as` IDENT] | ||
|
||
IMPORT_TREE_LIST = Ø | (IMPORT_TREE `,`)* IMPORT_TREE [`,`] | ||
|
||
REL_MOD_PATH = (IDENT `::`)* IDENT | ||
``` | ||
|
||
Resolution: | ||
First the import tree is prefixed with `::`, unless it already starts with | ||
`::`, `self` or `super`. | ||
Then resolution is performed as if the whole import tree were flattened, except | ||
that `{self}`/`{self as name}` are processed specially because `a::b::self` | ||
is illegal. | ||
|
||
```rust | ||
use a::{ | ||
b::{self as s, c, d as e}, | ||
f::*, | ||
g::h as i, | ||
*, | ||
}; | ||
|
||
=> | ||
|
||
use ::a::b as s; | ||
use ::a::b::c; | ||
use ::a::b::d as e; | ||
use ::a::f::*; | ||
use ::a::g::h as i; | ||
use ::a::*; | ||
``` | ||
|
||
# Relationships with other proposal | ||
|
||
This RFC is an incremental improvement largely independent from other | ||
import-related proposals, but it can have effect on some other RFCs. | ||
|
||
Some RFCs propose new syntaxes for absolute paths in the current crate | ||
and paths from other crates. Some arguments in those proposals are based on | ||
usage statistics - "imports from other crates are more common" or "imports from | ||
the current crate are more common". More common imports are supposed to get | ||
less verbose syntax. | ||
|
||
This RFC removes the these statistics from the equation by reducing verbosity | ||
for all imports with common prefix. | ||
For example, the difference in verbosity between `A`, `B` and | ||
`C` is minimal and doesn't depend on the number of imports. | ||
```rust | ||
// A | ||
use extern::{ | ||
a::b::c, | ||
d::e::f, | ||
g::h::i, | ||
}; | ||
// B | ||
use crate::{ | ||
a::b::c, | ||
d::e::f, | ||
g::h::i, | ||
}; | ||
// C | ||
use { | ||
a::b::c, | ||
d::e::f, | ||
g::h::i, | ||
}; | ||
``` | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
The feature encourages (but not requires) multi-line formatting of a single | ||
import | ||
```rust | ||
use prefix::{ | ||
MyName, | ||
x::YourName, | ||
y::Surname, | ||
}; | ||
``` | ||
With this formatting it becomes harder to grep for `use.*MyName`. | ||
|
||
# Rationale and Alternatives | ||
[alternatives]: #alternatives | ||
|
||
Status quo is always an alternative. | ||
|
||
# Unresolved questions | ||
[unresolved]: #unresolved-questions | ||
|
||
None so far. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small correction: here the path should be
rustc::mir::transform::{MirPass, MirSource}
.