@@ -193,11 +193,13 @@ pub struct Parser<'a> {
193193}
194194
195195
196+ #[ derive( Clone ) ]
196197struct TokenCursor {
197198 frame : TokenCursorFrame ,
198199 stack : Vec < TokenCursorFrame > ,
199200}
200201
202+ #[ derive( Clone ) ]
201203struct TokenCursorFrame {
202204 delim : token:: DelimToken ,
203205 span : Span ,
@@ -397,6 +399,7 @@ impl Error {
397399 }
398400}
399401
402+ #[ derive( Debug ) ]
400403pub enum LhsExpr {
401404 NotYetParsed ,
402405 AttributesParsed ( ThinVec < Attribute > ) ,
@@ -438,6 +441,8 @@ fn dummy_arg(span: Span) -> Arg {
438441 Arg { ty : P ( ty) , pat : pat, id : ast:: DUMMY_NODE_ID }
439442}
440443
444+ type RewindPoint = ( token:: Token , Span , Option < Span > , Span , TokenCursor , Vec < TokenType > ) ;
445+
441446impl < ' a > Parser < ' a > {
442447 pub fn new ( sess : & ' a ParseSess ,
443448 tokens : TokenStream ,
@@ -786,6 +791,13 @@ impl<'a> Parser<'a> {
786791 }
787792 }
788793
794+ fn is_lt ( & mut self ) -> bool {
795+ match self . token {
796+ token:: Lt | token:: BinOp ( token:: Shl ) => true ,
797+ _ => false ,
798+ }
799+ }
800+
789801 /// Attempt to consume a `<`. If `<<` is seen, replace it with a single
790802 /// `<` and continue. If a `<` is not seen, return false.
791803 ///
@@ -1724,7 +1736,7 @@ impl<'a> Parser<'a> {
17241736
17251737 let segments = match mode {
17261738 PathStyle :: Type => {
1727- self . parse_path_segments_without_colons ( ) ?
1739+ self . parse_path_segments_without_colons ( false ) ?
17281740 }
17291741 PathStyle :: Expr => {
17301742 self . parse_path_segments_with_colons ( ) ?
@@ -1745,6 +1757,16 @@ impl<'a> Parser<'a> {
17451757 /// bounds are permitted and whether `::` must precede type parameter
17461758 /// groups.
17471759 pub fn parse_path ( & mut self , mode : PathStyle ) -> PResult < ' a , ast:: Path > {
1760+ self . parse_path_common ( mode, false )
1761+ }
1762+
1763+ pub fn parse_path_without_generics ( & mut self , mode : PathStyle ) -> PResult < ' a , ast:: Path > {
1764+ self . parse_path_common ( mode, true )
1765+ }
1766+
1767+ fn parse_path_common ( & mut self , mode : PathStyle , dont_parse_generics : bool )
1768+ -> PResult < ' a , ast:: Path >
1769+ {
17481770 maybe_whole ! ( self , NtPath , |x| x) ;
17491771
17501772 let lo = self . meta_var_span . unwrap_or ( self . span ) ;
@@ -1755,7 +1777,7 @@ impl<'a> Parser<'a> {
17551777 // A bound set is a set of type parameter bounds.
17561778 let mut segments = match mode {
17571779 PathStyle :: Type => {
1758- self . parse_path_segments_without_colons ( ) ?
1780+ self . parse_path_segments_without_colons ( dont_parse_generics ) ?
17591781 }
17601782 PathStyle :: Expr => {
17611783 self . parse_path_segments_with_colons ( ) ?
@@ -1800,7 +1822,9 @@ impl<'a> Parser<'a> {
18001822 /// - `a::b<T,U>::c<V,W>`
18011823 /// - `a::b<T,U>::c(V) -> W`
18021824 /// - `a::b<T,U>::c(V)`
1803- pub fn parse_path_segments_without_colons ( & mut self ) -> PResult < ' a , Vec < PathSegment > > {
1825+ pub fn parse_path_segments_without_colons ( & mut self , dont_parse_generics : bool )
1826+ -> PResult < ' a , Vec < PathSegment > >
1827+ {
18041828 let mut segments = Vec :: new ( ) ;
18051829 loop {
18061830 // First, parse an identifier.
@@ -1819,7 +1843,8 @@ impl<'a> Parser<'a> {
18191843 }
18201844
18211845 // Parse types, optionally.
1822- let parameters = if self . eat_lt ( ) {
1846+ let parameters = if self . is_lt ( ) && !dont_parse_generics {
1847+ let _ = self . eat_lt ( ) ;
18231848 let ( lifetimes, types, bindings) = self . parse_generic_args ( ) ?;
18241849 self . expect_gt ( ) ?;
18251850 ast:: AngleBracketedParameterData {
@@ -2798,8 +2823,40 @@ impl<'a> Parser<'a> {
27982823 }
27992824 // Special cases:
28002825 if op == AssocOp :: As {
2801- let rhs = self . parse_ty_no_plus ( ) ?;
2802- lhs = self . mk_expr ( lhs_span. to ( rhs. span ) , ExprKind :: Cast ( lhs, rhs) , ThinVec :: new ( ) ) ;
2826+ // Save the state of the parser before parsing type normally, in case there is a
2827+ // LessThan comparison after this cast.
2828+ let rp = self . get_rewind_point ( ) ;
2829+ match self . parse_ty_no_plus ( ) {
2830+ Ok ( rhs) => {
2831+ lhs = self . mk_expr ( lhs_span. to ( rhs. span ) ,
2832+ ExprKind :: Cast ( lhs, rhs) , ThinVec :: new ( ) ) ;
2833+ }
2834+ Err ( mut err) => {
2835+ // Rewind to before attempting to parse the type with generics, to get
2836+ // arround #22644.
2837+ let rp_err = self . get_rewind_point ( ) ;
2838+ self . rewind ( rp) ;
2839+ let lo = self . span ;
2840+ let path = match self . parse_path_without_generics ( PathStyle :: Type ) {
2841+ Ok ( path) => {
2842+ // Successfully parsed the type leaving a `<` yet to parse
2843+ err. cancel ( ) ;
2844+ path
2845+ }
2846+ Err ( mut path_err) => {
2847+ // Still couldn't parse, return original error and parser state
2848+ path_err. cancel ( ) ;
2849+ self . rewind ( rp_err) ;
2850+ return Err ( err) ;
2851+ }
2852+ } ;
2853+ let path = TyKind :: Path ( None , path) ;
2854+ let span = lo. to ( self . prev_span ) ;
2855+ let rhs = P ( Ty { node : path, span : span, id : ast:: DUMMY_NODE_ID } ) ;
2856+ lhs = self . mk_expr ( lhs_span. to ( rhs. span ) ,
2857+ ExprKind :: Cast ( lhs, rhs) , ThinVec :: new ( ) ) ;
2858+ }
2859+ } ;
28032860 continue
28042861 } else if op == AssocOp :: Colon {
28052862 let rhs = self . parse_ty_no_plus ( ) ?;
@@ -2901,7 +2958,9 @@ impl<'a> Parser<'a> {
29012958 /// We only need to check lhs, not rhs, because all comparison ops
29022959 /// have same precedence and are left-associative
29032960 fn check_no_chained_comparison ( & mut self , lhs : & Expr , outer_op : & AssocOp ) {
2904- debug_assert ! ( outer_op. is_comparison( ) ) ;
2961+ debug_assert ! ( outer_op. is_comparison( ) ,
2962+ "check_no_chained_comparison: {:?} is not comparison" ,
2963+ outer_op) ;
29052964 match lhs. node {
29062965 ExprKind :: Binary ( op, _, _) if op. node . is_comparison ( ) => {
29072966 // respan to include both operators
@@ -2925,7 +2984,9 @@ impl<'a> Parser<'a> {
29252984 fn parse_prefix_range_expr ( & mut self ,
29262985 already_parsed_attrs : Option < ThinVec < Attribute > > )
29272986 -> PResult < ' a , P < Expr > > {
2928- debug_assert ! ( self . token == token:: DotDot || self . token == token:: DotDotDot ) ;
2987+ debug_assert ! ( self . token == token:: DotDot || self . token == token:: DotDotDot ,
2988+ "parse_prefix_range_expr: token {:?} is not DotDot or DotDotDot" ,
2989+ self . token) ;
29292990 let tok = self . token . clone ( ) ;
29302991 let attrs = self . parse_or_use_outer_attributes ( already_parsed_attrs) ?;
29312992 let lo = self . span ;
@@ -6174,4 +6235,25 @@ impl<'a> Parser<'a> {
61746235 _ => Err ( self . fatal ( "expected string literal" ) )
61756236 }
61766237 }
6238+
6239+ fn get_rewind_point ( & mut self ) -> RewindPoint {
6240+ (
6241+ self . token . clone ( ) ,
6242+ self . span ,
6243+ self . meta_var_span ,
6244+ self . prev_span ,
6245+ self . token_cursor . clone ( ) ,
6246+ self . expected_tokens . clone ( ) ,
6247+ )
6248+ }
6249+
6250+ fn rewind ( & mut self , rp : RewindPoint ) {
6251+ let ( token, span, meta_var_span, prev_span, token_cursor, expected_tokens, ) = rp;
6252+ self . token = token;
6253+ self . span = span;
6254+ self . meta_var_span = meta_var_span;
6255+ self . prev_span = prev_span;
6256+ self . token_cursor = token_cursor;
6257+ self . expected_tokens = expected_tokens;
6258+ }
61776259}
0 commit comments