From bc096549e84d1edbd051f0b42662c038dd935ff6 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 24 Nov 2016 06:11:31 +0200 Subject: [PATCH] rustc: desugar `use a::{b,c};` into `use a::b; use a::c;` in HIR. --- src/librustc/hir/intravisit.rs | 29 +-- src/librustc/hir/lowering.rs | 194 +++++++++++------- src/librustc/hir/map/collector.rs | 10 - src/librustc/hir/map/def_collector.rs | 15 +- src/librustc/hir/map/mod.rs | 12 +- src/librustc/hir/mod.rs | 46 ++--- src/librustc/hir/print.rs | 50 ++--- src/librustc/lint/context.rs | 5 - src/librustc/lint/mod.rs | 1 - src/librustc/middle/dead.rs | 5 - src/librustc/middle/reachable.rs | 2 +- src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc/middle/stability.rs | 14 -- .../calculate_svh/svh_visitor.rs | 13 +- src/librustc_lint/builtin.rs | 8 - src/librustc_lint/lib.rs | 2 +- src/librustc_lint/unused.rs | 10 +- src/librustc_metadata/encoder.rs | 4 +- src/librustc_passes/hir_stats.rs | 6 - src/librustc_typeck/check_unused.rs | 13 +- src/librustc_typeck/collect.rs | 2 +- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustc_typeck/variance/terms.rs | 2 +- src/librustdoc/clean/mod.rs | 72 ++----- src/librustdoc/doctree.rs | 4 +- src/librustdoc/html/format.rs | 27 --- src/librustdoc/visit_ast.rs | 59 ++---- src/test/rustdoc/viewpath-rename.rs | 7 +- src/test/rustdoc/viewpath-self.rs | 7 +- 29 files changed, 228 insertions(+), 395 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 743eed74d0c..3de788b8c1a 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -250,9 +250,6 @@ pub trait Visitor<'v> : Sized { fn visit_path(&mut self, path: &'v Path, _id: NodeId) { walk_path(self, path) } - fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) { - walk_path_list_item(self, prefix, item) - } fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) { walk_path_segment(self, path_span, path_segment) } @@ -352,23 +349,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_id(item.id); walk_opt_name(visitor, item.span, opt_name) } - ItemUse(ref vp) => { + ItemUse(ref path, _) => { visitor.visit_id(item.id); - match vp.node { - ViewPathSimple(name, ref path) => { - visitor.visit_name(vp.span, name); - visitor.visit_path(path, item.id); - } - ViewPathGlob(ref path) => { - visitor.visit_path(path, item.id); - } - ViewPathList(ref prefix, ref list) => { - visitor.visit_path(prefix, item.id); - for item in list { - visitor.visit_path_list_item(prefix, item) - } - } - } + visitor.visit_path(path, item.id); } ItemStatic(ref typ, _, ref expr) | ItemConst(ref typ, ref expr) => { @@ -529,14 +512,6 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { } } -pub fn walk_path_list_item<'v, V>(visitor: &mut V, _prefix: &'v Path, item: &'v PathListItem) - where V: Visitor<'v>, -{ - visitor.visit_id(item.node.id); - visitor.visit_name(item.span, item.node.name); - walk_opt_name(visitor, item.span, item.node.rename); -} - pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, path_span: Span, segment: &'v PathSegment) { diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 056c1b90620..af0448cc277 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -55,6 +55,7 @@ use syntax::ptr::P; use syntax::codemap::{respan, Spanned}; use syntax::std_inject; use syntax::symbol::{Symbol, keywords}; +use syntax::util::small_vector::SmallVector; use syntax::visit::{self, Visitor}; use syntax_pos::Span; @@ -67,6 +68,11 @@ pub struct LoweringContext<'a> { // a definition, then we can properly create the def id. parent_def: Option, resolver: &'a mut Resolver, + + /// The items being lowered are collected here. + items: BTreeMap, + + impl_items: BTreeMap, } pub trait Resolver { @@ -98,6 +104,8 @@ pub fn lower_crate(sess: &Session, sess: sess, parent_def: None, resolver: resolver, + items: BTreeMap::new(), + impl_items: BTreeMap::new(), }.lower_crate(krate) } @@ -110,41 +118,35 @@ enum ParamMode { } impl<'a> LoweringContext<'a> { - fn lower_crate(&mut self, c: &Crate) -> hir::Crate { + fn lower_crate(mut self, c: &Crate) -> hir::Crate { struct ItemLowerer<'lcx, 'interner: 'lcx> { - items: BTreeMap, - impl_items: BTreeMap, lctx: &'lcx mut LoweringContext<'interner>, } impl<'lcx, 'interner> Visitor for ItemLowerer<'lcx, 'interner> { fn visit_item(&mut self, item: &Item) { - self.items.insert(item.id, self.lctx.lower_item(item)); + let hir_item = self.lctx.lower_item(item); + self.lctx.items.insert(item.id, hir_item); visit::walk_item(self, item); } fn visit_impl_item(&mut self, item: &ImplItem) { let id = self.lctx.lower_impl_item_ref(item).id; - self.impl_items.insert(id, self.lctx.lower_impl_item(item)); + let hir_item = self.lctx.lower_impl_item(item); + self.lctx.impl_items.insert(id, hir_item); visit::walk_impl_item(self, item); } } - let (items, impl_items) = { - let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), - impl_items: BTreeMap::new(), - lctx: self }; - visit::walk_crate(&mut item_lowerer, c); - (item_lowerer.items, item_lowerer.impl_items) - }; + visit::walk_crate(&mut ItemLowerer { lctx: &mut self }, c); hir::Crate { module: self.lower_mod(&c.module), attrs: self.lower_attrs(&c.attrs), span: c.span, exported_macros: c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(), - items: items, - impl_items: impl_items, + items: self.items, + impl_items: self.impl_items, } } @@ -183,38 +185,6 @@ impl<'a> LoweringContext<'a> { attrs.clone().into() } - fn lower_view_path(&mut self, view_path: &ViewPath) -> P { - P(Spanned { - node: match view_path.node { - ViewPathSimple(ident, ref path) => { - hir::ViewPathSimple(ident.name, - self.lower_path(path, ParamMode::Explicit)) - } - ViewPathGlob(ref path) => { - hir::ViewPathGlob(self.lower_path(path, ParamMode::Explicit)) - } - ViewPathList(ref path, ref path_list_idents) => { - hir::ViewPathList(self.lower_path(path, ParamMode::Explicit), - path_list_idents.iter() - .map(|item| self.lower_path_list_item(item)) - .collect()) - } - }, - span: view_path.span, - }) - } - - fn lower_path_list_item(&mut self, path_list_ident: &PathListItem) -> hir::PathListItem { - Spanned { - node: hir::PathListItem_ { - id: path_list_ident.node.id, - name: path_list_ident.node.name.name, - rename: path_list_ident.node.rename.map(|rename| rename.name), - }, - span: path_list_ident.span, - } - } - fn lower_arm(&mut self, arm: &Arm) -> hir::Arm { hir::Arm { attrs: self.lower_attrs(&arm.attrs), @@ -382,19 +352,32 @@ impl<'a> LoweringContext<'a> { proj_start, p.segments.len()) } - fn lower_path(&mut self, - p: &Path, - param_mode: ParamMode) - -> hir::Path { + fn lower_path_extra(&mut self, + p: &Path, + name: Option, + param_mode: ParamMode) + -> hir::Path { hir::Path { global: p.global, segments: p.segments.iter().map(|segment| { self.lower_path_segment(segment, param_mode) - }).collect(), + }).chain(name.map(|name| { + hir::PathSegment { + name: name, + parameters: hir::PathParameters::none() + } + })).collect(), span: p.span, } } + fn lower_path(&mut self, + p: &Path, + param_mode: ParamMode) + -> hir::Path { + self.lower_path_extra(p, None, param_mode) + } + fn lower_path_segment(&mut self, segment: &PathSegment, param_mode: ParamMode) @@ -661,12 +644,10 @@ impl<'a> LoweringContext<'a> { } fn lower_block(&mut self, b: &Block) -> P { - let mut stmts = Vec::new(); let mut expr = None; - if let Some((last, rest)) = b.stmts.split_last() { - stmts = rest.iter().map(|s| self.lower_stmt(s)).collect::>(); - let last = self.lower_stmt(last); + let mut stmts = b.stmts.iter().flat_map(|s| self.lower_stmt(s)).collect::>(); + if let Some(last) = stmts.pop() { if let hir::StmtExpr(e, _) = last.node { expr = Some(e); } else { @@ -683,11 +664,65 @@ impl<'a> LoweringContext<'a> { }) } - fn lower_item_kind(&mut self, i: &ItemKind) -> hir::Item_ { + fn lower_item_kind(&mut self, + name: &mut Name, + attrs: &hir::HirVec, + vis: &mut hir::Visibility, + i: &ItemKind) + -> hir::Item_ { match *i { ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), ItemKind::Use(ref view_path) => { - hir::ItemUse(self.lower_view_path(view_path)) + let path = match view_path.node { + ViewPathSimple(_, ref path) => path, + ViewPathGlob(ref path) => path, + ViewPathList(ref path, ref path_list_idents) => { + for &Spanned { node: ref import, span } in path_list_idents { + // `use a::{self as x, b as y};` lowers to + // `use a as x; use a::b as y;` + let mut ident = import.name; + let suffix = if ident.name == keywords::SelfValue.name() { + if let Some(last) = path.segments.last() { + ident = last.identifier; + } + None + } else { + Some(ident.name) + }; + + let mut path = self.lower_path_extra(path, suffix, + ParamMode::Explicit); + path.span = span; + self.items.insert(import.id, hir::Item { + id: import.id, + name: import.rename.unwrap_or(ident).name, + attrs: attrs.clone(), + node: hir::ItemUse(P(path), hir::UseKind::Single), + vis: vis.clone(), + span: span, + }); + } + path + } + }; + let path = P(self.lower_path(path, ParamMode::Explicit)); + let kind = match view_path.node { + ViewPathSimple(ident, _) => { + *name = ident.name; + hir::UseKind::Single + } + ViewPathGlob(_) => { + hir::UseKind::Glob + } + ViewPathList(..) => { + // Privatize the degenerate import base, used only to check + // the stability of `use a::{};`, to avoid it showing up as + // a reexport by accident when `pub`, e.g. in documentation. + *vis = hir::Inherited; + hir::UseKind::ListStem + } + }; + hir::ItemUse(path, kind) } ItemKind::Static(ref t, m, ref e) => { hir::ItemStatic(self.lower_ty(t), @@ -835,7 +870,7 @@ impl<'a> LoweringContext<'a> { fn lower_mod(&mut self, m: &Mod) -> hir::Mod { hir::Mod { inner: m.inner, - item_ids: m.items.iter().map(|x| self.lower_item_id(x)).collect(), + item_ids: m.items.iter().flat_map(|x| self.lower_item_id(x)).collect(), } } @@ -851,21 +886,30 @@ impl<'a> LoweringContext<'a> { } } - fn lower_item_id(&mut self, i: &Item) -> hir::ItemId { - hir::ItemId { id: i.id } + fn lower_item_id(&mut self, i: &Item) -> SmallVector { + if let ItemKind::Use(ref view_path) = i.node { + if let ViewPathList(_, ref imports) = view_path.node { + return iter::once(i.id).chain(imports.iter().map(|import| import.node.id)) + .map(|id| hir::ItemId { id: id }).collect(); + } + } + SmallVector::one(hir::ItemId { id: i.id }) } pub fn lower_item(&mut self, i: &Item) -> hir::Item { + let mut name = i.ident.name; + let attrs = self.lower_attrs(&i.attrs); + let mut vis = self.lower_visibility(&i.vis); let node = self.with_parent_def(i.id, |this| { - this.lower_item_kind(&i.node) + this.lower_item_kind(&mut name, &attrs, &mut vis, &i.node) }); hir::Item { id: i.id, - name: i.ident.name, - attrs: self.lower_attrs(&i.attrs), + name: name, + attrs: attrs, node: node, - vis: self.lower_visibility(&i.vis), + vis: vis, span: i.span, } } @@ -1701,8 +1745,8 @@ impl<'a> LoweringContext<'a> { } } - fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt { - match s.node { + fn lower_stmt(&mut self, s: &Stmt) -> SmallVector { + SmallVector::one(match s.node { StmtKind::Local(ref l) => Spanned { node: hir::StmtDecl(P(Spanned { node: hir::DeclLocal(self.lower_local(l)), @@ -1710,13 +1754,17 @@ impl<'a> LoweringContext<'a> { }), s.id), span: s.span, }, - StmtKind::Item(ref it) => Spanned { - node: hir::StmtDecl(P(Spanned { - node: hir::DeclItem(self.lower_item_id(it)), + StmtKind::Item(ref it) => { + // Can only use the ID once. + let mut id = Some(s.id); + return self.lower_item_id(it).into_iter().map(|item_id| Spanned { + node: hir::StmtDecl(P(Spanned { + node: hir::DeclItem(item_id), + span: s.span, + }), id.take().unwrap_or_else(|| self.next_id())), span: s.span, - }), s.id), - span: s.span, - }, + }).collect(); + } StmtKind::Expr(ref e) => { Spanned { node: hir::StmtExpr(P(self.lower_expr(e)), s.id), @@ -1730,7 +1778,7 @@ impl<'a> LoweringContext<'a> { } } StmtKind::Mac(..) => panic!("Shouldn't exist here"), - } + }) } fn lower_capture_clause(&mut self, c: CaptureBy) -> hir::CaptureClause { diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 64bf4bbf080..67e9b24f42d 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -124,16 +124,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { this.insert(struct_def.id(), NodeStructCtor(struct_def)); } } - ItemUse(ref view_path) => { - match view_path.node { - ViewPathList(_, ref paths) => { - for path in paths { - this.insert(path.node.id, NodeItem(i)); - } - } - _ => () - } - } _ => {} } intravisit::walk_item(this, i); diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 7486d954c48..9d1c7d41faa 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -155,7 +155,20 @@ impl<'a> visit::Visitor for DefCollector<'a> { DefPathData::ValueNs(i.ident.name.as_str()), ItemKind::Mac(..) if i.id == DUMMY_NODE_ID => return, // Scope placeholder ItemKind::Mac(..) => return self.visit_macro_invoc(i.id, false), - ItemKind::Use(..) => DefPathData::Misc, + ItemKind::Use(ref view_path) => { + match view_path.node { + ViewPathGlob(..) => {} + + // FIXME(eddyb) Should use the real name. Which namespace? + ViewPathSimple(..) => {} + ViewPathList(_, ref imports) => { + for import in imports { + self.create_def(import.node.id, DefPathData::Misc); + } + } + } + DefPathData::Misc + } }; let def = self.create_def(i.id, def_data); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 7f6c85eeaac..a8986530d1d 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -250,16 +250,8 @@ impl<'ast> Map<'ast> { loop { match map[id.as_usize()] { EntryItem(_, item) => { - let def_id = self.local_def_id(item.id); - // NB ^~~~~~~ - // - // You would expect that `item.id == id`, but this - // is not always the case. In particular, for a - // ViewPath item like `use self::{mem, foo}`, we - // map the ids for `mem` and `foo` to the - // enclosing view path item. This seems mega super - // ultra wrong, but then who am I to judge? - // -nmatsakis + assert_eq!(id, item.id); + let def_id = self.local_def_id(id); assert!(!self.is_inlined_def_id(def_id)); return DepNode::Hir(def_id); } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index e9e84eed3e7..da759b2d4da 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -27,7 +27,6 @@ pub use self::Ty_::*; pub use self::TyParamBound::*; pub use self::UnOp::*; pub use self::UnsafeSource::*; -pub use self::ViewPath_::*; pub use self::Visibility::{Public, Inherited}; pub use self::PathParameters::*; @@ -1385,32 +1384,20 @@ pub struct Variant_ { pub type Variant = Spanned; -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub struct PathListItem_ { - pub name: Name, - /// renamed in list, eg `use foo::{bar as baz};` - pub rename: Option, - pub id: NodeId, -} +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum UseKind { + /// One import, e.g. `use foo::bar` or `use foo::bar as baz`. + /// Also produced for each element of a list `use`, e.g. + // `use foo::{a, b}` lowers to `use foo::a; use foo::b;`. + Single, -pub type PathListItem = Spanned; + /// Glob import, e.g. `use foo::*`. + Glob, -pub type ViewPath = Spanned; - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum ViewPath_ { - /// `foo::bar::baz as quux` - /// - /// or just - /// - /// `foo::bar::baz` (with `as baz` implicitly on the right) - ViewPathSimple(Name, Path), - - /// `foo::bar::*` - ViewPathGlob(Path), - - /// `foo::bar::{a,b,c}` - ViewPathList(Path, HirVec), + /// Degenerate list import, e.g. `use foo::{a, b}` produces + /// an additional `use foo::{}` for performing checks such as + /// unstable feature gating. May be removed in the future. + ListStem, } /// TraitRef's appear in impls. @@ -1544,8 +1531,13 @@ pub enum Item_ { /// /// e.g. `extern crate foo` or `extern crate foo_bar as foo` ItemExternCrate(Option), - /// A `use` or `pub use` item - ItemUse(P), + + /// `use foo::bar::*;` or `use foo::bar::baz as quux;` + /// + /// or just + /// + /// `use foo::bar::baz;` (with `as baz` implicitly on the right) + ItemUse(P, UseKind), /// A `static` item ItemStatic(P, Mutability, P), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index f6f40a91bf4..4dd08def251 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -669,10 +669,22 @@ impl<'a> State<'a> { self.end()?; // end inner head-block self.end()?; // end outer head-block } - hir::ItemUse(ref vp) => { + hir::ItemUse(ref path, kind) => { self.head(&visibility_qualified(&item.vis, "use"))?; - self.print_view_path(&vp)?; - word(&mut self.s, ";")?; + self.print_path(path, false)?; + + match kind { + hir::UseKind::Single => { + if path.segments.last().unwrap().name != item.name { + space(&mut self.s)?; + self.word_space("as")?; + self.print_name(item.name)?; + } + word(&mut self.s, ";")?; + } + hir::UseKind::Glob => word(&mut self.s, "::*;")?, + hir::UseKind::ListStem => word(&mut self.s, "::{};")? + } self.end()?; // end inner head-block self.end()?; // end outer head-block } @@ -2153,38 +2165,6 @@ impl<'a> State<'a> { Ok(()) } - pub fn print_view_path(&mut self, vp: &hir::ViewPath) -> io::Result<()> { - match vp.node { - hir::ViewPathSimple(name, ref path) => { - self.print_path(path, false)?; - - if path.segments.last().unwrap().name != name { - space(&mut self.s)?; - self.word_space("as")?; - self.print_name(name)?; - } - - Ok(()) - } - - hir::ViewPathGlob(ref path) => { - self.print_path(path, false)?; - word(&mut self.s, "::*") - } - - hir::ViewPathList(ref path, ref segments) => { - if path.segments.is_empty() { - word(&mut self.s, "{")?; - } else { - self.print_path(path, false)?; - word(&mut self.s, "::{")?; - } - self.commasep(Inconsistent, &segments[..], |s, w| s.print_name(w.node.name))?; - word(&mut self.s, "}") - } - } - } - pub fn print_mutability(&mut self, mutbl: hir::Mutability) -> io::Result<()> { match mutbl { hir::MutMutable => self.word_nbsp("mut"), diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 4a082944010..41c8d413486 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -948,11 +948,6 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { hir_visit::walk_path(self, p); } - fn visit_path_list_item(&mut self, prefix: &'tcx hir::Path, item: &'tcx hir::PathListItem) { - run_lints!(self, check_path_list_item, late_passes, item); - hir_visit::walk_path_list_item(self, prefix, item); - } - fn visit_attribute(&mut self, attr: &ast::Attribute) { check_lint_name_attribute(self, attr); run_lints!(self, check_attribute, late_passes, attr); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 6f7102229f8..4e06e0abf01 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -168,7 +168,6 @@ pub trait LateLintPass: LintPass { fn check_lifetime(&mut self, _: &LateContext, _: &hir::Lifetime) { } fn check_lifetime_def(&mut self, _: &LateContext, _: &hir::LifetimeDef) { } fn check_path(&mut self, _: &LateContext, _: &hir::Path, _: ast::NodeId) { } - fn check_path_list_item(&mut self, _: &LateContext, _: &hir::PathListItem) { } fn check_attribute(&mut self, _: &LateContext, _: &ast::Attribute) { } /// Called when entering a syntax node that can have lint attributes such diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index efbec7bf13b..ec064e264ab 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -297,11 +297,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> { self.lookup_and_handle_definition(id); intravisit::walk_path(self, path); } - - fn visit_path_list_item(&mut self, path: &hir::Path, item: &hir::PathListItem) { - self.lookup_and_handle_definition(item.node.id); - intravisit::walk_path_list_item(self, path, item); - } } fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool { diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 0329b4c4a30..91c1c63d890 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -265,7 +265,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // These are normal, nothing reachable about these // inherently and their children are already in the // worklist, as determined by the privacy pass - hir::ItemExternCrate(_) | hir::ItemUse(_) | + hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemTy(..) | hir::ItemStatic(..) | hir::ItemMod(..) | hir::ItemForeignMod(..) | hir::ItemImpl(..) | hir::ItemTrait(..) | diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index c65fd25950d..f256d6d9b4f 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -151,7 +151,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { intravisit::walk_item(this, item); } hir::ItemExternCrate(_) | - hir::ItemUse(_) | + hir::ItemUse(..) | hir::ItemMod(..) | hir::ItemDefaultImpl(..) | hir::ItemForeignMod(..) | diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index a044ffd9a7f..d7a29e190a8 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -474,12 +474,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { intravisit::walk_path(self, path) } - fn visit_path_list_item(&mut self, prefix: &'tcx hir::Path, item: &'tcx hir::PathListItem) { - check_path_list_item(self.tcx, item, - &mut |id, sp, stab, depr| self.check(id, sp, stab, depr)); - intravisit::walk_path_list_item(self, prefix, item) - } - fn visit_pat(&mut self, pat: &'tcx hir::Pat) { check_pat(self.tcx, pat, &mut |id, sp, stab, depr| self.check(id, sp, stab, depr)); @@ -628,14 +622,6 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } -pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - item: &hir::PathListItem, - cb: &mut FnMut(DefId, Span, - &Option<&Stability>, - &Option)) { - maybe_do_stability_check(tcx, tcx.expect_def(item.node.id).def_id(), item.span, cb); -} - pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat, cb: &mut FnMut(DefId, Span, &Option<&Stability>, diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index ec405311012..8c6d8dffa1d 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -189,7 +189,6 @@ enum SawAbiComponent<'a> { SawPath(bool), SawPathSegment, SawPathParameters, - SawPathListItem, SawBlock, SawPat(SawPatComponent), SawLocal, @@ -357,7 +356,7 @@ fn saw_lit(lit: &ast::Lit) -> SawExprComponent<'static> { #[derive(Hash)] enum SawItemComponent { SawItemExternCrate, - SawItemUse, + SawItemUse(UseKind), SawItemStatic(Mutability), SawItemConst, SawItemFn(Unsafety, Constness, Abi), @@ -375,7 +374,7 @@ enum SawItemComponent { fn saw_item(node: &Item_) -> SawItemComponent { match *node { ItemExternCrate(..) => SawItemExternCrate, - ItemUse(..) => SawItemUse, + ItemUse(_, kind) => SawItemUse(kind), ItemStatic(_, mutability, _) => SawItemStatic(mutability), ItemConst(..) =>SawItemConst, ItemFn(_, unsafety, constness, abi, _, _) => SawItemFn(unsafety, constness, abi), @@ -747,14 +746,6 @@ impl<'a, 'hash, 'tcx> visit::Visitor<'tcx> for StrictVersionHashVisitor<'a, 'has visit::walk_poly_trait_ref(self, t, m) } - fn visit_path_list_item(&mut self, prefix: &'tcx Path, item: &'tcx PathListItem) { - debug!("visit_path_list_item: st={:?}", self.st); - SawPathListItem.hash(self.st); - self.hash_discriminant(&item.node); - hash_span!(self, item.span); - visit::walk_path_list_item(self, prefix, item) - } - fn visit_path_segment(&mut self, path_span: Span, path_segment: &'tcx PathSegment) { debug!("visit_path_segment: st={:?}", self.st); SawPathSegment.hash(self.st); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 7be591293c9..d91327bc86b 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -704,14 +704,6 @@ impl LateLintPass for Deprecated { &mut |id, sp, stab, depr| self.lint(cx, id, sp, &stab, &depr)); } - fn check_path_list_item(&mut self, cx: &LateContext, item: &hir::PathListItem) { - stability::check_path_list_item(cx.tcx, - item, - &mut |id, sp, stab, depr| { - self.lint(cx, id, sp, &stab, &depr) - }); - } - fn check_pat(&mut self, cx: &LateContext, pat: &hir::Pat) { stability::check_pat(cx.tcx, pat, diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 1a3ea5db871..0b92107c817 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -111,6 +111,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { add_early_builtin!(sess, UnusedParens, + UnusedImportBraces, ); add_early_builtin_with_new!(sess, @@ -129,7 +130,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { NonCamelCaseTypes, NonSnakeCase, NonUpperCaseGlobals, - UnusedImportBraces, NonShorthandFieldPatterns, UnusedUnsafe, UnsafeCode, diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index d0ad682fb58..324cbd17ab3 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -406,11 +406,11 @@ impl LintPass for UnusedImportBraces { } } -impl LateLintPass for UnusedImportBraces { - fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { - if let hir::ItemUse(ref view_path) = item.node { - if let hir::ViewPathList(_, ref items) = view_path.node { - if items.len() == 1 && items[0].node.name != keywords::SelfValue.name() { +impl EarlyLintPass for UnusedImportBraces { + fn check_item(&mut self, cx: &EarlyContext, item: &ast::Item) { + if let ast::ItemKind::Use(ref view_path) = item.node { + if let ast::ViewPathList(_, ref items) = view_path.node { + if items.len() == 1 && items[0].node.name.name != keywords::SelfValue.name() { let msg = format!("braces around {} is unnecessary", items[0].node.name); cx.span_lint(UNUSED_IMPORT_BRACES, item.span, &msg); } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 665f3de0a3b..8f3e8a48b1a 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -729,7 +729,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { EntryKind::Trait(self.lazy(&data)) } hir::ItemExternCrate(_) | - hir::ItemUse(_) => bug!("cannot encode info for item {:?}", item), + hir::ItemUse(..) => bug!("cannot encode info for item {:?}", item), }; Entry { @@ -982,7 +982,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { let def_id = self.index.tcx.map.local_def_id(item.id); match item.node { hir::ItemExternCrate(_) | - hir::ItemUse(_) => (), // ignore these + hir::ItemUse(..) => (), // ignore these _ => self.index.record(def_id, EncodeContext::encode_info_for_item, (def_id, item)), } self.index.encode_addl_info_for_item(item); diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index 9028821ef11..ba236ea93a4 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -226,12 +226,6 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { self.record("Path", Id::None, path); hir_visit::walk_path(self, path) } - fn visit_path_list_item(&mut self, - prefix: &'v hir::Path, - item: &'v hir::PathListItem) { - self.record("PathListItem", Id::Node(item.node.id), item); - hir_visit::walk_path_list_item(self, prefix, item) - } fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v hir::PathSegment) { diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index b4a10c52270..0034a85f8e2 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -45,17 +45,8 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for UnusedTraitImportVisitor<'a, 'tcx> { if item.vis == hir::Public || item.span == DUMMY_SP { return; } - if let hir::ItemUse(ref path) = item.node { - match path.node { - hir::ViewPathSimple(..) | hir::ViewPathGlob(..) => { - self.check_import(item.id, path.span); - } - hir::ViewPathList(_, ref path_list) => { - for path_item in path_list { - self.check_import(path_item.node.id, path_item.span); - } - } - } + if let hir::ItemUse(ref path, _) = item.node { + self.check_import(item.id, path.span); } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ca5208b7a03..b83e453b2de 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -696,7 +696,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { debug!("convert: item {} with id {}", it.name, it.id); match it.node { // These don't define types. - hir::ItemExternCrate(_) | hir::ItemUse(_) | hir::ItemMod(_) => { + hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemMod(_) => { } hir::ItemForeignMod(ref foreign_mod) => { for item in &foreign_mod.items { diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 8a0c1c68322..686d1a4a771 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -104,7 +104,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> { } hir::ItemExternCrate(_) | - hir::ItemUse(_) | + hir::ItemUse(..) | hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) | diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index 0a3238480d9..851cfcd8723 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -246,7 +246,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for TermsContext<'a, 'tcx> { } hir::ItemExternCrate(_) | - hir::ItemUse(_) | + hir::ItemUse(..) | hir::ItemDefaultImpl(..) | hir::ItemImpl(..) | hir::ItemStatic(..) | diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index aff38404349..5e1b12e80d4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2589,47 +2589,19 @@ impl Clean> for doctree::Import { None => false, } }); - let (mut ret, inner) = match self.node { - hir::ViewPathGlob(ref p) => { - (vec![], Import::Glob(resolve_use_source(cx, p.clean(cx), self.id))) - } - hir::ViewPathList(ref p, ref list) => { - // Attempt to inline all reexported items, but be sure - // to keep any non-inlineable reexports so they can be - // listed in the documentation. - let mut ret = vec![]; - let remaining = if !denied { - let mut remaining = vec![]; - for path in list { - match inline::try_inline(cx, path.node.id, path.node.rename) { - Some(items) => { - ret.extend(items); - } - None => { - remaining.push(path.clean(cx)); - } - } - } - remaining - } else { - list.clean(cx) - }; - if remaining.is_empty() { - return ret; + let path = self.path.clean(cx); + let inner = if self.glob { + Import::Glob(resolve_use_source(cx, path, self.id)) + } else { + let name = self.name; + if !denied { + if let Some(items) = inline::try_inline(cx, self.id, Some(name)) { + return items; } - (ret, Import::List(resolve_use_source(cx, p.clean(cx), self.id), remaining)) - } - hir::ViewPathSimple(name, ref p) => { - if !denied { - if let Some(items) = inline::try_inline(cx, self.id, Some(name)) { - return items; - } - } - (vec![], Import::Simple(name.clean(cx), - resolve_use_source(cx, p.clean(cx), self.id))) } + Import::Simple(name.clean(cx), resolve_use_source(cx, path, self.id)) }; - ret.push(Item { + vec![Item { name: None, attrs: self.attrs.clean(cx), source: self.whence.clean(cx), @@ -2638,8 +2610,7 @@ impl Clean> for doctree::Import { stability: None, deprecation: None, inner: ImportItem(inner) - }); - ret + }] } } @@ -2648,9 +2619,7 @@ pub enum Import { // use source as str; Simple(String, ImportSource), // use source::*; - Glob(ImportSource), - // use source::{a, b, c}; - List(ImportSource, Vec), + Glob(ImportSource) } #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] @@ -2659,23 +2628,6 @@ pub struct ImportSource { pub did: Option, } -#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub struct ViewListIdent { - pub name: String, - pub rename: Option, - pub source: Option, -} - -impl Clean for hir::PathListItem { - fn clean(&self, cx: &DocContext) -> ViewListIdent { - ViewListIdent { - name: self.node.name.clean(cx), - rename: self.node.rename.map(|r| r.clean(cx)), - source: resolve_def(cx, self.node.id) - } - } -} - impl Clean> for hir::ForeignMod { fn clean(&self, cx: &DocContext) -> Vec { let mut items = self.items.clean(cx); diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 609ae0c0e6d..21fc135eaad 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -254,10 +254,12 @@ pub struct ExternCrate { } pub struct Import { + pub name: Name, pub id: NodeId, pub vis: hir::Visibility, pub attrs: hir::HirVec, - pub node: hir::ViewPath_, + pub path: hir::Path, + pub glob: bool, pub whence: Span, } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index eef530081ab..aed41916f5c 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -969,16 +969,6 @@ impl fmt::Display for clean::Import { clean::Import::Glob(ref src) => { write!(f, "use {}::*;", *src) } - clean::Import::List(ref src, ref names) => { - write!(f, "use {}::{{", *src)?; - for (i, n) in names.iter().enumerate() { - if i > 0 { - write!(f, ", ")?; - } - write!(f, "{}", *n)?; - } - write!(f, "}};") - } } } } @@ -1000,23 +990,6 @@ impl fmt::Display for clean::ImportSource { } } -impl fmt::Display for clean::ViewListIdent { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.source { - Some(did) => { - let path = clean::Path::singleton(self.name.clone()); - resolved_path(f, did, &path, false)?; - } - _ => write!(f, "{}", self.name)?, - } - - if let Some(ref name) = self.rename { - write!(f, " as {}", name)?; - } - Ok(()) - } -} - impl fmt::Display for clean::TypeBinding { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if f.alternate() { diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 8ed0567d820..fcf747a7c17 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -225,42 +225,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { om } - fn visit_view_path(&mut self, path: hir::ViewPath_, - om: &mut Module, - id: ast::NodeId, - please_inline: bool) -> Option { - match path { - hir::ViewPathSimple(dst, base) => { - if self.maybe_inline_local(id, Some(dst), false, om, please_inline) { - None - } else { - Some(hir::ViewPathSimple(dst, base)) - } - } - hir::ViewPathList(p, paths) => { - let mine = paths.into_iter().filter(|path| { - !self.maybe_inline_local(path.node.id, path.node.rename, - false, om, please_inline) - }).collect::>(); - - if mine.is_empty() { - None - } else { - Some(hir::ViewPathList(p, mine)) - } - } - - hir::ViewPathGlob(base) => { - if self.maybe_inline_local(id, None, true, om, please_inline) { - None - } else { - Some(hir::ViewPathGlob(base)) - } - } - } - - } - /// Tries to resolve the target of a `pub use` statement and inlines the /// target if it is defined locally and would not be documented otherwise, /// or when it is specifically requested with `please_inline`. @@ -388,11 +352,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { whence: item.span, }) } - hir::ItemUse(ref vpath) => { - let node = vpath.node.clone(); + hir::ItemUse(_, hir::UseKind::ListStem) => {} + hir::ItemUse(ref path, kind) => { + let is_glob = kind == hir::UseKind::Glob; + // If there was a private module in the current path then don't bother inlining // anything as it will probably be stripped anyway. - let node = if item.vis == hir::Public && self.inside_public_path { + if item.vis == hir::Public && self.inside_public_path { let please_inline = item.attrs.iter().any(|item| { match item.meta_item_list() { Some(list) if item.check_name("doc") => { @@ -401,18 +367,19 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { _ => false, } }); - match self.visit_view_path(node, om, item.id, please_inline) { - None => return, - Some(p) => p + let name = if is_glob { None } else { Some(name) }; + if self.maybe_inline_local(item.id, name, is_glob, om, please_inline) { + return; } - } else { - node - }; + } + om.imports.push(Import { + name: item.name, id: item.id, vis: item.vis.clone(), attrs: item.attrs.clone(), - node: node, + path: (**path).clone(), + glob: is_glob, whence: item.span, }); } diff --git a/src/test/rustdoc/viewpath-rename.rs b/src/test/rustdoc/viewpath-rename.rs index ccc0acab7f3..4b6843d33f7 100644 --- a/src/test/rustdoc/viewpath-rename.rs +++ b/src/test/rustdoc/viewpath-rename.rs @@ -21,8 +21,11 @@ pub enum Maybe { // @has foo/prelude/index.html pub mod prelude { - // @has foo/prelude/index.html '//code' 'pub use io::{self as FooIo, Reader as FooReader}' + // @has foo/prelude/index.html '//code' 'pub use io as FooIo;' + // @has foo/prelude/index.html '//code' 'pub use io::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}' + // @has foo/prelude/index.html '//code' 'pub use Maybe;' + // @has foo/prelude/index.html '//code' 'pub use Maybe::Just as MaybeJust;' + // @has foo/prelude/index.html '//code' 'pub use Maybe::Nothing;' #[doc(no_inline)] pub use Maybe::{self, Just as MaybeJust, Nothing}; } diff --git a/src/test/rustdoc/viewpath-self.rs b/src/test/rustdoc/viewpath-self.rs index 65a981353f0..000960ad972 100644 --- a/src/test/rustdoc/viewpath-self.rs +++ b/src/test/rustdoc/viewpath-self.rs @@ -21,8 +21,11 @@ pub enum Maybe { // @has foo/prelude/index.html pub mod prelude { - // @has foo/prelude/index.html '//code' 'pub use io::{self, Reader}' + // @has foo/prelude/index.html '//code' 'pub use io;' + // @has foo/prelude/index.html '//code' 'pub use io::Reader;' #[doc(no_inline)] pub use io::{self, Reader}; - // @has foo/prelude/index.html '//code' 'pub use Maybe::{self, Just, Nothing}' + // @has foo/prelude/index.html '//code' 'pub use Maybe;' + // @has foo/prelude/index.html '//code' 'pub use Maybe::Just;' + // @has foo/prelude/index.html '//code' 'pub use Maybe::Nothing;' #[doc(no_inline)] pub use Maybe::{self, Just, Nothing}; }