@@ -91,7 +91,11 @@ impl Printer {
91
91
self . outer_attrs ( & item. attrs ) ;
92
92
self . cbox ( INDENT ) ;
93
93
self . visibility ( & item. vis ) ;
94
- self . signature ( & item. sig ) ;
94
+ self . signature (
95
+ & item. sig ,
96
+ #[ cfg( feature = "verbatim" ) ]
97
+ & verbatim:: Safety :: Disallowed ,
98
+ ) ;
95
99
self . where_clause_for_body ( & item. sig . generics . where_clause ) ;
96
100
self . word ( "{" ) ;
97
101
self . hardbreak_if_nonempty ( ) ;
@@ -794,7 +798,11 @@ impl Printer {
794
798
self . outer_attrs ( & foreign_item. attrs ) ;
795
799
self . cbox ( INDENT ) ;
796
800
self . visibility ( & foreign_item. vis ) ;
797
- self . signature ( & foreign_item. sig ) ;
801
+ self . signature (
802
+ & foreign_item. sig ,
803
+ #[ cfg( feature = "verbatim" ) ]
804
+ & verbatim:: Safety :: Disallowed ,
805
+ ) ;
798
806
self . where_clause_semi ( & foreign_item. sig . generics . where_clause ) ;
799
807
self . end ( ) ;
800
808
self . hardbreak ( ) ;
@@ -844,8 +852,10 @@ impl Printer {
844
852
#[ cfg( feature = "verbatim" ) ]
845
853
fn foreign_item_verbatim ( & mut self , tokens : & TokenStream ) {
846
854
use syn:: parse:: { Parse , ParseStream , Result } ;
847
- use syn:: { Attribute , Token , Visibility } ;
848
- use verbatim:: { FlexibleItemFn , FlexibleItemStatic , FlexibleItemType , WhereClauseLocation } ;
855
+ use syn:: { Abi , Attribute , Token , Visibility } ;
856
+ use verbatim:: {
857
+ kw, FlexibleItemFn , FlexibleItemStatic , FlexibleItemType , WhereClauseLocation ,
858
+ } ;
849
859
850
860
enum ForeignItemVerbatim {
851
861
Empty ,
@@ -855,6 +865,16 @@ impl Printer {
855
865
TypeFlexible ( FlexibleItemType ) ,
856
866
}
857
867
868
+ fn peek_signature ( input : ParseStream ) -> bool {
869
+ let fork = input. fork ( ) ;
870
+ fork. parse :: < Option < Token ! [ const ] > > ( ) . is_ok ( )
871
+ && fork. parse :: < Option < Token ! [ async ] > > ( ) . is_ok ( )
872
+ && ( ( fork. peek ( kw:: safe) && fork. parse :: < kw:: safe > ( ) . is_ok ( ) )
873
+ || fork. parse :: < Option < Token ! [ unsafe ] > > ( ) . is_ok ( ) )
874
+ && fork. parse :: < Option < Abi > > ( ) . is_ok ( )
875
+ && fork. peek ( Token ! [ fn ] )
876
+ }
877
+
858
878
impl Parse for ForeignItemVerbatim {
859
879
fn parse ( input : ParseStream ) -> Result < Self > {
860
880
if input. is_empty ( ) {
@@ -869,15 +889,13 @@ impl Printer {
869
889
let defaultness = false ;
870
890
871
891
let lookahead = input. lookahead1 ( ) ;
872
- if lookahead. peek ( Token ! [ const ] )
873
- || lookahead. peek ( Token ! [ async ] )
874
- || lookahead. peek ( Token ! [ unsafe ] )
875
- || lookahead. peek ( Token ! [ extern] )
876
- || lookahead. peek ( Token ! [ fn ] )
877
- {
892
+ if lookahead. peek ( Token ! [ fn ] ) || peek_signature ( input) {
878
893
let flexible_item = FlexibleItemFn :: parse ( attrs, vis, defaultness, input) ?;
879
894
Ok ( ForeignItemVerbatim :: FnFlexible ( flexible_item) )
880
- } else if lookahead. peek ( Token ! [ static ] ) {
895
+ } else if lookahead. peek ( Token ! [ static ] )
896
+ || ( ( input. peek ( Token ! [ unsafe ] ) || input. peek ( kw:: safe) )
897
+ && input. peek2 ( Token ! [ static ] ) )
898
+ {
881
899
let flexible_item = FlexibleItemStatic :: parse ( attrs, vis, input) ?;
882
900
Ok ( ForeignItemVerbatim :: StaticFlexible ( flexible_item) )
883
901
} else if lookahead. peek ( Token ! [ type ] ) {
@@ -953,7 +971,11 @@ impl Printer {
953
971
fn trait_item_fn ( & mut self , trait_item : & TraitItemFn ) {
954
972
self . outer_attrs ( & trait_item. attrs ) ;
955
973
self . cbox ( INDENT ) ;
956
- self . signature ( & trait_item. sig ) ;
974
+ self . signature (
975
+ & trait_item. sig ,
976
+ #[ cfg( feature = "verbatim" ) ]
977
+ & verbatim:: Safety :: Disallowed ,
978
+ ) ;
957
979
if let Some ( block) = & trait_item. default {
958
980
self . where_clause_for_body ( & trait_item. sig . generics . where_clause ) ;
959
981
self . word ( "{" ) ;
@@ -1149,7 +1171,11 @@ impl Printer {
1149
1171
if impl_item. defaultness . is_some ( ) {
1150
1172
self . word ( "default " ) ;
1151
1173
}
1152
- self . signature ( & impl_item. sig ) ;
1174
+ self . signature (
1175
+ & impl_item. sig ,
1176
+ #[ cfg( feature = "verbatim" ) ]
1177
+ & verbatim:: Safety :: Disallowed ,
1178
+ ) ;
1153
1179
self . where_clause_for_body ( & impl_item. sig . generics . where_clause ) ;
1154
1180
self . word ( "{" ) ;
1155
1181
self . hardbreak_if_nonempty ( ) ;
@@ -1277,15 +1303,32 @@ impl Printer {
1277
1303
}
1278
1304
}
1279
1305
1280
- fn signature ( & mut self , signature : & Signature ) {
1306
+ fn signature (
1307
+ & mut self ,
1308
+ signature : & Signature ,
1309
+ #[ cfg( feature = "verbatim" ) ] safety : & verbatim:: Safety ,
1310
+ ) {
1281
1311
if signature. constness . is_some ( ) {
1282
1312
self . word ( "const " ) ;
1283
1313
}
1284
1314
if signature. asyncness . is_some ( ) {
1285
1315
self . word ( "async " ) ;
1286
1316
}
1287
- if signature. unsafety . is_some ( ) {
1288
- self . word ( "unsafe " ) ;
1317
+ #[ cfg( feature = "verbatim" ) ]
1318
+ {
1319
+ if let verbatim:: Safety :: Disallowed = safety {
1320
+ if signature. unsafety . is_some ( ) {
1321
+ self . word ( "unsafe " ) ;
1322
+ }
1323
+ } else {
1324
+ self . safety ( safety) ;
1325
+ }
1326
+ }
1327
+ #[ cfg( not( feature = "verbatim" ) ) ]
1328
+ {
1329
+ if signature. unsafety . is_some ( ) {
1330
+ self . word ( "unsafe " ) ;
1331
+ }
1289
1332
}
1290
1333
if let Some ( abi) = & signature. abi {
1291
1334
self . abi ( abi) ;
@@ -1381,12 +1424,16 @@ mod verbatim {
1381
1424
use crate :: iter:: IterDelimited ;
1382
1425
use crate :: INDENT ;
1383
1426
use syn:: ext:: IdentExt ;
1384
- use syn:: parse:: { ParseStream , Result } ;
1427
+ use syn:: parse:: { Parse , ParseStream , Result } ;
1385
1428
use syn:: {
1386
1429
braced, token, Attribute , Block , Expr , Generics , Ident , Signature , StaticMutability , Stmt ,
1387
1430
Token , Type , TypeParamBound , Visibility , WhereClause ,
1388
1431
} ;
1389
1432
1433
+ pub mod kw {
1434
+ syn:: custom_keyword!( safe) ;
1435
+ }
1436
+
1390
1437
pub struct FlexibleItemConst {
1391
1438
pub attrs : Vec < Attribute > ,
1392
1439
pub vis : Visibility ,
@@ -1401,13 +1448,15 @@ mod verbatim {
1401
1448
pub attrs : Vec < Attribute > ,
1402
1449
pub vis : Visibility ,
1403
1450
pub defaultness : bool ,
1451
+ pub safety : Safety ,
1404
1452
pub sig : Signature ,
1405
1453
pub body : Option < Vec < Stmt > > ,
1406
1454
}
1407
1455
1408
1456
pub struct FlexibleItemStatic {
1409
1457
pub attrs : Vec < Attribute > ,
1410
1458
pub vis : Visibility ,
1459
+ pub safety : Safety ,
1411
1460
pub mutability : StaticMutability ,
1412
1461
pub ident : Ident ,
1413
1462
pub ty : Option < Type > ,
@@ -1425,6 +1474,13 @@ mod verbatim {
1425
1474
pub where_clause_after_eq : Option < WhereClause > ,
1426
1475
}
1427
1476
1477
+ pub enum Safety {
1478
+ Unsafe ,
1479
+ Safe ,
1480
+ Default ,
1481
+ Disallowed ,
1482
+ }
1483
+
1428
1484
pub enum WhereClauseLocation {
1429
1485
// type Ty<T> where T: 'static = T;
1430
1486
BeforeEq ,
@@ -1474,7 +1530,16 @@ mod verbatim {
1474
1530
defaultness : bool ,
1475
1531
input : ParseStream ,
1476
1532
) -> Result < Self > {
1477
- let sig: Signature = input. parse ( ) ?;
1533
+ let constness: Option < Token ! [ const ] > = input. parse ( ) ?;
1534
+ let asyncness: Option < Token ! [ async ] > = input. parse ( ) ?;
1535
+ let safety: Safety = input. parse ( ) ?;
1536
+
1537
+ let lookahead = input. lookahead1 ( ) ;
1538
+ let sig: Signature = if lookahead. peek ( Token ! [ extern] ) || lookahead. peek ( Token ! [ fn ] ) {
1539
+ input. parse ( ) ?
1540
+ } else {
1541
+ return Err ( lookahead. error ( ) ) ;
1542
+ } ;
1478
1543
1479
1544
let lookahead = input. lookahead1 ( ) ;
1480
1545
let body = if lookahead. peek ( Token ! [ ; ] ) {
@@ -1493,14 +1558,21 @@ mod verbatim {
1493
1558
attrs,
1494
1559
vis,
1495
1560
defaultness,
1496
- sig,
1561
+ safety,
1562
+ sig : Signature {
1563
+ constness,
1564
+ asyncness,
1565
+ unsafety : None ,
1566
+ ..sig
1567
+ } ,
1497
1568
body,
1498
1569
} )
1499
1570
}
1500
1571
}
1501
1572
1502
1573
impl FlexibleItemStatic {
1503
1574
pub fn parse ( attrs : Vec < Attribute > , vis : Visibility , input : ParseStream ) -> Result < Self > {
1575
+ let safety: Safety = input. parse ( ) ?;
1504
1576
input. parse :: < Token ! [ static ] > ( ) ?;
1505
1577
let mutability: StaticMutability = input. parse ( ) ?;
1506
1578
let ident = input. parse ( ) ?;
@@ -1530,6 +1602,7 @@ mod verbatim {
1530
1602
Ok ( FlexibleItemStatic {
1531
1603
attrs,
1532
1604
vis,
1605
+ safety,
1533
1606
mutability,
1534
1607
ident,
1535
1608
ty,
@@ -1601,6 +1674,20 @@ mod verbatim {
1601
1674
}
1602
1675
}
1603
1676
1677
+ impl Parse for Safety {
1678
+ fn parse ( input : ParseStream ) -> Result < Self > {
1679
+ if input. peek ( Token ! [ unsafe ] ) {
1680
+ input. parse :: < Token ! [ unsafe ] > ( ) ?;
1681
+ Ok ( Safety :: Unsafe )
1682
+ } else if input. peek ( kw:: safe) {
1683
+ input. parse :: < kw:: safe > ( ) ?;
1684
+ Ok ( Safety :: Safe )
1685
+ } else {
1686
+ Ok ( Safety :: Default )
1687
+ }
1688
+ }
1689
+ }
1690
+
1604
1691
impl Printer {
1605
1692
pub fn flexible_item_const ( & mut self , item : & FlexibleItemConst ) {
1606
1693
self . outer_attrs ( & item. attrs ) ;
@@ -1635,7 +1722,7 @@ mod verbatim {
1635
1722
if item. defaultness {
1636
1723
self . word ( "default " ) ;
1637
1724
}
1638
- self . signature ( & item. sig ) ;
1725
+ self . signature ( & item. sig , & item . safety ) ;
1639
1726
if let Some ( body) = & item. body {
1640
1727
self . where_clause_for_body ( & item. sig . generics . where_clause ) ;
1641
1728
self . word ( "{" ) ;
@@ -1658,6 +1745,7 @@ mod verbatim {
1658
1745
self . outer_attrs ( & item. attrs ) ;
1659
1746
self . cbox ( 0 ) ;
1660
1747
self . visibility ( & item. vis ) ;
1748
+ self . safety ( & item. safety ) ;
1661
1749
self . word ( "static " ) ;
1662
1750
self . static_mutability ( & item. mutability ) ;
1663
1751
self . ident ( & item. ident ) ;
@@ -1708,5 +1796,14 @@ mod verbatim {
1708
1796
self . end ( ) ;
1709
1797
self . hardbreak ( ) ;
1710
1798
}
1799
+
1800
+ pub fn safety ( & mut self , safety : & Safety ) {
1801
+ match safety {
1802
+ Safety :: Unsafe => self . word ( "unsafe " ) ,
1803
+ Safety :: Safe => self . word ( "safe " ) ,
1804
+ Safety :: Default => { }
1805
+ Safety :: Disallowed => unreachable ! ( ) ,
1806
+ }
1807
+ }
1711
1808
}
1712
1809
}
0 commit comments