@@ -823,24 +823,18 @@ impl<'a> Parser<'a> {
823
823
let attrs = ThinVec :: new ( ) ;
824
824
825
825
let lo = self . token . span ;
826
- let mut hi = self . token . span ;
827
-
828
- let ex: ExprKind ;
829
826
830
827
macro_rules! parse_lit {
831
828
( ) => {
832
829
match self . parse_opt_lit( ) {
833
- Some ( literal) => {
834
- hi = self . prev_span;
835
- ex = ExprKind :: Lit ( literal) ;
836
- }
830
+ Some ( literal) => ( self . prev_span, ExprKind :: Lit ( literal) ) ,
837
831
None => return Err ( self . expected_expression_found( ) ) ,
838
832
}
839
833
}
840
834
}
841
835
842
836
// Note: when adding new syntax here, don't forget to adjust `TokenKind::can_begin_expr()`.
843
- match self . token . kind {
837
+ let ( hi , ex ) = match self . token . kind {
844
838
// This match arm is a special-case of the `_` match arm below and
845
839
// could be removed without changing functionality, but it's faster
846
840
// to have it here, especially for programs with large constants.
@@ -911,13 +905,7 @@ impl<'a> Parser<'a> {
911
905
} ;
912
906
}
913
907
if self . eat_keyword ( kw:: Return ) {
914
- if self . token . can_begin_expr ( ) {
915
- let e = self . parse_expr ( ) ?;
916
- hi = e. span ;
917
- ex = ExprKind :: Ret ( Some ( e) ) ;
918
- } else {
919
- ex = ExprKind :: Ret ( None ) ;
920
- }
908
+ return self . parse_return_expr ( attrs) ;
921
909
} else if self . eat_keyword ( kw:: Break ) {
922
910
let label = self . eat_label ( ) ;
923
911
let e = if self . token . can_begin_expr ( )
@@ -928,25 +916,13 @@ impl<'a> Parser<'a> {
928
916
} else {
929
917
None
930
918
} ;
931
- ex = ExprKind :: Break ( label, e) ;
932
- hi = self . prev_span ;
919
+ ( self . prev_span , ExprKind :: Break ( label, e) )
933
920
} else if self . eat_keyword ( kw:: Yield ) {
934
- if self . token . can_begin_expr ( ) {
935
- let e = self . parse_expr ( ) ?;
936
- hi = e. span ;
937
- ex = ExprKind :: Yield ( Some ( e) ) ;
938
- } else {
939
- ex = ExprKind :: Yield ( None ) ;
940
- }
941
-
942
- let span = lo. to ( hi) ;
943
- self . sess . gated_spans . gate ( sym:: generators, span) ;
921
+ return self . parse_yield_expr ( attrs) ;
944
922
} else if self . eat_keyword ( kw:: Let ) {
945
923
return self . parse_let_expr ( attrs) ;
946
924
} else if is_span_rust_2018 && self . eat_keyword ( kw:: Await ) {
947
- let ( await_hi, e_kind) = self . parse_incorrect_await_syntax ( lo, self . prev_span ) ?;
948
- hi = await_hi;
949
- ex = e_kind;
925
+ self . parse_incorrect_await_syntax ( lo, self . prev_span ) ?
950
926
} else if !self . unclosed_delims . is_empty ( ) && self . check ( & token:: Semi ) {
951
927
// Don't complain about bare semicolons after unclosed braces
952
928
// recovery in order to keep the error count down. Fixing the
@@ -964,7 +940,7 @@ impl<'a> Parser<'a> {
964
940
parse_lit ! ( )
965
941
}
966
942
}
967
- }
943
+ } ;
968
944
969
945
let expr = self . mk_expr ( lo. to ( hi) , ex, attrs) ;
970
946
self . maybe_recover_from_bad_qpath ( expr, true )
@@ -1116,6 +1092,33 @@ impl<'a> Parser<'a> {
1116
1092
self . parse_try_block ( lo, attrs)
1117
1093
}
1118
1094
1095
+ /// Parse an expression if the token can begin one.
1096
+ fn parse_expr_opt ( & mut self ) -> PResult < ' a , Option < P < Expr > > > {
1097
+ Ok ( if self . token . can_begin_expr ( ) {
1098
+ Some ( self . parse_expr ( ) ?)
1099
+ } else {
1100
+ None
1101
+ } )
1102
+ }
1103
+
1104
+ /// Parse `"return" expr?`.
1105
+ fn parse_return_expr ( & mut self , attrs : ThinVec < Attribute > ) -> PResult < ' a , P < Expr > > {
1106
+ let lo = self . prev_span ;
1107
+ let kind = ExprKind :: Ret ( self . parse_expr_opt ( ) ?) ;
1108
+ let expr = self . mk_expr ( lo. to ( self . prev_span ) , kind, attrs) ;
1109
+ self . maybe_recover_from_bad_qpath ( expr, true )
1110
+ }
1111
+
1112
+ /// Parse `"yield" expr?`.
1113
+ fn parse_yield_expr ( & mut self , attrs : ThinVec < Attribute > ) -> PResult < ' a , P < Expr > > {
1114
+ let lo = self . prev_span ;
1115
+ let kind = ExprKind :: Yield ( self . parse_expr_opt ( ) ?) ;
1116
+ let span = lo. to ( self . prev_span ) ;
1117
+ self . sess . gated_spans . gate ( sym:: generators, span) ;
1118
+ let expr = self . mk_expr ( span, kind, attrs) ;
1119
+ self . maybe_recover_from_bad_qpath ( expr, true )
1120
+ }
1121
+
1119
1122
/// Returns a string literal if the next token is a string literal.
1120
1123
/// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
1121
1124
/// and returns `None` if the next token is not literal at all.
0 commit comments