Skip to content

Commit ae33aa7

Browse files
committed
Auto merge of #32875 - jseyfried:1422_implementation, r=nikomatsakis
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
2 parents a7c3a29 + e14504a commit ae33aa7

26 files changed

+478
-196
lines changed

src/librustc/hir/intravisit.rs

+13
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ pub trait Visitor<'v> : Sized {
203203
fn visit_macro_def(&mut self, macro_def: &'v MacroDef) {
204204
walk_macro_def(self, macro_def)
205205
}
206+
fn visit_vis(&mut self, vis: &'v Visibility) {
207+
walk_vis(self, vis)
208+
}
206209
}
207210

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

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

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

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

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

692698
pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) {
699+
visitor.visit_vis(&struct_field.vis);
693700
visitor.visit_name(struct_field.span, struct_field.name);
694701
visitor.visit_ty(&struct_field.ty);
695702
walk_list!(visitor, visit_attribute, &struct_field.attrs);
@@ -839,6 +846,12 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
839846
walk_list!(visitor, visit_attribute, &arm.attrs);
840847
}
841848

849+
pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
850+
if let Visibility::Restricted { ref path, id } = *vis {
851+
visitor.visit_path(path, id)
852+
}
853+
}
854+
842855
#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)]
843856
pub struct IdRange {
844857
pub min: NodeId,

src/librustc/hir/lowering.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1708,8 +1708,10 @@ pub fn lower_capture_clause(_lctx: &LoweringContext, c: CaptureBy) -> hir::Captu
17081708
pub fn lower_visibility(lctx: &LoweringContext, v: &Visibility) -> hir::Visibility {
17091709
match *v {
17101710
Visibility::Public => hir::Public,
1711+
Visibility::Crate(_) => hir::Visibility::Crate,
1712+
Visibility::Restricted { ref path, id } =>
1713+
hir::Visibility::Restricted { path: P(lower_path(lctx, path)), id: id },
17111714
Visibility::Inherited => hir::Inherited,
1712-
_ => panic!(lctx.diagnostic().fatal("pub(restricted) is not implemented yet!"))
17131715
}
17141716
}
17151717

src/librustc/hir/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub use self::TyParamBound::*;
3030
pub use self::UnOp::*;
3131
pub use self::UnsafeSource::*;
3232
pub use self::ViewPath_::*;
33-
pub use self::Visibility::*;
33+
pub use self::Visibility::{Public, Inherited};
3434
pub use self::PathParameters::*;
3535

3636
use hir::def::Def;
@@ -1434,6 +1434,8 @@ pub struct PolyTraitRef {
14341434
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
14351435
pub enum Visibility {
14361436
Public,
1437+
Crate,
1438+
Restricted { path: P<Path>, id: NodeId },
14371439
Inherited,
14381440
}
14391441

src/librustc/hir/print.rs

+5
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ pub fn arg_to_string(arg: &hir::Arg) -> String {
325325
pub fn visibility_qualified(vis: &hir::Visibility, s: &str) -> String {
326326
match *vis {
327327
hir::Public => format!("pub {}", s),
328+
hir::Visibility::Crate => format!("pub(crate) {}", s),
329+
hir::Visibility::Restricted { ref path, .. } => format!("pub({}) {}", path, s),
328330
hir::Inherited => s.to_string(),
329331
}
330332
}
@@ -898,6 +900,9 @@ impl<'a> State<'a> {
898900
pub fn print_visibility(&mut self, vis: &hir::Visibility) -> io::Result<()> {
899901
match *vis {
900902
hir::Public => self.word_nbsp("pub"),
903+
hir::Visibility::Crate => self.word_nbsp("pub(crate)"),
904+
hir::Visibility::Restricted { ref path, .. } =>
905+
self.word_nbsp(&format!("pub({})", path)),
901906
hir::Inherited => Ok(()),
902907
}
903908
}

src/librustc/ty/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,15 @@ impl Visibility {
287287
pub fn from_hir(visibility: &hir::Visibility, id: NodeId, tcx: &TyCtxt) -> Self {
288288
match *visibility {
289289
hir::Public => Visibility::Public,
290+
hir::Visibility::Crate => Visibility::Restricted(ast::CRATE_NODE_ID),
291+
hir::Visibility::Restricted { id, .. } => match tcx.def_map.borrow().get(&id) {
292+
Some(resolution) => Visibility::Restricted({
293+
tcx.map.as_local_node_id(resolution.base_def.def_id()).unwrap()
294+
}),
295+
// If there is no resolution, `resolve` will have already reported an error, so
296+
// assume that the visibility is public to avoid reporting more privacy errors.
297+
None => Visibility::Public,
298+
},
290299
hir::Inherited => Visibility::Restricted(tcx.map.get_module_parent(id)),
291300
}
292301
}

src/librustc_privacy/lib.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,8 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
10231023
self.min_visibility = vis;
10241024
}
10251025
if !vis.is_at_least(self.required_visibility, &self.tcx.map) {
1026-
if self.old_error_set.contains(&ty.id) {
1026+
if self.tcx.sess.features.borrow().pub_restricted ||
1027+
self.old_error_set.contains(&ty.id) {
10271028
span_err!(self.tcx.sess, ty.span, E0446,
10281029
"private type in public interface");
10291030
} else {
@@ -1053,7 +1054,8 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
10531054
self.min_visibility = vis;
10541055
}
10551056
if !vis.is_at_least(self.required_visibility, &self.tcx.map) {
1056-
if self.old_error_set.contains(&trait_ref.ref_id) {
1057+
if self.tcx.sess.features.borrow().pub_restricted ||
1058+
self.old_error_set.contains(&trait_ref.ref_id) {
10571059
span_err!(self.tcx.sess, trait_ref.path.span, E0445,
10581060
"private trait in public interface");
10591061
} else {

0 commit comments

Comments
 (0)