@@ -192,14 +192,22 @@ pub enum TokenType {
192
192
Token ( token:: Token ) ,
193
193
Keyword ( keywords:: Keyword ) ,
194
194
Operator ,
195
+ Lifetime ,
196
+ Ident ,
197
+ Path ,
198
+ Type ,
195
199
}
196
200
197
201
impl TokenType {
198
202
fn to_string ( & self ) -> String {
199
203
match * self {
200
204
TokenType :: Token ( ref t) => format ! ( "`{}`" , Parser :: token_to_string( t) ) ,
201
- TokenType :: Operator => "an operator" . to_string ( ) ,
202
205
TokenType :: Keyword ( kw) => format ! ( "`{}`" , kw. name( ) ) ,
206
+ TokenType :: Operator => "an operator" . to_string ( ) ,
207
+ TokenType :: Lifetime => "lifetime" . to_string ( ) ,
208
+ TokenType :: Ident => "identifier" . to_string ( ) ,
209
+ TokenType :: Path => "path" . to_string ( ) ,
210
+ TokenType :: Type => "type" . to_string ( ) ,
203
211
}
204
212
}
205
213
}
@@ -552,6 +560,33 @@ impl<'a> Parser<'a> {
552
560
}
553
561
}
554
562
563
+ fn check_ident ( & mut self ) -> bool {
564
+ if self . token . is_ident ( ) {
565
+ true
566
+ } else {
567
+ self . expected_tokens . push ( TokenType :: Ident ) ;
568
+ false
569
+ }
570
+ }
571
+
572
+ fn check_path ( & mut self ) -> bool {
573
+ if self . token . is_path_start ( ) {
574
+ true
575
+ } else {
576
+ self . expected_tokens . push ( TokenType :: Path ) ;
577
+ false
578
+ }
579
+ }
580
+
581
+ fn check_type ( & mut self ) -> bool {
582
+ if self . token . can_begin_type ( ) {
583
+ true
584
+ } else {
585
+ self . expected_tokens . push ( TokenType :: Type ) ;
586
+ false
587
+ }
588
+ }
589
+
555
590
/// Expect and consume an `&`. If `&&` is seen, replace it with a single
556
591
/// `&` and continue. If an `&` is not seen, signal an error.
557
592
fn expect_and ( & mut self ) -> PResult < ' a , ( ) > {
@@ -1802,7 +1837,10 @@ impl<'a> Parser<'a> {
1802
1837
name : ident. name
1803
1838
} )
1804
1839
}
1805
- _ => None
1840
+ _ => {
1841
+ self . expected_tokens . push ( TokenType :: Lifetime ) ;
1842
+ None
1843
+ }
1806
1844
}
1807
1845
}
1808
1846
@@ -3953,7 +3991,7 @@ impl<'a> Parser<'a> {
3953
3991
"`?` may only modify trait bounds, not lifetime bounds" ) ;
3954
3992
}
3955
3993
bounds. push ( RegionTyParamBound ( lifetime) ) ;
3956
- } else if self . token . is_keyword ( keywords:: For ) || self . token . is_path_start ( ) {
3994
+ } else { if self . check_keyword ( keywords:: For ) || self . check_path ( ) {
3957
3995
let poly_trait_ref = self . parse_poly_trait_ref ( ) ?;
3958
3996
let modifier = if question. is_some ( ) {
3959
3997
TraitBoundModifier :: Maybe
@@ -3963,7 +4001,7 @@ impl<'a> Parser<'a> {
3963
4001
bounds. push ( TraitTyParamBound ( poly_trait_ref, modifier) ) ;
3964
4002
} else {
3965
4003
break
3966
- }
4004
+ } }
3967
4005
3968
4006
// Trailing plus is not allowed for now and we have to detect it.
3969
4007
let is_bound_start = |token : & token:: Token | {
@@ -4047,7 +4085,7 @@ impl<'a> Parser<'a> {
4047
4085
self . span_err ( self . prev_span ,
4048
4086
"lifetime parameters must be declared prior to type parameters" ) ;
4049
4087
}
4050
- } else if self . token . is_ident ( ) {
4088
+ } else { if self . check_ident ( ) {
4051
4089
// Parse type parameter.
4052
4090
ty_params. push ( self . parse_ty_param ( attrs) ?) ;
4053
4091
seen_ty_param = true ;
@@ -4059,7 +4097,7 @@ impl<'a> Parser<'a> {
4059
4097
& format ! ( "trailing attribute after {} parameters" , param_kind) ) ;
4060
4098
}
4061
4099
break
4062
- }
4100
+ } }
4063
4101
4064
4102
if !self . eat ( & token:: Comma ) {
4065
4103
break
@@ -4105,15 +4143,14 @@ impl<'a> Parser<'a> {
4105
4143
let mut seen_type = false ;
4106
4144
let mut seen_binding = false ;
4107
4145
loop {
4108
- let eq_is_next = self . look_ahead ( 1 , |t| t == & token:: Eq ) ; // borrowck workaround
4109
4146
if let Some ( lifetime) = self . eat_lifetime ( ) {
4110
4147
// Parse lifetime argument.
4111
4148
lifetimes. push ( lifetime) ;
4112
4149
if seen_type || seen_binding {
4113
4150
self . span_err ( self . prev_span ,
4114
4151
"lifetime parameters must be declared prior to type parameters" ) ;
4115
4152
}
4116
- } else if self . token . is_ident ( ) && eq_is_next {
4153
+ } else { if self . check_ident ( ) && self . look_ahead ( 1 , |t| t == & token :: Eq ) {
4117
4154
// Parse associated type binding.
4118
4155
let lo = self . span . lo ;
4119
4156
let ident = self . parse_ident ( ) ?;
@@ -4126,7 +4163,7 @@ impl<'a> Parser<'a> {
4126
4163
span : mk_sp ( lo, self . prev_span . hi ) ,
4127
4164
} ) ;
4128
4165
seen_binding = true ;
4129
- } else if self . token . can_begin_type ( ) {
4166
+ } else if self . check_type ( ) {
4130
4167
// Parse type argument.
4131
4168
types. push ( self . parse_ty ( ) ?) ;
4132
4169
if seen_binding {
@@ -4136,7 +4173,7 @@ impl<'a> Parser<'a> {
4136
4173
seen_type = true ;
4137
4174
} else {
4138
4175
break
4139
- }
4176
+ } }
4140
4177
4141
4178
if !self . eat ( & token:: Comma ) {
4142
4179
break
@@ -4192,7 +4229,7 @@ impl<'a> Parser<'a> {
4192
4229
bounds : bounds,
4193
4230
}
4194
4231
) ) ;
4195
- } else if self . token . can_begin_type ( ) {
4232
+ } else { if self . check_type ( ) {
4196
4233
// Parse optional `for<'a, 'b>`.
4197
4234
// This `for` is parsed greedily and applies to the whole predicate,
4198
4235
// the bounded type can have its own `for` applying only to it.
@@ -4230,7 +4267,7 @@ impl<'a> Parser<'a> {
4230
4267
}
4231
4268
} else {
4232
4269
break
4233
- }
4270
+ } }
4234
4271
4235
4272
if !self . eat ( & token:: Comma ) {
4236
4273
break
0 commit comments