@@ -245,6 +245,22 @@ enum PrevTokenKind {
245
245
Other ,
246
246
}
247
247
248
+ // Simple circular buffer used for keeping few next tokens.
249
+ #[ derive( Default ) ]
250
+ struct LookaheadBuffer {
251
+ buffer : [ TokenAndSpan ; LOOKAHEAD_BUFFER_CAPACITY ] ,
252
+ start : usize ,
253
+ end : usize ,
254
+ }
255
+
256
+ const LOOKAHEAD_BUFFER_CAPACITY : usize = 8 ;
257
+
258
+ impl LookaheadBuffer {
259
+ fn len ( & self ) -> usize {
260
+ ( LOOKAHEAD_BUFFER_CAPACITY + self . end - self . start ) % LOOKAHEAD_BUFFER_CAPACITY
261
+ }
262
+ }
263
+
248
264
/* ident is handled by common.rs */
249
265
250
266
pub struct Parser < ' a > {
@@ -258,9 +274,7 @@ pub struct Parser<'a> {
258
274
pub cfg : CrateConfig ,
259
275
/// the previous token kind
260
276
prev_token_kind : PrevTokenKind ,
261
- pub buffer : [ TokenAndSpan ; 4 ] ,
262
- pub buffer_start : isize ,
263
- pub buffer_end : isize ,
277
+ lookahead_buffer : LookaheadBuffer ,
264
278
pub tokens_consumed : usize ,
265
279
pub restrictions : Restrictions ,
266
280
pub quote_depth : usize , // not (yet) related to the quasiquoter
@@ -356,10 +370,6 @@ impl<'a> Parser<'a> {
356
370
_ => PathBuf :: from ( sess. codemap ( ) . span_to_filename ( span) ) ,
357
371
} ;
358
372
directory. pop ( ) ;
359
- let placeholder = TokenAndSpan {
360
- tok : token:: Underscore ,
361
- sp : span,
362
- } ;
363
373
364
374
Parser {
365
375
reader : rdr,
@@ -369,14 +379,7 @@ impl<'a> Parser<'a> {
369
379
span : span,
370
380
prev_span : span,
371
381
prev_token_kind : PrevTokenKind :: Other ,
372
- buffer : [
373
- placeholder. clone ( ) ,
374
- placeholder. clone ( ) ,
375
- placeholder. clone ( ) ,
376
- placeholder. clone ( ) ,
377
- ] ,
378
- buffer_start : 0 ,
379
- buffer_end : 0 ,
382
+ lookahead_buffer : Default :: default ( ) ,
380
383
tokens_consumed : 0 ,
381
384
restrictions : Restrictions :: empty ( ) ,
382
385
quote_depth : 0 ,
@@ -937,19 +940,13 @@ impl<'a> Parser<'a> {
937
940
_ => PrevTokenKind :: Other ,
938
941
} ;
939
942
940
- let next = if self . buffer_start == self . buffer_end {
943
+ let next = if self . lookahead_buffer . start == self . lookahead_buffer . end {
941
944
self . reader . real_token ( )
942
945
} else {
943
946
// Avoid token copies with `replace`.
944
- let buffer_start = self . buffer_start as usize ;
945
- let next_index = ( buffer_start + 1 ) & 3 ;
946
- self . buffer_start = next_index as isize ;
947
-
948
- let placeholder = TokenAndSpan {
949
- tok : token:: Underscore ,
950
- sp : self . span ,
951
- } ;
952
- mem:: replace ( & mut self . buffer [ buffer_start] , placeholder)
947
+ let old_start = self . lookahead_buffer . start ;
948
+ self . lookahead_buffer . start = ( old_start + 1 ) % LOOKAHEAD_BUFFER_CAPACITY ;
949
+ mem:: replace ( & mut self . lookahead_buffer . buffer [ old_start] , Default :: default ( ) )
953
950
} ;
954
951
self . span = next. sp ;
955
952
self . token = next. tok ;
@@ -982,21 +979,22 @@ impl<'a> Parser<'a> {
982
979
self . expected_tokens . clear ( ) ;
983
980
}
984
981
985
- pub fn buffer_length ( & mut self ) -> isize {
986
- if self . buffer_start <= self . buffer_end {
987
- return self . buffer_end - self . buffer_start ;
988
- }
989
- return ( 4 - self . buffer_start ) + self . buffer_end ;
990
- }
991
- pub fn look_ahead < R , F > ( & mut self , distance : usize , f : F ) -> R where
982
+ pub fn look_ahead < R , F > ( & mut self , dist : usize , f : F ) -> R where
992
983
F : FnOnce ( & token:: Token ) -> R ,
993
984
{
994
- let dist = distance as isize ;
995
- while self . buffer_length ( ) < dist {
996
- self . buffer [ self . buffer_end as usize ] = self . reader . real_token ( ) ;
997
- self . buffer_end = ( self . buffer_end + 1 ) & 3 ;
985
+ if dist == 0 {
986
+ f ( & self . token )
987
+ } else if dist < LOOKAHEAD_BUFFER_CAPACITY {
988
+ while self . lookahead_buffer . len ( ) < dist {
989
+ self . lookahead_buffer . buffer [ self . lookahead_buffer . end ] = self . reader . real_token ( ) ;
990
+ self . lookahead_buffer . end =
991
+ ( self . lookahead_buffer . end + 1 ) % LOOKAHEAD_BUFFER_CAPACITY ;
992
+ }
993
+ let index = ( self . lookahead_buffer . start + dist - 1 ) % LOOKAHEAD_BUFFER_CAPACITY ;
994
+ f ( & self . lookahead_buffer . buffer [ index] . tok )
995
+ } else {
996
+ self . bug ( "lookahead distance is too large" ) ;
998
997
}
999
- f ( & self . buffer [ ( ( self . buffer_start + dist - 1 ) & 3 ) as usize ] . tok )
1000
998
}
1001
999
pub fn fatal ( & self , m : & str ) -> DiagnosticBuilder < ' a > {
1002
1000
self . sess . span_diagnostic . struct_span_fatal ( self . span , m)
@@ -1118,7 +1116,6 @@ impl<'a> Parser<'a> {
1118
1116
Ok ( ast:: TyKind :: ImplTrait ( bounds) )
1119
1117
}
1120
1118
1121
-
1122
1119
pub fn parse_ty_path ( & mut self ) -> PResult < ' a , TyKind > {
1123
1120
Ok ( TyKind :: Path ( None , self . parse_path ( PathStyle :: Type ) ?) )
1124
1121
}
@@ -3623,7 +3620,7 @@ impl<'a> Parser<'a> {
3623
3620
// Parse box pat
3624
3621
let subpat = self . parse_pat ( ) ?;
3625
3622
pat = PatKind :: Box ( subpat) ;
3626
- } else if self . token . is_ident ( ) && self . token . is_path_start ( ) &&
3623
+ } else if self . token . is_ident ( ) && ! self . token . is_any_keyword ( ) &&
3627
3624
self . look_ahead ( 1 , |t| match * t {
3628
3625
token:: OpenDelim ( token:: Paren ) | token:: OpenDelim ( token:: Brace ) |
3629
3626
token:: DotDotDot | token:: ModSep | token:: Not => false ,
@@ -3874,6 +3871,11 @@ impl<'a> Parser<'a> {
3874
3871
} )
3875
3872
}
3876
3873
3874
+ fn is_union_item ( & mut self ) -> bool {
3875
+ self . token . is_keyword ( keywords:: Union ) &&
3876
+ self . look_ahead ( 1 , |t| t. is_ident ( ) && !t. is_any_keyword ( ) )
3877
+ }
3878
+
3877
3879
fn parse_stmt_without_recovery ( & mut self ,
3878
3880
macro_legacy_warnings : bool )
3879
3881
-> PResult < ' a , Option < Stmt > > {
@@ -3888,10 +3890,10 @@ impl<'a> Parser<'a> {
3888
3890
node : StmtKind :: Local ( self . parse_local ( attrs. into ( ) ) ?) ,
3889
3891
span : mk_sp ( lo, self . prev_span . hi ) ,
3890
3892
}
3891
- } else if self . token . is_path_start ( ) && self . token != token :: Lt && {
3892
- ! self . check_keyword ( keywords :: Union ) ||
3893
- self . look_ahead ( 1 , |t| * t == token :: Not || * t == token:: ModSep )
3894
- } {
3893
+ // Starts like a simple path, but not a union item.
3894
+ } else if self . token . is_path_start ( ) &&
3895
+ ! self . token . is_qpath_start ( ) &&
3896
+ ! self . is_union_item ( ) {
3895
3897
let pth = self . parse_path ( PathStyle :: Expr ) ?;
3896
3898
3897
3899
if !self . eat ( & token:: Not ) {
@@ -4602,6 +4604,10 @@ impl<'a> Parser<'a> {
4602
4604
token:: Ident ( ident) => { this. bump ( ) ; codemap:: respan ( this. prev_span , ident) }
4603
4605
_ => unreachable ! ( )
4604
4606
} ;
4607
+ let isolated_self = |this : & mut Self , n| {
4608
+ this. look_ahead ( n, |t| t. is_keyword ( keywords:: SelfValue ) ) &&
4609
+ this. look_ahead ( n + 1 , |t| t != & token:: ModSep )
4610
+ } ;
4605
4611
4606
4612
// Parse optional self parameter of a method.
4607
4613
// Only a limited set of initial token sequences is considered self parameters, anything
@@ -4614,22 +4620,22 @@ impl<'a> Parser<'a> {
4614
4620
// &'lt self
4615
4621
// &'lt mut self
4616
4622
// ¬_self
4617
- if self . look_ahead ( 1 , |t| t . is_keyword ( keywords :: SelfValue ) ) {
4623
+ if isolated_self ( self , 1 ) {
4618
4624
self . bump ( ) ;
4619
4625
( SelfKind :: Region ( None , Mutability :: Immutable ) , expect_ident ( self ) )
4620
4626
} else if self . look_ahead ( 1 , |t| t. is_keyword ( keywords:: Mut ) ) &&
4621
- self . look_ahead ( 2 , |t| t . is_keyword ( keywords :: SelfValue ) ) {
4627
+ isolated_self ( self , 2 ) {
4622
4628
self . bump ( ) ;
4623
4629
self . bump ( ) ;
4624
4630
( SelfKind :: Region ( None , Mutability :: Mutable ) , expect_ident ( self ) )
4625
4631
} else if self . look_ahead ( 1 , |t| t. is_lifetime ( ) ) &&
4626
- self . look_ahead ( 2 , |t| t . is_keyword ( keywords :: SelfValue ) ) {
4632
+ isolated_self ( self , 2 ) {
4627
4633
self . bump ( ) ;
4628
4634
let lt = self . parse_lifetime ( ) ?;
4629
4635
( SelfKind :: Region ( Some ( lt) , Mutability :: Immutable ) , expect_ident ( self ) )
4630
4636
} else if self . look_ahead ( 1 , |t| t. is_lifetime ( ) ) &&
4631
4637
self . look_ahead ( 2 , |t| t. is_keyword ( keywords:: Mut ) ) &&
4632
- self . look_ahead ( 3 , |t| t . is_keyword ( keywords :: SelfValue ) ) {
4638
+ isolated_self ( self , 3 ) {
4633
4639
self . bump ( ) ;
4634
4640
let lt = self . parse_lifetime ( ) ?;
4635
4641
self . bump ( ) ;
@@ -4644,12 +4650,12 @@ impl<'a> Parser<'a> {
4644
4650
// *mut self
4645
4651
// *not_self
4646
4652
// Emit special error for `self` cases.
4647
- if self . look_ahead ( 1 , |t| t . is_keyword ( keywords :: SelfValue ) ) {
4653
+ if isolated_self ( self , 1 ) {
4648
4654
self . bump ( ) ;
4649
4655
self . span_err ( self . span , "cannot pass `self` by raw pointer" ) ;
4650
4656
( SelfKind :: Value ( Mutability :: Immutable ) , expect_ident ( self ) )
4651
4657
} else if self . look_ahead ( 1 , |t| t. is_mutability ( ) ) &&
4652
- self . look_ahead ( 2 , |t| t . is_keyword ( keywords :: SelfValue ) ) {
4658
+ isolated_self ( self , 2 ) {
4653
4659
self . bump ( ) ;
4654
4660
self . bump ( ) ;
4655
4661
self . span_err ( self . span , "cannot pass `self` by raw pointer" ) ;
@@ -4659,7 +4665,7 @@ impl<'a> Parser<'a> {
4659
4665
}
4660
4666
}
4661
4667
token:: Ident ( ..) => {
4662
- if self . token . is_keyword ( keywords :: SelfValue ) {
4668
+ if isolated_self ( self , 0 ) {
4663
4669
// self
4664
4670
// self: TYPE
4665
4671
let eself_ident = expect_ident ( self ) ;
@@ -4670,7 +4676,7 @@ impl<'a> Parser<'a> {
4670
4676
( SelfKind :: Value ( Mutability :: Immutable ) , eself_ident)
4671
4677
}
4672
4678
} else if self . token . is_keyword ( keywords:: Mut ) &&
4673
- self . look_ahead ( 1 , |t| t . is_keyword ( keywords :: SelfValue ) ) {
4679
+ isolated_self ( self , 1 ) {
4674
4680
// mut self
4675
4681
// mut self: TYPE
4676
4682
self . bump ( ) ;
@@ -5961,8 +5967,7 @@ impl<'a> Parser<'a> {
5961
5967
maybe_append ( attrs, extra_attrs) ) ;
5962
5968
return Ok ( Some ( item) ) ;
5963
5969
}
5964
- if self . check_keyword ( keywords:: Union ) &&
5965
- self . look_ahead ( 1 , |t| t. is_ident ( ) && !t. is_any_keyword ( ) ) {
5970
+ if self . is_union_item ( ) {
5966
5971
// UNION ITEM
5967
5972
self . bump ( ) ;
5968
5973
let ( ident, item_, extra_attrs) = self . parse_item_union ( ) ?;
0 commit comments