Skip to content

Commit

Permalink
Auto merge of #32875 - jseyfried:1422_implementation, r=nikomatsakis
Browse files Browse the repository at this point in the history
Implement `pub(restricted)` privacy (RFC 1422)

This implements `pub(restricted)` privacy from RFC 1422 (cc #32409) behind a feature gate.

`pub(restricted)` paths currently cannot use re-exported modules both for simplicity of implementation and for future compatibility with RFC 1560 (cf #31783).

r? @nikomatsakis
  • Loading branch information
bors committed Apr 16, 2016
2 parents a7c3a29 + e14504a commit ae33aa7
Show file tree
Hide file tree
Showing 26 changed files with 478 additions and 196 deletions.
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

0 comments on commit ae33aa7

Please sign in to comment.