@@ -1417,68 +1417,84 @@ impl<'a> Parser<'a> {
1417
1417
// `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`.
1418
1418
// Because of this, we only `bump` the `(` if we're assured it is appropriate to do so
1419
1419
// by the following tokens.
1420
- if self . is_keyword_ahead ( 1 , & [ kw:: Crate ] ) &&
1421
- self . look_ahead ( 2 , |t| t != & token:: ModSep ) // account for `pub(crate::foo)`
1420
+ if self . is_keyword_ahead ( 1 , & [ kw:: Crate ] )
1421
+ && self . look_ahead ( 2 , |t| t != & token:: ModSep ) // account for `pub(crate::foo)`
1422
1422
{
1423
- // `pub(crate)`
1424
- self . bump ( ) ; // `(`
1425
- self . bump ( ) ; // `crate`
1426
- self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?; // `)`
1427
- let vis = respan (
1428
- lo. to ( self . prev_span ) ,
1429
- VisibilityKind :: Crate ( CrateSugar :: PubCrate ) ,
1430
- ) ;
1431
- return Ok ( vis)
1423
+ return self . parse_vis_pub_crate ( lo) ;
1432
1424
} else if self . is_keyword_ahead ( 1 , & [ kw:: In ] ) {
1433
- // `pub(in path)`
1434
- self . bump ( ) ; // `(`
1435
- self . bump ( ) ; // `in`
1436
- let path = self . parse_path ( PathStyle :: Mod ) ?; // `path`
1437
- self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?; // `)`
1438
- let vis = respan ( lo. to ( self . prev_span ) , VisibilityKind :: Restricted {
1439
- path : P ( path) ,
1440
- id : ast:: DUMMY_NODE_ID ,
1441
- } ) ;
1442
- return Ok ( vis)
1443
- } else if self . look_ahead ( 2 , |t| t == & token:: CloseDelim ( token:: Paren ) ) &&
1444
- self . is_keyword_ahead ( 1 , & [ kw:: Super , kw:: SelfLower ] )
1425
+ return self . parse_vis_pub_in ( lo) ;
1426
+ } else if self . look_ahead ( 2 , |t| t == & token:: CloseDelim ( token:: Paren ) )
1427
+ && self . is_keyword_ahead ( 1 , & [ kw:: Super , kw:: SelfLower ] )
1445
1428
{
1446
- // `pub(self)` or `pub(super)`
1447
- self . bump ( ) ; // `(`
1448
- let path = self . parse_path ( PathStyle :: Mod ) ?; // `super`/`self`
1449
- self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?; // `)`
1450
- let vis = respan ( lo. to ( self . prev_span ) , VisibilityKind :: Restricted {
1451
- path : P ( path) ,
1452
- id : ast:: DUMMY_NODE_ID ,
1453
- } ) ;
1454
- return Ok ( vis)
1455
- } else if !can_take_tuple { // Provide this diagnostic if this is not a tuple struct
1456
- // `pub(something) fn ...` or `struct X { pub(something) y: Z }`
1457
- self . bump ( ) ; // `(`
1458
- let msg = "incorrect visibility restriction" ;
1459
- let suggestion = r##"some possible visibility restrictions are:
1460
- `pub(crate)`: visible only on the current crate
1461
- `pub(super)`: visible only in the current module's parent
1462
- `pub(in path::to::module)`: visible only on the specified path"## ;
1463
- let path = self . parse_path ( PathStyle :: Mod ) ?;
1464
- let sp = path. span ;
1465
- let help_msg = format ! ( "make this visible only to module `{}` with `in`" , path) ;
1466
- self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?; // `)`
1467
- struct_span_err ! ( self . sess. span_diagnostic, sp, E0704 , "{}" , msg)
1468
- . help ( suggestion)
1469
- . span_suggestion (
1470
- sp,
1471
- & help_msg,
1472
- format ! ( "in {}" , path) ,
1473
- Applicability :: MachineApplicable ,
1474
- )
1475
- . emit ( ) ; // Emit diagnostic, but continue with public visibility.
1429
+ return self . parse_vis_self_super ( lo) ;
1430
+ } else if !can_take_tuple { // Provide this diagnostic if this is not a tuple struct.
1431
+ self . recover_incorrect_vis_restriction ( ) ?;
1432
+ // Emit diagnostic, but continue with public visibility.
1476
1433
}
1477
1434
}
1478
1435
1479
1436
Ok ( respan ( lo, VisibilityKind :: Public ) )
1480
1437
}
1481
1438
1439
+ /// Parse `pub(crate)`.
1440
+ fn parse_vis_pub_crate ( & mut self , lo : Span ) -> PResult < ' a , Visibility > {
1441
+ self . bump ( ) ; // `(`
1442
+ self . bump ( ) ; // `crate`
1443
+ self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?; // `)`
1444
+ Ok ( respan (
1445
+ lo. to ( self . prev_span ) ,
1446
+ VisibilityKind :: Crate ( CrateSugar :: PubCrate ) ,
1447
+ ) )
1448
+ }
1449
+
1450
+ /// Parse `pub(in path)`.
1451
+ fn parse_vis_pub_in ( & mut self , lo : Span ) -> PResult < ' a , Visibility > {
1452
+ self . bump ( ) ; // `(`
1453
+ self . bump ( ) ; // `in`
1454
+ let path = self . parse_path ( PathStyle :: Mod ) ?; // `path`
1455
+ self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?; // `)`
1456
+ Ok ( respan ( lo. to ( self . prev_span ) , VisibilityKind :: Restricted {
1457
+ path : P ( path) ,
1458
+ id : ast:: DUMMY_NODE_ID ,
1459
+ } ) )
1460
+ }
1461
+
1462
+ /// Parse `pub(self)` or `pub(super)`.
1463
+ fn parse_vis_self_super ( & mut self , lo : Span ) -> PResult < ' a , Visibility > {
1464
+ self . bump ( ) ; // `(`
1465
+ let path = self . parse_path ( PathStyle :: Mod ) ?; // `super`/`self`
1466
+ self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?; // `)`
1467
+ Ok ( respan ( lo. to ( self . prev_span ) , VisibilityKind :: Restricted {
1468
+ path : P ( path) ,
1469
+ id : ast:: DUMMY_NODE_ID ,
1470
+ } ) )
1471
+ }
1472
+
1473
+ /// Recovery for e.g. `pub(something) fn ...` or `struct X { pub(something) y: Z }`
1474
+ fn recover_incorrect_vis_restriction ( & mut self ) -> PResult < ' a , ( ) > {
1475
+ self . bump ( ) ; // `(`
1476
+ let path = self . parse_path ( PathStyle :: Mod ) ?;
1477
+ self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?; // `)`
1478
+
1479
+ let msg = "incorrect visibility restriction" ;
1480
+ let suggestion = r##"some possible visibility restrictions are:
1481
+ `pub(crate)`: visible only on the current crate
1482
+ `pub(super)`: visible only in the current module's parent
1483
+ `pub(in path::to::module)`: visible only on the specified path"## ;
1484
+
1485
+ struct_span_err ! ( self . sess. span_diagnostic, path. span, E0704 , "{}" , msg)
1486
+ . help ( suggestion)
1487
+ . span_suggestion (
1488
+ path. span ,
1489
+ & format ! ( "make this visible only to module `{}` with `in`" , path) ,
1490
+ format ! ( "in {}" , path) ,
1491
+ Applicability :: MachineApplicable ,
1492
+ )
1493
+ . emit ( ) ;
1494
+
1495
+ Ok ( ( ) )
1496
+ }
1497
+
1482
1498
/// Parses a string as an ABI spec on an extern type or module. Consumes
1483
1499
/// the `extern` keyword, if one is found.
1484
1500
fn parse_opt_abi ( & mut self ) -> PResult < ' a , Option < Abi > > {
0 commit comments