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) { @@ -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, 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)), } }