]> git.lizzy.rs Git - rust.git/commitdiff
AST: Make renames in imports closer to the source
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Fri, 9 Mar 2018 15:58:44 +0000 (18:58 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sat, 17 Mar 2018 19:12:21 +0000 (22:12 +0300)
Fix `unused_import_braces` lint false positive on `use prefix::{self as rename}`

12 files changed:
src/librustc/hir/lowering.rs
src/librustc_lint/unused.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_save_analysis/dump_visitor.rs
src/libsyntax/ast.rs
src/libsyntax/ext/build.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/test.rs
src/libsyntax/visit.rs
src/test/compile-fail/lint-unnecessary-import-braces.rs

index 41950d21c09c839f8645dbf22094f0da4ae72bb0..1e355bb30cbec0f7e07633075389f3d4943d36cf 100644 (file)
@@ -2047,8 +2047,8 @@ fn lower_use_tree(&mut self,
         let path = &tree.prefix;
 
         match tree.kind {
-            UseTreeKind::Simple(ident) => {
-                *name = ident.name;
+            UseTreeKind::Simple(rename) => {
+                *name = tree.ident().name;
 
                 // First apply the prefix to the path
                 let mut path = Path {
@@ -2064,7 +2064,7 @@ fn lower_use_tree(&mut self,
                 if path.segments.len() > 1 &&
                    path.segments.last().unwrap().identifier.name == keywords::SelfValue.name() {
                     let _ = path.segments.pop();
-                    if ident.name == keywords::SelfValue.name() {
+                    if rename.is_none() {
                         *name = path.segments.last().unwrap().identifier.name;
                     }
                 }
index d777f6f19b0ffd8ca7af3aa916ec0f13780533a5..86f79c553c3917fc9249e7cd49a8c69a7445f55a 100644 (file)
@@ -377,11 +377,12 @@ fn check_use_tree(&self, cx: &EarlyContext, use_tree: &ast::UseTree, item: &ast:
             // Trigger the lint if the nested item is a non-self single item
             let node_ident;
             match items[0].0.kind {
-                ast::UseTreeKind::Simple(ident) => {
-                    if ident.name == keywords::SelfValue.name() {
+                ast::UseTreeKind::Simple(rename) => {
+                    let orig_ident = items[0].0.prefix.segments.last().unwrap().identifier;
+                    if orig_ident.name == keywords::SelfValue.name() {
                         return;
                     } else {
-                        node_ident = ident;
+                        node_ident = rename.unwrap_or(orig_ident);
                     }
                 }
                 ast::UseTreeKind::Glob => {
index 335064402c475019bff67770b2f3c16ab4134baa..e6c8dfa83565450870b2d946c41116fe3cb0eb93 100644 (file)
@@ -119,7 +119,8 @@ fn build_reduced_graph_for_use_tree(&mut self,
             .collect();
 
         match use_tree.kind {
-            ast::UseTreeKind::Simple(mut ident) => {
+            ast::UseTreeKind::Simple(rename) => {
+                let mut ident = use_tree.ident();
                 let mut source = module_path.pop().unwrap().node;
                 let mut type_ns_only = false;
 
@@ -142,7 +143,7 @@ fn build_reduced_graph_for_use_tree(&mut self,
                         // Replace `use foo::self;` with `use foo;`
                         let _ = module_path.pop();
                         source = last_segment.node;
-                        if ident.name == keywords::SelfValue.name() {
+                        if rename.is_none() {
                             ident = last_segment.node;
                         }
                     }
@@ -162,7 +163,7 @@ fn build_reduced_graph_for_use_tree(&mut self,
                             ModuleKind::Block(..) => unreachable!(),
                         };
                         source.name = crate_name;
-                        if ident.name == keywords::DollarCrate.name() {
+                        if rename.is_none() {
                             ident.name = crate_name;
                         }
 
@@ -206,8 +207,8 @@ fn build_reduced_graph_for_use_tree(&mut self,
 
                 // Ensure there is at most one `self` in the list
                 let self_spans = items.iter().filter_map(|&(ref use_tree, _)| {
-                    if let ast::UseTreeKind::Simple(ident) = use_tree.kind {
-                        if ident.name == keywords::SelfValue.name() {
+                    if let ast::UseTreeKind::Simple(..) = use_tree.kind {
+                        if use_tree.ident().name == keywords::SelfValue.name() {
                             return Some(use_tree.span);
                         }
                     }
index d92025a6787d6f63597ab87accae8599e012f37b..b9b4186c818ae5a0e6a6a0d88c12fc8e4dea00b4 100644 (file)
@@ -1342,7 +1342,8 @@ fn process_use_tree(&mut self,
             .map(::id_from_def_id);
 
         match use_tree.kind {
-            ast::UseTreeKind::Simple(ident) => {
+            ast::UseTreeKind::Simple(..) => {
+                let ident = use_tree.ident();
                 let path = ast::Path {
                     segments: prefix.segments
                         .iter()
index 7ced642482477695b0d5307e25927145f9c14e04..fdb32486b5de2cdc13023bb3577a4a3e7df79947 100644 (file)
@@ -1880,18 +1880,29 @@ pub struct Variant_ {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum UseTreeKind {
-    Simple(Ident),
-    Glob,
+    Simple(Option<Ident>),
     Nested(Vec<(UseTree, NodeId)>),
+    Glob,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct UseTree {
-    pub kind: UseTreeKind,
     pub prefix: Path,
+    pub kind: UseTreeKind,
     pub span: Span,
 }
 
+impl UseTree {
+    pub fn ident(&self) -> Ident {
+        match self.kind {
+            UseTreeKind::Simple(Some(rename)) => rename,
+            UseTreeKind::Simple(None) =>
+                self.prefix.segments.last().expect("empty prefix in a simple import").identifier,
+            _ => panic!("`UseTree::ident` can only be used on a simple import"),
+        }
+    }
+}
+
 /// Distinguishes between Attributes that decorate items and Attributes that
 /// are contained as statements within items. These two cases need to be
 /// distinguished for pretty-printing.
index b88e064e7e56dd059c8d54290a9cd005c3a9d6f7..97f784dd6179e20d49fb7f699e0ed2fc6cdf3bc9 100644 (file)
@@ -294,7 +294,7 @@ fn item_use(&self, sp: Span,
                 vis: ast::Visibility, vp: P<ast::UseTree>) -> P<ast::Item>;
     fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item>;
     fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
-                        ident: ast::Ident, path: ast::Path) -> P<ast::Item>;
+                        ident: Option<ast::Ident>, path: ast::Path) -> P<ast::Item>;
     fn item_use_list(&self, sp: Span, vis: ast::Visibility,
                      path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item>;
     fn item_use_glob(&self, sp: Span,
@@ -1159,16 +1159,15 @@ fn item_use(&self, sp: Span,
     }
 
     fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item> {
-        let last = path.segments.last().unwrap().identifier;
-        self.item_use_simple_(sp, vis, last, path)
+        self.item_use_simple_(sp, vis, None, path)
     }
 
     fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
-                        ident: ast::Ident, path: ast::Path) -> P<ast::Item> {
+                        rename: Option<ast::Ident>, path: ast::Path) -> P<ast::Item> {
         self.item_use(sp, vis, P(ast::UseTree {
             span: sp,
             prefix: path,
-            kind: ast::UseTreeKind::Simple(ident),
+            kind: ast::UseTreeKind::Simple(rename),
         }))
     }
 
@@ -1178,7 +1177,7 @@ fn item_use_list(&self, sp: Span, vis: ast::Visibility,
             (ast::UseTree {
                 span: sp,
                 prefix: self.path(sp, vec![*id]),
-                kind: ast::UseTreeKind::Simple(*id),
+                kind: ast::UseTreeKind::Simple(None),
             }, ast::DUMMY_NODE_ID)
         }).collect();
 
index 1a65fb7639a43f3b5e6e9dbcb8fee20612207df9..146f580e04ee4577b77006ccf1c42154c1f6f981 100644 (file)
@@ -323,7 +323,8 @@ pub fn noop_fold_use_tree<T: Folder>(use_tree: UseTree, fld: &mut T) -> UseTree
         span: fld.new_span(use_tree.span),
         prefix: fld.fold_path(use_tree.prefix),
         kind: match use_tree.kind {
-            UseTreeKind::Simple(ident) => UseTreeKind::Simple(fld.fold_ident(ident)),
+            UseTreeKind::Simple(rename) =>
+                UseTreeKind::Simple(rename.map(|ident| fld.fold_ident(ident))),
             UseTreeKind::Glob => UseTreeKind::Glob,
             UseTreeKind::Nested(items) => UseTreeKind::Nested(items.move_map(|(tree, id)| {
                 (fld.fold_use_tree(tree), fld.new_id(id))
index d1234d25764d87799acd19ffe42e2428d84b047e..7a4329304907f2759571b5fdadbdaea8867c690a 100644 (file)
@@ -7033,9 +7033,7 @@ fn parse_use_tree(&mut self, nested: bool) -> PResult<'a, UseTree> {
                 }
             } else {
                 // `use path::foo;` or `use path::foo as bar;`
-                let rename = self.parse_rename()?.
-                                  unwrap_or(prefix.segments.last().unwrap().identifier);
-                UseTreeKind::Simple(rename)
+                UseTreeKind::Simple(self.parse_rename()?)
             }
         };
 
index 097c0fd16d0842c14e564d96066aa0237b6e32b1..18a758ba96846480d472dc76215580c266853313 100644 (file)
@@ -2949,13 +2949,12 @@ pub fn print_where_clause(&mut self, where_clause: &ast::WhereClause)
 
     pub fn print_use_tree(&mut self, tree: &ast::UseTree) -> io::Result<()> {
         match tree.kind {
-            ast::UseTreeKind::Simple(ref ident) => {
+            ast::UseTreeKind::Simple(rename) => {
                 self.print_path(&tree.prefix, false, 0, true)?;
-
-                if tree.prefix.segments.last().unwrap().identifier.name != ident.name {
+                if let Some(rename) = rename {
                     self.s.space()?;
                     self.word_space("as")?;
-                    self.print_ident(*ident)?;
+                    self.print_ident(rename)?;
                 }
             }
             ast::UseTreeKind::Glob => {
index 39306229c82b2e8f28cc73a957946c67f1b910c5..9edfa767d31958df8c0ff07e7850c49708c072b0 100644 (file)
@@ -78,7 +78,7 @@ pub fn modify_for_testing(sess: &ParseSess,
                           span_diagnostic: &errors::Handler,
                           features: &Features) -> ast::Crate {
     // Check for #[reexport_test_harness_main = "some_name"] which
-    // creates a `use some_name = __test::main;`. This needs to be
+    // creates a `use __test::main as some_name;`. This needs to be
     // unconditional, so that the attribute is still marked as used in
     // non-test builds.
     let reexport_test_harness_main =
@@ -240,7 +240,8 @@ fn mk_reexport_mod(cx: &mut TestCtxt,
                                   cx.ext_cx.path(DUMMY_SP, vec![super_, r]))
     }).chain(tested_submods.into_iter().map(|(r, sym)| {
         let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]);
-        cx.ext_cx.item_use_simple_(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public), r, path)
+        cx.ext_cx.item_use_simple_(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public),
+                                   Some(r), path)
     })).collect();
 
     let reexport_mod = ast::Mod {
@@ -502,7 +503,7 @@ fn mk_std(cx: &TestCtxt) -> P<ast::Item> {
         (ast::ItemKind::Use(P(ast::UseTree {
             span: DUMMY_SP,
             prefix: path_node(vec![id_test]),
-            kind: ast::UseTreeKind::Simple(id_test),
+            kind: ast::UseTreeKind::Simple(None),
         })),
          ast::VisibilityKind::Public, keywords::Invalid.ident())
     } else {
@@ -590,13 +591,13 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) {
         tokens: None,
     })).pop().unwrap();
     let reexport = cx.reexport_test_harness_main.map(|s| {
-        // building `use <ident> = __test::main`
-        let reexport_ident = Ident::with_empty_ctxt(s);
+        // building `use __test::main as <ident>;`
+        let rename = Ident::with_empty_ctxt(s);
 
         let use_path = ast::UseTree {
             span: DUMMY_SP,
             prefix: path_node(vec![mod_ident, Ident::from_str("main")]),
-            kind: ast::UseTreeKind::Simple(reexport_ident),
+            kind: ast::UseTreeKind::Simple(Some(rename)),
         };
 
         expander.fold_item(P(ast::Item {
index 3bf9bfab2456366d8a47c4d09458d53493363528..bbf1fe124f1ba3f4f4b29fe124873bc3dab25bc6 100644 (file)
@@ -354,10 +354,11 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(
     visitor: &mut V, use_tree: &'a UseTree, id: NodeId,
 ) {
     visitor.visit_path(&use_tree.prefix, id);
-
     match use_tree.kind {
-        UseTreeKind::Simple(ident) => {
-            visitor.visit_ident(use_tree.span, ident);
+        UseTreeKind::Simple(rename) => {
+            if let Some(rename) = rename {
+                visitor.visit_ident(use_tree.span, rename);
+            }
         }
         UseTreeKind::Glob => {},
         UseTreeKind::Nested(ref use_trees) => {
index 1c0401ec56b853bbbde4ced5ec2aef8f51b75ab3..214a03c13f4e56bde68d486ad77b99e0427e2687 100644 (file)
@@ -9,12 +9,12 @@
 // except according to those terms.
 
 #![deny(unused_import_braces)]
-#![allow(dead_code)]
-#![allow(unused_imports)]
 
 use test::{A}; //~ ERROR braces around A is unnecessary
 
 mod test {
+    use test::{self}; // OK
+    use test::{self as rename}; // OK
     pub struct A;
 }