@@ -792,7 +792,7 @@ impl<'a> Parser<'a> {
792
792
793
793
let span = cast_expr. span ;
794
794
795
- let with_postfix = self . parse_expr_dot_or_call_with_ ( cast_expr, span) ?;
795
+ let with_postfix = self . parse_expr_dot_or_call_with ( AttrVec :: new ( ) , cast_expr, span) ?;
796
796
797
797
// Check if an illegal postfix operator has been added after the cast.
798
798
// If the resulting expression is not a cast, it is an illegal postfix operator.
@@ -883,16 +883,56 @@ impl<'a> Parser<'a> {
883
883
pub ( super ) fn parse_expr_dot_or_call_with (
884
884
& mut self ,
885
885
mut attrs : ast:: AttrVec ,
886
- e0 : P < Expr > ,
886
+ mut e : P < Expr > ,
887
887
lo : Span ,
888
888
) -> PResult < ' a , P < Expr > > {
889
- // Stitch the list of outer attributes onto the return value.
890
- // A little bit ugly, but the best way given the current code
891
- // structure
892
- let res = ensure_sufficient_stack (
893
- // this expr demonstrates the recursion it guards against
894
- || self . parse_expr_dot_or_call_with_ ( e0, lo) ,
895
- ) ;
889
+ let res = ensure_sufficient_stack ( || {
890
+ loop {
891
+ let has_question =
892
+ if self . prev_token . kind == TokenKind :: Ident ( kw:: Return , IdentIsRaw :: No ) {
893
+ // We are using noexpect here because we don't expect a `?` directly after
894
+ // a `return` which could be suggested otherwise.
895
+ self . eat_noexpect ( & token:: Question )
896
+ } else {
897
+ self . eat ( & token:: Question )
898
+ } ;
899
+ if has_question {
900
+ // `expr?`
901
+ e = self . mk_expr ( lo. to ( self . prev_token . span ) , ExprKind :: Try ( e) ) ;
902
+ continue ;
903
+ }
904
+ let has_dot =
905
+ if self . prev_token . kind == TokenKind :: Ident ( kw:: Return , IdentIsRaw :: No ) {
906
+ // We are using noexpect here because we don't expect a `.` directly after
907
+ // a `return` which could be suggested otherwise.
908
+ self . eat_noexpect ( & token:: Dot )
909
+ } else if self . token . kind == TokenKind :: RArrow && self . may_recover ( ) {
910
+ // Recovery for `expr->suffix`.
911
+ self . bump ( ) ;
912
+ let span = self . prev_token . span ;
913
+ self . dcx ( ) . emit_err ( errors:: ExprRArrowCall { span } ) ;
914
+ true
915
+ } else {
916
+ self . eat ( & token:: Dot )
917
+ } ;
918
+ if has_dot {
919
+ // expr.f
920
+ e = self . parse_dot_suffix_expr ( lo, e) ?;
921
+ continue ;
922
+ }
923
+ if self . expr_is_complete ( & e) {
924
+ return Ok ( e) ;
925
+ }
926
+ e = match self . token . kind {
927
+ token:: OpenDelim ( Delimiter :: Parenthesis ) => self . parse_expr_fn_call ( lo, e) ,
928
+ token:: OpenDelim ( Delimiter :: Bracket ) => self . parse_expr_index ( lo, e) ?,
929
+ _ => return Ok ( e) ,
930
+ }
931
+ }
932
+ } ) ;
933
+
934
+ // Stitch the list of outer attributes onto the return value. A little
935
+ // bit ugly, but the best way given the current code structure.
896
936
if attrs. is_empty ( ) {
897
937
res
898
938
} else {
@@ -906,50 +946,6 @@ impl<'a> Parser<'a> {
906
946
}
907
947
}
908
948
909
- fn parse_expr_dot_or_call_with_ ( & mut self , mut e : P < Expr > , lo : Span ) -> PResult < ' a , P < Expr > > {
910
- loop {
911
- let has_question =
912
- if self . prev_token . kind == TokenKind :: Ident ( kw:: Return , IdentIsRaw :: No ) {
913
- // we are using noexpect here because we don't expect a `?` directly after a `return`
914
- // which could be suggested otherwise
915
- self . eat_noexpect ( & token:: Question )
916
- } else {
917
- self . eat ( & token:: Question )
918
- } ;
919
- if has_question {
920
- // `expr?`
921
- e = self . mk_expr ( lo. to ( self . prev_token . span ) , ExprKind :: Try ( e) ) ;
922
- continue ;
923
- }
924
- let has_dot = if self . prev_token . kind == TokenKind :: Ident ( kw:: Return , IdentIsRaw :: No ) {
925
- // we are using noexpect here because we don't expect a `.` directly after a `return`
926
- // which could be suggested otherwise
927
- self . eat_noexpect ( & token:: Dot )
928
- } else if self . token . kind == TokenKind :: RArrow && self . may_recover ( ) {
929
- // Recovery for `expr->suffix`.
930
- self . bump ( ) ;
931
- let span = self . prev_token . span ;
932
- self . dcx ( ) . emit_err ( errors:: ExprRArrowCall { span } ) ;
933
- true
934
- } else {
935
- self . eat ( & token:: Dot )
936
- } ;
937
- if has_dot {
938
- // expr.f
939
- e = self . parse_dot_suffix_expr ( lo, e) ?;
940
- continue ;
941
- }
942
- if self . expr_is_complete ( & e) {
943
- return Ok ( e) ;
944
- }
945
- e = match self . token . kind {
946
- token:: OpenDelim ( Delimiter :: Parenthesis ) => self . parse_expr_fn_call ( lo, e) ,
947
- token:: OpenDelim ( Delimiter :: Bracket ) => self . parse_expr_index ( lo, e) ?,
948
- _ => return Ok ( e) ,
949
- }
950
- }
951
- }
952
-
953
949
pub ( super ) fn parse_dot_suffix_expr (
954
950
& mut self ,
955
951
lo : Span ,
0 commit comments