1
Fork 0

privacy: change def_privacy so that it checks for visiblity instead of nameability

This commit is contained in:
Jeffrey Seyfried 2016-02-26 19:20:53 +00:00
parent c97524bef9
commit 13f5fca0f2

View file

@ -492,11 +492,6 @@ enum FieldName {
} }
impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
// used when debugging
fn nodestr(&self, id: ast::NodeId) -> String {
self.tcx.map.node_to_string(id).to_string()
}
// Determines whether the given definition is public from the point of view // Determines whether the given definition is public from the point of view
// of the current item. // of the current item.
fn def_privacy(&self, did: DefId) -> PrivacyResult { fn def_privacy(&self, did: DefId) -> PrivacyResult {
@ -604,12 +599,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
return Allowable; return Allowable;
} }
// We now know that there is at least one private member between the let vis = match self.tcx.map.find(node_id) {
// destination and the root.
let mut closest_private_id = node_id;
loop {
debug!("privacy - examining {}", self.nodestr(closest_private_id));
let vis = match self.tcx.map.find(closest_private_id) {
// If this item is a method, then we know for sure that it's an // If this item is a method, then we know for sure that it's an
// actual method and not a static method. The reason for this is // actual method and not a static method. The reason for this is
// that these cases are only hit in the ExprMethodCall // that these cases are only hit in the ExprMethodCall
@ -624,55 +614,35 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
// However, if this is an impl method, then we dictate this // However, if this is an impl method, then we dictate this
// decision solely based on the privacy of the method // decision solely based on the privacy of the method
// invocation. // invocation.
// FIXME(#10573) is this the right behavior? Why not consider
// where the method was defined?
Some(ast_map::NodeImplItem(ii)) => { Some(ast_map::NodeImplItem(ii)) => {
match ii.node { match ii.node {
hir::ImplItemKind::Const(..) | hir::ImplItemKind::Const(..) |
hir::ImplItemKind::Method(..) => { hir::ImplItemKind::Method(..) => {
let imp = self.tcx.map let imp = self.tcx.map.get_parent_did(node_id);
.get_parent_did(closest_private_id);
match self.tcx.impl_trait_ref(imp) { match self.tcx.impl_trait_ref(imp) {
Some(..) => return Allowable, Some(..) => hir::Public,
_ if ii.vis == hir::Public => {
return Allowable
}
_ => ii.vis _ => ii.vis
} }
} }
hir::ImplItemKind::Type(_) => return Allowable, hir::ImplItemKind::Type(_) => hir::Public,
} }
} }
Some(ast_map::NodeTraitItem(_)) => { Some(ast_map::NodeTraitItem(_)) => hir::Public,
return Allowable;
}
// This is not a method call, extract the visibility as one // This is not a method call, extract the visibility as one
// would normally look at it // would normally look at it
Some(ast_map::NodeItem(it)) => it.vis, Some(ast_map::NodeItem(it)) => it.vis,
Some(ast_map::NodeForeignItem(_)) => { Some(ast_map::NodeForeignItem(_)) => {
self.tcx.map.get_foreign_vis(closest_private_id) self.tcx.map.get_foreign_vis(node_id)
}
Some(ast_map::NodeVariant(..)) => {
hir::Public // need to move up a level (to the enum)
} }
_ => hir::Public, _ => hir::Public,
}; };
if vis != hir::Public { break } if vis == hir::Public { return Allowable }
// if we've reached the root, then everything was allowable and this
// access is public.
if closest_private_id == ast::CRATE_NODE_ID { return Allowable }
closest_private_id = *self.parents.get(&closest_private_id).unwrap();
// If we reached the top, then we were public all the way down and if self.private_accessible(node_id) {
// we can allow this access.
if closest_private_id == ast::DUMMY_NODE_ID { return Allowable }
}
debug!("privacy - closest priv {}", self.nodestr(closest_private_id));
if self.private_accessible(closest_private_id) {
Allowable Allowable
} else { } else {
DisallowedBy(closest_private_id) DisallowedBy(node_id)
} }
} }