about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/hir/intravisit.rs13
-rw-r--r--src/librustc/hir/lowering.rs4
-rw-r--r--src/librustc/hir/mod.rs4
-rw-r--r--src/librustc/hir/print.rs5
-rw-r--r--src/librustc/ty/mod.rs9
5 files changed, 33 insertions, 2 deletions
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 55fd58da866..6e6f845abd3 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -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>) {
@@ -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) => {
@@ -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 {
@@ -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 {
@@ -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);
@@ -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,
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 738a04dea58..7c476657041 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -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!"))
     }
 }
 
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 8e748875b93..4e752003523 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -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;
@@ -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,
 }
 
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index e9ed0ed574e..e595c619e85 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -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(),
     }
 }
@@ -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(()),
         }
     }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index eaba5d2a860..0377ef92a6f 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -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)),
         }
     }