@@ -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