@@ -78,24 +78,25 @@ pub(super) type ItemInfo = (Ident, ItemKind);
7878
7979impl < ' a > Parser < ' a > {
8080 pub fn parse_item ( & mut self , force_collect : ForceCollect ) -> PResult < ' a , Option < P < Item > > > {
81- self . parse_item_ ( |_| true , force_collect) . map ( |i| i. map ( P ) )
81+ let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
82+ self . parse_item_ ( fn_parse_mode, force_collect) . map ( |i| i. map ( P ) )
8283 }
8384
8485 fn parse_item_ (
8586 & mut self ,
86- req_name : ReqName ,
87+ fn_parse_mode : FnParseMode ,
8788 force_collect : ForceCollect ,
8889 ) -> PResult < ' a , Option < Item > > {
8990 let attrs = self . parse_outer_attributes ( ) ?;
90- self . parse_item_common ( attrs, true , false , req_name , force_collect)
91+ self . parse_item_common ( attrs, true , false , fn_parse_mode , force_collect)
9192 }
9293
9394 pub ( super ) fn parse_item_common (
9495 & mut self ,
9596 attrs : AttrWrapper ,
9697 mac_allowed : bool ,
9798 attrs_allowed : bool ,
98- req_name : ReqName ,
99+ fn_parse_mode : FnParseMode ,
99100 force_collect : ForceCollect ,
100101 ) -> PResult < ' a , Option < Item > > {
101102 // Don't use `maybe_whole` so that we have precise control
@@ -113,7 +114,8 @@ impl<'a> Parser<'a> {
113114 let mut unclosed_delims = vec ! [ ] ;
114115 let item =
115116 self . collect_tokens_trailing_token ( attrs, force_collect, |this : & mut Self , attrs| {
116- let item = this. parse_item_common_ ( attrs, mac_allowed, attrs_allowed, req_name) ;
117+ let item =
118+ this. parse_item_common_ ( attrs, mac_allowed, attrs_allowed, fn_parse_mode) ;
117119 unclosed_delims. append ( & mut this. unclosed_delims ) ;
118120 Ok ( ( item?, TrailingToken :: None ) )
119121 } ) ?;
@@ -127,12 +129,13 @@ impl<'a> Parser<'a> {
127129 mut attrs : Vec < Attribute > ,
128130 mac_allowed : bool ,
129131 attrs_allowed : bool ,
130- req_name : ReqName ,
132+ fn_parse_mode : FnParseMode ,
131133 ) -> PResult < ' a , Option < Item > > {
132134 let lo = self . token . span ;
133135 let vis = self . parse_visibility ( FollowedByType :: No ) ?;
134136 let mut def = self . parse_defaultness ( ) ;
135- let kind = self . parse_item_kind ( & mut attrs, mac_allowed, lo, & vis, & mut def, req_name) ?;
137+ let kind =
138+ self . parse_item_kind ( & mut attrs, mac_allowed, lo, & vis, & mut def, fn_parse_mode) ?;
136139 if let Some ( ( ident, kind) ) = kind {
137140 self . error_on_unconsumed_default ( def, & kind) ;
138141 let span = lo. to ( self . prev_token . span ) ;
@@ -192,7 +195,7 @@ impl<'a> Parser<'a> {
192195 lo : Span ,
193196 vis : & Visibility ,
194197 def : & mut Defaultness ,
195- req_name : ReqName ,
198+ fn_parse_mode : FnParseMode ,
196199 ) -> PResult < ' a , Option < ItemInfo > > {
197200 let def_final = def == & Defaultness :: Final ;
198201 let mut def = || mem:: replace ( def, Defaultness :: Final ) ;
@@ -219,7 +222,7 @@ impl<'a> Parser<'a> {
219222 ( Ident :: empty ( ) , ItemKind :: Use ( tree) )
220223 } else if self . check_fn_front_matter ( def_final) {
221224 // FUNCTION ITEM
222- let ( ident, sig, generics, body) = self . parse_fn ( attrs, req_name , lo) ?;
225+ let ( ident, sig, generics, body) = self . parse_fn ( attrs, fn_parse_mode , lo) ?;
223226 ( ident, ItemKind :: Fn ( Box :: new ( Fn { defaultness : def ( ) , sig, generics, body } ) ) )
224227 } else if self . eat_keyword ( kw:: Extern ) {
225228 if self . eat_keyword ( kw:: Crate ) {
@@ -733,23 +736,26 @@ impl<'a> Parser<'a> {
733736 & mut self ,
734737 force_collect : ForceCollect ,
735738 ) -> PResult < ' a , Option < Option < P < AssocItem > > > > {
736- self . parse_assoc_item ( |_| true , force_collect)
739+ let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
740+ self . parse_assoc_item ( fn_parse_mode, force_collect)
737741 }
738742
739743 pub fn parse_trait_item (
740744 & mut self ,
741745 force_collect : ForceCollect ,
742746 ) -> PResult < ' a , Option < Option < P < AssocItem > > > > {
743- self . parse_assoc_item ( |edition| edition >= Edition :: Edition2018 , force_collect)
747+ let fn_parse_mode =
748+ FnParseMode { req_name : |edition| edition >= Edition :: Edition2018 , req_body : false } ;
749+ self . parse_assoc_item ( fn_parse_mode, force_collect)
744750 }
745751
746752 /// Parses associated items.
747753 fn parse_assoc_item (
748754 & mut self ,
749- req_name : ReqName ,
755+ fn_parse_mode : FnParseMode ,
750756 force_collect : ForceCollect ,
751757 ) -> PResult < ' a , Option < Option < P < AssocItem > > > > {
752- Ok ( self . parse_item_ ( req_name , force_collect) ?. map (
758+ Ok ( self . parse_item_ ( fn_parse_mode , force_collect) ?. map (
753759 |Item { attrs, id, span, vis, ident, kind, tokens } | {
754760 let kind = match AssocItemKind :: try_from ( kind) {
755761 Ok ( kind) => kind,
@@ -944,7 +950,8 @@ impl<'a> Parser<'a> {
944950 & mut self ,
945951 force_collect : ForceCollect ,
946952 ) -> PResult < ' a , Option < Option < P < ForeignItem > > > > {
947- Ok ( self . parse_item_ ( |_| true , force_collect) ?. map (
953+ let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
954+ Ok ( self . parse_item_ ( fn_parse_mode, force_collect) ?. map (
948955 |Item { attrs, id, span, vis, ident, kind, tokens } | {
949956 let kind = match ForeignItemKind :: try_from ( kind) {
950957 Ok ( kind) => kind,
@@ -1484,7 +1491,8 @@ impl<'a> Parser<'a> {
14841491 if !is_raw && ident. is_reserved ( ) {
14851492 let err = if self . check_fn_front_matter ( false ) {
14861493 // We use `parse_fn` to get a span for the function
1487- if let Err ( mut db) = self . parse_fn ( & mut Vec :: new ( ) , |_| true , lo) {
1494+ let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
1495+ if let Err ( mut db) = self . parse_fn ( & mut Vec :: new ( ) , fn_parse_mode, lo) {
14881496 db. delay_as_bug ( ) ;
14891497 }
14901498 let mut err = self . struct_span_err (
@@ -1700,23 +1708,33 @@ impl<'a> Parser<'a> {
17001708/// The function decides if, per-parameter `p`, `p` must have a pattern or just a type.
17011709type ReqName = fn ( Edition ) -> bool ;
17021710
1711+ /// Parsing configuration for functions.
1712+ /// This include the edition-specific name requirements, plus information on whether the
1713+ /// function is allowed to go without a body.
1714+ #[ derive( Clone , Copy ) ]
1715+ pub ( crate ) struct FnParseMode {
1716+ pub req_name : ReqName ,
1717+ pub req_body : bool ,
1718+ }
1719+
17031720/// Parsing of functions and methods.
17041721impl < ' a > Parser < ' a > {
17051722 /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
17061723 fn parse_fn (
17071724 & mut self ,
17081725 attrs : & mut Vec < Attribute > ,
1709- req_name : ReqName ,
1726+ fn_parse_mode : FnParseMode ,
17101727 sig_lo : Span ,
17111728 ) -> PResult < ' a , ( Ident , FnSig , Generics , Option < P < Block > > ) > {
17121729 let header = self . parse_fn_front_matter ( ) ?; // `const ... fn`
17131730 let ident = self . parse_ident ( ) ?; // `foo`
17141731 let mut generics = self . parse_generics ( ) ?; // `<'a, T, ...>`
1715- let decl = self . parse_fn_decl ( req_name, AllowPlus :: Yes , RecoverReturnSign :: Yes ) ?; // `(p: u8, ...)`
1732+ let decl =
1733+ self . parse_fn_decl ( fn_parse_mode. req_name , AllowPlus :: Yes , RecoverReturnSign :: Yes ) ?; // `(p: u8, ...)`
17161734 generics. where_clause = self . parse_where_clause ( ) ?; // `where T: Ord`
17171735
17181736 let mut sig_hi = self . prev_token . span ;
1719- let body = self . parse_fn_body ( attrs, & ident, & mut sig_hi) ?; // `;` or `{ ... }`.
1737+ let body = self . parse_fn_body ( attrs, & ident, & mut sig_hi, fn_parse_mode . req_body ) ?; // `;` or `{ ... }`.
17201738 let fn_sig_span = sig_lo. to ( sig_hi) ;
17211739 Ok ( ( ident, FnSig { header, decl, span : fn_sig_span } , generics, body) )
17221740 }
@@ -1729,9 +1747,17 @@ impl<'a> Parser<'a> {
17291747 attrs : & mut Vec < Attribute > ,
17301748 ident : & Ident ,
17311749 sig_hi : & mut Span ,
1750+ req_body : bool ,
17321751 ) -> PResult < ' a , Option < P < Block > > > {
1733- let ( inner_attrs, body) = if self . eat ( & token:: Semi ) {
1752+ let has_semi = if req_body {
1753+ self . token . kind == TokenKind :: Semi
1754+ } else {
1755+ // Only include `;` in list of expected tokens if body is not required
1756+ self . check ( & TokenKind :: Semi )
1757+ } ;
1758+ let ( inner_attrs, body) = if has_semi {
17341759 // Include the trailing semicolon in the span of the signature
1760+ self . expect_semi ( ) ?;
17351761 * sig_hi = self . prev_token . span ;
17361762 ( Vec :: new ( ) , None )
17371763 } else if self . check ( & token:: OpenDelim ( token:: Brace ) ) || self . token . is_whole_block ( ) {
@@ -1752,9 +1778,12 @@ impl<'a> Parser<'a> {
17521778 . emit ( ) ;
17531779 ( Vec :: new ( ) , Some ( self . mk_block_err ( span) ) )
17541780 } else {
1755- if let Err ( mut err) =
1756- self . expected_one_of_not_found ( & [ ] , & [ token:: Semi , token:: OpenDelim ( token:: Brace ) ] )
1757- {
1781+ let expected = if req_body {
1782+ & [ token:: OpenDelim ( token:: Brace ) ] [ ..]
1783+ } else {
1784+ & [ token:: Semi , token:: OpenDelim ( token:: Brace ) ]
1785+ } ;
1786+ if let Err ( mut err) = self . expected_one_of_not_found ( & [ ] , & expected) {
17581787 if self . token . kind == token:: CloseDelim ( token:: Brace ) {
17591788 // The enclosing `mod`, `trait` or `impl` is being closed, so keep the `fn` in
17601789 // the AST for typechecking.
0 commit comments