middle & privacy: partially HirIdify

This commit is contained in:
ljedrz 2019-02-27 15:56:24 +01:00
parent d987b46bd7
commit 7e277d96fe
2 changed files with 120 additions and 106 deletions

View file

@ -14,10 +14,9 @@ use crate::ty::{self, TyCtxt};
use crate::ty::query::Providers; use crate::ty::query::Providers;
use crate::middle::privacy; use crate::middle::privacy;
use crate::session::config; use crate::session::config;
use crate::util::nodemap::{NodeSet, FxHashSet}; use crate::util::nodemap::{HirIdSet, FxHashSet};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use syntax::ast;
use crate::hir; use crate::hir;
use crate::hir::def_id::LOCAL_CRATE; use crate::hir::def_id::LOCAL_CRATE;
use crate::hir::intravisit::{Visitor, NestedVisitorMap}; use crate::hir::intravisit::{Visitor, NestedVisitorMap};
@ -70,10 +69,10 @@ struct ReachableContext<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>, tables: &'a ty::TypeckTables<'tcx>,
// The set of items which must be exported in the linkage sense. // The set of items which must be exported in the linkage sense.
reachable_symbols: NodeSet, reachable_symbols: HirIdSet,
// A worklist of item IDs. Each item ID in this worklist will be inlined // A worklist of item IDs. Each item ID in this worklist will be inlined
// and will be scanned for further references. // and will be scanned for further references.
worklist: Vec<ast::NodeId>, worklist: Vec<hir::HirId>,
// Whether any output of this compilation is a library // Whether any output of this compilation is a library
any_library: bool, any_library: bool,
} }
@ -104,27 +103,28 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
match def { match def {
Some(Def::Local(node_id)) | Some(Def::Upvar(node_id, ..)) => { Some(Def::Local(node_id)) | Some(Def::Upvar(node_id, ..)) => {
self.reachable_symbols.insert(node_id); let hir_id = self.tcx.hir().node_to_hir_id(node_id);
self.reachable_symbols.insert(hir_id);
} }
Some(def) => { Some(def) => {
if let Some((node_id, def_id)) = def.opt_def_id().and_then(|def_id| { if let Some((hir_id, def_id)) = def.opt_def_id().and_then(|def_id| {
self.tcx.hir().as_local_node_id(def_id).map(|node_id| (node_id, def_id)) self.tcx.hir().as_local_hir_id(def_id).map(|hir_id| (hir_id, def_id))
}) { }) {
if self.def_id_represents_local_inlined_item(def_id) { if self.def_id_represents_local_inlined_item(def_id) {
self.worklist.push(node_id); self.worklist.push(hir_id);
} else { } else {
match def { match def {
// If this path leads to a constant, then we need to // If this path leads to a constant, then we need to
// recurse into the constant to continue finding // recurse into the constant to continue finding
// items that are reachable. // items that are reachable.
Def::Const(..) | Def::AssociatedConst(..) => { Def::Const(..) | Def::AssociatedConst(..) => {
self.worklist.push(node_id); self.worklist.push(hir_id);
} }
// If this wasn't a static, then the destination is // If this wasn't a static, then the destination is
// surely reachable. // surely reachable.
_ => { _ => {
self.reachable_symbols.insert(node_id); self.reachable_symbols.insert(hir_id);
} }
} }
} }
@ -204,14 +204,14 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
continue continue
} }
if let Some(ref item) = self.tcx.hir().find(search_item) { if let Some(ref item) = self.tcx.hir().find_by_hir_id(search_item) {
self.propagate_node(item, search_item); self.propagate_node(item, search_item);
} }
} }
} }
fn propagate_node(&mut self, node: &Node<'tcx>, fn propagate_node(&mut self, node: &Node<'tcx>,
search_item: ast::NodeId) { search_item: hir::HirId) {
if !self.any_library { if !self.any_library {
// If we are building an executable, only explicitly extern // If we are building an executable, only explicitly extern
// types need to be exported. // types need to be exported.
@ -221,7 +221,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
} else { } else {
false false
}; };
let def_id = self.tcx.hir().local_def_id(item.id); let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
let codegen_attrs = self.tcx.codegen_fn_attrs(def_id); let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
let is_extern = codegen_attrs.contains_extern_indicator(); let is_extern = codegen_attrs.contains_extern_indicator();
let std_internal = codegen_attrs.flags.contains( let std_internal = codegen_attrs.flags.contains(
@ -242,7 +242,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
Node::Item(item) => { Node::Item(item) => {
match item.node { match item.node {
hir::ItemKind::Fn(.., body) => { hir::ItemKind::Fn(.., body) => {
let def_id = self.tcx.hir().local_def_id(item.id); let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
if item_might_be_inlined(self.tcx, if item_might_be_inlined(self.tcx,
&item, &item,
self.tcx.codegen_fn_attrs(def_id)) { self.tcx.codegen_fn_attrs(def_id)) {
@ -295,7 +295,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
self.visit_nested_body(body); self.visit_nested_body(body);
} }
hir::ImplItemKind::Method(_, body) => { hir::ImplItemKind::Method(_, body) => {
let did = self.tcx.hir().get_parent_did(search_item); let did = self.tcx.hir().get_parent_did_by_hir_id(search_item);
if method_might_be_inlined(self.tcx, impl_item, did) { if method_might_be_inlined(self.tcx, impl_item, did) {
self.visit_nested_body(body) self.visit_nested_body(body)
} }
@ -317,7 +317,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
_ => { _ => {
bug!( bug!(
"found unexpected node kind in worklist: {} ({:?})", "found unexpected node kind in worklist: {} ({:?})",
self.tcx.hir().node_to_string(search_item), self.tcx.hir().hir_to_string(search_item),
node, node,
); );
} }
@ -336,7 +336,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
struct CollectPrivateImplItemsVisitor<'a, 'tcx: 'a> { struct CollectPrivateImplItemsVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
access_levels: &'a privacy::AccessLevels, access_levels: &'a privacy::AccessLevels,
worklist: &'a mut Vec<ast::NodeId>, worklist: &'a mut Vec<hir::HirId>,
} }
impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> { impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx> {
@ -348,13 +348,18 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
let codegen_attrs = self.tcx.codegen_fn_attrs(def_id); let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
if codegen_attrs.contains_extern_indicator() || if codegen_attrs.contains_extern_indicator() ||
codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) { codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
self.worklist.push(item.id); self.worklist.push(item.hir_id);
} }
// We need only trait impls here, not inherent impls, and only non-exported ones // We need only trait impls here, not inherent impls, and only non-exported ones
if let hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.node { if let hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.node {
if !self.access_levels.is_reachable(item.id) { let node_id = self.tcx.hir().hir_to_node_id(item.hir_id);
self.worklist.extend(impl_item_refs.iter().map(|r| r.id.node_id)); if !self.access_levels.is_reachable(node_id) {
// FIXME(@ljedrz): rework back to a nice extend when item Ids contain HirId
for impl_item_ref in impl_item_refs {
let hir_id = self.tcx.hir().node_to_hir_id(impl_item_ref.id.node_id);
self.worklist.push(hir_id);
}
let trait_def_id = match trait_ref.path.def { let trait_def_id = match trait_ref.path.def {
Def::Trait(def_id) => def_id, Def::Trait(def_id) => def_id,
@ -368,11 +373,11 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
let provided_trait_methods = self.tcx.provided_trait_methods(trait_def_id); let provided_trait_methods = self.tcx.provided_trait_methods(trait_def_id);
self.worklist.reserve(provided_trait_methods.len()); self.worklist.reserve(provided_trait_methods.len());
for default_method in provided_trait_methods { for default_method in provided_trait_methods {
let node_id = self.tcx let hir_id = self.tcx
.hir() .hir()
.as_local_node_id(default_method.def_id) .as_local_hir_id(default_method.def_id)
.unwrap(); .unwrap();
self.worklist.push(node_id); self.worklist.push(hir_id);
} }
} }
} }
@ -388,7 +393,7 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
// We introduce a new-type here, so we can have a specialized HashStable // We introduce a new-type here, so we can have a specialized HashStable
// implementation for it. // implementation for it.
#[derive(Clone)] #[derive(Clone)]
pub struct ReachableSet(pub Lrc<NodeSet>); pub struct ReachableSet(pub Lrc<HirIdSet>);
fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> ReachableSet { fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> ReachableSet {
debug_assert!(crate_num == LOCAL_CRATE); debug_assert!(crate_num == LOCAL_CRATE);
@ -412,11 +417,12 @@ fn reachable_set<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) ->
// If other crates link to us, they're going to expect to be able to // If other crates link to us, they're going to expect to be able to
// use the lang items, so we need to be sure to mark them as // use the lang items, so we need to be sure to mark them as
// exported. // exported.
reachable_context.worklist.extend(access_levels.map.iter().map(|(id, _)| *id)); reachable_context.worklist.extend(
access_levels.map.iter().map(|(id, _)| tcx.hir().node_to_hir_id(*id)));
for item in tcx.lang_items().items().iter() { for item in tcx.lang_items().items().iter() {
if let Some(did) = *item { if let Some(did) = *item {
if let Some(node_id) = tcx.hir().as_local_node_id(did) { if let Some(hir_id) = tcx.hir().as_local_hir_id(did) {
reachable_context.worklist.push(node_id); reachable_context.worklist.push(hir_id);
} }
} }
} }

View file

@ -24,7 +24,7 @@ use rustc::ty::subst::InternalSubsts;
use rustc::util::nodemap::HirIdSet; use rustc::util::nodemap::HirIdSet;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use syntax::ast::{self, DUMMY_NODE_ID, Ident}; use syntax::ast::Ident;
use syntax::attr; use syntax::attr;
use syntax::symbol::keywords; use syntax::symbol::keywords;
use syntax_pos::Span; use syntax_pos::Span;
@ -349,10 +349,10 @@ trait VisibilityLike: Sized {
// Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to
// associated types for which we can't determine visibility precisely. // associated types for which we can't determine visibility precisely.
fn of_impl<'a, 'tcx>(node_id: ast::NodeId, tcx: TyCtxt<'a, 'tcx, 'tcx>, fn of_impl<'a, 'tcx>(hir_id: hir::HirId, tcx: TyCtxt<'a, 'tcx, 'tcx>,
access_levels: &'a AccessLevels) -> Self { access_levels: &'a AccessLevels) -> Self {
let mut find = FindMin { tcx, access_levels, min: Self::MAX }; let mut find = FindMin { tcx, access_levels, min: Self::MAX };
let def_id = tcx.hir().local_def_id(node_id); let def_id = tcx.hir().local_def_id_from_hir_id(hir_id);
find.visit(tcx.type_of(def_id)); find.visit(tcx.type_of(def_id));
if let Some(trait_ref) = tcx.impl_trait_ref(def_id) { if let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
find.visit_trait(trait_ref); find.visit_trait(trait_ref);
@ -409,16 +409,18 @@ struct ReachEverythingInTheInterfaceVisitor<'b, 'a: 'b, 'tcx: 'a> {
} }
impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> { impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
fn get(&self, id: ast::NodeId) -> Option<AccessLevel> { fn get(&self, id: hir::HirId) -> Option<AccessLevel> {
self.access_levels.map.get(&id).cloned() let node_id = self.tcx.hir().hir_to_node_id(id);
self.access_levels.map.get(&node_id).cloned()
} }
// Updates node level and returns the updated level. // Updates node level and returns the updated level.
fn update(&mut self, id: ast::NodeId, level: Option<AccessLevel>) -> Option<AccessLevel> { fn update(&mut self, id: hir::HirId, level: Option<AccessLevel>) -> Option<AccessLevel> {
let old_level = self.get(id); let old_level = self.get(id);
// Accessibility levels can only grow. // Accessibility levels can only grow.
if level > old_level { if level > old_level {
self.access_levels.map.insert(id, level.unwrap()); let node_id = self.tcx.hir().hir_to_node_id(id);
self.access_levels.map.insert(node_id, level.unwrap());
self.changed = true; self.changed = true;
level level
} else { } else {
@ -426,11 +428,11 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
} }
} }
fn reach(&mut self, item_id: ast::NodeId, access_level: Option<AccessLevel>) fn reach(&mut self, item_id: hir::HirId, access_level: Option<AccessLevel>)
-> ReachEverythingInTheInterfaceVisitor<'_, 'a, 'tcx> { -> ReachEverythingInTheInterfaceVisitor<'_, 'a, 'tcx> {
ReachEverythingInTheInterfaceVisitor { ReachEverythingInTheInterfaceVisitor {
access_level: cmp::min(access_level, Some(AccessLevel::Reachable)), access_level: cmp::min(access_level, Some(AccessLevel::Reachable)),
item_def_id: self.tcx.hir().local_def_id(item_id), item_def_id: self.tcx.hir().local_def_id_from_hir_id(item_id),
ev: self, ev: self,
} }
} }
@ -464,7 +466,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
let def_id = self.tcx.hir().local_def_id(item_id.id); let def_id = self.tcx.hir().local_def_id(item_id.id);
if !self.tcx.hygienic_eq(segment.ident, item.ident, def_id) { continue; } if !self.tcx.hygienic_eq(segment.ident, item.ident, def_id) { continue; }
if let hir::ItemKind::Use(..) = item.node { if let hir::ItemKind::Use(..) = item.node {
self.update(item.id, Some(AccessLevel::Exported)); self.update(item.hir_id, Some(AccessLevel::Exported));
} }
} }
} }
@ -483,7 +485,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item) { fn visit_item(&mut self, item: &'tcx hir::Item) {
let inherited_item_level = match item.node { let inherited_item_level = match item.node {
hir::ItemKind::Impl(..) => hir::ItemKind::Impl(..) =>
Option::<AccessLevel>::of_impl(item.id, self.tcx, &self.access_levels), Option::<AccessLevel>::of_impl(item.hir_id, self.tcx, &self.access_levels),
// Foreign modules inherit level from parents. // Foreign modules inherit level from parents.
hir::ItemKind::ForeignMod(..) => self.prev_level, hir::ItemKind::ForeignMod(..) => self.prev_level,
// Other `pub` items inherit levels from parents. // Other `pub` items inherit levels from parents.
@ -498,44 +500,46 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
}; };
// Update level of the item itself. // Update level of the item itself.
let item_level = self.update(item.id, inherited_item_level); let item_level = self.update(item.hir_id, inherited_item_level);
// Update levels of nested things. // Update levels of nested things.
match item.node { match item.node {
hir::ItemKind::Enum(ref def, _) => { hir::ItemKind::Enum(ref def, _) => {
for variant in &def.variants { for variant in &def.variants {
let variant_level = self.update(variant.node.data.id(), item_level); let variant_level = self.update(variant.node.data.hir_id(), item_level);
for field in variant.node.data.fields() { for field in variant.node.data.fields() {
self.update(field.id, variant_level); self.update(field.hir_id, variant_level);
} }
} }
} }
hir::ItemKind::Impl(.., ref trait_ref, _, ref impl_item_refs) => { hir::ItemKind::Impl(.., ref trait_ref, _, ref impl_item_refs) => {
for impl_item_ref in impl_item_refs { for impl_item_ref in impl_item_refs {
if trait_ref.is_some() || impl_item_ref.vis.node.is_pub() { if trait_ref.is_some() || impl_item_ref.vis.node.is_pub() {
self.update(impl_item_ref.id.node_id, item_level); let hir_id = self.tcx.hir().node_to_hir_id(impl_item_ref.id.node_id);
self.update(hir_id, item_level);
} }
} }
} }
hir::ItemKind::Trait(.., ref trait_item_refs) => { hir::ItemKind::Trait(.., ref trait_item_refs) => {
for trait_item_ref in trait_item_refs { for trait_item_ref in trait_item_refs {
self.update(trait_item_ref.id.node_id, item_level); let hir_id = self.tcx.hir().node_to_hir_id(trait_item_ref.id.node_id);
self.update(hir_id, item_level);
} }
} }
hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => { hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
if !def.is_struct() { if !def.is_struct() {
self.update(def.id(), item_level); self.update(def.hir_id(), item_level);
} }
for field in def.fields() { for field in def.fields() {
if field.vis.node.is_pub() { if field.vis.node.is_pub() {
self.update(field.id, item_level); self.update(field.hir_id, item_level);
} }
} }
} }
hir::ItemKind::ForeignMod(ref foreign_mod) => { hir::ItemKind::ForeignMod(ref foreign_mod) => {
for foreign_item in &foreign_mod.items { for foreign_item in &foreign_mod.items {
if foreign_item.vis.node.is_pub() { if foreign_item.vis.node.is_pub() {
self.update(foreign_item.id, item_level); self.update(foreign_item.hir_id, item_level);
} }
} }
} }
@ -572,21 +576,22 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
// reachable if they are returned via `impl Trait`, even from private functions. // reachable if they are returned via `impl Trait`, even from private functions.
let exist_level = cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait)); let exist_level = cmp::max(item_level, Some(AccessLevel::ReachableFromImplTrait));
self.reach(item.id, exist_level).generics().predicates().ty(); self.reach(item.hir_id, exist_level).generics().predicates().ty();
} }
// Visit everything. // Visit everything.
hir::ItemKind::Const(..) | hir::ItemKind::Static(..) | hir::ItemKind::Const(..) | hir::ItemKind::Static(..) |
hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) => { hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) => {
if item_level.is_some() { if item_level.is_some() {
self.reach(item.id, item_level).generics().predicates().ty(); self.reach(item.hir_id, item_level).generics().predicates().ty();
} }
} }
hir::ItemKind::Trait(.., ref trait_item_refs) => { hir::ItemKind::Trait(.., ref trait_item_refs) => {
if item_level.is_some() { if item_level.is_some() {
self.reach(item.id, item_level).generics().predicates(); self.reach(item.hir_id, item_level).generics().predicates();
for trait_item_ref in trait_item_refs { for trait_item_ref in trait_item_refs {
let mut reach = self.reach(trait_item_ref.id.node_id, item_level); let hir_id = self.tcx.hir().node_to_hir_id(trait_item_ref.id.node_id);
let mut reach = self.reach(hir_id, item_level);
reach.generics().predicates(); reach.generics().predicates();
if trait_item_ref.kind == AssociatedItemKind::Type && if trait_item_ref.kind == AssociatedItemKind::Type &&
@ -600,18 +605,19 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
} }
hir::ItemKind::TraitAlias(..) => { hir::ItemKind::TraitAlias(..) => {
if item_level.is_some() { if item_level.is_some() {
self.reach(item.id, item_level).generics().predicates(); self.reach(item.hir_id, item_level).generics().predicates();
} }
} }
// Visit everything except for private impl items. // Visit everything except for private impl items.
hir::ItemKind::Impl(.., ref impl_item_refs) => { hir::ItemKind::Impl(.., ref impl_item_refs) => {
if item_level.is_some() { if item_level.is_some() {
self.reach(item.id, item_level).generics().predicates().ty().trait_ref(); self.reach(item.hir_id, item_level).generics().predicates().ty().trait_ref();
for impl_item_ref in impl_item_refs { for impl_item_ref in impl_item_refs {
let impl_item_level = self.get(impl_item_ref.id.node_id); let hir_id = self.tcx.hir().node_to_hir_id(impl_item_ref.id.node_id);
let impl_item_level = self.get(hir_id);
if impl_item_level.is_some() { if impl_item_level.is_some() {
self.reach(impl_item_ref.id.node_id, impl_item_level) self.reach(hir_id, impl_item_level)
.generics().predicates().ty(); .generics().predicates().ty();
} }
} }
@ -621,26 +627,26 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
// Visit everything, but enum variants have their own levels. // Visit everything, but enum variants have their own levels.
hir::ItemKind::Enum(ref def, _) => { hir::ItemKind::Enum(ref def, _) => {
if item_level.is_some() { if item_level.is_some() {
self.reach(item.id, item_level).generics().predicates(); self.reach(item.hir_id, item_level).generics().predicates();
} }
for variant in &def.variants { for variant in &def.variants {
let variant_level = self.get(variant.node.data.id()); let variant_level = self.get(variant.node.data.hir_id());
if variant_level.is_some() { if variant_level.is_some() {
for field in variant.node.data.fields() { for field in variant.node.data.fields() {
self.reach(field.id, variant_level).ty(); self.reach(field.hir_id, variant_level).ty();
} }
// Corner case: if the variant is reachable, but its // Corner case: if the variant is reachable, but its
// enum is not, make the enum reachable as well. // enum is not, make the enum reachable as well.
self.update(item.id, variant_level); self.update(item.hir_id, variant_level);
} }
} }
} }
// Visit everything, but foreign items have their own levels. // Visit everything, but foreign items have their own levels.
hir::ItemKind::ForeignMod(ref foreign_mod) => { hir::ItemKind::ForeignMod(ref foreign_mod) => {
for foreign_item in &foreign_mod.items { for foreign_item in &foreign_mod.items {
let foreign_item_level = self.get(foreign_item.id); let foreign_item_level = self.get(foreign_item.hir_id);
if foreign_item_level.is_some() { if foreign_item_level.is_some() {
self.reach(foreign_item.id, foreign_item_level) self.reach(foreign_item.hir_id, foreign_item_level)
.generics().predicates().ty(); .generics().predicates().ty();
} }
} }
@ -649,11 +655,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
hir::ItemKind::Struct(ref struct_def, _) | hir::ItemKind::Struct(ref struct_def, _) |
hir::ItemKind::Union(ref struct_def, _) => { hir::ItemKind::Union(ref struct_def, _) => {
if item_level.is_some() { if item_level.is_some() {
self.reach(item.id, item_level).generics().predicates(); self.reach(item.hir_id, item_level).generics().predicates();
for field in struct_def.fields() { for field in struct_def.fields() {
let field_level = self.get(field.id); let field_level = self.get(field.hir_id);
if field_level.is_some() { if field_level.is_some() {
self.reach(field.id, field_level).ty(); self.reach(field.hir_id, field_level).ty();
} }
} }
} }
@ -683,8 +689,8 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
for export in exports.iter() { for export in exports.iter() {
if export.vis == ty::Visibility::Public { if export.vis == ty::Visibility::Public {
if let Some(def_id) = export.def.opt_def_id() { if let Some(def_id) = export.def.opt_def_id() {
if let Some(node_id) = self.tcx.hir().as_local_node_id(def_id) { if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
self.update(node_id, Some(AccessLevel::Exported)); self.update(hir_id, Some(AccessLevel::Exported));
} }
} }
} }
@ -696,10 +702,8 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
} }
fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) { fn visit_macro_def(&mut self, md: &'tcx hir::MacroDef) {
let node_id = self.tcx.hir().hir_to_node_id(md.hir_id);
if md.legacy { if md.legacy {
self.update(node_id, Some(AccessLevel::Public)); self.update(md.hir_id, Some(AccessLevel::Public));
return return
} }
@ -707,38 +711,39 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
self.tcx, self.tcx,
self.tcx.hir().local_def_id_from_hir_id(md.hir_id) self.tcx.hir().local_def_id_from_hir_id(md.hir_id)
).unwrap(); ).unwrap();
let mut module_id = self.tcx.hir().as_local_node_id(module_did).unwrap(); let mut module_id = self.tcx.hir().as_local_hir_id(module_did).unwrap();
let level = if md.vis.node.is_pub() { self.get(module_id) } else { None }; let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
let level = self.update(node_id, level); let level = self.update(md.hir_id, level);
if level.is_none() { if level.is_none() {
return return
} }
loop { loop {
let module = if module_id == ast::CRATE_NODE_ID { let module = if module_id == hir::CRATE_HIR_ID {
&self.tcx.hir().krate().module &self.tcx.hir().krate().module
} else if let hir::ItemKind::Mod(ref module) = } else if let hir::ItemKind::Mod(ref module) =
self.tcx.hir().expect_item(module_id).node { self.tcx.hir().expect_item_by_hir_id(module_id).node {
module module
} else { } else {
unreachable!() unreachable!()
}; };
for id in &module.item_ids { for id in &module.item_ids {
self.update(id.id, level); let hir_id = self.tcx.hir().node_to_hir_id(id.id);
self.update(hir_id, level);
} }
let def_id = self.tcx.hir().local_def_id(module_id); let def_id = self.tcx.hir().local_def_id_from_hir_id(module_id);
if let Some(exports) = self.tcx.module_exports(def_id) { if let Some(exports) = self.tcx.module_exports(def_id) {
for export in exports.iter() { for export in exports.iter() {
if let Some(node_id) = self.tcx.hir().as_local_node_id(export.def.def_id()) { if let Some(hir_id) = self.tcx.hir().as_local_hir_id(export.def.def_id()) {
self.update(node_id, level); self.update(hir_id, level);
} }
} }
} }
if module_id == ast::CRATE_NODE_ID { if module_id == hir::CRATE_HIR_ID {
break break
} }
module_id = self.tcx.hir().get_parent_node(module_id); module_id = self.tcx.hir().get_parent_node_by_hir_id(module_id);
} }
} }
} }
@ -779,8 +784,8 @@ impl<'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'_, 'a, 'tcx> {
impl<'a, 'tcx> DefIdVisitor<'a, 'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'a, 'tcx> { impl<'a, 'tcx> DefIdVisitor<'a, 'tcx> for ReachEverythingInTheInterfaceVisitor<'_, 'a, 'tcx> {
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.ev.tcx } fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> { self.ev.tcx }
fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display) -> bool { fn visit_def_id(&mut self, def_id: DefId, _kind: &str, _descr: &dyn fmt::Display) -> bool {
if let Some(node_id) = self.ev.tcx.hir().as_local_node_id(def_id) { if let Some(hir_id) = self.ev.tcx.hir().as_local_hir_id(def_id) {
self.ev.update(node_id, self.access_level); self.ev.update(hir_id, self.access_level);
} }
false false
} }
@ -796,7 +801,7 @@ impl<'a, 'tcx> DefIdVisitor<'a, 'tcx> for ReachEverythingInTheInterfaceVisitor<'
struct NamePrivacyVisitor<'a, 'tcx: 'a> { struct NamePrivacyVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::TypeckTables<'tcx>, tables: &'a ty::TypeckTables<'tcx>,
current_item: ast::NodeId, current_item: hir::HirId,
empty_tables: &'a ty::TypeckTables<'tcx>, empty_tables: &'a ty::TypeckTables<'tcx>,
} }
@ -808,7 +813,7 @@ impl<'a, 'tcx> NamePrivacyVisitor<'a, 'tcx> {
def: &'tcx ty::AdtDef, // definition of the struct or enum def: &'tcx ty::AdtDef, // definition of the struct or enum
field: &'tcx ty::FieldDef) { // definition of the field field: &'tcx ty::FieldDef) { // definition of the field
let ident = Ident::new(keywords::Invalid.name(), use_ctxt); let ident = Ident::new(keywords::Invalid.name(), use_ctxt);
let current_hir = self.tcx.hir().node_to_hir_id(self.current_item); let current_hir = self.current_item;
let def_id = self.tcx.adjust_ident(ident, def.did, current_hir).1; let def_id = self.tcx.adjust_ident(ident, def.did, current_hir).1;
if !def.is_enum() && !field.vis.is_accessible_from(def_id, self.tcx) { 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", struct_span_err!(self.tcx.sess, span, E0451, "field `{}` of {} `{}` is private",
@ -839,7 +844,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NamePrivacyVisitor<'a, 'tcx> {
} }
fn visit_item(&mut self, item: &'tcx hir::Item) { fn visit_item(&mut self, item: &'tcx hir::Item) {
let orig_current_item = mem::replace(&mut self.current_item, item.id); let orig_current_item = mem::replace(&mut self.current_item, item.hir_id);
let orig_tables = let orig_tables =
mem::replace(&mut self.tables, item_tables(self.tcx, item.hir_id, self.empty_tables)); mem::replace(&mut self.tables, item_tables(self.tcx, item.hir_id, self.empty_tables));
intravisit::walk_item(self, item); intravisit::walk_item(self, item);
@ -1110,8 +1115,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
// Check types in item interfaces. // Check types in item interfaces.
fn visit_item(&mut self, item: &'tcx hir::Item) { fn visit_item(&mut self, item: &'tcx hir::Item) {
let orig_current_item = let orig_current_item = mem::replace(&mut self.current_item,
mem::replace(&mut self.current_item, self.tcx.hir().local_def_id(item.id)); self.tcx.hir().local_def_id_from_hir_id(item.hir_id));
let orig_in_body = mem::replace(&mut self.in_body, false); let orig_in_body = mem::replace(&mut self.in_body, false);
let orig_tables = let orig_tables =
mem::replace(&mut self.tables, item_tables(self.tcx, item.hir_id, self.empty_tables)); mem::replace(&mut self.tables, item_tables(self.tcx, item.hir_id, self.empty_tables));
@ -1190,10 +1195,11 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
} }
} }
fn trait_is_public(&self, trait_id: ast::NodeId) -> bool { fn trait_is_public(&self, trait_id: hir::HirId) -> bool {
// FIXME: this would preferably be using `exported_items`, but all // FIXME: this would preferably be using `exported_items`, but all
// traits are exported currently (see `EmbargoVisitor.exported_trait`). // traits are exported currently (see `EmbargoVisitor.exported_trait`).
self.access_levels.is_public(trait_id) let node_id = self.tcx.hir().hir_to_node_id(trait_id);
self.access_levels.is_public(node_id)
} }
fn check_generic_bound(&mut self, bound: &hir::GenericBound) { fn check_generic_bound(&mut self, bound: &hir::GenericBound) {
@ -1204,8 +1210,9 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
} }
} }
fn item_is_public(&self, id: &ast::NodeId, vis: &hir::Visibility) -> bool { fn item_is_public(&self, id: &hir::HirId, vis: &hir::Visibility) -> bool {
self.access_levels.is_reachable(*id) || vis.node.is_pub() let node_id = self.tcx.hir().hir_to_node_id(*id);
self.access_levels.is_reachable(node_id) || vis.node.is_pub()
} }
} }
@ -1253,7 +1260,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
hir::ItemKind::ForeignMod(_) => {} hir::ItemKind::ForeignMod(_) => {}
hir::ItemKind::Trait(.., ref bounds, _) => { hir::ItemKind::Trait(.., ref bounds, _) => {
if !self.trait_is_public(item.id) { if !self.trait_is_public(item.hir_id) {
return return
} }
@ -1295,8 +1302,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|tr| { |tr| {
let did = tr.path.def.def_id(); let did = tr.path.def.def_id();
if let Some(node_id) = self.tcx.hir().as_local_node_id(did) { if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) {
self.trait_is_public(node_id) self.trait_is_public(hir_id)
} else { } else {
true // external traits must be public true // external traits must be public
} }
@ -1318,9 +1325,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
match impl_item.node { match impl_item.node {
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Const(..) |
hir::ImplItemKind::Method(..) => { hir::ImplItemKind::Method(..) => {
let node_id = self.tcx.hir().hir_to_node_id( self.access_levels.is_reachable(
impl_item.hir_id); impl_item_ref.id.node_id)
self.access_levels.is_reachable(node_id)
} }
hir::ImplItemKind::Existential(..) | hir::ImplItemKind::Existential(..) |
hir::ImplItemKind::Type(_) => false, hir::ImplItemKind::Type(_) => false,
@ -1342,11 +1348,10 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
// don't erroneously report errors for private // don't erroneously report errors for private
// types in private items. // types in private items.
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
let node_id = self.tcx.hir().hir_to_node_id(impl_item.hir_id);
match impl_item.node { match impl_item.node {
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Const(..) |
hir::ImplItemKind::Method(..) hir::ImplItemKind::Method(..)
if self.item_is_public(&node_id, &impl_item.vis) => if self.item_is_public(&impl_item.hir_id, &impl_item.vis) =>
{ {
intravisit::walk_impl_item(self, impl_item) intravisit::walk_impl_item(self, impl_item)
} }
@ -1387,7 +1392,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
// methods will be visible as `Public::foo`. // methods will be visible as `Public::foo`.
let mut found_pub_static = false; let mut found_pub_static = false;
for impl_item_ref in impl_item_refs { for impl_item_ref in impl_item_refs {
if self.item_is_public(&impl_item_ref.id.node_id, &impl_item_ref.vis) { let hir_id = self.tcx.hir().node_to_hir_id(impl_item_ref.id.node_id);
if self.item_is_public(&hir_id, &impl_item_ref.vis) {
let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
match impl_item_ref.kind { match impl_item_ref.kind {
AssociatedItemKind::Const => { AssociatedItemKind::Const => {
@ -1414,7 +1420,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
hir::ItemKind::Ty(..) => return, hir::ItemKind::Ty(..) => return,
// Not at all public, so we don't care. // Not at all public, so we don't care.
_ if !self.item_is_public(&item.id, &item.vis) => { _ if !self.item_is_public(&item.hir_id, &item.vis) => {
return; return;
} }
@ -1450,7 +1456,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
} }
fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) { fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem) {
if self.access_levels.is_reachable(item.id) { let node_id = self.tcx.hir().hir_to_node_id(item.hir_id);
if self.access_levels.is_reachable(node_id) {
intravisit::walk_foreign_item(self, item) intravisit::walk_foreign_item(self, item)
} }
} }
@ -1468,7 +1475,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
v: &'tcx hir::Variant, v: &'tcx hir::Variant,
g: &'tcx hir::Generics, g: &'tcx hir::Generics,
item_id: hir::HirId) { item_id: hir::HirId) {
if self.access_levels.is_reachable(v.node.data.id()) { let node_id = self.tcx.hir().hir_to_node_id(v.node.data.hir_id());
if self.access_levels.is_reachable(node_id) {
self.in_variant = true; self.in_variant = true;
intravisit::walk_variant(self, v, g, item_id); intravisit::walk_variant(self, v, g, item_id);
self.in_variant = false; self.in_variant = false;
@ -1735,7 +1743,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
// A trait impl is public when both its type and its trait are public // A trait impl is public when both its type and its trait are public
// Subitems of trait impls have inherited publicity. // Subitems of trait impls have inherited publicity.
hir::ItemKind::Impl(.., ref trait_ref, _, ref impl_item_refs) => { hir::ItemKind::Impl(.., ref trait_ref, _, ref impl_item_refs) => {
let impl_vis = ty::Visibility::of_impl(item.id, tcx, &Default::default()); let impl_vis = ty::Visibility::of_impl(item.hir_id, tcx, &Default::default());
self.check(item.hir_id, impl_vis).generics().predicates(); self.check(item.hir_id, impl_vis).generics().predicates();
for impl_item_ref in impl_item_refs { for impl_item_ref in impl_item_refs {
let impl_item = tcx.hir().impl_item(impl_item_ref.id); let impl_item = tcx.hir().impl_item(impl_item_ref.id);
@ -1773,7 +1781,7 @@ fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
let mut visitor = NamePrivacyVisitor { let mut visitor = NamePrivacyVisitor {
tcx, tcx,
tables: &empty_tables, tables: &empty_tables,
current_item: DUMMY_NODE_ID, current_item: hir::DUMMY_HIR_ID,
empty_tables: &empty_tables, empty_tables: &empty_tables,
}; };
let (module, span, node_id) = tcx.hir().get_module(module_def_id); let (module, span, node_id) = tcx.hir().get_module(module_def_id);
@ -1827,7 +1835,7 @@ fn privacy_access_levels<'tcx>(
break break
} }
} }
visitor.update(ast::CRATE_NODE_ID, Some(AccessLevel::Public)); visitor.update(hir::CRATE_HIR_ID, Some(AccessLevel::Public));
{ {
let mut visitor = ObsoleteVisiblePrivateTypesVisitor { let mut visitor = ObsoleteVisiblePrivateTypesVisitor {