@@ -587,16 +587,64 @@ impl<'a> Parser<'a> {
587
587
self . replace_token ( token:: BINOP ( token:: OR ) , lo, self . span . hi )
588
588
}
589
589
_ => {
590
- let token_str = self . this_token_to_str ( ) ;
591
- let found_token =
590
+ let found_token = self . this_token_to_str ( ) ;
591
+ let token_str =
592
592
Parser :: token_to_str ( & token:: BINOP ( token:: OR ) ) ;
593
593
self . fatal ( format ! ( "expected `{}`, found `{}`" ,
594
- found_token,
595
- token_str) )
594
+ token_str, found_token) )
596
595
}
597
596
}
598
597
}
599
598
599
+ // Attempt to consume a `<`. If `<<` is seen, replace it with a single
600
+ // `<` and continue. If a `<` is not seen, return false.
601
+ //
602
+ // This is meant to be used when parsing generics on a path to get the
603
+ // starting token. The `force` parameter is used to forcefully break up a
604
+ // `<<` token. If `force` is false, then `<<` is only broken when a lifetime
605
+ // shows up next. For example, consider the expression:
606
+ //
607
+ // foo as bar << test
608
+ //
609
+ // The parser needs to know if `bar <<` is the start of a generic path or if
610
+ // it's a left-shift token. If `test` were a lifetime, then it's impossible
611
+ // for the token to be a left-shift, but if it's not a lifetime, then it's
612
+ // considered a left-shift.
613
+ //
614
+ // The reason for this is that the only current ambiguity with `<<` is when
615
+ // parsing closure types:
616
+ //
617
+ // foo::<<'a> ||>();
618
+ // impl Foo<<'a> ||>() { ... }
619
+ fn eat_lt ( & mut self , force : bool ) -> bool {
620
+ match self . token {
621
+ token:: LT => { self . bump ( ) ; true }
622
+ token:: BINOP ( token:: SHL ) => {
623
+ let next_lifetime = self . look_ahead ( 1 , |t| match * t {
624
+ token:: LIFETIME ( ..) => true ,
625
+ _ => false ,
626
+ } ) ;
627
+ if force || next_lifetime {
628
+ let lo = self . span . lo + BytePos ( 1 ) ;
629
+ self . replace_token ( token:: LT , lo, self . span . hi ) ;
630
+ true
631
+ } else {
632
+ false
633
+ }
634
+ }
635
+ _ => false ,
636
+ }
637
+ }
638
+
639
+ fn expect_lt ( & mut self ) {
640
+ if !self . eat_lt ( true ) {
641
+ let found_token = self . this_token_to_str ( ) ;
642
+ let token_str = Parser :: token_to_str ( & token:: LT ) ;
643
+ self . fatal ( format ! ( "expected `{}`, found `{}`" ,
644
+ token_str, found_token) )
645
+ }
646
+ }
647
+
600
648
// Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
601
649
fn parse_seq_to_before_or < T > (
602
650
& mut self ,
@@ -1500,7 +1548,7 @@ impl<'a> Parser<'a> {
1500
1548
1501
1549
// Parse the `<` before the lifetime and types, if applicable.
1502
1550
let ( any_lifetime_or_types, lifetimes, types) = {
1503
- if mode != NoTypesAllowed && self . eat ( & token :: LT ) {
1551
+ if mode != NoTypesAllowed && self . eat_lt ( false ) {
1504
1552
let ( lifetimes, types) =
1505
1553
self . parse_generic_values_after_lt ( ) ;
1506
1554
( true , lifetimes, OwnedSlice :: from_vec ( types) )
@@ -1948,7 +1996,7 @@ impl<'a> Parser<'a> {
1948
1996
hi = self . span . hi ;
1949
1997
self . bump ( ) ;
1950
1998
let ( _, tys) = if self . eat ( & token:: MOD_SEP ) {
1951
- self . expect ( & token :: LT ) ;
1999
+ self . expect_lt ( ) ;
1952
2000
self . parse_generic_values_after_lt ( )
1953
2001
} else {
1954
2002
( Vec :: new ( ) , Vec :: new ( ) )
0 commit comments