pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
let mut name = i.ident.name;
+ let mut vis = self.lower_visibility(&i.vis, None);
let attrs = self.lower_attrs(&i.attrs);
if let ItemKind::MacroDef(ref def) = i.node {
if !def.legacy || i.attrs.iter().any(|attr| attr.path == "macro_export") {
- let (body, legacy) = (def.stream(), def.legacy);
self.exported_macros.push(hir::MacroDef {
- name: name, attrs: attrs, id: i.id, span: i.span, body: body, legacy: legacy,
+ name: name,
+ vis: vis,
+ attrs: attrs,
+ id: i.id,
+ span: i.span,
+ body: def.stream(),
+ legacy: def.legacy,
});
}
return None;
}
- let mut vis = self.lower_visibility(&i.vis, None);
let node = self.with_parent_def(i.id, |this| {
this.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node)
});
use rustc::hir::{self, PatKind};
use rustc::hir::def::Def;
-use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
+use rustc::hir::def_id::{LOCAL_CRATE, CrateNum, DefId};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::itemlikevisit::DeepVisitor;
use rustc::lint;
use rustc::ty::fold::TypeVisitor;
use rustc::ty::maps::Providers;
use rustc::util::nodemap::NodeSet;
-use syntax::ast;
+use syntax::ast::{self, CRATE_NODE_ID, Ident};
+use syntax::symbol::keywords;
use syntax_pos::Span;
use std::cmp;
}
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
- self.update(md.id, Some(AccessLevel::Public));
+ if md.legacy {
+ self.update(md.id, Some(AccessLevel::Public));
+ return
+ }
+
+ let module_did = ty::DefIdTree::parent(self.tcx, self.tcx.hir.local_def_id(md.id)).unwrap();
+ let mut module_id = self.tcx.hir.as_local_node_id(module_did).unwrap();
+ let level = if md.vis == hir::Public { self.get(module_id) } else { None };
+ let level = self.update(md.id, level);
+ if level.is_none() {
+ return
+ }
+
+ loop {
+ let module = if module_id == ast::CRATE_NODE_ID {
+ &self.tcx.hir.krate().module
+ } else if let hir::ItemMod(ref module) = self.tcx.hir.expect_item(module_id).node {
+ module
+ } else {
+ unreachable!()
+ };
+ for id in &module.item_ids {
+ self.update(id.id, level);
+ }
+ if module_id == ast::CRATE_NODE_ID {
+ break
+ }
+ module_id = self.tcx.hir.get_parent_node(module_id);
+ }
}
fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
struct NamePrivacyVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
- current_item: DefId,
+ current_item: ast::NodeId,
}
impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> {
// Checks that a field is accessible.
fn check_field(&mut self, span: Span, def: &'tcx ty::AdtDef, field: &'tcx ty::FieldDef) {
- if !def.is_enum() && !field.vis.is_accessible_from(self.current_item, self.tcx) {
+ let ident = Ident { ctxt: span.ctxt.modern(), ..keywords::Invalid.ident() };
+ let def_id = self.tcx.adjust_ident(ident, def.did, self.current_item).1;
+ if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) {
struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
field.name, def.variant_descr(), self.tcx.item_path_str(def.did))
.span_label(span, format!("field `{}` is private", field.name))
}
fn visit_item(&mut self, item: &'tcx hir::Item) {
- let orig_current_item = replace(&mut self.current_item, self.tcx.hir.local_def_id(item.id));
+ let orig_current_item = replace(&mut self.current_item, item.id);
intravisit::walk_item(self, item);
self.current_item = orig_current_item;
}
let mut visitor = NamePrivacyVisitor {
tcx: tcx,
tables: &ty::TypeckTables::empty(),
- current_item: DefId::local(CRATE_DEF_INDEX),
+ current_item: CRATE_NODE_ID,
};
intravisit::walk_crate(&mut visitor, krate);