@@ -186,6 +186,7 @@ enum PrevTokenKind {
186186 Interpolated ,
187187 Eof ,
188188 Ident ,
189+ BitOr ,
189190 Other ,
190191}
191192
@@ -1375,6 +1376,7 @@ impl<'a> Parser<'a> {
13751376 token:: DocComment ( ..) => PrevTokenKind :: DocComment ,
13761377 token:: Comma => PrevTokenKind :: Comma ,
13771378 token:: BinOp ( token:: Plus ) => PrevTokenKind :: Plus ,
1379+ token:: BinOp ( token:: Or ) => PrevTokenKind :: BitOr ,
13781380 token:: Interpolated ( ..) => PrevTokenKind :: Interpolated ,
13791381 token:: Eof => PrevTokenKind :: Eof ,
13801382 token:: Ident ( ..) => PrevTokenKind :: Ident ,
@@ -2806,6 +2808,12 @@ impl<'a> Parser<'a> {
28062808 let msg = format ! ( "expected expression, found {}" ,
28072809 self . this_token_descr( ) ) ;
28082810 let mut err = self . fatal ( & msg) ;
2811+ let sp = self . sess . source_map ( ) . start_point ( self . span ) ;
2812+ if let Some ( sp) = self . sess . ambiguous_block_expr_parse . borrow ( )
2813+ . get ( & sp)
2814+ {
2815+ self . sess . expr_parentheses_needed ( & mut err, * sp, None ) ;
2816+ }
28092817 err. span_label ( self . span , "expected expression" ) ;
28102818 return Err ( err) ;
28112819 }
@@ -2845,7 +2853,7 @@ impl<'a> Parser<'a> {
28452853 "struct literals are not allowed here" ,
28462854 ) ;
28472855 err. multipart_suggestion (
2848- "surround the struct literal with parenthesis " ,
2856+ "surround the struct literal with parentheses " ,
28492857 vec ! [
28502858 ( lo. shrink_to_lo( ) , "(" . to_string( ) ) ,
28512859 ( expr. span. shrink_to_hi( ) , ")" . to_string( ) ) ,
@@ -3506,9 +3514,42 @@ impl<'a> Parser<'a> {
35063514 }
35073515 } ;
35083516
3509- if self . expr_is_complete ( & lhs) {
3510- // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
3511- return Ok ( lhs) ;
3517+ match ( self . expr_is_complete ( & lhs) , AssocOp :: from_token ( & self . token ) ) {
3518+ ( true , None ) => {
3519+ // Semi-statement forms are odd. See https://github.com/rust-lang/rust/issues/29071
3520+ return Ok ( lhs) ;
3521+ }
3522+ ( false , _) => { } // continue parsing the expression
3523+ // An exhaustive check is done in the following block, but these are checked first
3524+ // because they *are* ambiguous but also reasonable looking incorrect syntax, so we
3525+ // want to keep their span info to improve diagnostics in these cases in a later stage.
3526+ ( true , Some ( AssocOp :: Multiply ) ) | // `{ 42 } *foo = bar;` or `{ 42 } * 3`
3527+ ( true , Some ( AssocOp :: Subtract ) ) | // `{ 42 } -5`
3528+ ( true , Some ( AssocOp :: Add ) ) => { // `{ 42 } + 42
3529+ // These cases are ambiguous and can't be identified in the parser alone
3530+ let sp = self . sess . source_map ( ) . start_point ( self . span ) ;
3531+ self . sess . ambiguous_block_expr_parse . borrow_mut ( ) . insert ( sp, lhs. span ) ;
3532+ return Ok ( lhs) ;
3533+ }
3534+ ( true , Some ( ref op) ) if !op. can_continue_expr_unambiguously ( ) => {
3535+ return Ok ( lhs) ;
3536+ }
3537+ ( true , Some ( _) ) => {
3538+ // We've found an expression that would be parsed as a statement, but the next
3539+ // token implies this should be parsed as an expression.
3540+ // For example: `if let Some(x) = x { x } else { 0 } / 2`
3541+ let mut err = self . sess . span_diagnostic . struct_span_err ( self . span , & format ! (
3542+ "expected expression, found `{}`" ,
3543+ pprust:: token_to_string( & self . token) ,
3544+ ) ) ;
3545+ err. span_label ( self . span , "expected expression" ) ;
3546+ self . sess . expr_parentheses_needed (
3547+ & mut err,
3548+ lhs. span ,
3549+ Some ( pprust:: expr_to_string ( & lhs) ,
3550+ ) ) ;
3551+ err. emit ( ) ;
3552+ }
35123553 }
35133554 self . expected_tokens . push ( TokenType :: Operator ) ;
35143555 while let Some ( op) = AssocOp :: from_token ( & self . token ) {
@@ -4819,6 +4860,10 @@ impl<'a> Parser<'a> {
48194860 ) ;
48204861 let mut err = self . fatal ( & msg) ;
48214862 err. span_label ( self . span , format ! ( "expected {}" , expected) ) ;
4863+ let sp = self . sess . source_map ( ) . start_point ( self . span ) ;
4864+ if let Some ( sp) = self . sess . ambiguous_block_expr_parse . borrow ( ) . get ( & sp) {
4865+ self . sess . expr_parentheses_needed ( & mut err, * sp, None ) ;
4866+ }
48224867 return Err ( err) ;
48234868 }
48244869 }
0 commit comments