Skip to content

Commit 9faf796

Browse files
committed
parse pub(restricted) visibilities for struct fields
1 parent 1930483 commit 9faf796

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5218,8 +5218,25 @@ impl<'a> Parser<'a> {
52185218
|p| {
52195219
let attrs = p.parse_outer_attributes()?;
52205220
let lo = p.span.lo;
5221-
let vis = p.parse_visibility(false)?;
5222-
let ty = p.parse_ty_sum()?;
5221+
let mut vis = p.parse_visibility(false)?;
5222+
let ty_is_interpolated =
5223+
p.token.is_interpolated() || p.look_ahead(1, |t| t.is_interpolated());
5224+
let mut ty = p.parse_ty_sum()?;
5225+
5226+
// Handle `pub(path) type`, in which `vis` will be `pub` and `ty` will be `(path)`.
5227+
if vis == Visibility::Public && !ty_is_interpolated &&
5228+
p.token != token::Comma && p.token != token::CloseDelim(token::Paren) {
5229+
ty = if let TyKind::Paren(ref path_ty) = ty.node {
5230+
if let TyKind::Path(None, ref path) = path_ty.node {
5231+
vis = Visibility::Restricted { path: P(path.clone()), id: path_ty.id };
5232+
Some(p.parse_ty_sum()?)
5233+
} else {
5234+
None
5235+
}
5236+
} else {
5237+
None
5238+
}.unwrap_or(ty);
5239+
}
52235240
Ok(StructField {
52245241
span: mk_sp(lo, p.span.hi),
52255242
vis: vis,
@@ -5263,15 +5280,29 @@ impl<'a> Parser<'a> {
52635280
self.parse_single_struct_field(vis, attrs)
52645281
}
52655282

5266-
fn parse_visibility(&mut self, allow_restricted: bool) -> PResult<'a, Visibility> {
5283+
// If `allow_path` is false, just parse the `pub` in `pub(path)` (but still parse `pub(crate)`)
5284+
fn parse_visibility(&mut self, allow_path: bool) -> PResult<'a, Visibility> {
5285+
let pub_crate = |this: &mut Self| {
5286+
let span = this.last_span;
5287+
this.expect(&token::CloseDelim(token::Paren))?;
5288+
Ok(Visibility::Crate(span))
5289+
};
5290+
52675291
if !self.eat_keyword(keywords::Pub) {
52685292
Ok(Visibility::Inherited)
5269-
} else if !allow_restricted || !self.eat(&token::OpenDelim(token::Paren)) {
5293+
} else if !allow_path {
5294+
// Look ahead to avoid eating the `(` in `pub(path)` while still parsing `pub(crate)`
5295+
if self.token == token::OpenDelim(token::Paren) &&
5296+
self.look_ahead(1, |t| t.is_keyword(keywords::Crate)) {
5297+
self.bump(); self.bump();
5298+
pub_crate(self)
5299+
} else {
5300+
Ok(Visibility::Public)
5301+
}
5302+
} else if !self.eat(&token::OpenDelim(token::Paren)) {
52705303
Ok(Visibility::Public)
52715304
} else if self.eat_keyword(keywords::Crate) {
5272-
let span = self.last_span;
5273-
self.expect(&token::CloseDelim(token::Paren))?;
5274-
Ok(Visibility::Crate(span))
5305+
pub_crate(self)
52755306
} else {
52765307
let path = self.parse_path(PathStyle::Mod)?;
52775308
self.expect(&token::CloseDelim(token::Paren))?;

0 commit comments

Comments
 (0)