Improve some expected/found error messages from parser
This commit is contained in:
parent
a8f5047430
commit
375cb2eec7
10 changed files with 61 additions and 21 deletions
|
@ -192,14 +192,22 @@ pub enum TokenType {
|
||||||
Token(token::Token),
|
Token(token::Token),
|
||||||
Keyword(keywords::Keyword),
|
Keyword(keywords::Keyword),
|
||||||
Operator,
|
Operator,
|
||||||
|
Lifetime,
|
||||||
|
Ident,
|
||||||
|
Path,
|
||||||
|
Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TokenType {
|
impl TokenType {
|
||||||
fn to_string(&self) -> String {
|
fn to_string(&self) -> String {
|
||||||
match *self {
|
match *self {
|
||||||
TokenType::Token(ref t) => format!("`{}`", Parser::token_to_string(t)),
|
TokenType::Token(ref t) => format!("`{}`", Parser::token_to_string(t)),
|
||||||
TokenType::Operator => "an operator".to_string(),
|
|
||||||
TokenType::Keyword(kw) => format!("`{}`", kw.name()),
|
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(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,6 +560,33 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
/// Expect and consume an `&`. If `&&` is seen, replace it with a single
|
||||||
/// `&` and continue. If an `&` is not seen, signal an error.
|
/// `&` and continue. If an `&` is not seen, signal an error.
|
||||||
fn expect_and(&mut self) -> PResult<'a, ()> {
|
fn expect_and(&mut self) -> PResult<'a, ()> {
|
||||||
|
@ -1802,7 +1837,10 @@ impl<'a> Parser<'a> {
|
||||||
name: ident.name
|
name: ident.name
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => None
|
_ => {
|
||||||
|
self.expected_tokens.push(TokenType::Lifetime);
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3953,7 +3991,7 @@ impl<'a> Parser<'a> {
|
||||||
"`?` may only modify trait bounds, not lifetime bounds");
|
"`?` may only modify trait bounds, not lifetime bounds");
|
||||||
}
|
}
|
||||||
bounds.push(RegionTyParamBound(lifetime));
|
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 poly_trait_ref = self.parse_poly_trait_ref()?;
|
||||||
let modifier = if question.is_some() {
|
let modifier = if question.is_some() {
|
||||||
TraitBoundModifier::Maybe
|
TraitBoundModifier::Maybe
|
||||||
|
@ -3963,7 +4001,7 @@ impl<'a> Parser<'a> {
|
||||||
bounds.push(TraitTyParamBound(poly_trait_ref, modifier));
|
bounds.push(TraitTyParamBound(poly_trait_ref, modifier));
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}}
|
||||||
|
|
||||||
// Trailing plus is not allowed for now and we have to detect it.
|
// Trailing plus is not allowed for now and we have to detect it.
|
||||||
let is_bound_start = |token: &token::Token| {
|
let is_bound_start = |token: &token::Token| {
|
||||||
|
@ -4047,7 +4085,7 @@ impl<'a> Parser<'a> {
|
||||||
self.span_err(self.prev_span,
|
self.span_err(self.prev_span,
|
||||||
"lifetime parameters must be declared prior to type parameters");
|
"lifetime parameters must be declared prior to type parameters");
|
||||||
}
|
}
|
||||||
} else if self.token.is_ident() {
|
} else {if self.check_ident() {
|
||||||
// Parse type parameter.
|
// Parse type parameter.
|
||||||
ty_params.push(self.parse_ty_param(attrs)?);
|
ty_params.push(self.parse_ty_param(attrs)?);
|
||||||
seen_ty_param = true;
|
seen_ty_param = true;
|
||||||
|
@ -4059,7 +4097,7 @@ impl<'a> Parser<'a> {
|
||||||
&format!("trailing attribute after {} parameters", param_kind));
|
&format!("trailing attribute after {} parameters", param_kind));
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}}
|
||||||
|
|
||||||
if !self.eat(&token::Comma) {
|
if !self.eat(&token::Comma) {
|
||||||
break
|
break
|
||||||
|
@ -4105,7 +4143,6 @@ impl<'a> Parser<'a> {
|
||||||
let mut seen_type = false;
|
let mut seen_type = false;
|
||||||
let mut seen_binding = false;
|
let mut seen_binding = false;
|
||||||
loop {
|
loop {
|
||||||
let eq_is_next = self.look_ahead(1, |t| t == &token::Eq); // borrowck workaround
|
|
||||||
if let Some(lifetime) = self.eat_lifetime() {
|
if let Some(lifetime) = self.eat_lifetime() {
|
||||||
// Parse lifetime argument.
|
// Parse lifetime argument.
|
||||||
lifetimes.push(lifetime);
|
lifetimes.push(lifetime);
|
||||||
|
@ -4113,7 +4150,7 @@ impl<'a> Parser<'a> {
|
||||||
self.span_err(self.prev_span,
|
self.span_err(self.prev_span,
|
||||||
"lifetime parameters must be declared prior to type parameters");
|
"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.
|
// Parse associated type binding.
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
let ident = self.parse_ident()?;
|
let ident = self.parse_ident()?;
|
||||||
|
@ -4126,7 +4163,7 @@ impl<'a> Parser<'a> {
|
||||||
span: mk_sp(lo, self.prev_span.hi),
|
span: mk_sp(lo, self.prev_span.hi),
|
||||||
});
|
});
|
||||||
seen_binding = true;
|
seen_binding = true;
|
||||||
} else if self.token.can_begin_type() {
|
} else if self.check_type() {
|
||||||
// Parse type argument.
|
// Parse type argument.
|
||||||
types.push(self.parse_ty()?);
|
types.push(self.parse_ty()?);
|
||||||
if seen_binding {
|
if seen_binding {
|
||||||
|
@ -4136,7 +4173,7 @@ impl<'a> Parser<'a> {
|
||||||
seen_type = true;
|
seen_type = true;
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}}
|
||||||
|
|
||||||
if !self.eat(&token::Comma) {
|
if !self.eat(&token::Comma) {
|
||||||
break
|
break
|
||||||
|
@ -4192,7 +4229,7 @@ impl<'a> Parser<'a> {
|
||||||
bounds: bounds,
|
bounds: bounds,
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
} else if self.token.can_begin_type() {
|
} else {if self.check_type() {
|
||||||
// Parse optional `for<'a, 'b>`.
|
// Parse optional `for<'a, 'b>`.
|
||||||
// This `for` is parsed greedily and applies to the whole predicate,
|
// This `for` is parsed greedily and applies to the whole predicate,
|
||||||
// the bounded type can have its own `for` applying only to it.
|
// the bounded type can have its own `for` applying only to it.
|
||||||
|
@ -4230,7 +4267,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}}
|
||||||
|
|
||||||
if !self.eat(&token::Comma) {
|
if !self.eat(&token::Comma) {
|
||||||
break
|
break
|
||||||
|
|
|
@ -22,7 +22,7 @@ type Type_1_<'a, T> = &'a T;
|
||||||
//type Type_2 = Type_1_<'static ()>; // error: expected `,` or `>` after lifetime name, found `(`
|
//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_4<T> = Type_1_<'static,, T>; // error: expected type, found `,`
|
||||||
|
|
|
@ -25,7 +25,8 @@ type Type_1_<'a, T> = &'a T;
|
||||||
//type Type_3<T> = Box<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, ()>;
|
||||||
|
|
|
@ -31,7 +31,8 @@ type Type_1_<'a, T> = &'a T;
|
||||||
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_6 = Type_5_<'a,,>; // error: expected type, found `,`
|
||||||
|
|
|
@ -34,7 +34,8 @@ type Type_5_<'a> = Type_1_<'a, ()>;
|
||||||
//type Type_5<'a> = Type_1_<'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_7 = Box<(),,>; // error: expected type, found `,`
|
||||||
|
|
|
@ -37,7 +37,7 @@ type Type_5_<'a> = Type_1_<'a, ()>;
|
||||||
//type Type_6 = Type_5_<'a,,>; // 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_8<'a,,> = &'a (); // error: expected ident, found `,`
|
||||||
|
|
|
@ -40,7 +40,7 @@ type Type_5_<'a> = Type_1_<'a, ()>;
|
||||||
//type Type_7 = Box<(),,>; // error: expected type, 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_9<T,,> = Box<T>; // error: expected identifier, found `,`
|
||||||
|
|
|
@ -43,4 +43,4 @@ type Type_5_<'a> = Type_1_<'a, ()>;
|
||||||
//type Type_8<'a,,> = &'a (); // 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 `,`
|
||||||
|
|
|
@ -10,6 +10,6 @@
|
||||||
|
|
||||||
// compile-flags: -Z parse-only
|
// 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() {}
|
fn main() {}
|
||||||
|
|
|
@ -10,6 +10,6 @@
|
||||||
|
|
||||||
// compile-flags: -Z parse-only
|
// 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() {}
|
fn main() {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue