@@ -785,23 +785,14 @@ impl<'a> Parser<'a> {
785785 }
786786 } ;
787787
788- self . parse_and_disallow_postfix_after_cast ( cast_expr)
789- }
790-
791- /// Parses a postfix operators such as `.`, `?`, or index (`[]`) after a cast,
792- /// then emits an error and returns the newly parsed tree.
793- /// The resulting parse tree for `&x as T[0]` has a precedence of `((&x) as T)[0]`.
794- fn parse_and_disallow_postfix_after_cast (
795- & mut self ,
796- cast_expr : P < Expr > ,
797- ) -> PResult < ' a , P < Expr > > {
798- if let ExprKind :: Type ( _, _) = cast_expr. kind {
799- panic ! ( "ExprKind::Type must not be parsed" ) ;
800- }
788+ // Try to parse a postfix operator such as `.`, `?`, or index (`[]`)
789+ // after a cast. If one is present, emit an error then return a valid
790+ // parse tree; For something like `&x as T[0]` will be as if it was
791+ // written `((&x) as T)[0]`.
801792
802793 let span = cast_expr. span ;
803794
804- 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) ?;
805796
806797 // Check if an illegal postfix operator has been added after the cast.
807798 // If the resulting expression is not a cast, it is an illegal postfix operator.
@@ -885,23 +876,63 @@ impl<'a> Parser<'a> {
885876 self . collect_tokens_for_expr ( attrs, |this, attrs| {
886877 let base = this. parse_expr_bottom ( ) ?;
887878 let span = this. interpolated_or_expr_span ( & base) ;
888- this. parse_expr_dot_or_call_with ( base , span , attrs )
879+ this. parse_expr_dot_or_call_with ( attrs , base , span )
889880 } )
890881 }
891882
892883 pub ( super ) fn parse_expr_dot_or_call_with (
893884 & mut self ,
894- e0 : P < Expr > ,
895- lo : Span ,
896885 mut attrs : ast:: AttrVec ,
886+ mut e : P < Expr > ,
887+ lo : Span ,
897888 ) -> PResult < ' a , P < Expr > > {
898- // Stitch the list of outer attributes onto the return value.
899- // A little bit ugly, but the best way given the current code
900- // structure
901- let res = ensure_sufficient_stack (
902- // this expr demonstrates the recursion it guards against
903- || self . parse_expr_dot_or_call_with_ ( e0, lo) ,
904- ) ;
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.
905936 if attrs. is_empty ( ) {
906937 res
907938 } else {
@@ -915,50 +946,6 @@ impl<'a> Parser<'a> {
915946 }
916947 }
917948
918- fn parse_expr_dot_or_call_with_ ( & mut self , mut e : P < Expr > , lo : Span ) -> PResult < ' a , P < Expr > > {
919- loop {
920- let has_question =
921- if self . prev_token . kind == TokenKind :: Ident ( kw:: Return , IdentIsRaw :: No ) {
922- // we are using noexpect here because we don't expect a `?` directly after a `return`
923- // which could be suggested otherwise
924- self . eat_noexpect ( & token:: Question )
925- } else {
926- self . eat ( & token:: Question )
927- } ;
928- if has_question {
929- // `expr?`
930- e = self . mk_expr ( lo. to ( self . prev_token . span ) , ExprKind :: Try ( e) ) ;
931- continue ;
932- }
933- let has_dot = if self . prev_token . kind == TokenKind :: Ident ( kw:: Return , IdentIsRaw :: No ) {
934- // we are using noexpect here because we don't expect a `.` directly after a `return`
935- // which could be suggested otherwise
936- self . eat_noexpect ( & token:: Dot )
937- } else if self . token . kind == TokenKind :: RArrow && self . may_recover ( ) {
938- // Recovery for `expr->suffix`.
939- self . bump ( ) ;
940- let span = self . prev_token . span ;
941- self . dcx ( ) . emit_err ( errors:: ExprRArrowCall { span } ) ;
942- true
943- } else {
944- self . eat ( & token:: Dot )
945- } ;
946- if has_dot {
947- // expr.f
948- e = self . parse_dot_suffix_expr ( lo, e) ?;
949- continue ;
950- }
951- if self . expr_is_complete ( & e) {
952- return Ok ( e) ;
953- }
954- e = match self . token . kind {
955- token:: OpenDelim ( Delimiter :: Parenthesis ) => self . parse_expr_fn_call ( lo, e) ,
956- token:: OpenDelim ( Delimiter :: Bracket ) => self . parse_expr_index ( lo, e) ?,
957- _ => return Ok ( e) ,
958- }
959- }
960- }
961-
962949 pub ( super ) fn parse_dot_suffix_expr (
963950 & mut self ,
964951 lo : Span ,
@@ -1388,7 +1375,7 @@ impl<'a> Parser<'a> {
13881375 /// Parses things like parenthesized exprs, macros, `return`, etc.
13891376 ///
13901377 /// N.B., this does not parse outer attributes, and is private because it only works
1391- /// correctly if called from `parse_dot_or_call_expr() `.
1378+ /// correctly if called from `parse_expr_dot_or_call `.
13921379 fn parse_expr_bottom ( & mut self ) -> PResult < ' a , P < Expr > > {
13931380 maybe_recover_from_interpolated_ty_qpath ! ( self , true ) ;
13941381
0 commit comments