diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2018-03-09 18:58:44 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2018-03-17 22:12:21 +0300 |
| commit | b057c554ab9c7615ebdb3c920010a164ec5bf3ed (patch) | |
| tree | 3fcc7c2945653152d55af9c48a498b9bb5384c94 /src/libsyntax | |
| parent | c6c6cf9515b330551b04f36025bc72e1288a96d9 (diff) | |
| download | rust-b057c554ab9c7615ebdb3c920010a164ec5bf3ed.tar.gz rust-b057c554ab9c7615ebdb3c920010a164ec5bf3ed.zip | |
AST: Make renames in imports closer to the source
Fix `unused_import_braces` lint false positive on `use prefix::{self as rename}`
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/test.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 7 |
7 files changed, 36 insertions, 26 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7ced6424824..fdb32486b5d 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1880,18 +1880,29 @@ pub type Variant = Spanned<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. diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index b88e064e7e5..97f784dd617 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -294,7 +294,7 @@ pub trait AstBuilder { 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 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } 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 @@ impl<'a> AstBuilder for ExtCtxt<'a> { (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(); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 1a65fb7639a..146f580e04e 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -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)) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d1234d25764..7a432930490 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7033,9 +7033,7 @@ impl<'a> Parser<'a> { } } 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()?) } }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 097c0fd16d0..18a758ba968 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2949,13 +2949,12 @@ impl<'a> State<'a> { 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 => { diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 39306229c82..9edfa767d31 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -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 { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 3bf9bfab245..bbf1fe124f1 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -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) => { |
