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)
}
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) => {
}
}
-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) {
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;
// a definition, then we can properly create the def id.
parent_def: Option<DefIndex>,
resolver: &'a mut Resolver,
+
+ /// The items being lowered are collected here.
+ items: BTreeMap<NodeId, hir::Item>,
+
+ impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
}
pub trait Resolver {
sess: sess,
parent_def: None,
resolver: resolver,
+ items: BTreeMap::new(),
+ impl_items: BTreeMap::new(),
}.lower_crate(krate)
}
}
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<NodeId, hir::Item>,
- impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
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,
}
}
attrs.clone().into()
}
- fn lower_view_path(&mut self, view_path: &ViewPath) -> P<hir::ViewPath> {
- 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),
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<Name>,
+ 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)
}
fn lower_block(&mut self, b: &Block) -> P<hir::Block> {
- 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::<Vec<_>>();
- let last = self.lower_stmt(last);
+ let mut stmts = b.stmts.iter().flat_map(|s| self.lower_stmt(s)).collect::<Vec<_>>();
+ if let Some(last) = stmts.pop() {
if let hir::StmtExpr(e, _) = last.node {
expr = Some(e);
} else {
})
}
- fn lower_item_kind(&mut self, i: &ItemKind) -> hir::Item_ {
+ fn lower_item_kind(&mut self,
+ name: &mut Name,
+ attrs: &hir::HirVec<Attribute>,
+ 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),
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(),
}
}
}
}
- fn lower_item_id(&mut self, i: &Item) -> hir::ItemId {
- hir::ItemId { id: i.id }
+ fn lower_item_id(&mut self, i: &Item) -> SmallVector<hir::ItemId> {
+ 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,
}
}
}
}
- fn lower_stmt(&mut self, s: &Stmt) -> hir::Stmt {
- match s.node {
+ fn lower_stmt(&mut self, s: &Stmt) -> SmallVector<hir::Stmt> {
+ SmallVector::one(match s.node {
StmtKind::Local(ref l) => Spanned {
node: hir::StmtDecl(P(Spanned {
node: hir::DeclLocal(self.lower_local(l)),
}), 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),
}
}
StmtKind::Mac(..) => panic!("Shouldn't exist here"),
- }
+ })
}
fn lower_capture_clause(&mut self, c: CaptureBy) -> hir::CaptureClause {
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);
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);
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);
}
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::*;
pub type Variant = Spanned<Variant_>;
-#[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<Name>,
- pub id: NodeId,
-}
-
-pub type PathListItem = Spanned<PathListItem_>;
-
-pub type ViewPath = Spanned<ViewPath_>;
-
-#[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),
+#[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,
- /// `foo::bar::*`
- ViewPathGlob(Path),
+ /// Glob import, e.g. `use foo::*`.
+ Glob,
- /// `foo::bar::{a,b,c}`
- ViewPathList(Path, HirVec<PathListItem>),
+ /// 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.
///
/// e.g. `extern crate foo` or `extern crate foo_bar as foo`
ItemExternCrate(Option<Name>),
- /// A `use` or `pub use` item
- ItemUse(P<ViewPath>),
+
+ /// `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<Path>, UseKind),
/// A `static` item
ItemStatic(P<Ty>, Mutability, P<Expr>),
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
}
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"),
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);
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
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 {
// 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(..) |
intravisit::walk_item(this, item);
}
hir::ItemExternCrate(_) |
- hir::ItemUse(_) |
+ hir::ItemUse(..) |
hir::ItemMod(..) |
hir::ItemDefaultImpl(..) |
hir::ItemForeignMod(..) |
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));
}
}
-pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- item: &hir::PathListItem,
- cb: &mut FnMut(DefId, Span,
- &Option<&Stability>,
- &Option<DeprecationEntry>)) {
- 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>,
SawPath(bool),
SawPathSegment,
SawPathParameters,
- SawPathListItem,
SawBlock,
SawPat(SawPatComponent),
SawLocal,
#[derive(Hash)]
enum SawItemComponent {
SawItemExternCrate,
- SawItemUse,
+ SawItemUse(UseKind),
SawItemStatic(Mutability),
SawItemConst,
SawItemFn(Unsafety, Constness, Abi),
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),
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);
&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,
add_early_builtin!(sess,
UnusedParens,
+ UnusedImportBraces,
);
add_early_builtin_with_new!(sess,
NonCamelCaseTypes,
NonSnakeCase,
NonUpperCaseGlobals,
- UnusedImportBraces,
NonShorthandFieldPatterns,
UnusedUnsafe,
UnsafeCode,
}
}
-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);
}
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 {
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);
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) {
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);
}
}
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 {
}
hir::ItemExternCrate(_) |
- hir::ItemUse(_) |
+ hir::ItemUse(..) |
hir::ItemStatic(..) |
hir::ItemConst(..) |
hir::ItemFn(..) |
}
hir::ItemExternCrate(_) |
- hir::ItemUse(_) |
+ hir::ItemUse(..) |
hir::ItemDefaultImpl(..) |
hir::ItemImpl(..) |
hir::ItemStatic(..) |
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;
- }
- (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;
- }
+ 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;
}
- (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),
stability: None,
deprecation: None,
inner: ImportItem(inner)
- });
- ret
+ }]
}
}
// use source as str;
Simple(String, ImportSource),
// use source::*;
- Glob(ImportSource),
- // use source::{a, b, c};
- List(ImportSource, Vec<ViewListIdent>),
+ Glob(ImportSource)
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub did: Option<DefId>,
}
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct ViewListIdent {
- pub name: String,
- pub rename: Option<String>,
- pub source: Option<DefId>,
-}
-
-impl Clean<ViewListIdent> 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<Vec<Item>> for hir::ForeignMod {
fn clean(&self, cx: &DocContext) -> Vec<Item> {
let mut items = self.items.clean(cx);
}
pub struct Import {
+ pub name: Name,
pub id: NodeId,
pub vis: hir::Visibility,
pub attrs: hir::HirVec<ast::Attribute>,
- pub node: hir::ViewPath_,
+ pub path: hir::Path,
+ pub glob: bool,
pub whence: Span,
}
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, "}};")
- }
}
}
}
}
}
-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() {
om
}
- fn visit_view_path(&mut self, path: hir::ViewPath_,
- om: &mut Module,
- id: ast::NodeId,
- please_inline: bool) -> Option<hir::ViewPath_> {
- 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::<hir::HirVec<hir::PathListItem>>();
-
- 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`.
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") => {
_ => 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,
});
}
// @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};
}
// @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};
}