@@ -792,7 +792,7 @@ impl<'a> Parser<'a> {
792792
793793 let span = cast_expr. span ;
794794
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) ?;
796796
797797 // Check if an illegal postfix operator has been added after the cast.
798798 // If the resulting expression is not a cast, it is an illegal postfix operator.
@@ -883,16 +883,56 @@ impl<'a> Parser<'a> {
883883 pub ( super ) fn parse_expr_dot_or_call_with (
884884 & mut self ,
885885 mut attrs : ast:: AttrVec ,
886- e0 : P < Expr > ,
886+ mut e : P < Expr > ,
887887 lo : Span ,
888888 ) -> 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.
896936 if attrs. is_empty ( ) {
897937 res
898938 } else {
@@ -906,50 +946,6 @@ impl<'a> Parser<'a> {
906946 }
907947 }
908948
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-
953949 pub ( super ) fn parse_dot_suffix_expr (
954950 & mut self ,
955951 lo : Span ,
0 commit comments