Skip to content

Commit e7737b3

Browse files
authored
Merge pull request #2128 from petrochenkov/use
RFC: Nested groups in imports
2 parents aa6c09b + 995a40d commit e7737b3

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed

text/2128-use-nested-groups.md

+196
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
- Feature Name: use_nested_groups
2+
- Start Date: 2017-08-25
3+
- RFC PR: https://github.com/rust-lang/rfcs/pull/2128
4+
- Rust Issue: https://github.com/rust-lang/rust/issues/44494
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
Permit nested `{}` groups in imports.
10+
Permit `*` in `{}` groups in imports.
11+
12+
```rust
13+
use syntax::{
14+
tokenstream::TokenTree, // >1 segments
15+
ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}, // nested braces
16+
ext::build::AstBuilder,
17+
ext::quote::rt::Span,
18+
};
19+
20+
use syntax::ast::{self, *}; // * in braces
21+
22+
use rustc::mir::{*, transform::{MirPass, MirSource}}; // both * and nested braces
23+
```
24+
25+
# Motivation
26+
[motivation]: #motivation
27+
28+
The motivation is ergonomics.
29+
Prefixes are often shared among imports, especially if many imports
30+
import names from the same crate. With this nested grouping it's more often
31+
possible to merge common import prefixes and write them once instead of writing
32+
them multiple times.
33+
34+
# Guide-level explanation
35+
[guide-level-explanation]: #guide-level-explanation
36+
37+
Several `use` items with common prefix can be merged into one `use` item,
38+
in which the prefix is written once and all the suffixes are listed inside
39+
curly braces `{}`.
40+
All kinds of suffixes can be listed inside curly braces, including globs `*` and
41+
"subtrees" with their own curly braces.
42+
43+
```rust
44+
// BEFORE
45+
use syntax::tokenstream::TokenTree;
46+
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
47+
use syntax::ext::build::AstBuilder,
48+
use syntax::ext::quote::rt::Span,
49+
50+
use syntax::ast;
51+
use syntax::ast::*;
52+
53+
use rustc::mir::*;
54+
use rustc::mir::transform::{MirPass, MirSource};
55+
56+
// AFTER
57+
use syntax::{
58+
// paths with >1 segments are permitted inside braces
59+
tokenstream::TokenTree,
60+
// nested braces are permitted as well
61+
ext::base::{ExtCtxt, MacResult, DummyResult, MacEager},
62+
ext::build::AstBuilder,
63+
ext::quote::rt::Span,
64+
};
65+
66+
// `*` can be listed in braces too
67+
use syntax::ast::{self, *};
68+
69+
// both `*` and nested braces
70+
use rustc::mir::{*, transform::{MirPass, MirSource}};
71+
72+
// the prefix can be empty
73+
use {
74+
syntax::ast::*;
75+
rustc::mir::*;
76+
};
77+
78+
// `pub` imports can use this syntax as well
79+
pub use self::Visibility::{self, Public, Inherited};
80+
```
81+
82+
A `use` item with merged prefixes behaves identically to several `use` items
83+
with all the prefixes "unmerged".
84+
85+
# Reference-level explanation
86+
[reference-level-explanation]: #reference-level-explanation
87+
88+
Syntax:
89+
```
90+
IMPORT = ATTRS VISIBILITY `use` [`::`] IMPORT_TREE `;`
91+
92+
IMPORT_TREE = `*` |
93+
REL_MOD_PATH `::` `*` |
94+
`{` IMPORT_TREE_LIST `}` |
95+
REL_MOD_PATH `::` `{` IMPORT_TREE_LIST `}` |
96+
REL_MOD_PATH [`as` IDENT]
97+
98+
IMPORT_TREE_LIST = Ø | (IMPORT_TREE `,`)* IMPORT_TREE [`,`]
99+
100+
REL_MOD_PATH = (IDENT `::`)* IDENT
101+
```
102+
103+
Resolution:
104+
First the import tree is prefixed with `::`, unless it already starts with
105+
`::`, `self` or `super`.
106+
Then resolution is performed as if the whole import tree were flattened, except
107+
that `{self}`/`{self as name}` are processed specially because `a::b::self`
108+
is illegal.
109+
110+
```rust
111+
use a::{
112+
b::{self as s, c, d as e},
113+
f::*,
114+
g::h as i,
115+
*,
116+
};
117+
118+
=>
119+
120+
use ::a::b as s;
121+
use ::a::b::c;
122+
use ::a::b::d as e;
123+
use ::a::f::*;
124+
use ::a::g::h as i;
125+
use ::a::*;
126+
```
127+
128+
Various corner cases are resolved naturally through desugaring
129+
```rust
130+
use an::{*, *}; // Use an owl!
131+
132+
=>
133+
134+
use an::*;
135+
use an::*; // Legal, but reported as unused by `unused_imports` lint.
136+
```
137+
138+
# Relationships with other proposal
139+
140+
This RFC is an incremental improvement largely independent from other
141+
import-related proposals, but it can have effect on some other RFCs.
142+
143+
Some RFCs propose new syntaxes for absolute paths in the current crate
144+
and paths from other crates. Some arguments in those proposals are based on
145+
usage statistics - "imports from other crates are more common" or "imports from
146+
the current crate are more common". More common imports are supposed to get
147+
less verbose syntax.
148+
149+
This RFC removes the these statistics from the equation by reducing verbosity
150+
for all imports with common prefix.
151+
For example, the difference in verbosity between `A`, `B` and
152+
`C` is minimal and doesn't depend on the number of imports.
153+
```rust
154+
// A
155+
use extern::{
156+
a::b::c,
157+
d::e::f,
158+
g::h::i,
159+
};
160+
// B
161+
use crate::{
162+
a::b::c,
163+
d::e::f,
164+
g::h::i,
165+
};
166+
// C
167+
use {
168+
a::b::c,
169+
d::e::f,
170+
g::h::i,
171+
};
172+
```
173+
174+
# Drawbacks
175+
[drawbacks]: #drawbacks
176+
177+
The feature encourages (but not requires) multi-line formatting of a single
178+
import
179+
```rust
180+
use prefix::{
181+
MyName,
182+
x::YourName,
183+
y::Surname,
184+
};
185+
```
186+
With this formatting it becomes harder to grep for `use.*MyName`.
187+
188+
# Rationale and Alternatives
189+
[alternatives]: #alternatives
190+
191+
Status quo is always an alternative.
192+
193+
# Unresolved questions
194+
[unresolved]: #unresolved-questions
195+
196+
None so far.

0 commit comments

Comments
 (0)