Skip to content

Commit cfcd449

Browse files
committed
rustc: rename multiple imports in a list
1 parent d034561 commit cfcd449

File tree

16 files changed

+169
-33
lines changed

16 files changed

+169
-33
lines changed

src/grammar/parser-lalr.y

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ visibility
472472

473473
idents_or_self
474474
: ident_or_self { $$ = mk_node("IdentsOrSelf", 1, $1); }
475+
| ident_or_self AS ident { $$ = mk_node("IdentsOrSelf", 2, $1, $3); }
475476
| idents_or_self ',' ident_or_self { $$ = ext_node($1, 1, $3); }
476477
;
477478

src/librustc_privacy/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -862,11 +862,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
862862
if let ast::ViewPathList(ref prefix, ref list) = vpath.node {
863863
for pid in list {
864864
match pid.node {
865-
ast::PathListIdent { id, name } => {
865+
ast::PathListIdent { id, name, .. } => {
866866
debug!("privacy - ident item {}", id);
867867
self.check_path(pid.span, id, name.name);
868868
}
869-
ast::PathListMod { id } => {
869+
ast::PathListMod { id, .. } => {
870870
debug!("privacy - mod item {}", id);
871871
let name = prefix.segments.last().unwrap().identifier.name;
872872
self.check_path(pid.span, id, name);

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
341341
}
342342

343343
for source_item in source_items {
344-
let (module_path, name) = match source_item.node {
345-
PathListIdent { name, .. } =>
346-
(module_path.clone(), name.name),
347-
PathListMod { .. } => {
344+
let (module_path, name, rename) = match source_item.node {
345+
PathListIdent { name, rename, .. } =>
346+
(module_path.clone(), name.name, rename.unwrap_or(name).name),
347+
PathListMod { rename, .. } => {
348348
let name = match module_path.last() {
349349
Some(name) => *name,
350350
None => {
@@ -358,13 +358,14 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
358358
}
359359
};
360360
let module_path = module_path.split_last().unwrap().1;
361-
(module_path.to_vec(), name)
361+
let rename = rename.map(|n| n.name).unwrap_or(name);
362+
(module_path.to_vec(), name, rename)
362363
}
363364
};
364365
self.build_import_directive(
365366
&**parent,
366367
module_path,
367-
SingleImport(name, name),
368+
SingleImport(rename, name),
368369
source_item.span,
369370
source_item.node.id(),
370371
is_public,

src/librustdoc/clean/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,7 +2362,7 @@ impl Clean<Vec<Item>> for doctree::Import {
23622362
let remaining = if !denied {
23632363
let mut remaining = vec![];
23642364
for path in list {
2365-
match inline::try_inline(cx, path.node.id(), None) {
2365+
match inline::try_inline(cx, path.node.id(), path.node.rename()) {
23662366
Some(items) => {
23672367
ret.extend(items);
23682368
}
@@ -2424,18 +2424,21 @@ pub struct ImportSource {
24242424
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
24252425
pub struct ViewListIdent {
24262426
pub name: String,
2427+
pub rename: Option<String>,
24272428
pub source: Option<ast::DefId>,
24282429
}
24292430

24302431
impl Clean<ViewListIdent> for ast::PathListItem {
24312432
fn clean(&self, cx: &DocContext) -> ViewListIdent {
24322433
match self.node {
2433-
ast::PathListIdent { id, name } => ViewListIdent {
2434+
ast::PathListIdent { id, name, rename } => ViewListIdent {
24342435
name: name.clean(cx),
2436+
rename: rename.map(|r| r.clean(cx)),
24352437
source: resolve_def(cx, id)
24362438
},
2437-
ast::PathListMod { id } => ViewListIdent {
2439+
ast::PathListMod { id, rename } => ViewListIdent {
24382440
name: "self".to_string(),
2441+
rename: rename.map(|r| r.clean(cx)),
24392442
source: resolve_def(cx, id)
24402443
}
24412444
}

src/librustdoc/html/format.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -687,10 +687,15 @@ impl fmt::Display for clean::ViewListIdent {
687687
match self.source {
688688
Some(did) => {
689689
let path = clean::Path::singleton(self.name.clone());
690-
resolved_path(f, did, &path, false)
690+
try!(resolved_path(f, did, &path, false));
691691
}
692-
_ => write!(f, "{}", self.name),
692+
_ => try!(write!(f, "{}", self.name)),
693+
}
694+
695+
if let Some(ref name) = self.rename {
696+
try!(write!(f, " as {}", name));
693697
}
698+
Ok(())
694699
}
695700
}
696701

src/libsyntax/ast.rs

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

16571657
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
16581658
pub enum PathListItem_ {
1659-
PathListIdent { name: Ident, id: NodeId },
1660-
PathListMod { id: NodeId }
1659+
PathListIdent {
1660+
name: Ident,
1661+
/// renamed in list, eg `use foo::{bar as baz};`
1662+
rename: Option<Ident>,
1663+
id: NodeId
1664+
},
1665+
PathListMod {
1666+
/// renamed in list, eg `use foo::{self as baz};`
1667+
rename: Option<Ident>,
1668+
id: NodeId
1669+
}
16611670
}
16621671

16631672
impl PathListItem_ {
16641673
pub fn id(&self) -> NodeId {
16651674
match *self {
1666-
PathListIdent { id, .. } | PathListMod { id } => id
1675+
PathListIdent { id, .. } | PathListMod { id, .. } => id
1676+
}
1677+
}
1678+
1679+
pub fn rename(&self) -> Option<Ident> {
1680+
match *self {
1681+
PathListIdent { rename, .. } | PathListMod { rename, .. } => rename
16671682
}
16681683
}
16691684
}

src/libsyntax/ext/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
11411141
fn item_use_list(&self, sp: Span, vis: ast::Visibility,
11421142
path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item> {
11431143
let imports = imports.iter().map(|id| {
1144-
respan(sp, ast::PathListIdent { name: *id, id: ast::DUMMY_NODE_ID })
1144+
respan(sp, ast::PathListIdent { name: *id, rename: None, id: ast::DUMMY_NODE_ID })
11451145
}).collect();
11461146

11471147
self.item_use(sp, vis,

src/libsyntax/fold.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,13 +335,17 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<
335335
path_list_idents.move_map(|path_list_ident| {
336336
Spanned {
337337
node: match path_list_ident.node {
338-
PathListIdent { id, name } =>
338+
PathListIdent { id, name, rename } =>
339339
PathListIdent {
340340
id: fld.new_id(id),
341+
rename: rename,
341342
name: name
342343
},
343-
PathListMod { id } =>
344-
PathListMod { id: fld.new_id(id) }
344+
PathListMod { id, rename } =>
345+
PathListMod {
346+
id: fld.new_id(id),
347+
rename: rename
348+
}
345349
},
346350
span: fld.new_span(path_list_ident.span)
347351
}

src/libsyntax/parse/parser.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -573,10 +573,12 @@ impl<'a> Parser<'a> {
573573
pub fn parse_path_list_item(&mut self) -> PResult<ast::PathListItem> {
574574
let lo = self.span.lo;
575575
let node = if try!(self.eat_keyword(keywords::SelfValue)) {
576-
ast::PathListMod { id: ast::DUMMY_NODE_ID }
576+
let rename = try!(self.parse_rename());
577+
ast::PathListMod { id: ast::DUMMY_NODE_ID, rename: rename }
577578
} else {
578579
let ident = try!(self.parse_ident());
579-
ast::PathListIdent { name: ident, id: ast::DUMMY_NODE_ID }
580+
let rename = try!(self.parse_rename());
581+
ast::PathListIdent { name: ident, rename: rename, id: ast::DUMMY_NODE_ID }
580582
};
581583
let hi = self.last_span.hi;
582584
Ok(spanned(lo, hi, node))
@@ -5104,8 +5106,8 @@ impl<'a> Parser<'a> {
51045106
-> PResult<P<Item>> {
51055107

51065108
let crate_name = try!(self.parse_ident());
5107-
let (maybe_path, ident) = if try!(self.eat_keyword(keywords::As)) {
5108-
(Some(crate_name.name), try!(self.parse_ident()))
5109+
let (maybe_path, ident) = if let Some(ident) = try!(self.parse_rename()) {
5110+
(Some(crate_name.name), ident)
51095111
} else {
51105112
(None, crate_name)
51115113
};
@@ -5766,10 +5768,16 @@ impl<'a> Parser<'a> {
57665768
}
57675769
}).collect()
57685770
};
5771+
rename_to = try!(self.parse_rename()).unwrap_or(rename_to);
5772+
Ok(P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path))))
5773+
}
5774+
5775+
fn parse_rename(&mut self) -> PResult<Option<Ident>> {
57695776
if try!(self.eat_keyword(keywords::As)) {
5770-
rename_to = try!(self.parse_ident())
5777+
self.parse_ident().map(Some)
5778+
} else {
5779+
Ok(None)
57715780
}
5772-
Ok(P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path))))
57735781
}
57745782

57755783
/// Parses a source module as a crate. This is the main

src/libsyntax/print/pprust.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2643,11 +2643,23 @@ impl<'a> State<'a> {
26432643
}
26442644
try!(self.commasep(Inconsistent, &idents[..], |s, w| {
26452645
match w.node {
2646-
ast::PathListIdent { name, .. } => {
2647-
s.print_ident(name)
2646+
ast::PathListIdent { name, rename, .. } => {
2647+
try!(s.print_ident(name));
2648+
if let Some(ident) = rename {
2649+
try!(space(&mut s.s));
2650+
try!(s.word_space("as"));
2651+
try!(s.print_ident(ident));
2652+
}
2653+
Ok(())
26482654
},
2649-
ast::PathListMod { .. } => {
2650-
word(&mut s.s, "self")
2655+
ast::PathListMod { rename, .. } => {
2656+
try!(word(&mut s.s, "self"));
2657+
if let Some(ident) = rename {
2658+
try!(space(&mut s.s));
2659+
try!(s.word_space("as"));
2660+
try!(s.print_ident(ident));
2661+
}
2662+
Ok(())
26512663
}
26522664
}
26532665
}));

src/libsyntax/visit.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,17 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
233233
ViewPathList(ref prefix, ref list) => {
234234
for id in list {
235235
match id.node {
236-
PathListIdent { name, .. } => {
236+
PathListIdent { name, rename, .. } => {
237237
visitor.visit_ident(id.span, name);
238+
if let Some(ident) = rename {
239+
visitor.visit_ident(id.span, ident);
240+
}
241+
}
242+
PathListMod { rename, .. } => {
243+
if let Some(ident) = rename {
244+
visitor.visit_ident(id.span, ident);
245+
}
238246
}
239-
PathListMod { .. } => ()
240247
}
241248
}
242249

src/test/compile-fail/unresolved-import.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -12,6 +12,20 @@ use foo::bar; //~ ERROR unresolved import `foo::bar`. Maybe a missing `extern cr
1212

1313
use bar::baz as x; //~ ERROR unresolved import `bar::baz`. There is no `baz` in `bar`
1414

15+
use food::baz; //~ ERROR unresolved import `food::baz`. There is no `baz` in `food`
16+
17+
use food::{quux as beans}; //~ ERROR unresolved import `food::quux`. There is no `quux` in `food`
18+
1519
mod bar {
1620
struct bar;
1721
}
22+
23+
mod food {
24+
pub use self::zug::baz::{self as bag, quux as beans};
25+
26+
mod zug {
27+
pub mod baz {
28+
pub struct quux;
29+
}
30+
}
31+
}

src/test/pretty/import-renames.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// pp-exact
12+
13+
use std::io::{self, Error as IoError};
14+
use std::net::{self as stdnet, TcpStream};

src/test/run-pass/import-rename.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use foo::{x, y as fooy};
12+
use Maybe::{Yes as MaybeYes};
13+
14+
pub enum Maybe { Yes, No }
15+
mod foo {
16+
use super::Maybe::{self as MaybeFoo};
17+
pub fn x(a: MaybeFoo) {}
18+
pub fn y(a: i32) { println!("{}", a); }
19+
}
20+
21+
pub fn main() { x(MaybeYes); fooy(10); }

src/test/run-pass/use.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ extern crate std as zed;
1919

2020
use std::str;
2121
use zed::str as x;
22+
23+
use std::io::{self, Error as IoError, Result as IoResult};
24+
use std::error::{self as foo};
2225
mod baz {
2326
pub use std::str as x;
2427
}

src/test/rustdoc/viewpath-rename.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![crate_name = "foo"]
12+
13+
pub mod io {
14+
pub trait Reader { fn dummy(&self) { } }
15+
}
16+
17+
pub enum Maybe<A> {
18+
Just(A),
19+
Nothing
20+
}
21+
22+
// @has foo/prelude/index.html
23+
pub mod prelude {
24+
// @has foo/prelude/index.html '//code' 'pub use io::{self as FooIo, Reader as FooReader}'
25+
#[doc(no_inline)] pub use io::{self as FooIo, Reader as FooReader};
26+
// @has foo/prelude/index.html '//code' 'pub use Maybe::{self, Just as MaybeJust, Nothing}'
27+
#[doc(no_inline)] pub use Maybe::{self, Just as MaybeJust, Nothing};
28+
}

0 commit comments

Comments
 (0)