syntax: Make is_path_start
precise and improve some error messages about unexpected tokens
This commit is contained in:
parent
6c44bea644
commit
a97f60ee86
@ -394,6 +394,17 @@ impl<'a> Parser<'a> {
|
|||||||
Parser::token_to_string(&self.token)
|
Parser::token_to_string(&self.token)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn this_token_descr(&self) -> String {
|
||||||
|
let s = self.this_token_to_string();
|
||||||
|
if self.token.is_strict_keyword() {
|
||||||
|
format!("keyword `{}`", s)
|
||||||
|
} else if self.token.is_reserved_keyword() {
|
||||||
|
format!("reserved keyword `{}`", s)
|
||||||
|
} else {
|
||||||
|
format!("`{}`", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
|
pub fn unexpected_last<T>(&self, t: &token::Token) -> PResult<'a, T> {
|
||||||
let token_str = Parser::token_to_string(t);
|
let token_str = Parser::token_to_string(t);
|
||||||
let last_span = self.last_span;
|
let last_span = self.last_span;
|
||||||
@ -1466,7 +1477,7 @@ impl<'a> Parser<'a> {
|
|||||||
self.parse_qualified_path(PathStyle::Type)?;
|
self.parse_qualified_path(PathStyle::Type)?;
|
||||||
|
|
||||||
TyKind::Path(Some(qself), path)
|
TyKind::Path(Some(qself), path)
|
||||||
} else if self.is_path_start() {
|
} else if self.token.is_path_start() {
|
||||||
let path = self.parse_path(PathStyle::Type)?;
|
let path = self.parse_path(PathStyle::Type)?;
|
||||||
if self.check(&token::Not) {
|
if self.check(&token::Not) {
|
||||||
// MACRO INVOCATION
|
// MACRO INVOCATION
|
||||||
@ -1485,9 +1496,8 @@ impl<'a> Parser<'a> {
|
|||||||
// TYPE TO BE INFERRED
|
// TYPE TO BE INFERRED
|
||||||
TyKind::Infer
|
TyKind::Infer
|
||||||
} else {
|
} else {
|
||||||
let this_token_str = self.this_token_to_string();
|
let msg = format!("expected type, found {}", self.this_token_descr());
|
||||||
let msg = format!("expected type, found `{}`", this_token_str);
|
return Err(self.fatal(&msg));
|
||||||
return Err(self.fatal(&msg[..]));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let sp = mk_sp(lo, self.last_span.hi);
|
let sp = mk_sp(lo, self.last_span.hi);
|
||||||
@ -1604,12 +1614,12 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Matches token_lit = LIT_INTEGER | ...
|
/// Matches token_lit = LIT_INTEGER | ...
|
||||||
pub fn lit_from_token(&self, tok: &token::Token) -> PResult<'a, LitKind> {
|
pub fn parse_lit_token(&mut self) -> PResult<'a, LitKind> {
|
||||||
match *tok {
|
let out = match self.token {
|
||||||
token::Interpolated(token::NtExpr(ref v)) => {
|
token::Interpolated(token::NtExpr(ref v)) => {
|
||||||
match v.node {
|
match v.node {
|
||||||
ExprKind::Lit(ref lit) => { Ok(lit.node.clone()) }
|
ExprKind::Lit(ref lit) => { lit.node.clone() }
|
||||||
_ => { return self.unexpected_last(tok); }
|
_ => { return self.unexpected_last(&self.token); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
token::Literal(lit, suf) => {
|
token::Literal(lit, suf) => {
|
||||||
@ -1624,13 +1634,13 @@ impl<'a> Parser<'a> {
|
|||||||
(false, parse::integer_lit(&s.as_str(),
|
(false, parse::integer_lit(&s.as_str(),
|
||||||
suf.as_ref().map(|s| s.as_str()),
|
suf.as_ref().map(|s| s.as_str()),
|
||||||
&self.sess.span_diagnostic,
|
&self.sess.span_diagnostic,
|
||||||
self.last_span))
|
self.span))
|
||||||
}
|
}
|
||||||
token::Float(s) => {
|
token::Float(s) => {
|
||||||
(false, parse::float_lit(&s.as_str(),
|
(false, parse::float_lit(&s.as_str(),
|
||||||
suf.as_ref().map(|s| s.as_str()),
|
suf.as_ref().map(|s| s.as_str()),
|
||||||
&self.sess.span_diagnostic,
|
&self.sess.span_diagnostic,
|
||||||
self.last_span))
|
self.span))
|
||||||
}
|
}
|
||||||
|
|
||||||
token::Str_(s) => {
|
token::Str_(s) => {
|
||||||
@ -1652,15 +1662,18 @@ impl<'a> Parser<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if suffix_illegal {
|
if suffix_illegal {
|
||||||
let sp = self.last_span;
|
let sp = self.span;
|
||||||
self.expect_no_suffix(sp, &format!("{} literal", lit.short_name()), suf)
|
self.expect_no_suffix(sp, &format!("{} literal", lit.short_name()), suf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
_ => { return self.unexpected_last(&self.token); }
|
||||||
|
};
|
||||||
|
|
||||||
|
self.bump();
|
||||||
Ok(out)
|
Ok(out)
|
||||||
}
|
}
|
||||||
_ => { return self.unexpected_last(tok); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Matches lit = true | false | token_lit
|
/// Matches lit = true | false | token_lit
|
||||||
pub fn parse_lit(&mut self) -> PResult<'a, Lit> {
|
pub fn parse_lit(&mut self) -> PResult<'a, Lit> {
|
||||||
@ -1670,8 +1683,7 @@ impl<'a> Parser<'a> {
|
|||||||
} else if self.eat_keyword(keywords::False) {
|
} else if self.eat_keyword(keywords::False) {
|
||||||
LitKind::Bool(false)
|
LitKind::Bool(false)
|
||||||
} else {
|
} else {
|
||||||
let token = self.bump_and_get();
|
let lit = self.parse_lit_token()?;
|
||||||
let lit = self.lit_from_token(&token)?;
|
|
||||||
lit
|
lit
|
||||||
};
|
};
|
||||||
Ok(codemap::Spanned { node: lit, span: mk_sp(lo, self.last_span.hi) })
|
Ok(codemap::Spanned { node: lit, span: mk_sp(lo, self.last_span.hi) })
|
||||||
@ -2338,7 +2350,7 @@ impl<'a> Parser<'a> {
|
|||||||
let mut db = self.fatal("expected expression, found statement (`let`)");
|
let mut db = self.fatal("expected expression, found statement (`let`)");
|
||||||
db.note("variable declaration using `let` is a statement");
|
db.note("variable declaration using `let` is a statement");
|
||||||
return Err(db);
|
return Err(db);
|
||||||
} else if self.is_path_start() {
|
} else if self.token.is_path_start() {
|
||||||
let pth = self.parse_path(PathStyle::Expr)?;
|
let pth = self.parse_path(PathStyle::Expr)?;
|
||||||
|
|
||||||
// `!`, as an operator, is prefix, so we know this isn't that
|
// `!`, as an operator, is prefix, so we know this isn't that
|
||||||
@ -2419,11 +2431,19 @@ impl<'a> Parser<'a> {
|
|||||||
hi = pth.span.hi;
|
hi = pth.span.hi;
|
||||||
ex = ExprKind::Path(None, pth);
|
ex = ExprKind::Path(None, pth);
|
||||||
} else {
|
} else {
|
||||||
// other literal expression
|
match self.parse_lit() {
|
||||||
let lit = self.parse_lit()?;
|
Ok(lit) => {
|
||||||
hi = lit.span.hi;
|
hi = lit.span.hi;
|
||||||
ex = ExprKind::Lit(P(lit));
|
ex = ExprKind::Lit(P(lit));
|
||||||
}
|
}
|
||||||
|
Err(mut err) => {
|
||||||
|
err.cancel();
|
||||||
|
let msg = format!("expected expression, found {}",
|
||||||
|
self.this_token_descr());
|
||||||
|
return Err(self.fatal(&msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3567,7 +3587,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> {
|
fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> {
|
||||||
if self.is_path_start() {
|
if self.token.is_path_start() {
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
let (qself, path) = if self.eat_lt() {
|
let (qself, path) = if self.eat_lt() {
|
||||||
// Parse a qualified path
|
// Parse a qualified path
|
||||||
@ -3585,12 +3605,6 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_path_start(&self) -> bool {
|
|
||||||
(self.token == token::Lt || self.token == token::ModSep
|
|
||||||
|| self.token.is_ident() || self.token.is_path())
|
|
||||||
&& !self.token.is_keyword(keywords::True) && !self.token.is_keyword(keywords::False)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse a pattern.
|
/// Parse a pattern.
|
||||||
pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
|
pub fn parse_pat(&mut self) -> PResult<'a, P<Pat>> {
|
||||||
maybe_whole!(self, NtPat);
|
maybe_whole!(self, NtPat);
|
||||||
@ -3641,7 +3655,7 @@ impl<'a> Parser<'a> {
|
|||||||
// Parse box pat
|
// Parse box pat
|
||||||
let subpat = self.parse_pat()?;
|
let subpat = self.parse_pat()?;
|
||||||
pat = PatKind::Box(subpat);
|
pat = PatKind::Box(subpat);
|
||||||
} else if self.is_path_start() {
|
} else if self.token.is_path_start() {
|
||||||
// Parse pattern starting with a path
|
// Parse pattern starting with a path
|
||||||
if self.token.is_ident() && self.look_ahead(1, |t| *t != token::DotDotDot &&
|
if self.token.is_ident() && self.look_ahead(1, |t| *t != token::DotDotDot &&
|
||||||
*t != token::OpenDelim(token::Brace) &&
|
*t != token::OpenDelim(token::Brace) &&
|
||||||
@ -3731,7 +3745,8 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Try to parse everything else as literal with optional minus
|
// Try to parse everything else as literal with optional minus
|
||||||
let begin = self.parse_pat_literal_maybe_minus()?;
|
match self.parse_pat_literal_maybe_minus() {
|
||||||
|
Ok(begin) => {
|
||||||
if self.eat(&token::DotDotDot) {
|
if self.eat(&token::DotDotDot) {
|
||||||
let end = self.parse_pat_range_end()?;
|
let end = self.parse_pat_range_end()?;
|
||||||
pat = PatKind::Range(begin, end);
|
pat = PatKind::Range(begin, end);
|
||||||
@ -3739,6 +3754,13 @@ impl<'a> Parser<'a> {
|
|||||||
pat = PatKind::Lit(begin);
|
pat = PatKind::Lit(begin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(mut err) => {
|
||||||
|
err.cancel();
|
||||||
|
let msg = format!("expected pattern, found {}", self.this_token_descr());
|
||||||
|
return Err(self.fatal(&msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,6 +243,11 @@ impl Token {
|
|||||||
self.is_keyword(keywords::Const)
|
self.is_keyword(keywords::Const)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_path_start(&self) -> bool {
|
||||||
|
self == &ModSep || self == &Lt || self.is_path() ||
|
||||||
|
self.is_path_segment_keyword() || self.is_ident() && !self.is_any_keyword()
|
||||||
|
}
|
||||||
|
|
||||||
/// Maps a token to its corresponding binary operator.
|
/// Maps a token to its corresponding binary operator.
|
||||||
pub fn to_binop(&self) -> Option<BinOpKind> {
|
pub fn to_binop(&self) -> Option<BinOpKind> {
|
||||||
match *self {
|
match *self {
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
|
|
||||||
// error-pattern:unexpected token
|
|
||||||
fn main() {
|
fn main() {
|
||||||
panic!(@);
|
panic!(@); //~ ERROR expected expression, found `@`
|
||||||
}
|
}
|
||||||
|
@ -15,4 +15,4 @@ pub fn trace_option(option: Option<isize>) {
|
|||||||
option.map(|some| 42; //~ NOTE: unclosed delimiter
|
option.map(|some| 42; //~ NOTE: unclosed delimiter
|
||||||
//~^ ERROR: expected one of
|
//~^ ERROR: expected one of
|
||||||
} //~ ERROR: incorrect close delimiter
|
} //~ ERROR: incorrect close delimiter
|
||||||
//~^ ERROR: unexpected token
|
//~^ ERROR: expected expression, found `)`
|
||||||
|
@ -13,4 +13,4 @@
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let
|
let
|
||||||
} //~ ERROR unexpected token: `}`
|
} //~ ERROR expected pattern, found `}`
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
// (typeof used because it's surprisingly hard to find an unparsed token after a stmt)
|
// (typeof used because it's surprisingly hard to find an unparsed token after a stmt)
|
||||||
macro_rules! m {
|
macro_rules! m {
|
||||||
() => ( i ; typeof ); //~ ERROR `typeof` is a reserved keyword
|
() => ( i ; typeof ); //~ ERROR expected expression, found reserved keyword `typeof`
|
||||||
//~| ERROR macro expansion ignores token `typeof`
|
//~| ERROR macro expansion ignores token `typeof`
|
||||||
//~| ERROR macro expansion ignores token `;`
|
//~| ERROR macro expansion ignores token `;`
|
||||||
//~| ERROR macro expansion ignores token `;`
|
//~| ERROR macro expansion ignores token `;`
|
||||||
|
@ -19,7 +19,7 @@ macro_rules! ignored_item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! ignored_expr {
|
macro_rules! ignored_expr {
|
||||||
() => ( 1, //~ ERROR unexpected token: `,`
|
() => ( 1, //~ ERROR expected expression, found `,`
|
||||||
2 )
|
2 )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,5 +10,5 @@
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let become = 0;
|
let become = 0;
|
||||||
//~^ ERROR `become` is a reserved keyword
|
//~^ ERROR expected pattern, found reserved keyword `become`
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,10 @@
|
|||||||
fn main() {
|
fn main() {
|
||||||
foo(bar(; //~ NOTE: unclosed delimiter
|
foo(bar(; //~ NOTE: unclosed delimiter
|
||||||
//~^ NOTE: unclosed delimiter
|
//~^ NOTE: unclosed delimiter
|
||||||
//~^^ ERROR: unexpected token: `;`
|
//~^^ ERROR: expected expression, found `;`
|
||||||
//~^^^ ERROR: unresolved name `bar`
|
//~^^^ ERROR: unresolved name `bar`
|
||||||
//~^^^^ ERROR: unresolved name `foo`
|
//~^^^^ ERROR: unresolved name `foo`
|
||||||
|
//~^^^^^ ERROR: expected one of `)`, `,`, `.`, `<`, `?`
|
||||||
} //~ ERROR: incorrect close delimiter: `}`
|
} //~ ERROR: incorrect close delimiter: `}`
|
||||||
//~^ ERROR: incorrect close delimiter: `}`
|
//~^ ERROR: incorrect close delimiter: `}`
|
||||||
|
//~^^ ERROR: expected expression, found `)`
|
||||||
|
@ -9,5 +9,5 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
vec!(,); //~ ERROR unexpected token
|
vec!(,); //~ ERROR expected expression, found `,`
|
||||||
}
|
}
|
||||||
|
@ -12,4 +12,4 @@
|
|||||||
|
|
||||||
fn bar<'a, T>(x: mymodule::X<'a, T, 'b, 'c>) {}
|
fn bar<'a, T>(x: mymodule::X<'a, T, 'b, 'c>) {}
|
||||||
//~^ ERROR lifetime parameters must be declared prior to type parameters
|
//~^ ERROR lifetime parameters must be declared prior to type parameters
|
||||||
//~^^ ERROR unexpected token
|
//~^^ ERROR expected pattern, found `'c`
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// compile-flags: -Z parse-only -Z continue-parse-after-error
|
// compile-flags: -Z parse-only -Z continue-parse-after-error
|
||||||
|
|
||||||
pub fn test() {
|
pub fn test() {
|
||||||
foo(|_|) //~ ERROR unexpected token: `)`
|
foo(|_|) //~ ERROR expected expression, found `)`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
@ -11,5 +11,5 @@
|
|||||||
// compile-flags: -Z parse-only
|
// compile-flags: -Z parse-only
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let abstract = (); //~ ERROR `abstract` is a reserved keyword
|
let abstract = (); //~ ERROR expected pattern, found reserved keyword `abstract`
|
||||||
}
|
}
|
||||||
|
@ -11,5 +11,5 @@
|
|||||||
// compile-flags: -Z parse-only
|
// compile-flags: -Z parse-only
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let final = (); //~ ERROR `final` is a reserved keyword
|
let final = (); //~ ERROR expected pattern, found reserved keyword `final`
|
||||||
}
|
}
|
||||||
|
@ -11,5 +11,5 @@
|
|||||||
// compile-flags: -Z parse-only
|
// compile-flags: -Z parse-only
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let override = (); //~ ERROR `override` is a reserved keyword
|
let override = (); //~ ERROR expected pattern, found reserved keyword `override`
|
||||||
}
|
}
|
||||||
|
@ -11,5 +11,5 @@
|
|||||||
// compile-flags: -Z parse-only
|
// compile-flags: -Z parse-only
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let typeof = (); //~ ERROR `typeof` is a reserved keyword
|
let typeof = (); //~ ERROR expected pattern, found reserved keyword `typeof`
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,5 @@
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
struct::foo(); //~ ERROR expected identifier
|
struct::foo(); //~ ERROR expected identifier
|
||||||
mut::baz(); //~ ERROR expected identifier
|
mut::baz(); //~ ERROR expected expression, found keyword `mut`
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,6 @@ fn main() {
|
|||||||
|
|
||||||
match 0 {
|
match 0 {
|
||||||
0 => {
|
0 => {
|
||||||
} + 5 //~ ERROR unexpected token: `+`
|
} + 5 //~ ERROR expected pattern, found `+`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,8 @@
|
|||||||
|
|
||||||
// Test that we generate obsolete syntax errors around usages of `proc`.
|
// Test that we generate obsolete syntax errors around usages of `proc`.
|
||||||
|
|
||||||
fn foo(p: proc()) { } //~ ERROR `proc` is a reserved keyword
|
fn foo(p: proc()) { } //~ ERROR expected type, found reserved keyword `proc`
|
||||||
|
|
||||||
fn bar() { proc() 1; } //~ ERROR `proc` is a reserved keyword
|
fn bar() { proc() 1; } //~ ERROR expected expression, found reserved keyword `proc`
|
||||||
//~^ ERROR expected
|
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
@ -10,4 +10,4 @@
|
|||||||
|
|
||||||
// compile-flags: -Z parse-only
|
// compile-flags: -Z parse-only
|
||||||
|
|
||||||
fn f(+x: isize) {} //~ ERROR unexpected token: `+`
|
fn f(+x: isize) {} //~ ERROR expected pattern, found `+`
|
||||||
|
@ -11,7 +11,5 @@
|
|||||||
// compile-flags: -Z parse-only
|
// compile-flags: -Z parse-only
|
||||||
|
|
||||||
fn f() {
|
fn f() {
|
||||||
let v = [mut 1, 2, 3, 4];
|
let v = [mut 1, 2, 3, 4]; //~ ERROR expected expression, found keyword `mut`
|
||||||
//~^ ERROR expected identifier, found keyword `mut`
|
|
||||||
//~^^ ERROR expected one of `!`, `,`, `.`, `::`, `;`, `?`, `]`, `{`, or an operator, found `1`
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,4 @@
|
|||||||
|
|
||||||
// compile-flags: -Z parse-only
|
// compile-flags: -Z parse-only
|
||||||
|
|
||||||
type v = [mut isize];
|
type v = [mut isize]; //~ ERROR expected type, found keyword `mut`
|
||||||
//~^ ERROR expected identifier, found keyword `mut`
|
|
||||||
//~^^ ERROR expected one of `!`, `(`, `+`, `::`, `;`, `<`, or `]`, found `isize`
|
|
||||||
|
@ -11,7 +11,5 @@
|
|||||||
// compile-flags: -Z parse-only
|
// compile-flags: -Z parse-only
|
||||||
|
|
||||||
fn f() {
|
fn f() {
|
||||||
let a_box = box mut 42;
|
let a_box = box mut 42; //~ ERROR expected expression, found keyword `mut`
|
||||||
//~^ ERROR expected identifier, found keyword `mut`
|
|
||||||
//~^^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, or an operator, found `42`
|
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,4 @@
|
|||||||
|
|
||||||
// compile-flags: -Z parse-only
|
// compile-flags: -Z parse-only
|
||||||
|
|
||||||
type mut_box = Box<mut isize>;
|
type mut_box = Box<mut isize>; //~ ERROR expected type, found keyword `mut`
|
||||||
//~^ ERROR expected identifier, found keyword `mut`
|
|
||||||
//~^^ ERROR expected one of `!`, `(`, `+`, `,`, `::`, `<`, or `>`, found `isize`
|
|
||||||
|
@ -15,8 +15,5 @@
|
|||||||
fn f<X>() {}
|
fn f<X>() {}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
f<type>();
|
f<type>(); //~ ERROR expected expression, found keyword `type`
|
||||||
//~^ ERROR expected identifier, found keyword `type`
|
|
||||||
//~^^ ERROR: chained comparison
|
|
||||||
//~^^^ HELP: use `::<
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user