@@ -601,141 +601,76 @@ impl<'a> Parser<'a> {
601
601
)
602
602
}
603
603
604
- /// Expects and consumes a `+`. if `+=` is seen, replaces it with a `=`
605
- /// and continues. If a `+` is not seen, returns `false`.
606
- ///
607
- /// This is used when token-splitting `+=` into `+`.
608
- /// See issue #47856 for an example of when this may occur.
609
- fn eat_plus ( & mut self ) -> bool {
610
- self . expected_tokens . push ( TokenType :: Token ( token:: BinOp ( token:: Plus ) ) ) ;
611
- match self . token . kind {
612
- token:: BinOp ( token:: Plus ) => {
613
- self . bump ( ) ;
604
+ /// Eats the expected token if it's present possibly breaking
605
+ /// compound tokens like multi-character operators in process.
606
+ /// Returns `true` if the token was eaten.
607
+ fn break_and_eat ( & mut self , expected : TokenKind ) -> bool {
608
+ if self . token . kind == expected {
609
+ self . bump ( ) ;
610
+ return true ;
611
+ }
612
+ match self . token . kind . break_two_token_op ( ) {
613
+ Some ( ( first, second) ) if first == expected => {
614
+ let first_span = self . sess . source_map ( ) . start_point ( self . token . span ) ;
615
+ let second_span = self . token . span . with_lo ( first_span. hi ( ) ) ;
616
+ self . set_token ( Token :: new ( first, first_span) ) ;
617
+ self . bump_with ( Token :: new ( second, second_span) ) ;
614
618
true
615
619
}
616
- token:: BinOpEq ( token:: Plus ) => {
617
- let start_point = self . sess . source_map ( ) . start_point ( self . token . span ) ;
618
- self . bump_with ( token:: Eq , self . token . span . with_lo ( start_point. hi ( ) ) ) ;
619
- true
620
+ _ => {
621
+ self . expected_tokens . push ( TokenType :: Token ( expected) ) ;
622
+ false
620
623
}
621
- _ => false ,
622
624
}
623
625
}
624
626
625
- /// Expects and consumes an `&`. If `&&` is seen, replaces it with a single
626
- /// `&` and continues. If an `&` is not seen, signals an error.
627
+ /// Eats `+` possibly breaking tokens like `+=` in process.
628
+ fn eat_plus ( & mut self ) -> bool {
629
+ self . break_and_eat ( token:: BinOp ( token:: Plus ) )
630
+ }
631
+
632
+ /// Eats `&` possibly breaking tokens like `&&` in process.
633
+ /// Signals an error if `&` is not eaten.
627
634
fn expect_and ( & mut self ) -> PResult < ' a , ( ) > {
628
- self . expected_tokens . push ( TokenType :: Token ( token:: BinOp ( token:: And ) ) ) ;
629
- match self . token . kind {
630
- token:: BinOp ( token:: And ) => {
631
- self . bump ( ) ;
632
- Ok ( ( ) )
633
- }
634
- token:: AndAnd => {
635
- let start_point = self . sess . source_map ( ) . start_point ( self . token . span ) ;
636
- Ok ( self
637
- . bump_with ( token:: BinOp ( token:: And ) , self . token . span . with_lo ( start_point. hi ( ) ) ) )
638
- }
639
- _ => self . unexpected ( ) ,
640
- }
635
+ if self . break_and_eat ( token:: BinOp ( token:: And ) ) { Ok ( ( ) ) } else { self . unexpected ( ) }
641
636
}
642
637
643
- /// Expects and consumes an `|`. If `||` is seen, replaces it with a single
644
- /// `|` and continues. If an `|` is not seen, signals an error .
638
+ /// Eats `|` possibly breaking tokens like `||` in process.
639
+ /// Signals an error if `|` was not eaten .
645
640
fn expect_or ( & mut self ) -> PResult < ' a , ( ) > {
646
- self . expected_tokens . push ( TokenType :: Token ( token:: BinOp ( token:: Or ) ) ) ;
647
- match self . token . kind {
648
- token:: BinOp ( token:: Or ) => {
649
- self . bump ( ) ;
650
- Ok ( ( ) )
651
- }
652
- token:: OrOr => {
653
- let start_point = self . sess . source_map ( ) . start_point ( self . token . span ) ;
654
- Ok ( self
655
- . bump_with ( token:: BinOp ( token:: Or ) , self . token . span . with_lo ( start_point. hi ( ) ) ) )
656
- }
657
- _ => self . unexpected ( ) ,
658
- }
641
+ if self . break_and_eat ( token:: BinOp ( token:: Or ) ) { Ok ( ( ) ) } else { self . unexpected ( ) }
659
642
}
660
643
661
- /// Attempts to consume a `<`. If `<<` is seen, replaces it with a single
662
- /// `<` and continue. If `<-` is seen, replaces it with a single `<`
663
- /// and continue. If a `<` is not seen, returns false.
664
- ///
665
- /// This is meant to be used when parsing generics on a path to get the
666
- /// starting token.
644
+ /// Eats `<` possibly breaking tokens like `<<` in process.
667
645
fn eat_lt ( & mut self ) -> bool {
668
- self . expected_tokens . push ( TokenType :: Token ( token:: Lt ) ) ;
669
- let ate = match self . token . kind {
670
- token:: Lt => {
671
- self . bump ( ) ;
672
- true
673
- }
674
- token:: BinOp ( token:: Shl ) => {
675
- let start_point = self . sess . source_map ( ) . start_point ( self . token . span ) ;
676
- self . bump_with ( token:: Lt , self . token . span . with_lo ( start_point. hi ( ) ) ) ;
677
- true
678
- }
679
- token:: LArrow => {
680
- let start_point = self . sess . source_map ( ) . start_point ( self . token . span ) ;
681
- self . bump_with (
682
- token:: BinOp ( token:: Minus ) ,
683
- self . token . span . with_lo ( start_point. hi ( ) ) ,
684
- ) ;
685
- true
686
- }
687
- _ => false ,
688
- } ;
689
-
646
+ let ate = self . break_and_eat ( token:: Lt ) ;
690
647
if ate {
691
648
// See doc comment for `unmatched_angle_bracket_count`.
692
649
self . unmatched_angle_bracket_count += 1 ;
693
650
self . max_angle_bracket_count += 1 ;
694
651
debug ! ( "eat_lt: (increment) count={:?}" , self . unmatched_angle_bracket_count) ;
695
652
}
696
-
697
653
ate
698
654
}
699
655
656
+ /// Eats `<` possibly breaking tokens like `<<` in process.
657
+ /// Signals an error if `<` was not eaten.
700
658
fn expect_lt ( & mut self ) -> PResult < ' a , ( ) > {
701
- if ! self . eat_lt ( ) { self . unexpected ( ) } else { Ok ( ( ) ) }
659
+ if self . eat_lt ( ) { Ok ( ( ) ) } else { self . unexpected ( ) }
702
660
}
703
661
704
- /// Expects and consumes a single `>` token. if a `>>` is seen, replaces it
705
- /// with a single `>` and continues. If a `>` is not seen, signals an error .
662
+ /// Eats `>` possibly breaking tokens like `>>` in process.
663
+ /// Signals an error if `>` was not eaten .
706
664
fn expect_gt ( & mut self ) -> PResult < ' a , ( ) > {
707
- self . expected_tokens . push ( TokenType :: Token ( token:: Gt ) ) ;
708
- let ate = match self . token . kind {
709
- token:: Gt => {
710
- self . bump ( ) ;
711
- Some ( ( ) )
712
- }
713
- token:: BinOp ( token:: Shr ) => {
714
- let start_point = self . sess . source_map ( ) . start_point ( self . token . span ) ;
715
- Some ( self . bump_with ( token:: Gt , self . token . span . with_lo ( start_point. hi ( ) ) ) )
716
- }
717
- token:: BinOpEq ( token:: Shr ) => {
718
- let start_point = self . sess . source_map ( ) . start_point ( self . token . span ) ;
719
- Some ( self . bump_with ( token:: Ge , self . token . span . with_lo ( start_point. hi ( ) ) ) )
720
- }
721
- token:: Ge => {
722
- let start_point = self . sess . source_map ( ) . start_point ( self . token . span ) ;
723
- Some ( self . bump_with ( token:: Eq , self . token . span . with_lo ( start_point. hi ( ) ) ) )
724
- }
725
- _ => None ,
726
- } ;
727
-
728
- match ate {
729
- Some ( _) => {
730
- // See doc comment for `unmatched_angle_bracket_count`.
731
- if self . unmatched_angle_bracket_count > 0 {
732
- self . unmatched_angle_bracket_count -= 1 ;
733
- debug ! ( "expect_gt: (decrement) count={:?}" , self . unmatched_angle_bracket_count) ;
734
- }
735
-
736
- Ok ( ( ) )
665
+ if self . break_and_eat ( token:: Gt ) {
666
+ // See doc comment for `unmatched_angle_bracket_count`.
667
+ if self . unmatched_angle_bracket_count > 0 {
668
+ self . unmatched_angle_bracket_count -= 1 ;
669
+ debug ! ( "expect_gt: (decrement) count={:?}" , self . unmatched_angle_bracket_count) ;
737
670
}
738
- None => self . unexpected ( ) ,
671
+ Ok ( ( ) )
672
+ } else {
673
+ self . unexpected ( )
739
674
}
740
675
}
741
676
@@ -903,41 +838,30 @@ impl<'a> Parser<'a> {
903
838
}
904
839
}
905
840
906
- /// Advance the parser by one token.
907
- pub fn bump ( & mut self ) {
841
+ /// Advance the parser by one token using provided token as the next one.
842
+ fn bump_with ( & mut self , next_token : Token ) {
843
+ // Bumping after EOF is a bad sign, usually an infinite loop.
908
844
if self . prev_token . kind == TokenKind :: Eof {
909
- // Bumping after EOF is a bad sign, usually an infinite loop.
910
845
let msg = "attempted to bump the parser past EOF (may be stuck in a loop)" ;
911
846
self . span_bug ( self . token . span , msg) ;
912
847
}
913
848
914
849
// Update the current and previous tokens.
915
850
self . prev_token = self . token . take ( ) ;
916
851
self . unnormalized_prev_token = self . unnormalized_token . take ( ) ;
917
- let next_token = self . next_tok ( self . unnormalized_prev_token . span ) ;
918
852
self . set_token ( next_token) ;
919
853
920
854
// Update fields derived from the previous token.
921
855
self . prev_span = self . unnormalized_prev_token . span ;
922
856
857
+ // Diagnostics.
923
858
self . expected_tokens . clear ( ) ;
924
859
}
925
860
926
- /// Advances the parser using provided token as a next one. Use this when
927
- /// consuming a part of a token. For example a single `<` from `<<`.
928
- /// FIXME: this function sets the previous token data to some semi-nonsensical values
929
- /// which kind of work because they are currently used in very limited ways in practice.
930
- /// Correct token kinds and spans need to be calculated instead.
931
- fn bump_with ( & mut self , next : TokenKind , span : Span ) {
932
- // Update the current and previous tokens.
933
- self . prev_token = self . token . take ( ) ;
934
- self . unnormalized_prev_token = self . unnormalized_token . take ( ) ;
935
- self . set_token ( Token :: new ( next, span) ) ;
936
-
937
- // Update fields derived from the previous token.
938
- self . prev_span = self . unnormalized_prev_token . span . with_hi ( span. lo ( ) ) ;
939
-
940
- self . expected_tokens . clear ( ) ;
861
+ /// Advance the parser by one token.
862
+ pub fn bump ( & mut self ) {
863
+ let next_token = self . next_tok ( self . unnormalized_token . span ) ;
864
+ self . bump_with ( next_token) ;
941
865
}
942
866
943
867
/// Look-ahead `dist` tokens of `self.token` and get access to that token there.
0 commit comments