@@ -204,6 +204,7 @@ impl<'a> Parser<'a> {
204
204
def : & mut Defaultness ,
205
205
req_name : ReqName ,
206
206
) -> PResult < ' a , Option < ItemInfo > > {
207
+ let def_final = def == & Defaultness :: Final ;
207
208
let mut def = || mem:: replace ( def, Defaultness :: Final ) ;
208
209
209
210
let info = if self . eat_keyword ( kw:: Use ) {
@@ -226,7 +227,7 @@ impl<'a> Parser<'a> {
226
227
}
227
228
228
229
( Ident :: invalid ( ) , ItemKind :: Use ( tree) )
229
- } else if self . check_fn_front_matter ( ) {
230
+ } else if self . check_fn_front_matter ( def_final ) {
230
231
// FUNCTION ITEM
231
232
let ( ident, sig, generics, body) = self . parse_fn ( attrs, req_name, lo) ?;
232
233
( ident, ItemKind :: Fn ( box FnKind ( def ( ) , sig, generics, body) ) )
@@ -1636,19 +1637,27 @@ impl<'a> Parser<'a> {
1636
1637
}
1637
1638
1638
1639
/// Is the current token the start of an `FnHeader` / not a valid parse?
1639
- pub ( super ) fn check_fn_front_matter ( & mut self ) -> bool {
1640
+ ///
1641
+ /// `check_pub` adds additional `pub` to the checks in case users place it
1642
+ /// wrongly, can be used to ensure `pub` never comes after `default`.
1643
+ pub ( super ) fn check_fn_front_matter ( & mut self , check_pub : bool ) -> bool {
1640
1644
// We use an over-approximation here.
1641
1645
// `const const`, `fn const` won't parse, but we're not stepping over other syntax either.
1642
- // `pub` is added in case users got confused with the ordering like `async pub fn`.
1643
- const QUALS : [ Symbol ; 5 ] = [ kw:: Pub , kw:: Const , kw:: Async , kw:: Unsafe , kw:: Extern ] ;
1646
+ // `pub` is added in case users got confused with the ordering like `async pub fn`,
1647
+ // only if it wasn't preceeded by `default` as `default pub` is invalid.
1648
+ let quals: & [ Symbol ] = if check_pub {
1649
+ & [ kw:: Pub , kw:: Const , kw:: Async , kw:: Unsafe , kw:: Extern ]
1650
+ } else {
1651
+ & [ kw:: Const , kw:: Async , kw:: Unsafe , kw:: Extern ]
1652
+ } ;
1644
1653
self . check_keyword ( kw:: Fn ) // Definitely an `fn`.
1645
1654
// `$qual fn` or `$qual $qual`:
1646
- || QUALS . iter ( ) . any ( |& kw| self . check_keyword ( kw) )
1655
+ || quals . iter ( ) . any ( |& kw| self . check_keyword ( kw) )
1647
1656
&& self . look_ahead ( 1 , |t| {
1648
1657
// `$qual fn`, e.g. `const fn` or `async fn`.
1649
1658
t. is_keyword ( kw:: Fn )
1650
1659
// Two qualifiers `$qual $qual` is enough, e.g. `async unsafe`.
1651
- || t. is_non_raw_ident_where ( |i| QUALS . contains ( & i. name )
1660
+ || t. is_non_raw_ident_where ( |i| quals . contains ( & i. name )
1652
1661
// Rule out 2015 `const async: T = val`.
1653
1662
&& i. is_reserved ( )
1654
1663
// Rule out unsafe extern block.
0 commit comments