Skip to content

Commit

Permalink
rustc: rename multiple imports in a list
Browse files Browse the repository at this point in the history
  • Loading branch information
seanmonstar committed Aug 8, 2015
1 parent d034561 commit cfcd449
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 33 deletions.
1 change: 1 addition & 0 deletions src/grammar/parser-lalr.y
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ visibility

idents_or_self
: ident_or_self { $$ = mk_node("IdentsOrSelf", 1, $1); }
| ident_or_self AS ident { $$ = mk_node("IdentsOrSelf", 2, $1, $3); }
| idents_or_self ',' ident_or_self { $$ = ext_node($1, 1, $3); }
;

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -862,11 +862,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
if let ast::ViewPathList(ref prefix, ref list) = vpath.node {
for pid in list {
match pid.node {
ast::PathListIdent { id, name } => {
ast::PathListIdent { id, name, .. } => {
debug!("privacy - ident item {}", id);
self.check_path(pid.span, id, name.name);
}
ast::PathListMod { id } => {
ast::PathListMod { id, .. } => {
debug!("privacy - mod item {}", id);
let name = prefix.segments.last().unwrap().identifier.name;
self.check_path(pid.span, id, name);
Expand Down
13 changes: 7 additions & 6 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,10 +341,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
}

for source_item in source_items {
let (module_path, name) = match source_item.node {
PathListIdent { name, .. } =>
(module_path.clone(), name.name),
PathListMod { .. } => {
let (module_path, name, rename) = match source_item.node {
PathListIdent { name, rename, .. } =>
(module_path.clone(), name.name, rename.unwrap_or(name).name),
PathListMod { rename, .. } => {
let name = match module_path.last() {
Some(name) => *name,
None => {
Expand All @@ -358,13 +358,14 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
}
};
let module_path = module_path.split_last().unwrap().1;
(module_path.to_vec(), name)
let rename = rename.map(|n| n.name).unwrap_or(name);
(module_path.to_vec(), name, rename)
}
};
self.build_import_directive(
&**parent,
module_path,
SingleImport(name, name),
SingleImport(rename, name),
source_item.span,
source_item.node.id(),
is_public,
Expand Down
9 changes: 6 additions & 3 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2362,7 +2362,7 @@ impl Clean<Vec<Item>> for doctree::Import {
let remaining = if !denied {
let mut remaining = vec![];
for path in list {
match inline::try_inline(cx, path.node.id(), None) {
match inline::try_inline(cx, path.node.id(), path.node.rename()) {
Some(items) => {
ret.extend(items);
}
Expand Down Expand Up @@ -2424,18 +2424,21 @@ pub struct ImportSource {
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct ViewListIdent {
pub name: String,
pub rename: Option<String>,
pub source: Option<ast::DefId>,
}

impl Clean<ViewListIdent> for ast::PathListItem {
fn clean(&self, cx: &DocContext) -> ViewListIdent {
match self.node {
ast::PathListIdent { id, name } => ViewListIdent {
ast::PathListIdent { id, name, rename } => ViewListIdent {
name: name.clean(cx),
rename: rename.map(|r| r.clean(cx)),
source: resolve_def(cx, id)
},
ast::PathListMod { id } => ViewListIdent {
ast::PathListMod { id, rename } => ViewListIdent {
name: "self".to_string(),
rename: rename.map(|r| r.clean(cx)),
source: resolve_def(cx, id)
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,10 +687,15 @@ impl fmt::Display for clean::ViewListIdent {
match self.source {
Some(did) => {
let path = clean::Path::singleton(self.name.clone());
resolved_path(f, did, &path, false)
try!(resolved_path(f, did, &path, false));
}
_ => write!(f, "{}", self.name),
_ => try!(write!(f, "{}", self.name)),
}

if let Some(ref name) = self.rename {
try!(write!(f, " as {}", name));
}
Ok(())
}
}

Expand Down
21 changes: 18 additions & 3 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1656,14 +1656,29 @@ pub type Variant = Spanned<Variant_>;

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum PathListItem_ {
PathListIdent { name: Ident, id: NodeId },
PathListMod { id: NodeId }
PathListIdent {
name: Ident,
/// renamed in list, eg `use foo::{bar as baz};`
rename: Option<Ident>,
id: NodeId
},
PathListMod {
/// renamed in list, eg `use foo::{self as baz};`
rename: Option<Ident>,
id: NodeId
}
}

impl PathListItem_ {
pub fn id(&self) -> NodeId {
match *self {
PathListIdent { id, .. } | PathListMod { id } => id
PathListIdent { id, .. } | PathListMod { id, .. } => id
}
}

pub fn rename(&self) -> Option<Ident> {
match *self {
PathListIdent { rename, .. } | PathListMod { rename, .. } => rename
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn item_use_list(&self, sp: Span, vis: ast::Visibility,
path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item> {
let imports = imports.iter().map(|id| {
respan(sp, ast::PathListIdent { name: *id, id: ast::DUMMY_NODE_ID })
respan(sp, ast::PathListIdent { name: *id, rename: None, id: ast::DUMMY_NODE_ID })
}).collect();

self.item_use(sp, vis,
Expand Down
10 changes: 7 additions & 3 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,17 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<
path_list_idents.move_map(|path_list_ident| {
Spanned {
node: match path_list_ident.node {
PathListIdent { id, name } =>
PathListIdent { id, name, rename } =>
PathListIdent {
id: fld.new_id(id),
rename: rename,
name: name
},
PathListMod { id } =>
PathListMod { id: fld.new_id(id) }
PathListMod { id, rename } =>
PathListMod {
id: fld.new_id(id),
rename: rename
}
},
span: fld.new_span(path_list_ident.span)
}
Expand Down
20 changes: 14 additions & 6 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,10 +573,12 @@ impl<'a> Parser<'a> {
pub fn parse_path_list_item(&mut self) -> PResult<ast::PathListItem> {
let lo = self.span.lo;
let node = if try!(self.eat_keyword(keywords::SelfValue)) {
ast::PathListMod { id: ast::DUMMY_NODE_ID }
let rename = try!(self.parse_rename());
ast::PathListMod { id: ast::DUMMY_NODE_ID, rename: rename }
} else {
let ident = try!(self.parse_ident());
ast::PathListIdent { name: ident, id: ast::DUMMY_NODE_ID }
let rename = try!(self.parse_rename());
ast::PathListIdent { name: ident, rename: rename, id: ast::DUMMY_NODE_ID }
};
let hi = self.last_span.hi;
Ok(spanned(lo, hi, node))
Expand Down Expand Up @@ -5104,8 +5106,8 @@ impl<'a> Parser<'a> {
-> PResult<P<Item>> {

let crate_name = try!(self.parse_ident());
let (maybe_path, ident) = if try!(self.eat_keyword(keywords::As)) {
(Some(crate_name.name), try!(self.parse_ident()))
let (maybe_path, ident) = if let Some(ident) = try!(self.parse_rename()) {
(Some(crate_name.name), ident)
} else {
(None, crate_name)
};
Expand Down Expand Up @@ -5766,10 +5768,16 @@ impl<'a> Parser<'a> {
}
}).collect()
};
rename_to = try!(self.parse_rename()).unwrap_or(rename_to);
Ok(P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path))))
}

fn parse_rename(&mut self) -> PResult<Option<Ident>> {
if try!(self.eat_keyword(keywords::As)) {
rename_to = try!(self.parse_ident())
self.parse_ident().map(Some)
} else {
Ok(None)
}
Ok(P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path))))
}

/// Parses a source module as a crate. This is the main
Expand Down
20 changes: 16 additions & 4 deletions src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2643,11 +2643,23 @@ impl<'a> State<'a> {
}
try!(self.commasep(Inconsistent, &idents[..], |s, w| {
match w.node {
ast::PathListIdent { name, .. } => {
s.print_ident(name)
ast::PathListIdent { name, rename, .. } => {
try!(s.print_ident(name));
if let Some(ident) = rename {
try!(space(&mut s.s));
try!(s.word_space("as"));
try!(s.print_ident(ident));
}
Ok(())
},
ast::PathListMod { .. } => {
word(&mut s.s, "self")
ast::PathListMod { rename, .. } => {
try!(word(&mut s.s, "self"));
if let Some(ident) = rename {
try!(space(&mut s.s));
try!(s.word_space("as"));
try!(s.print_ident(ident));
}
Ok(())
}
}
}));
Expand Down
11 changes: 9 additions & 2 deletions src/libsyntax/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,17 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
ViewPathList(ref prefix, ref list) => {
for id in list {
match id.node {
PathListIdent { name, .. } => {
PathListIdent { name, rename, .. } => {
visitor.visit_ident(id.span, name);
if let Some(ident) = rename {
visitor.visit_ident(id.span, ident);
}
}
PathListMod { rename, .. } => {
if let Some(ident) = rename {
visitor.visit_ident(id.span, ident);
}
}
PathListMod { .. } => ()
}
}

Expand Down
16 changes: 15 additions & 1 deletion src/test/compile-fail/unresolved-import.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand All @@ -12,6 +12,20 @@ use foo::bar; //~ ERROR unresolved import `foo::bar`. Maybe a missing `extern cr

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

use food::baz; //~ ERROR unresolved import `food::baz`. There is no `baz` in `food`

use food::{quux as beans}; //~ ERROR unresolved import `food::quux`. There is no `quux` in `food`

mod bar {
struct bar;
}

mod food {
pub use self::zug::baz::{self as bag, quux as beans};

mod zug {
pub mod baz {
pub struct quux;
}
}
}
14 changes: 14 additions & 0 deletions src/test/pretty/import-renames.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// pp-exact

use std::io::{self, Error as IoError};
use std::net::{self as stdnet, TcpStream};
21 changes: 21 additions & 0 deletions src/test/run-pass/import-rename.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use foo::{x, y as fooy};
use Maybe::{Yes as MaybeYes};

pub enum Maybe { Yes, No }
mod foo {
use super::Maybe::{self as MaybeFoo};
pub fn x(a: MaybeFoo) {}
pub fn y(a: i32) { println!("{}", a); }
}

pub fn main() { x(MaybeYes); fooy(10); }
3 changes: 3 additions & 0 deletions src/test/run-pass/use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ extern crate std as zed;

use std::str;
use zed::str as x;

use std::io::{self, Error as IoError, Result as IoResult};
use std::error::{self as foo};
mod baz {
pub use std::str as x;
}
Expand Down
28 changes: 28 additions & 0 deletions src/test/rustdoc/viewpath-rename.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![crate_name = "foo"]

pub mod io {
pub trait Reader { fn dummy(&self) { } }
}

pub enum Maybe<A> {
Just(A),
Nothing
}

// @has foo/prelude/index.html
pub mod prelude {
// @has foo/prelude/index.html '//code' 'pub use io::{self as FooIo, Reader as FooReader}'
#[doc(no_inline)] pub use io::{self as FooIo, Reader as FooReader};
// @has foo/prelude/index.html '//code' 'pub use Maybe::{self, Just as MaybeJust, Nothing}'
#[doc(no_inline)] pub use Maybe::{self, Just as MaybeJust, Nothing};
}

0 comments on commit cfcd449

Please sign in to comment.