about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-04-16 16:21:09 -0700
committerbors <bors@rust-lang.org>2016-04-16 16:21:09 -0700
commitae33aa74f4e03b11a9a82e10dbf7369c3ae6bd04 (patch)
tree285c01dd08e9c3f426d99beeacba4e1e288297b1 /src/libsyntax
parenta7c3a294bf33880d27fc7c3f662a981b1625c0bb (diff)
parente14504a113b55c09686a5986c51bbdd6ae9c5da4 (diff)
downloadrust-ae33aa74f4e03b11a9a82e10dbf7369c3ae6bd04.tar.gz
rust-ae33aa74f4e03b11a9a82e10dbf7369c3ae6bd04.zip
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
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/feature_gate.rs15
-rw-r--r--src/libsyntax/fold.rs2
-rw-r--r--src/libsyntax/parse/parser.rs41
-rw-r--r--src/libsyntax/print/pprust.rs4
-rw-r--r--src/libsyntax/visit.rs9
6 files changed, 50 insertions, 23 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 16d4ed53b5b..df9f935446d 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1887,7 +1887,7 @@ pub struct PolyTraitRef {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Visibility {
     Public,
-    Crate,
+    Crate(Span),
     Restricted { path: P<Path>, id: NodeId },
     Inherited,
 }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 24a62a3dc2a..d8352430eb9 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -256,6 +256,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
 
     // impl specialization (RFC 1210)
     ("specialization", "1.7.0", Some(31844), Active),
+
+    // pub(restricted) visibilities (RFC 1422)
+    ("pub_restricted", "1.9.0", Some(32409), Active),
 ];
 // (changing above list without updating src/doc/reference.md makes @cmr sad)
 
@@ -608,6 +611,7 @@ pub struct Features {
     pub deprecated: bool,
     pub question_mark: bool,
     pub specialization: bool,
+    pub pub_restricted: bool,
 }
 
 impl Features {
@@ -644,6 +648,7 @@ impl Features {
             deprecated: false,
             question_mark: false,
             specialization: false,
+            pub_restricted: false,
         }
     }
 }
@@ -1159,6 +1164,15 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
         }
         visit::walk_impl_item(self, ii);
     }
+
+    fn visit_vis(&mut self, vis: &'v ast::Visibility) {
+        let span = match *vis {
+            ast::Visibility::Crate(span) => span,
+            ast::Visibility::Restricted { ref path, .. } => path.span,
+            _ => return,
+        };
+        self.gate_feature("pub_restricted", span, "`pub(restricted)` syntax is experimental");
+    }
 }
 
 fn check_crate_inner<F>(cm: &CodeMap, span_handler: &Handler,
@@ -1256,6 +1270,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &Handler,
         deprecated: cx.has_feature("deprecated"),
         question_mark: cx.has_feature("question_mark"),
         specialization: cx.has_feature("specialization"),
+        pub_restricted: cx.has_feature("pub_restricted"),
     }
 }
 
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 5d378763bef..89451e79550 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -850,7 +850,7 @@ pub fn noop_fold_struct_field<T: Folder>(f: StructField, fld: &mut T) -> StructF
         span: fld.new_span(f.span),
         id: fld.new_id(f.id),
         ident: f.ident.map(|ident| fld.fold_ident(ident)),
-        vis: f.vis,
+        vis: fld.fold_vis(f.vis),
         ty: fld.fold_ty(f.ty),
         attrs: fold_attrs(f.attrs, fld),
     }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f41aa835a75..05cd53a8a8e 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -70,6 +70,7 @@ bitflags! {
         const RESTRICTION_STMT_EXPR         = 1 << 0,
         const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1,
         const NO_NONINLINE_MOD  = 1 << 2,
+        const ALLOW_MODULE_PATHS = 1 << 3,
     }
 }
 
@@ -560,7 +561,9 @@ impl<'a> Parser<'a> {
     }
 
     pub fn parse_ident(&mut self) -> PResult<'a, ast::Ident> {
-        self.check_strict_keywords();
+        if !self.restrictions.contains(Restrictions::ALLOW_MODULE_PATHS) {
+            self.check_strict_keywords();
+        }
         self.check_reserved_keywords();
         match self.token {
             token::Ident(i, _) => {
@@ -4937,7 +4940,7 @@ impl<'a> Parser<'a> {
 
         let mut attrs = self.parse_outer_attributes()?;
         let lo = self.span.lo;
-        let vis = self.parse_visibility()?;
+        let vis = self.parse_visibility(true)?;
         let defaultness = self.parse_defaultness()?;
         let (name, node) = if self.eat_keyword(keywords::Type) {
             let name = self.parse_ident()?;
@@ -5249,7 +5252,7 @@ impl<'a> Parser<'a> {
             |p| {
                 let attrs = p.parse_outer_attributes()?;
                 let lo = p.span.lo;
-                let vis = p.parse_visibility()?;
+                let vis = p.parse_visibility(false)?;
                 let ty = p.parse_ty_sum()?;
                 Ok(StructField {
                     span: mk_sp(lo, p.span.hi),
@@ -5289,20 +5292,26 @@ impl<'a> Parser<'a> {
 
     /// Parse an element of a struct definition
     fn parse_struct_decl_field(&mut self) -> PResult<'a, StructField> {
-
         let attrs = self.parse_outer_attributes()?;
-
-        if self.eat_keyword(keywords::Pub) {
-            return self.parse_single_struct_field(Visibility::Public, attrs);
-        }
-
-        return self.parse_single_struct_field(Visibility::Inherited, attrs);
+        let vis = self.parse_visibility(true)?;
+        self.parse_single_struct_field(vis, attrs)
     }
 
-    /// Parse visibility: PUB or nothing
-    fn parse_visibility(&mut self) -> PResult<'a, Visibility> {
-        if self.eat_keyword(keywords::Pub) { Ok(Visibility::Public) }
-        else { Ok(Visibility::Inherited) }
+    fn parse_visibility(&mut self, allow_restricted: bool) -> PResult<'a, Visibility> {
+        if !self.eat_keyword(keywords::Pub) {
+            Ok(Visibility::Inherited)
+        } else if !allow_restricted || !self.eat(&token::OpenDelim(token::Paren)) {
+            Ok(Visibility::Public)
+        } else if self.eat_keyword(keywords::Crate) {
+            let span = self.last_span;
+            self.expect(&token::CloseDelim(token::Paren))?;
+            Ok(Visibility::Crate(span))
+        } else {
+            let path = self.with_res(Restrictions::ALLOW_MODULE_PATHS,
+                                     |this| this.parse_path(NoTypesAllowed))?;
+            self.expect(&token::CloseDelim(token::Paren))?;
+            Ok(Visibility::Restricted { path: P(path), id: ast::DUMMY_NODE_ID })
+        }
     }
 
     /// Parse defaultness: DEFAULT or nothing
@@ -5764,7 +5773,7 @@ impl<'a> Parser<'a> {
 
         let lo = self.span.lo;
 
-        let visibility = self.parse_visibility()?;
+        let visibility = self.parse_visibility(true)?;
 
         if self.eat_keyword(keywords::Use) {
             // USE ITEM
@@ -6014,7 +6023,7 @@ impl<'a> Parser<'a> {
     fn parse_foreign_item(&mut self) -> PResult<'a, Option<ForeignItem>> {
         let attrs = self.parse_outer_attributes()?;
         let lo = self.span.lo;
-        let visibility = self.parse_visibility()?;
+        let visibility = self.parse_visibility(true)?;
 
         if self.check_keyword(keywords::Static) {
             // FOREIGN STATIC ITEM
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index fcd83b41041..95f1b63168b 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -435,7 +435,7 @@ pub fn mac_to_string(arg: &ast::Mac) -> String {
 pub fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String {
     match *vis {
         ast::Visibility::Public => format!("pub {}", s),
-        ast::Visibility::Crate => format!("pub(crate) {}", s),
+        ast::Visibility::Crate(_) => format!("pub(crate) {}", s),
         ast::Visibility::Restricted { ref path, .. } => format!("pub({}) {}", path, s),
         ast::Visibility::Inherited => s.to_string()
     }
@@ -1386,7 +1386,7 @@ impl<'a> State<'a> {
     pub fn print_visibility(&mut self, vis: &ast::Visibility) -> io::Result<()> {
         match *vis {
             ast::Visibility::Public => self.word_nbsp("pub"),
-            ast::Visibility::Crate => self.word_nbsp("pub(crate)"),
+            ast::Visibility::Crate(_) => self.word_nbsp("pub(crate)"),
             ast::Visibility::Restricted { ref path, .. } =>
                 self.word_nbsp(&format!("pub({})", path)),
             ast::Visibility::Inherited => Ok(())
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 839bbf4805d..413017c7271 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -231,6 +231,7 @@ pub fn walk_trait_ref<'v,V>(visitor: &mut V,
 }
 
 pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
+    visitor.visit_vis(&item.vis);
     visitor.visit_ident(item.span, item.ident);
     match item.node {
         ItemKind::ExternCrate(opt_name) => {
@@ -470,6 +471,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_ident(foreign_item.span, foreign_item.ident);
 
     match foreign_item.node {
@@ -592,6 +594,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_ident(impl_item.span, impl_item.ident);
     walk_list!(visitor, visit_attribute, &impl_item.attrs);
     match impl_item.node {
@@ -619,6 +622,7 @@ pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V,
 
 pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,
                                              struct_field: &'v StructField) {
+    visitor.visit_vis(&struct_field.vis);
     walk_opt_ident(visitor, struct_field.span, struct_field.ident);
     visitor.visit_ty(&struct_field.ty);
     walk_list!(visitor, visit_attribute, &struct_field.attrs);
@@ -812,8 +816,7 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) {
 }
 
 pub fn walk_vis<'v, V: Visitor<'v>>(visitor: &mut V, vis: &'v Visibility) {
-    match *vis {
-        Visibility::Restricted { ref path, id } => visitor.visit_path(path, id),
-        _ => {}
+    if let Visibility::Restricted { ref path, id } = *vis {
+        visitor.visit_path(path, id);
     }
 }