@@ -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 : false } ;
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 (
@@ -1698,25 +1706,82 @@ impl<'a> Parser<'a> {
16981706/// The parsing configuration used to parse a parameter list (see `parse_fn_params`).
16991707///
17001708/// The function decides if, per-parameter `p`, `p` must have a pattern or just a type.
1709+ ///
1710+ /// This function pointer accepts an edition, because in edition 2015, trait declarations
1711+ /// were allowed to omit parameter names. In 2018, they became required.
17011712type ReqName = fn ( Edition ) -> bool ;
17021713
1714+ /// Parsing configuration for functions.
1715+ ///
1716+ /// The syntax of function items is slightly different within trait definitions,
1717+ /// impl blocks, and modules. It is still parsed using the same code, just with
1718+ /// different flags set, so that even when the input is wrong and produces a parse
1719+ /// error, it still gets into the AST and the rest of the parser and
1720+ /// type checker can run.
1721+ #[ derive( Clone , Copy ) ]
1722+ pub ( crate ) struct FnParseMode {
1723+ /// A function pointer that decides if, per-parameter `p`, `p` must have a
1724+ /// pattern or just a type. This field affects parsing of the parameters list.
1725+ ///
1726+ /// ```text
1727+ /// fn foo(alef: A) -> X { X::new() }
1728+ /// -----^^ affects parsing this part of the function signature
1729+ /// |
1730+ /// if req_name returns false, then this name is optional
1731+ ///
1732+ /// fn bar(A) -> X;
1733+ /// ^
1734+ /// |
1735+ /// if req_name returns true, this is an error
1736+ /// ```
1737+ ///
1738+ /// Calling this function pointer should only return false if:
1739+ ///
1740+ /// * The item is being parsed inside of a trait definition.
1741+ /// Within an impl block or a module, it should always evaluate
1742+ /// to true.
1743+ /// * The span is from Edition 2015. In particular, you can get a
1744+ /// 2015 span inside a 2021 crate using macros.
1745+ pub req_name : ReqName ,
1746+ /// If this flag is set to `true`, then plain, semicolon-terminated function
1747+ /// prototypes are not allowed here.
1748+ ///
1749+ /// ```text
1750+ /// fn foo(alef: A) -> X { X::new() }
1751+ /// ^^^^^^^^^^^^
1752+ /// |
1753+ /// this is always allowed
1754+ ///
1755+ /// fn bar(alef: A, bet: B) -> X;
1756+ /// ^
1757+ /// |
1758+ /// if req_body is set to true, this is an error
1759+ /// ```
1760+ ///
1761+ /// This field should only be set to false if the item is inside of a trait
1762+ /// definition or extern block. Within an impl block or a module, it should
1763+ /// always be set to true.
1764+ pub req_body : bool ,
1765+ }
1766+
17031767/// Parsing of functions and methods.
17041768impl < ' a > Parser < ' a > {
17051769 /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
17061770 fn parse_fn (
17071771 & mut self ,
17081772 attrs : & mut Vec < Attribute > ,
1709- req_name : ReqName ,
1773+ fn_parse_mode : FnParseMode ,
17101774 sig_lo : Span ,
17111775 ) -> PResult < ' a , ( Ident , FnSig , Generics , Option < P < Block > > ) > {
17121776 let header = self . parse_fn_front_matter ( ) ?; // `const ... fn`
17131777 let ident = self . parse_ident ( ) ?; // `foo`
17141778 let mut generics = self . parse_generics ( ) ?; // `<'a, T, ...>`
1715- let decl = self . parse_fn_decl ( req_name, AllowPlus :: Yes , RecoverReturnSign :: Yes ) ?; // `(p: u8, ...)`
1779+ let decl =
1780+ self . parse_fn_decl ( fn_parse_mode. req_name , AllowPlus :: Yes , RecoverReturnSign :: Yes ) ?; // `(p: u8, ...)`
17161781 generics. where_clause = self . parse_where_clause ( ) ?; // `where T: Ord`
17171782
17181783 let mut sig_hi = self . prev_token . span ;
1719- let body = self . parse_fn_body ( attrs, & ident, & mut sig_hi) ?; // `;` or `{ ... }`.
1784+ let body = self . parse_fn_body ( attrs, & ident, & mut sig_hi, fn_parse_mode . req_body ) ?; // `;` or `{ ... }`.
17201785 let fn_sig_span = sig_lo. to ( sig_hi) ;
17211786 Ok ( ( ident, FnSig { header, decl, span : fn_sig_span } , generics, body) )
17221787 }
@@ -1729,9 +1794,17 @@ impl<'a> Parser<'a> {
17291794 attrs : & mut Vec < Attribute > ,
17301795 ident : & Ident ,
17311796 sig_hi : & mut Span ,
1797+ req_body : bool ,
17321798 ) -> PResult < ' a , Option < P < Block > > > {
1733- let ( inner_attrs, body) = if self . eat ( & token:: Semi ) {
1799+ let has_semi = if req_body {
1800+ self . token . kind == TokenKind :: Semi
1801+ } else {
1802+ // Only include `;` in list of expected tokens if body is not required
1803+ self . check ( & TokenKind :: Semi )
1804+ } ;
1805+ let ( inner_attrs, body) = if has_semi {
17341806 // Include the trailing semicolon in the span of the signature
1807+ self . expect_semi ( ) ?;
17351808 * sig_hi = self . prev_token . span ;
17361809 ( Vec :: new ( ) , None )
17371810 } else if self . check ( & token:: OpenDelim ( token:: Brace ) ) || self . token . is_whole_block ( ) {
@@ -1752,9 +1825,12 @@ impl<'a> Parser<'a> {
17521825 . emit ( ) ;
17531826 ( Vec :: new ( ) , Some ( self . mk_block_err ( span) ) )
17541827 } else {
1755- if let Err ( mut err) =
1756- self . expected_one_of_not_found ( & [ ] , & [ token:: Semi , token:: OpenDelim ( token:: Brace ) ] )
1757- {
1828+ let expected = if req_body {
1829+ & [ token:: OpenDelim ( token:: Brace ) ] [ ..]
1830+ } else {
1831+ & [ token:: Semi , token:: OpenDelim ( token:: Brace ) ]
1832+ } ;
1833+ if let Err ( mut err) = self . expected_one_of_not_found ( & [ ] , & expected) {
17581834 if self . token . kind == token:: CloseDelim ( token:: Brace ) {
17591835 // The enclosing `mod`, `trait` or `impl` is being closed, so keep the `fn` in
17601836 // the AST for typechecking.
0 commit comments