@@ -193,11 +193,13 @@ pub struct Parser<'a> {
193
193
}
194
194
195
195
196
+ #[ derive( Clone ) ]
196
197
struct TokenCursor {
197
198
frame : TokenCursorFrame ,
198
199
stack : Vec < TokenCursorFrame > ,
199
200
}
200
201
202
+ #[ derive( Clone ) ]
201
203
struct TokenCursorFrame {
202
204
delim : token:: DelimToken ,
203
205
span : Span ,
@@ -397,6 +399,7 @@ impl Error {
397
399
}
398
400
}
399
401
402
+ #[ derive( Debug ) ]
400
403
pub enum LhsExpr {
401
404
NotYetParsed ,
402
405
AttributesParsed ( ThinVec < Attribute > ) ,
@@ -438,6 +441,8 @@ fn dummy_arg(span: Span) -> Arg {
438
441
Arg { ty : P ( ty) , pat : pat, id : ast:: DUMMY_NODE_ID }
439
442
}
440
443
444
+ type RewindPoint = ( token:: Token , Span , Option < Span > , Span , TokenCursor , Vec < TokenType > ) ;
445
+
441
446
impl < ' a > Parser < ' a > {
442
447
pub fn new ( sess : & ' a ParseSess ,
443
448
tokens : TokenStream ,
@@ -786,6 +791,13 @@ impl<'a> Parser<'a> {
786
791
}
787
792
}
788
793
794
+ fn is_lt ( & mut self ) -> bool {
795
+ match self . token {
796
+ token:: Lt | token:: BinOp ( token:: Shl ) => true ,
797
+ _ => false ,
798
+ }
799
+ }
800
+
789
801
/// Attempt to consume a `<`. If `<<` is seen, replace it with a single
790
802
/// `<` and continue. If a `<` is not seen, return false.
791
803
///
@@ -1724,7 +1736,7 @@ impl<'a> Parser<'a> {
1724
1736
1725
1737
let segments = match mode {
1726
1738
PathStyle :: Type => {
1727
- self . parse_path_segments_without_colons ( ) ?
1739
+ self . parse_path_segments_without_colons ( false ) ?
1728
1740
}
1729
1741
PathStyle :: Expr => {
1730
1742
self . parse_path_segments_with_colons ( ) ?
@@ -1745,6 +1757,16 @@ impl<'a> Parser<'a> {
1745
1757
/// bounds are permitted and whether `::` must precede type parameter
1746
1758
/// groups.
1747
1759
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
+ {
1748
1770
maybe_whole ! ( self , NtPath , |x| x) ;
1749
1771
1750
1772
let lo = self . meta_var_span . unwrap_or ( self . span ) ;
@@ -1755,7 +1777,7 @@ impl<'a> Parser<'a> {
1755
1777
// A bound set is a set of type parameter bounds.
1756
1778
let mut segments = match mode {
1757
1779
PathStyle :: Type => {
1758
- self . parse_path_segments_without_colons ( ) ?
1780
+ self . parse_path_segments_without_colons ( dont_parse_generics ) ?
1759
1781
}
1760
1782
PathStyle :: Expr => {
1761
1783
self . parse_path_segments_with_colons ( ) ?
@@ -1800,7 +1822,9 @@ impl<'a> Parser<'a> {
1800
1822
/// - `a::b<T,U>::c<V,W>`
1801
1823
/// - `a::b<T,U>::c(V) -> W`
1802
1824
/// - `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
+ {
1804
1828
let mut segments = Vec :: new ( ) ;
1805
1829
loop {
1806
1830
// First, parse an identifier.
@@ -1819,7 +1843,8 @@ impl<'a> Parser<'a> {
1819
1843
}
1820
1844
1821
1845
// 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 ( ) ;
1823
1848
let ( lifetimes, types, bindings) = self . parse_generic_args ( ) ?;
1824
1849
self . expect_gt ( ) ?;
1825
1850
ast:: AngleBracketedParameterData {
@@ -2798,8 +2823,40 @@ impl<'a> Parser<'a> {
2798
2823
}
2799
2824
// Special cases:
2800
2825
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
+ } ;
2803
2860
continue
2804
2861
} else if op == AssocOp :: Colon {
2805
2862
let rhs = self . parse_ty_no_plus ( ) ?;
@@ -2901,7 +2958,9 @@ impl<'a> Parser<'a> {
2901
2958
/// We only need to check lhs, not rhs, because all comparison ops
2902
2959
/// have same precedence and are left-associative
2903
2960
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) ;
2905
2964
match lhs. node {
2906
2965
ExprKind :: Binary ( op, _, _) if op. node . is_comparison ( ) => {
2907
2966
// respan to include both operators
@@ -2925,7 +2984,9 @@ impl<'a> Parser<'a> {
2925
2984
fn parse_prefix_range_expr ( & mut self ,
2926
2985
already_parsed_attrs : Option < ThinVec < Attribute > > )
2927
2986
-> 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) ;
2929
2990
let tok = self . token . clone ( ) ;
2930
2991
let attrs = self . parse_or_use_outer_attributes ( already_parsed_attrs) ?;
2931
2992
let lo = self . span ;
@@ -6174,4 +6235,25 @@ impl<'a> Parser<'a> {
6174
6235
_ => Err ( self . fatal ( "expected string literal" ) )
6175
6236
}
6176
6237
}
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
+ }
6177
6259
}
0 commit comments