New AccessLevel and accompanying propagation.

This commit is contained in:
Kyle Simpson 2018-08-21 00:11:59 +01:00
parent 00b260691f
commit 81684bf1aa
3 changed files with 12 additions and 8 deletions

View File

@ -1086,6 +1086,7 @@ impl_stable_hash_for!(enum traits::Reveal {
});
impl_stable_hash_for!(enum ::middle::privacy::AccessLevel {
ReachableFromImplTrait,
Reachable,
Exported,
Public

View File

@ -22,7 +22,7 @@ use syntax::ast::NodeId;
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum AccessLevel {
// Superset of Reachable used to mark impl Trait items.
// ReachableFromImplTrait,
ReachableFromImplTrait,
// Exported items + items participating in various kinds of public interfaces,
// but not directly nameable. For example, if function `fn f() -> T {...}` is
// public, then type `T` is reachable. Its values can be obtained by other crates
@ -42,7 +42,8 @@ pub struct AccessLevels<Id = NodeId> {
impl<Id: Hash + Eq> AccessLevels<Id> {
pub fn is_reachable(&self, id: Id) -> bool {
self.map.contains_key(&id)
// self.map.contains_key(&id)
self.map.get(&id) >= Some(&AccessLevel::Reachable)
}
pub fn is_exported(&self, id: Id) -> bool {
self.map.get(&id) >= Some(&AccessLevel::Exported)

View File

@ -84,6 +84,7 @@ struct EmbargoVisitor<'a, 'tcx: 'a> {
}
struct ReachEverythingInTheInterfaceVisitor<'b, 'a: 'b, 'tcx: 'a> {
access_level: Option<AccessLevel>,
item_def_id: DefId,
ev: &'b mut EmbargoVisitor<'a, 'tcx>,
}
@ -134,6 +135,7 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
fn reach<'b>(&'b mut self, item_id: ast::NodeId)
-> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
ReachEverythingInTheInterfaceVisitor {
access_level: self.prev_level.map(|l| l.min(AccessLevel::Reachable)),
item_def_id: self.tcx.hir.local_def_id(item_id),
ev: self,
}
@ -164,7 +166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
hir::ItemKind::Existential(ref ty_data) => {
if let Some(impl_trait_fn) = ty_data.impl_trait_fn {
if let Some(node_id) = self.tcx.hir.as_local_node_id(impl_trait_fn) {
self.update(node_id, Some(AccessLevel::Reachable));
self.update(node_id, Some(AccessLevel::ReachableFromImplTrait));
}
}
if item.vis.node.is_pub() { self.prev_level } else { None }
@ -240,6 +242,9 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
hir::ItemKind::ExternCrate(..) => {}
}
let orig_level = self.prev_level;
self.prev_level = item_level;
// Mark all items in interfaces of reachable items as reachable
match item.node {
// The interface is empty
@ -337,9 +342,6 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
}
}
let orig_level = self.prev_level;
self.prev_level = item_level;
intravisit::walk_item(self, item);
self.prev_level = orig_level;
@ -475,7 +477,7 @@ impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
fn check_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) {
if let Some(node_id) = self.ev.tcx.hir.as_local_node_id(trait_ref.def_id) {
let item = self.ev.tcx.hir.expect_item(node_id);
self.ev.update(item.id, Some(AccessLevel::Reachable));
self.ev.update(item.id, self.access_level);
}
}
}
@ -496,7 +498,7 @@ impl<'b, 'a, 'tcx> TypeVisitor<'tcx> for ReachEverythingInTheInterfaceVisitor<'b
if let Some(def_id) = ty_def_id {
if let Some(node_id) = self.ev.tcx.hir.as_local_node_id(def_id) {
self.ev.update(node_id, Some(AccessLevel::Reachable));
self.ev.update(node_id, self.access_level);
}
}