about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-09-30 06:42:56 +0200
committerMazdak Farrokhzad <twingoow@gmail.com>2019-09-30 06:42:56 +0200
commit66bf323a3bb8aaa6162cf02ce9e3db2aa44f4779 (patch)
tree100e2519704ef432678332e59efdc7c7083569a7 /src/libsyntax/parse/parser.rs
parent5b80ead489beab6ed1e8f0f4951b7d982bd789ab (diff)
downloadrust-66bf323a3bb8aaa6162cf02ce9e3db2aa44f4779.tar.gz
rust-66bf323a3bb8aaa6162cf02ce9e3db2aa44f4779.zip
syntax: cleanup `parse_visibility`.
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
-rw-r--r--src/libsyntax/parse/parser.rs122
1 files changed, 69 insertions, 53 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 4853da86564..43846685185 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1417,68 +1417,84 @@ impl<'a> Parser<'a> {
             // `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`.
             // Because of this, we only `bump` the `(` if we're assured it is appropriate to do so
             // by the following tokens.
-            if self.is_keyword_ahead(1, &[kw::Crate]) &&
-                self.look_ahead(2, |t| t != &token::ModSep) // account for `pub(crate::foo)`
+            if self.is_keyword_ahead(1, &[kw::Crate])
+                && self.look_ahead(2, |t| t != &token::ModSep) // account for `pub(crate::foo)`
             {
-                // `pub(crate)`
-                self.bump(); // `(`
-                self.bump(); // `crate`
-                self.expect(&token::CloseDelim(token::Paren))?; // `)`
-                let vis = respan(
-                    lo.to(self.prev_span),
-                    VisibilityKind::Crate(CrateSugar::PubCrate),
-                );
-                return Ok(vis)
+                return self.parse_vis_pub_crate(lo);
             } else if self.is_keyword_ahead(1, &[kw::In]) {
-                // `pub(in path)`
-                self.bump(); // `(`
-                self.bump(); // `in`
-                let path = self.parse_path(PathStyle::Mod)?; // `path`
-                self.expect(&token::CloseDelim(token::Paren))?; // `)`
-                let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
-                    path: P(path),
-                    id: ast::DUMMY_NODE_ID,
-                });
-                return Ok(vis)
-            } else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren)) &&
-                      self.is_keyword_ahead(1, &[kw::Super, kw::SelfLower])
+                return self.parse_vis_pub_in(lo);
+            } else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren))
+                && self.is_keyword_ahead(1, &[kw::Super, kw::SelfLower])
             {
-                // `pub(self)` or `pub(super)`
-                self.bump(); // `(`
-                let path = self.parse_path(PathStyle::Mod)?; // `super`/`self`
-                self.expect(&token::CloseDelim(token::Paren))?; // `)`
-                let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
-                    path: P(path),
-                    id: ast::DUMMY_NODE_ID,
-                });
-                return Ok(vis)
-            } else if !can_take_tuple {  // Provide this diagnostic if this is not a tuple struct
-                // `pub(something) fn ...` or `struct X { pub(something) y: Z }`
-                self.bump(); // `(`
-                let msg = "incorrect visibility restriction";
-                let suggestion = r##"some possible visibility restrictions are:
-`pub(crate)`: visible only on the current crate
-`pub(super)`: visible only in the current module's parent
-`pub(in path::to::module)`: visible only on the specified path"##;
-                let path = self.parse_path(PathStyle::Mod)?;
-                let sp = path.span;
-                let help_msg = format!("make this visible only to module `{}` with `in`", path);
-                self.expect(&token::CloseDelim(token::Paren))?;  // `)`
-                struct_span_err!(self.sess.span_diagnostic, sp, E0704, "{}", msg)
-                    .help(suggestion)
-                    .span_suggestion(
-                        sp,
-                        &help_msg,
-                        format!("in {}", path),
-                        Applicability::MachineApplicable,
-                    )
-                    .emit(); // Emit diagnostic, but continue with public visibility.
+                return self.parse_vis_self_super(lo);
+            } else if !can_take_tuple { // Provide this diagnostic if this is not a tuple struct.
+                self.recover_incorrect_vis_restriction()?;
+                // Emit diagnostic, but continue with public visibility.
             }
         }
 
         Ok(respan(lo, VisibilityKind::Public))
     }
 
+    /// Parse `pub(crate)`.
+    fn parse_vis_pub_crate(&mut self, lo: Span) -> PResult<'a, Visibility> {
+        self.bump(); // `(`
+        self.bump(); // `crate`
+        self.expect(&token::CloseDelim(token::Paren))?; // `)`
+        Ok(respan(
+            lo.to(self.prev_span),
+            VisibilityKind::Crate(CrateSugar::PubCrate),
+        ))
+    }
+
+    /// Parse `pub(in path)`.
+    fn parse_vis_pub_in(&mut self, lo: Span) -> PResult<'a, Visibility> {
+        self.bump(); // `(`
+        self.bump(); // `in`
+        let path = self.parse_path(PathStyle::Mod)?; // `path`
+        self.expect(&token::CloseDelim(token::Paren))?; // `)`
+        Ok(respan(lo.to(self.prev_span), VisibilityKind::Restricted {
+            path: P(path),
+            id: ast::DUMMY_NODE_ID,
+        }))
+    }
+
+    /// Parse `pub(self)` or `pub(super)`.
+    fn parse_vis_self_super(&mut self, lo: Span) -> PResult<'a, Visibility> {
+        self.bump(); // `(`
+        let path = self.parse_path(PathStyle::Mod)?; // `super`/`self`
+        self.expect(&token::CloseDelim(token::Paren))?; // `)`
+        Ok(respan(lo.to(self.prev_span), VisibilityKind::Restricted {
+            path: P(path),
+            id: ast::DUMMY_NODE_ID,
+        }))
+    }
+
+    /// Recovery for e.g. `pub(something) fn ...` or `struct X { pub(something) y: Z }`
+    fn recover_incorrect_vis_restriction(&mut self) -> PResult<'a, ()> {
+        self.bump(); // `(`
+        let path = self.parse_path(PathStyle::Mod)?;
+        self.expect(&token::CloseDelim(token::Paren))?;  // `)`
+
+        let msg = "incorrect visibility restriction";
+        let suggestion = r##"some possible visibility restrictions are:
+`pub(crate)`: visible only on the current crate
+`pub(super)`: visible only in the current module's parent
+`pub(in path::to::module)`: visible only on the specified path"##;
+
+        struct_span_err!(self.sess.span_diagnostic, path.span, E0704, "{}", msg)
+            .help(suggestion)
+            .span_suggestion(
+                path.span,
+                &format!("make this visible only to module `{}` with `in`", path),
+                format!("in {}", path),
+                Applicability::MachineApplicable,
+            )
+            .emit();
+
+        Ok(())
+    }
+
     /// Parses a string as an ABI spec on an extern type or module. Consumes
     /// the `extern` keyword, if one is found.
     fn parse_opt_abi(&mut self) -> PResult<'a, Option<Abi>> {