Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement pub(restricted) privacy (RFC 1422) #32875

Merged
merged 11 commits into from
Apr 17, 2016
13 changes: 13 additions & 0 deletions src/librustc/hir/intravisit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ pub trait Visitor<'v> : Sized {
fn visit_macro_def(&mut self, macro_def: &'v MacroDef) {
walk_macro_def(self, macro_def)
}
fn visit_vis(&mut self, vis: &'v Visibility) {
walk_vis(self, vis)
}
}

pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option<Name>) {
Expand Down Expand Up @@ -288,6 +291,7 @@ pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef)
}

pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_vis(&item.vis);
visitor.visit_name(item.span, item.name);
match item.node {
ItemExternCrate(opt_name) => {
Expand Down Expand Up @@ -529,6 +533,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
}

pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem) {
visitor.visit_vis(&foreign_item.vis);
visitor.visit_name(foreign_item.span, foreign_item.name);

match foreign_item.node {
Expand Down Expand Up @@ -662,6 +667,7 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
}

pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) {
visitor.visit_vis(&impl_item.vis);
visitor.visit_name(impl_item.span, impl_item.name);
walk_list!(visitor, visit_attribute, &impl_item.attrs);
match impl_item.node {
Expand Down Expand Up @@ -690,6 +696,7 @@ pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &
}

pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) {
visitor.visit_vis(&struct_field.vis);
visitor.visit_name(struct_field.span, struct_field.name);
visitor.visit_ty(&struct_field.ty);
walk_list!(visitor, visit_attribute, &struct_field.attrs);
Expand Down Expand Up @@ -839,6 +846,12 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
walk_list!(visitor, visit_attribute, &arm.attrs);
}

pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
if let Visibility::Restricted { ref path, id } = *vis {
visitor.visit_path(path, id)
}
}

#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct IdRange {
pub min: NodeId,
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1708,8 +1708,10 @@ pub fn lower_capture_clause(_lctx: &LoweringContext, c: CaptureBy) -> hir::Captu
pub fn lower_visibility(lctx: &LoweringContext, v: &Visibility) -> hir::Visibility {
match *v {
Visibility::Public => hir::Public,
Visibility::Crate(_) => hir::Visibility::Crate,
Visibility::Restricted { ref path, id } =>
hir::Visibility::Restricted { path: P(lower_path(lctx, path)), id: id },
Visibility::Inherited => hir::Inherited,
_ => panic!(lctx.diagnostic().fatal("pub(restricted) is not implemented yet!"))
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub use self::TyParamBound::*;
pub use self::UnOp::*;
pub use self::UnsafeSource::*;
pub use self::ViewPath_::*;
pub use self::Visibility::*;
pub use self::Visibility::{Public, Inherited};
pub use self::PathParameters::*;

use hir::def::Def;
Expand Down Expand Up @@ -1434,6 +1434,8 @@ pub struct PolyTraitRef {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Visibility {
Public,
Crate,
Restricted { path: P<Path>, id: NodeId },
Inherited,
}

Expand Down
5 changes: 5 additions & 0 deletions src/librustc/hir/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ pub fn arg_to_string(arg: &hir::Arg) -> String {
pub fn visibility_qualified(vis: &hir::Visibility, s: &str) -> String {
match *vis {
hir::Public => format!("pub {}", s),
hir::Visibility::Crate => format!("pub(crate) {}", s),
hir::Visibility::Restricted { ref path, .. } => format!("pub({}) {}", path, s),
hir::Inherited => s.to_string(),
}
}
Expand Down Expand Up @@ -898,6 +900,9 @@ impl<'a> State<'a> {
pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> {
match *vis {
hir::Public => self.word_nbsp("pub"),
hir::Visibility::Crate => self.word_nbsp("pub(crate)"),
hir::Visibility::Restricted { ref path, .. } =>
self.word_nbsp(&format!("pub({})", path)),
hir::Inherited => Ok(()),
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,15 @@ impl Visibility {
pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: &TyCtxt) -> Self {
match *visibility {
hir::Public => Visibility::Public,
hir::Visibility::Crate => Visibility::Restricted(ast::CRATE_NODE_ID),
hir::Visibility::Restricted { id, .. } => match tcx.def_map.borrow().get(&id) {
Some(resolution) => Visibility::Restricted({
tcx.map.as_local_node_id(resolution.base_def.def_id()).unwrap()
}),
// If there is no resolution, `resolve` will have already reported an error, so
// assume that the visibility is public to avoid reporting more privacy errors.
None => Visibility::Public,
},
hir::Inherited => Visibility::Restricted(tcx.map.get_module_parent(id)),
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,8 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
self.min_visibility = vis;
}
if !vis.is_at_least(self.required_visibility, &self.tcx.map) {
if self.old_error_set.contains(&ty.id) {
if self.tcx.sess.features.borrow().pub_restricted ||
self.old_error_set.contains(&ty.id) {
span_err!(self.tcx.sess, ty.span, E0446,
"private type in public interface");
} else {
Expand Down Expand Up @@ -1053,7 +1054,8 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
self.min_visibility = vis;
}
if !vis.is_at_least(self.required_visibility, &self.tcx.map) {
if self.old_error_set.contains(&trait_ref.ref_id) {
if self.tcx.sess.features.borrow().pub_restricted ||
self.old_error_set.contains(&trait_ref.ref_id) {
span_err!(self.tcx.sess, trait_ref.path.span, E0445,
"private trait in public interface");
} else {
Expand Down
Loading