Skip to content

Commit 13f5fca

Browse files
committedMar 4, 2016
privacy: change def_privacy so that it checks for visiblity instead of nameability
1 parent c97524b commit 13f5fca

File tree

1 file changed

+38
-68
lines changed

1 file changed

+38
-68
lines changed
 

‎src/librustc_privacy/lib.rs

+38-68
Original file line numberDiff line numberDiff line change
@@ -492,11 +492,6 @@ enum FieldName {
492492
}
493493

494494
impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
495-
// used when debugging
496-
fn nodestr(&self, id: ast::NodeId) -> String {
497-
self.tcx.map.node_to_string(id).to_string()
498-
}
499-
500495
// Determines whether the given definition is public from the point of view
501496
// of the current item.
502497
fn def_privacy(&self, did: DefId) -> PrivacyResult {
@@ -604,75 +599,50 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
604599
return Allowable;
605600
}
606601

607-
// We now know that there is at least one private member between the
608-
// destination and the root.
609-
let mut closest_private_id = node_id;
610-
loop {
611-
debug!("privacy - examining {}", self.nodestr(closest_private_id));
612-
let vis = match self.tcx.map.find(closest_private_id) {
613-
// If this item is a method, then we know for sure that it's an
614-
// actual method and not a static method. The reason for this is
615-
// that these cases are only hit in the ExprMethodCall
616-
// expression, and ExprCall will have its path checked later
617-
// (the path of the trait/impl) if it's a static method.
618-
//
619-
// With this information, then we can completely ignore all
620-
// trait methods. The privacy violation would be if the trait
621-
// couldn't get imported, not if the method couldn't be used
622-
// (all trait methods are public).
623-
//
624-
// However, if this is an impl method, then we dictate this
625-
// decision solely based on the privacy of the method
626-
// invocation.
627-
// FIXME(#10573) is this the right behavior? Why not consider
628-
// where the method was defined?
629-
Some(ast_map::NodeImplItem(ii)) => {
630-
match ii.node {
631-
hir::ImplItemKind::Const(..) |
632-
hir::ImplItemKind::Method(..) => {
633-
let imp = self.tcx.map
634-
.get_parent_did(closest_private_id);
635-
match self.tcx.impl_trait_ref(imp) {
636-
Some(..) => return Allowable,
637-
_ if ii.vis == hir::Public => {
638-
return Allowable
639-
}
640-
_ => ii.vis
641-
}
602+
let vis = match self.tcx.map.find(node_id) {
603+
// If this item is a method, then we know for sure that it's an
604+
// actual method and not a static method. The reason for this is
605+
// that these cases are only hit in the ExprMethodCall
606+
// expression, and ExprCall will have its path checked later
607+
// (the path of the trait/impl) if it's a static method.
608+
//
609+
// With this information, then we can completely ignore all
610+
// trait methods. The privacy violation would be if the trait
611+
// couldn't get imported, not if the method couldn't be used
612+
// (all trait methods are public).
613+
//
614+
// However, if this is an impl method, then we dictate this
615+
// decision solely based on the privacy of the method
616+
// invocation.
617+
Some(ast_map::NodeImplItem(ii)) => {
618+
match ii.node {
619+
hir::ImplItemKind::Const(..) |
620+
hir::ImplItemKind::Method(..) => {
621+
let imp = self.tcx.map.get_parent_did(node_id);
622+
match self.tcx.impl_trait_ref(imp) {
623+
Some(..) => hir::Public,
624+
_ => ii.vis
642625
}
643-
hir::ImplItemKind::Type(_) => return Allowable,
644626
}
627+
hir::ImplItemKind::Type(_) => hir::Public,
645628
}
646-
Some(ast_map::NodeTraitItem(_)) => {
647-
return Allowable;
648-
}
629+
}
630+
Some(ast_map::NodeTraitItem(_)) => hir::Public,
649631

650-
// This is not a method call, extract the visibility as one
651-
// would normally look at it
652-
Some(ast_map::NodeItem(it)) => it.vis,
653-
Some(ast_map::NodeForeignItem(_)) => {
654-
self.tcx.map.get_foreign_vis(closest_private_id)
655-
}
656-
Some(ast_map::NodeVariant(..)) => {
657-
hir::Public // need to move up a level (to the enum)
658-
}
659-
_ => hir::Public,
660-
};
661-
if vis != hir::Public { break }
662-
// if we've reached the root, then everything was allowable and this
663-
// access is public.
664-
if closest_private_id == ast::CRATE_NODE_ID { return Allowable }
665-
closest_private_id = *self.parents.get(&closest_private_id).unwrap();
666-
667-
// If we reached the top, then we were public all the way down and
668-
// we can allow this access.
669-
if closest_private_id == ast::DUMMY_NODE_ID { return Allowable }
670-
}
671-
debug!("privacy - closest priv {}", self.nodestr(closest_private_id));
672-
if self.private_accessible(closest_private_id) {
632+
// This is not a method call, extract the visibility as one
633+
// would normally look at it
634+
Some(ast_map::NodeItem(it)) => it.vis,
635+
Some(ast_map::NodeForeignItem(_)) => {
636+
self.tcx.map.get_foreign_vis(node_id)
637+
}
638+
_ => hir::Public,
639+
};
640+
if vis == hir::Public { return Allowable }
641+
642+
if self.private_accessible(node_id) {
673643
Allowable
674644
} else {
675-
DisallowedBy(closest_private_id)
645+
DisallowedBy(node_id)
676646
}
677647
}
678648

0 commit comments

Comments
 (0)
Please sign in to comment.