Skip to content

Commit b057c55

Browse files
committed
AST: Make renames in imports closer to the source
Fix `unused_import_braces` lint false positive on `use prefix::{self as rename}`
1 parent c6c6cf9 commit b057c55

File tree

12 files changed

+53
-40
lines changed

12 files changed

+53
-40
lines changed

src/librustc/hir/lowering.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2047,8 +2047,8 @@ impl<'a> LoweringContext<'a> {
20472047
let path = &tree.prefix;
20482048

20492049
match tree.kind {
2050-
UseTreeKind::Simple(ident) => {
2051-
*name = ident.name;
2050+
UseTreeKind::Simple(rename) => {
2051+
*name = tree.ident().name;
20522052

20532053
// First apply the prefix to the path
20542054
let mut path = Path {
@@ -2064,7 +2064,7 @@ impl<'a> LoweringContext<'a> {
20642064
if path.segments.len() > 1 &&
20652065
path.segments.last().unwrap().identifier.name == keywords::SelfValue.name() {
20662066
let _ = path.segments.pop();
2067-
if ident.name == keywords::SelfValue.name() {
2067+
if rename.is_none() {
20682068
*name = path.segments.last().unwrap().identifier.name;
20692069
}
20702070
}

src/librustc_lint/unused.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,12 @@ impl UnusedImportBraces {
377377
// Trigger the lint if the nested item is a non-self single item
378378
let node_ident;
379379
match items[0].0.kind {
380-
ast::UseTreeKind::Simple(ident) => {
381-
if ident.name == keywords::SelfValue.name() {
380+
ast::UseTreeKind::Simple(rename) => {
381+
let orig_ident = items[0].0.prefix.segments.last().unwrap().identifier;
382+
if orig_ident.name == keywords::SelfValue.name() {
382383
return;
383384
} else {
384-
node_ident = ident;
385+
node_ident = rename.unwrap_or(orig_ident);
385386
}
386387
}
387388
ast::UseTreeKind::Glob => {

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ impl<'a> Resolver<'a> {
119119
.collect();
120120

121121
match use_tree.kind {
122-
ast::UseTreeKind::Simple(mut ident) => {
122+
ast::UseTreeKind::Simple(rename) => {
123+
let mut ident = use_tree.ident();
123124
let mut source = module_path.pop().unwrap().node;
124125
let mut type_ns_only = false;
125126

@@ -142,7 +143,7 @@ impl<'a> Resolver<'a> {
142143
// Replace `use foo::self;` with `use foo;`
143144
let _ = module_path.pop();
144145
source = last_segment.node;
145-
if ident.name == keywords::SelfValue.name() {
146+
if rename.is_none() {
146147
ident = last_segment.node;
147148
}
148149
}
@@ -162,7 +163,7 @@ impl<'a> Resolver<'a> {
162163
ModuleKind::Block(..) => unreachable!(),
163164
};
164165
source.name = crate_name;
165-
if ident.name == keywords::DollarCrate.name() {
166+
if rename.is_none() {
166167
ident.name = crate_name;
167168
}
168169

@@ -206,8 +207,8 @@ impl<'a> Resolver<'a> {
206207

207208
// Ensure there is at most one `self` in the list
208209
let self_spans = items.iter().filter_map(|&(ref use_tree, _)| {
209-
if let ast::UseTreeKind::Simple(ident) = use_tree.kind {
210-
if ident.name == keywords::SelfValue.name() {
210+
if let ast::UseTreeKind::Simple(..) = use_tree.kind {
211+
if use_tree.ident().name == keywords::SelfValue.name() {
211212
return Some(use_tree.span);
212213
}
213214
}

src/librustc_save_analysis/dump_visitor.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1342,7 +1342,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
13421342
.map(::id_from_def_id);
13431343

13441344
match use_tree.kind {
1345-
ast::UseTreeKind::Simple(ident) => {
1345+
ast::UseTreeKind::Simple(..) => {
1346+
let ident = use_tree.ident();
13461347
let path = ast::Path {
13471348
segments: prefix.segments
13481349
.iter()

src/libsyntax/ast.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,18 +1880,29 @@ pub type Variant = Spanned<Variant_>;
18801880

18811881
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
18821882
pub enum UseTreeKind {
1883-
Simple(Ident),
1884-
Glob,
1883+
Simple(Option<Ident>),
18851884
Nested(Vec<(UseTree, NodeId)>),
1885+
Glob,
18861886
}
18871887

18881888
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
18891889
pub struct UseTree {
1890-
pub kind: UseTreeKind,
18911890
pub prefix: Path,
1891+
pub kind: UseTreeKind,
18921892
pub span: Span,
18931893
}
18941894

1895+
impl UseTree {
1896+
pub fn ident(&self) -> Ident {
1897+
match self.kind {
1898+
UseTreeKind::Simple(Some(rename)) => rename,
1899+
UseTreeKind::Simple(None) =>
1900+
self.prefix.segments.last().expect("empty prefix in a simple import").identifier,
1901+
_ => panic!("`UseTree::ident` can only be used on a simple import"),
1902+
}
1903+
}
1904+
}
1905+
18951906
/// Distinguishes between Attributes that decorate items and Attributes that
18961907
/// are contained as statements within items. These two cases need to be
18971908
/// distinguished for pretty-printing.

src/libsyntax/ext/build.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ pub trait AstBuilder {
294294
vis: ast::Visibility, vp: P<ast::UseTree>) -> P<ast::Item>;
295295
fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item>;
296296
fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
297-
ident: ast::Ident, path: ast::Path) -> P<ast::Item>;
297+
ident: Option<ast::Ident>, path: ast::Path) -> P<ast::Item>;
298298
fn item_use_list(&self, sp: Span, vis: ast::Visibility,
299299
path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item>;
300300
fn item_use_glob(&self, sp: Span,
@@ -1159,16 +1159,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
11591159
}
11601160

11611161
fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item> {
1162-
let last = path.segments.last().unwrap().identifier;
1163-
self.item_use_simple_(sp, vis, last, path)
1162+
self.item_use_simple_(sp, vis, None, path)
11641163
}
11651164

11661165
fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
1167-
ident: ast::Ident, path: ast::Path) -> P<ast::Item> {
1166+
rename: Option<ast::Ident>, path: ast::Path) -> P<ast::Item> {
11681167
self.item_use(sp, vis, P(ast::UseTree {
11691168
span: sp,
11701169
prefix: path,
1171-
kind: ast::UseTreeKind::Simple(ident),
1170+
kind: ast::UseTreeKind::Simple(rename),
11721171
}))
11731172
}
11741173

@@ -1178,7 +1177,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
11781177
(ast::UseTree {
11791178
span: sp,
11801179
prefix: self.path(sp, vec![*id]),
1181-
kind: ast::UseTreeKind::Simple(*id),
1180+
kind: ast::UseTreeKind::Simple(None),
11821181
}, ast::DUMMY_NODE_ID)
11831182
}).collect();
11841183

src/libsyntax/fold.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,8 @@ pub fn noop_fold_use_tree<T: Folder>(use_tree: UseTree, fld: &mut T) -> UseTree
323323
span: fld.new_span(use_tree.span),
324324
prefix: fld.fold_path(use_tree.prefix),
325325
kind: match use_tree.kind {
326-
UseTreeKind::Simple(ident) => UseTreeKind::Simple(fld.fold_ident(ident)),
326+
UseTreeKind::Simple(rename) =>
327+
UseTreeKind::Simple(rename.map(|ident| fld.fold_ident(ident))),
327328
UseTreeKind::Glob => UseTreeKind::Glob,
328329
UseTreeKind::Nested(items) => UseTreeKind::Nested(items.move_map(|(tree, id)| {
329330
(fld.fold_use_tree(tree), fld.new_id(id))

src/libsyntax/parse/parser.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7033,9 +7033,7 @@ impl<'a> Parser<'a> {
70337033
}
70347034
} else {
70357035
// `use path::foo;` or `use path::foo as bar;`
7036-
let rename = self.parse_rename()?.
7037-
unwrap_or(prefix.segments.last().unwrap().identifier);
7038-
UseTreeKind::Simple(rename)
7036+
UseTreeKind::Simple(self.parse_rename()?)
70397037
}
70407038
};
70417039

src/libsyntax/print/pprust.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2949,13 +2949,12 @@ impl<'a> State<'a> {
29492949

29502950
pub fn print_use_tree(&mut self, tree: &ast::UseTree) -> io::Result<()> {
29512951
match tree.kind {
2952-
ast::UseTreeKind::Simple(ref ident) => {
2952+
ast::UseTreeKind::Simple(rename) => {
29532953
self.print_path(&tree.prefix, false, 0, true)?;
2954-
2955-
if tree.prefix.segments.last().unwrap().identifier.name != ident.name {
2954+
if let Some(rename) = rename {
29562955
self.s.space()?;
29572956
self.word_space("as")?;
2958-
self.print_ident(*ident)?;
2957+
self.print_ident(rename)?;
29592958
}
29602959
}
29612960
ast::UseTreeKind::Glob => {

src/libsyntax/test.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub fn modify_for_testing(sess: &ParseSess,
7878
span_diagnostic: &errors::Handler,
7979
features: &Features) -> ast::Crate {
8080
// Check for #[reexport_test_harness_main = "some_name"] which
81-
// creates a `use some_name = __test::main;`. This needs to be
81+
// creates a `use __test::main as some_name;`. This needs to be
8282
// unconditional, so that the attribute is still marked as used in
8383
// non-test builds.
8484
let reexport_test_harness_main =
@@ -240,7 +240,8 @@ fn mk_reexport_mod(cx: &mut TestCtxt,
240240
cx.ext_cx.path(DUMMY_SP, vec![super_, r]))
241241
}).chain(tested_submods.into_iter().map(|(r, sym)| {
242242
let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]);
243-
cx.ext_cx.item_use_simple_(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public), r, path)
243+
cx.ext_cx.item_use_simple_(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public),
244+
Some(r), path)
244245
})).collect();
245246

246247
let reexport_mod = ast::Mod {
@@ -502,7 +503,7 @@ fn mk_std(cx: &TestCtxt) -> P<ast::Item> {
502503
(ast::ItemKind::Use(P(ast::UseTree {
503504
span: DUMMY_SP,
504505
prefix: path_node(vec![id_test]),
505-
kind: ast::UseTreeKind::Simple(id_test),
506+
kind: ast::UseTreeKind::Simple(None),
506507
})),
507508
ast::VisibilityKind::Public, keywords::Invalid.ident())
508509
} else {
@@ -590,13 +591,13 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) {
590591
tokens: None,
591592
})).pop().unwrap();
592593
let reexport = cx.reexport_test_harness_main.map(|s| {
593-
// building `use <ident> = __test::main`
594-
let reexport_ident = Ident::with_empty_ctxt(s);
594+
// building `use __test::main as <ident>;`
595+
let rename = Ident::with_empty_ctxt(s);
595596

596597
let use_path = ast::UseTree {
597598
span: DUMMY_SP,
598599
prefix: path_node(vec![mod_ident, Ident::from_str("main")]),
599-
kind: ast::UseTreeKind::Simple(reexport_ident),
600+
kind: ast::UseTreeKind::Simple(Some(rename)),
600601
};
601602

602603
expander.fold_item(P(ast::Item {

src/libsyntax/visit.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,10 +354,11 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(
354354
visitor: &mut V, use_tree: &'a UseTree, id: NodeId,
355355
) {
356356
visitor.visit_path(&use_tree.prefix, id);
357-
358357
match use_tree.kind {
359-
UseTreeKind::Simple(ident) => {
360-
visitor.visit_ident(use_tree.span, ident);
358+
UseTreeKind::Simple(rename) => {
359+
if let Some(rename) = rename {
360+
visitor.visit_ident(use_tree.span, rename);
361+
}
361362
}
362363
UseTreeKind::Glob => {},
363364
UseTreeKind::Nested(ref use_trees) => {

src/test/compile-fail/lint-unnecessary-import-braces.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
// except according to those terms.
1010

1111
#![deny(unused_import_braces)]
12-
#![allow(dead_code)]
13-
#![allow(unused_imports)]
1412

1513
use test::{A}; //~ ERROR braces around A is unnecessary
1614

1715
mod test {
16+
use test::{self}; // OK
17+
use test::{self as rename}; // OK
1818
pub struct A;
1919
}
2020

0 commit comments

Comments
 (0)