@@ -22,8 +22,8 @@ use tracing::debug;
2222use super :: diagnostics:: { ConsumeClosingDelim , dummy_arg} ;
2323use super :: ty:: { AllowPlus , RecoverQPath , RecoverReturnSign } ;
2424use super :: {
25- AttrWrapper , ExpKeywordPair , ExpTokenPair , FollowedByType , ForceCollect , Parser , PathStyle ,
26- Recovered , Trailing , UsePreAttrPos ,
25+ AttrWrapper , ConstBlockItemsAllowed , ExpKeywordPair , ExpTokenPair , FollowedByType ,
26+ ForceCollect , Parser , PathStyle , Recovered , Trailing , UsePreAttrPos ,
2727} ;
2828use crate :: errors:: { self , FnPointerCannotBeAsync , FnPointerCannotBeConst , MacroExpandsToAdtField } ;
2929use crate :: { exp, fluent_generated as fluent} ;
@@ -69,7 +69,7 @@ impl<'a> Parser<'a> {
6969 // `parse_item` consumes the appropriate semicolons so any leftover is an error.
7070 loop {
7171 while self . maybe_consume_incorrect_semicolon ( items. last ( ) . map ( |x| & * * x) ) { } // Eat all bad semicolons
72- let Some ( item) = self . parse_item ( ForceCollect :: No ) ? else {
72+ let Some ( item) = self . parse_item ( ForceCollect :: No , ConstBlockItemsAllowed :: Yes ) ? else {
7373 break ;
7474 } ;
7575 items. push ( item) ;
@@ -118,21 +118,34 @@ impl<'a> Parser<'a> {
118118}
119119
120120impl < ' a > Parser < ' a > {
121- pub fn parse_item ( & mut self , force_collect : ForceCollect ) -> PResult < ' a , Option < Box < Item > > > {
121+ pub fn parse_item (
122+ & mut self ,
123+ force_collect : ForceCollect ,
124+ const_block_items_allowed : ConstBlockItemsAllowed ,
125+ ) -> PResult < ' a , Option < Box < Item > > > {
122126 let fn_parse_mode =
123127 FnParseMode { req_name : |_, _| true , context : FnContext :: Free , req_body : true } ;
124- self . parse_item_ ( fn_parse_mode, force_collect) . map ( |i| i. map ( Box :: new) )
128+ self . parse_item_ ( fn_parse_mode, force_collect, const_block_items_allowed)
129+ . map ( |i| i. map ( Box :: new) )
125130 }
126131
127132 fn parse_item_ (
128133 & mut self ,
129134 fn_parse_mode : FnParseMode ,
130135 force_collect : ForceCollect ,
136+ const_block_items_allowed : ConstBlockItemsAllowed ,
131137 ) -> PResult < ' a , Option < Item > > {
132138 self . recover_vcs_conflict_marker ( ) ;
133139 let attrs = self . parse_outer_attributes ( ) ?;
134140 self . recover_vcs_conflict_marker ( ) ;
135- self . parse_item_common ( attrs, true , false , fn_parse_mode, force_collect)
141+ self . parse_item_common (
142+ attrs,
143+ true ,
144+ false ,
145+ fn_parse_mode,
146+ force_collect,
147+ const_block_items_allowed,
148+ )
136149 }
137150
138151 pub ( super ) fn parse_item_common (
@@ -142,10 +155,11 @@ impl<'a> Parser<'a> {
142155 attrs_allowed : bool ,
143156 fn_parse_mode : FnParseMode ,
144157 force_collect : ForceCollect ,
158+ const_block_items_allowed : ConstBlockItemsAllowed ,
145159 ) -> PResult < ' a , Option < Item > > {
146- if let Some ( item) =
147- self . eat_metavar_seq ( MetaVarKind :: Item , | this| this . parse_item ( ForceCollect :: Yes ) )
148- {
160+ if let Some ( item) = self . eat_metavar_seq ( MetaVarKind :: Item , |this| {
161+ this. parse_item ( ForceCollect :: Yes , const_block_items_allowed )
162+ } ) {
149163 let mut item = item. expect ( "an actual item" ) ;
150164 attrs. prepend_to_nt_inner ( & mut item. attrs ) ;
151165 return Ok ( Some ( * item) ) ;
@@ -158,6 +172,7 @@ impl<'a> Parser<'a> {
158172 let kind = this. parse_item_kind (
159173 & mut attrs,
160174 mac_allowed,
175+ const_block_items_allowed,
161176 lo,
162177 & vis,
163178 & mut def,
@@ -204,6 +219,7 @@ impl<'a> Parser<'a> {
204219 & mut self ,
205220 attrs : & mut AttrVec ,
206221 macros_allowed : bool ,
222+ const_block_items_allowed : ConstBlockItemsAllowed ,
207223 lo : Span ,
208224 vis : & Visibility ,
209225 def : & mut Defaultness ,
@@ -253,6 +269,34 @@ impl<'a> Parser<'a> {
253269 } else if self . check_impl_frontmatter ( ) {
254270 // IMPL ITEM
255271 self . parse_item_impl ( attrs, def_ ( ) ) ?
272+ } else if let ConstBlockItemsAllowed :: Yes = const_block_items_allowed
273+ && self . token . is_keyword ( kw:: Const )
274+ && self . look_ahead ( 1 , |t| * t == token:: OpenBrace || t. is_metavar_block ( ) )
275+ {
276+ // CONST BLOCK ITEM
277+ self . psess . gated_spans . gate ( sym:: const_block_items, self . token . span ) ;
278+ let block = self . parse_const_block ( DUMMY_SP , false ) ?;
279+ ItemKind :: Const ( Box :: new ( ConstItem {
280+ defaultness : Defaultness :: Final ,
281+ ident : Ident { name : kw:: Underscore , span : DUMMY_SP } ,
282+ generics : Generics {
283+ params : thin_vec ! [ ] ,
284+ where_clause : WhereClause {
285+ has_where_token : false ,
286+ predicates : thin_vec ! [ ] ,
287+ span : DUMMY_SP ,
288+ } ,
289+ span : DUMMY_SP ,
290+ } ,
291+ ty : Box :: new ( Ty {
292+ id : DUMMY_NODE_ID ,
293+ kind : TyKind :: Tup ( thin_vec ! [ ] ) ,
294+ span : DUMMY_SP ,
295+ tokens : None ,
296+ } ) ,
297+ rhs : Some ( ConstItemRhs :: Body ( block) ) ,
298+ define_opaque : None ,
299+ } ) )
256300 } else if let Const :: Yes ( const_span) = self . parse_constness ( Case :: Sensitive ) {
257301 // CONST ITEM
258302 self . recover_const_mut ( const_span) ;
@@ -312,6 +356,7 @@ impl<'a> Parser<'a> {
312356 return self . parse_item_kind (
313357 attrs,
314358 macros_allowed,
359+ const_block_items_allowed,
315360 lo,
316361 vis,
317362 def,
@@ -992,7 +1037,7 @@ impl<'a> Parser<'a> {
9921037 fn_parse_mode : FnParseMode ,
9931038 force_collect : ForceCollect ,
9941039 ) -> PResult < ' a , Option < Option < Box < AssocItem > > > > {
995- Ok ( self . parse_item_ ( fn_parse_mode, force_collect) ?. map (
1040+ Ok ( self . parse_item_ ( fn_parse_mode, force_collect, ConstBlockItemsAllowed :: No ) ?. map (
9961041 |Item { attrs, id, span, vis, kind, tokens } | {
9971042 let kind = match AssocItemKind :: try_from ( kind) {
9981043 Ok ( kind) => kind,
@@ -1244,7 +1289,7 @@ impl<'a> Parser<'a> {
12441289 context : FnContext :: Free ,
12451290 req_body : false ,
12461291 } ;
1247- Ok ( self . parse_item_ ( fn_parse_mode, force_collect) ?. map (
1292+ Ok ( self . parse_item_ ( fn_parse_mode, force_collect, ConstBlockItemsAllowed :: No ) ?. map (
12481293 |Item { attrs, id, span, vis, kind, tokens } | {
12491294 let kind = match ForeignItemKind :: try_from ( kind) {
12501295 Ok ( kind) => kind,
@@ -2300,7 +2345,7 @@ impl<'a> Parser<'a> {
23002345 {
23012346 let kw_token = self . token ;
23022347 let kw_str = pprust:: token_to_string ( & kw_token) ;
2303- let item = self . parse_item ( ForceCollect :: No ) ?;
2348+ let item = self . parse_item ( ForceCollect :: No , ConstBlockItemsAllowed :: No ) ?;
23042349 let mut item = item. unwrap ( ) . span ;
23052350 if self . token == token:: Comma {
23062351 item = item. to ( self . token . span ) ;
0 commit comments