@@ -88,6 +88,7 @@ pub enum restriction {
8888 RESTRICT_STMT_EXPR ,
8989 RESTRICT_NO_BAR_OP ,
9090 RESTRICT_NO_BAR_OR_DOUBLEBAR_OP ,
91+ RESTRICT_NO_STRUCT_LITERAL ,
9192}
9293
9394type ItemInfo = ( Ident , Item_ , Option < Vec < Attribute > > ) ;
@@ -2024,8 +2025,9 @@ impl<'a> Parser<'a> {
20242025
20252026 return self . mk_mac_expr ( lo, hi, MacInvocTT ( pth, tts, EMPTY_CTXT ) ) ;
20262027 } else if self . token == token:: LBRACE {
2027- // This might be a struct literal.
2028- if self . looking_at_struct_literal ( ) {
2028+ // This is a struct literal, unless we're prohibited from
2029+ // parsing struct literals here.
2030+ if self . restriction != RESTRICT_NO_STRUCT_LITERAL {
20292031 // It's a struct literal.
20302032 self . bump ( ) ;
20312033 let mut fields = Vec :: new ( ) ;
@@ -2042,6 +2044,14 @@ impl<'a> Parser<'a> {
20422044 & [ token:: COMMA ] , & [ token:: RBRACE ] ) ;
20432045 }
20442046
2047+ if fields. len ( ) == 0 && base. is_none ( ) {
2048+ let last_span = self . last_span ;
2049+ self . span_err ( last_span,
2050+ "structure literal must either have at \
2051+ least one field or use functional \
2052+ structure update syntax") ;
2053+ }
2054+
20452055 hi = self . span . hi ;
20462056 self . expect ( & token:: RBRACE ) ;
20472057 ex = ExprStruct ( pth, fields, base) ;
@@ -2548,7 +2558,7 @@ impl<'a> Parser<'a> {
25482558 // parse an 'if' expression ('if' token already eaten)
25492559 pub fn parse_if_expr ( & mut self ) -> Gc < Expr > {
25502560 let lo = self . last_span . lo ;
2551- let cond = self . parse_expr ( ) ;
2561+ let cond = self . parse_expr_res ( RESTRICT_NO_STRUCT_LITERAL ) ;
25522562 let thn = self . parse_block ( ) ;
25532563 let mut els: Option < Gc < Expr > > = None ;
25542564 let mut hi = thn. span . hi ;
@@ -2633,7 +2643,7 @@ impl<'a> Parser<'a> {
26332643 let lo = self . last_span . lo ;
26342644 let pat = self . parse_pat ( ) ;
26352645 self . expect_keyword ( keywords:: In ) ;
2636- let expr = self . parse_expr ( ) ;
2646+ let expr = self . parse_expr_res ( RESTRICT_NO_STRUCT_LITERAL ) ;
26372647 let loop_block = self . parse_block ( ) ;
26382648 let hi = self . span . hi ;
26392649
@@ -2642,7 +2652,7 @@ impl<'a> Parser<'a> {
26422652
26432653 pub fn parse_while_expr ( & mut self ) -> Gc < Expr > {
26442654 let lo = self . last_span . lo ;
2645- let cond = self . parse_expr ( ) ;
2655+ let cond = self . parse_expr_res ( RESTRICT_NO_STRUCT_LITERAL ) ;
26462656 let body = self . parse_block ( ) ;
26472657 let hi = body. span . hi ;
26482658 return self . mk_expr ( lo, hi, ExprWhile ( cond, body) ) ;
@@ -2655,17 +2665,9 @@ impl<'a> Parser<'a> {
26552665 self . mk_expr ( lo, hi, ExprLoop ( body, opt_ident) )
26562666 }
26572667
2658- // For distinguishing between struct literals and blocks
2659- fn looking_at_struct_literal ( & mut self ) -> bool {
2660- self . token == token:: LBRACE &&
2661- ( ( self . look_ahead ( 1 , |t| token:: is_plain_ident ( t) ) &&
2662- self . look_ahead ( 2 , |t| * t == token:: COLON ) )
2663- || self . look_ahead ( 1 , |t| * t == token:: DOTDOT ) )
2664- }
2665-
26662668 fn parse_match_expr ( & mut self ) -> Gc < Expr > {
26672669 let lo = self . last_span . lo ;
2668- let discriminant = self . parse_expr ( ) ;
2670+ let discriminant = self . parse_expr_res ( RESTRICT_NO_STRUCT_LITERAL ) ;
26692671 self . commit_expr_expecting ( discriminant, token:: LBRACE ) ;
26702672 let mut arms: Vec < Arm > = Vec :: new ( ) ;
26712673 while self . token != token:: RBRACE {
0 commit comments