From 8497061a49cde5b70c416f2c964d1f252d82a7a0 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 25 Mar 2017 01:46:38 +0000 Subject: [PATCH] Hygienize `librustc_privacy`. --- src/librustc/hir/lowering.rs | 11 ++++++--- src/librustc/hir/mod.rs | 1 + src/librustc/ich/impls_hir.rs | 1 + src/librustc_privacy/lib.rs | 45 +++++++++++++++++++++++++++++------ 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7ff7ad6a90e..f5c8d11caaa 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1515,18 +1515,23 @@ fn lower_item_id(&mut self, i: &Item) -> SmallVector { pub fn lower_item(&mut self, i: &Item) -> Option { 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) }); diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 6c355608f13..74a47b4e5b9 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -532,6 +532,7 @@ pub fn body(&self, id: BodyId) -> &Body { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct MacroDef { pub name: Name, + pub vis: Visibility, pub attrs: HirVec, pub id: NodeId, pub span: Span, diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index f9758ceea1e..86965723f30 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -329,6 +329,7 @@ fn hash_stable(&self, impl_stable_hash_for!(struct hir::MacroDef { name, + vis, attrs, id, span, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 2ced61f5753..153da91db68 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -28,7 +28,7 @@ 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; @@ -37,7 +37,8 @@ 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; @@ -344,7 +345,35 @@ fn visit_mod(&mut self, m: &'tcx hir::Mod, _sp: Span, id: ast::NodeId) { } 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) { @@ -425,13 +454,15 @@ fn visit_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool { 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)) @@ -455,7 +486,7 @@ fn visit_nested_body(&mut self, body: hir::BodyId) { } 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; } @@ -1182,7 +1213,7 @@ fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, 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); -- 2.44.0