Token(token::Token),
Keyword(keywords::Keyword),
Operator,
+ Lifetime,
+ Ident,
+ Path,
+ Type,
}
impl TokenType {
fn to_string(&self) -> String {
match *self {
TokenType::Token(ref t) => format!("`{}`", Parser::token_to_string(t)),
- TokenType::Operator => "an operator".to_string(),
TokenType::Keyword(kw) => format!("`{}`", kw.name()),
+ TokenType::Operator => "an operator".to_string(),
+ TokenType::Lifetime => "lifetime".to_string(),
+ TokenType::Ident => "identifier".to_string(),
+ TokenType::Path => "path".to_string(),
+ TokenType::Type => "type".to_string(),
}
}
}
}
}
+ fn check_ident(&mut self) -> bool {
+ if self.token.is_ident() {
+ true
+ } else {
+ self.expected_tokens.push(TokenType::Ident);
+ false
+ }
+ }
+
+ fn check_path(&mut self) -> bool {
+ if self.token.is_path_start() {
+ true
+ } else {
+ self.expected_tokens.push(TokenType::Path);
+ false
+ }
+ }
+
+ fn check_type(&mut self) -> bool {
+ if self.token.can_begin_type() {
+ true
+ } else {
+ self.expected_tokens.push(TokenType::Type);
+ false
+ }
+ }
+
/// Expect and consume an `&`. If `&&` is seen, replace it with a single
/// `&` and continue. If an `&` is not seen, signal an error.
fn expect_and(&mut self) -> PResult<'a, ()> {
name: ident.name
})
}
- _ => None
+ _ => {
+ self.expected_tokens.push(TokenType::Lifetime);
+ None
+ }
}
}
"`?` may only modify trait bounds, not lifetime bounds");
}
bounds.push(RegionTyParamBound(lifetime));
- } else if self.token.is_keyword(keywords::For) || self.token.is_path_start() {
+ } else {if self.check_keyword(keywords::For) || self.check_path() {
let poly_trait_ref = self.parse_poly_trait_ref()?;
let modifier = if question.is_some() {
TraitBoundModifier::Maybe
bounds.push(TraitTyParamBound(poly_trait_ref, modifier));
} else {
break
- }
+ }}
// Trailing plus is not allowed for now and we have to detect it.
let is_bound_start = |token: &token::Token| {
self.span_err(self.prev_span,
"lifetime parameters must be declared prior to type parameters");
}
- } else if self.token.is_ident() {
+ } else {if self.check_ident() {
// Parse type parameter.
ty_params.push(self.parse_ty_param(attrs)?);
seen_ty_param = true;
&format!("trailing attribute after {} parameters", param_kind));
}
break
- }
+ }}
if !self.eat(&token::Comma) {
break
let mut seen_type = false;
let mut seen_binding = false;
loop {
- let eq_is_next = self.look_ahead(1, |t| t == &token::Eq); // borrowck workaround
if let Some(lifetime) = self.eat_lifetime() {
// Parse lifetime argument.
lifetimes.push(lifetime);
self.span_err(self.prev_span,
"lifetime parameters must be declared prior to type parameters");
}
- } else if self.token.is_ident() && eq_is_next {
+ } else {if self.check_ident() && self.look_ahead(1, |t| t == &token::Eq) {
// Parse associated type binding.
let lo = self.span.lo;
let ident = self.parse_ident()?;
span: mk_sp(lo, self.prev_span.hi),
});
seen_binding = true;
- } else if self.token.can_begin_type() {
+ } else if self.check_type() {
// Parse type argument.
types.push(self.parse_ty()?);
if seen_binding {
seen_type = true;
} else {
break
- }
+ }}
if !self.eat(&token::Comma) {
break
bounds: bounds,
}
));
- } else if self.token.can_begin_type() {
+ } else {if self.check_type() {
// Parse optional `for<'a, 'b>`.
// This `for` is parsed greedily and applies to the whole predicate,
// the bounded type can have its own `for` applying only to it.
}
} else {
break
- }
+ }}
if !self.eat(&token::Comma) {
break
//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
-type Type_3<T> = Box<T,,>; //~ error: expected `>`, found `,`
+type Type_3<T> = Box<T,,>; //~ error: expected one of `>`, identifier, lifetime, or type, found `,`
//type Type_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
//type Type_3<T> = Box<T,,>; // error: expected type, found `,`
-type Type_4<T> = Type_1_<'static,, T>; //~ error: expected `>`, found `,`
+type Type_4<T> = Type_1_<'static,, T>;
+//~^ error: expected one of `>`, identifier, lifetime, or type, found `,`
type Type_5_<'a> = Type_1_<'a, ()>;
type Type_5_<'a> = Type_1_<'a, ()>;
-type Type_5<'a> = Type_1_<'a, (),,>; //~ error: expected `>`, found `,`
+type Type_5<'a> = Type_1_<'a, (),,>;
+//~^ error: expected one of `>`, identifier, lifetime, or type, found `,`
//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
//type Type_5<'a> = Type_1_<'a, (),,>; // error: expected type, found `,`
-type Type_6 = Type_5_<'a,,>; //~ error: expected `>`, found `,`
+type Type_6 = Type_5_<'a,,>;
+//~^ error: expected one of `>`, identifier, lifetime, or type, found `,`
//type Type_7 = Box<(),,>; // error: expected type, found `,`
//type Type_6 = Type_5_<'a,,>; // error: expected type, found `,`
-type Type_7 = Box<(),,>; //~ error: expected `>`, found `,`
+type Type_7 = Box<(),,>; //~ error: expected one of `>`, identifier, lifetime, or type, found `,`
//type Type_8<'a,,> = &'a (); // error: expected ident, found `,`
//type Type_7 = Box<(),,>; // error: expected type, found `,`
-type Type_8<'a,,> = &'a (); //~ error: expected `>`, found `,`
+type Type_8<'a,,> = &'a (); //~ error: expected one of `>`, identifier, or lifetime, found `,`
//type Type_9<T,,> = Box<T>; // error: expected identifier, found `,`
//type Type_8<'a,,> = &'a (); // error: expected identifier, found `,`
-type Type_9<T,,> = Box<T>; //~ error: expected `>`, found `,`
+type Type_9<T,,> = Box<T>; //~ error: expected one of `>`, identifier, or lifetime, found `,`
// compile-flags: -Z parse-only
-type A = for<,> fn(); //~ ERROR expected `>`, found `,`
+type A = for<,> fn(); //~ ERROR expected one of `>`, identifier, or lifetime, found `,`
fn main() {}
// compile-flags: -Z parse-only
-type A where , = u8; //~ ERROR expected `=`, found `,`
+type A where , = u8; //~ ERROR expected one of `=`, lifetime, or type, found `,`
fn main() {}