@@ -204,6 +204,7 @@ impl<'a> Parser<'a> {
204204 def : & mut Defaultness ,
205205 req_name : ReqName ,
206206 ) -> PResult < ' a , Option < ItemInfo > > {
207+ let def_final = def == & Defaultness :: Final ;
207208 let mut def = || mem:: replace ( def, Defaultness :: Final ) ;
208209
209210 let info = if self . eat_keyword ( kw:: Use ) {
@@ -226,7 +227,7 @@ impl<'a> Parser<'a> {
226227 }
227228
228229 ( Ident :: invalid ( ) , ItemKind :: Use ( tree) )
229- } else if self . check_fn_front_matter ( ) {
230+ } else if self . check_fn_front_matter ( def_final ) {
230231 // FUNCTION ITEM
231232 let ( ident, sig, generics, body) = self . parse_fn ( attrs, req_name, lo) ?;
232233 ( ident, ItemKind :: Fn ( box FnKind ( def ( ) , sig, generics, body) ) )
@@ -1636,19 +1637,27 @@ impl<'a> Parser<'a> {
16361637 }
16371638
16381639 /// 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 {
16401644 // We use an over-approximation here.
16411645 // `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+ } ;
16441653 self . check_keyword ( kw:: Fn ) // Definitely an `fn`.
16451654 // `$qual fn` or `$qual $qual`:
1646- || QUALS . iter ( ) . any ( |& kw| self . check_keyword ( kw) )
1655+ || quals . iter ( ) . any ( |& kw| self . check_keyword ( kw) )
16471656 && self . look_ahead ( 1 , |t| {
16481657 // `$qual fn`, e.g. `const fn` or `async fn`.
16491658 t. is_keyword ( kw:: Fn )
16501659 // 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 )
16521661 // Rule out 2015 `const async: T = val`.
16531662 && i. is_reserved ( )
16541663 // Rule out unsafe extern block.
0 commit comments