@@ -88,6 +88,7 @@ pub enum restriction {
88
88
RESTRICT_STMT_EXPR ,
89
89
RESTRICT_NO_BAR_OP ,
90
90
RESTRICT_NO_BAR_OR_DOUBLEBAR_OP ,
91
+ RESTRICT_NO_STRUCT_LITERAL ,
91
92
}
92
93
93
94
type ItemInfo = ( Ident , Item_ , Option < Vec < Attribute > > ) ;
@@ -2024,8 +2025,9 @@ impl<'a> Parser<'a> {
2024
2025
2025
2026
return self . mk_mac_expr ( lo, hi, MacInvocTT ( pth, tts, EMPTY_CTXT ) ) ;
2026
2027
} 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 {
2029
2031
// It's a struct literal.
2030
2032
self . bump ( ) ;
2031
2033
let mut fields = Vec :: new ( ) ;
@@ -2042,6 +2044,14 @@ impl<'a> Parser<'a> {
2042
2044
& [ token:: COMMA ] , & [ token:: RBRACE ] ) ;
2043
2045
}
2044
2046
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
+
2045
2055
hi = self . span . hi ;
2046
2056
self . expect ( & token:: RBRACE ) ;
2047
2057
ex = ExprStruct ( pth, fields, base) ;
@@ -2548,7 +2558,7 @@ impl<'a> Parser<'a> {
2548
2558
// parse an 'if' expression ('if' token already eaten)
2549
2559
pub fn parse_if_expr ( & mut self ) -> Gc < Expr > {
2550
2560
let lo = self . last_span . lo ;
2551
- let cond = self . parse_expr ( ) ;
2561
+ let cond = self . parse_expr_res ( RESTRICT_NO_STRUCT_LITERAL ) ;
2552
2562
let thn = self . parse_block ( ) ;
2553
2563
let mut els: Option < Gc < Expr > > = None ;
2554
2564
let mut hi = thn. span . hi ;
@@ -2633,7 +2643,7 @@ impl<'a> Parser<'a> {
2633
2643
let lo = self . last_span . lo ;
2634
2644
let pat = self . parse_pat ( ) ;
2635
2645
self . expect_keyword ( keywords:: In ) ;
2636
- let expr = self . parse_expr ( ) ;
2646
+ let expr = self . parse_expr_res ( RESTRICT_NO_STRUCT_LITERAL ) ;
2637
2647
let loop_block = self . parse_block ( ) ;
2638
2648
let hi = self . span . hi ;
2639
2649
@@ -2642,7 +2652,7 @@ impl<'a> Parser<'a> {
2642
2652
2643
2653
pub fn parse_while_expr ( & mut self ) -> Gc < Expr > {
2644
2654
let lo = self . last_span . lo ;
2645
- let cond = self . parse_expr ( ) ;
2655
+ let cond = self . parse_expr_res ( RESTRICT_NO_STRUCT_LITERAL ) ;
2646
2656
let body = self . parse_block ( ) ;
2647
2657
let hi = body. span . hi ;
2648
2658
return self . mk_expr ( lo, hi, ExprWhile ( cond, body) ) ;
@@ -2655,17 +2665,9 @@ impl<'a> Parser<'a> {
2655
2665
self . mk_expr ( lo, hi, ExprLoop ( body, opt_ident) )
2656
2666
}
2657
2667
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
-
2666
2668
fn parse_match_expr ( & mut self ) -> Gc < Expr > {
2667
2669
let lo = self . last_span . lo ;
2668
- let discriminant = self . parse_expr ( ) ;
2670
+ let discriminant = self . parse_expr_res ( RESTRICT_NO_STRUCT_LITERAL ) ;
2669
2671
self . commit_expr_expecting ( discriminant, token:: LBRACE ) ;
2670
2672
let mut arms: Vec < Arm > = Vec :: new ( ) ;
2671
2673
while self . token != token:: RBRACE {
0 commit comments