Rollup merge of #65640 - estebank:recover-missing-semi, r=Centril
Use heuristics to recover parsing of missing `;` - Detect `,` and `:` typos where `;` was intended. - When the next token could have been the start of a new statement, detect a missing semicolon. Fix #48160, fix #44767 (after adding note about statements).
This commit is contained in:
commit
2fe6f22dea
36 changed files with 175 additions and 157 deletions
|
|
@ -6,7 +6,7 @@ use crate::ast::{
|
|||
self, Param, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind,
|
||||
Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind,
|
||||
};
|
||||
use crate::parse::token::{self, TokenKind};
|
||||
use crate::parse::token::{self, TokenKind, token_can_begin_expr};
|
||||
use crate::print::pprust;
|
||||
use crate::ptr::P;
|
||||
use crate::symbol::{kw, sym};
|
||||
|
|
@ -274,23 +274,23 @@ impl<'a> Parser<'a> {
|
|||
expected.sort_by_cached_key(|x| x.to_string());
|
||||
expected.dedup();
|
||||
let expect = tokens_to_string(&expected[..]);
|
||||
let actual = self.this_token_to_string();
|
||||
let actual = self.this_token_descr();
|
||||
let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 {
|
||||
let short_expect = if expected.len() > 6 {
|
||||
format!("{} possible tokens", expected.len())
|
||||
} else {
|
||||
expect.clone()
|
||||
};
|
||||
(format!("expected one of {}, found `{}`", expect, actual),
|
||||
(format!("expected one of {}, found {}", expect, actual),
|
||||
(self.sess.source_map().next_point(self.prev_span),
|
||||
format!("expected one of {} here", short_expect)))
|
||||
} else if expected.is_empty() {
|
||||
(format!("unexpected token: `{}`", actual),
|
||||
(format!("unexpected token: {}", actual),
|
||||
(self.prev_span, "unexpected token after this".to_string()))
|
||||
} else {
|
||||
(format!("expected {}, found `{}`", expect, actual),
|
||||
(format!("expected {}, found {}", expect, actual),
|
||||
(self.sess.source_map().next_point(self.prev_span),
|
||||
format!("expected {} here", expect)))
|
||||
format!("expected {}", expect)))
|
||||
};
|
||||
self.last_unexpected_token_span = Some(self.token.span);
|
||||
let mut err = self.fatal(&msg_exp);
|
||||
|
|
@ -326,58 +326,28 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
let is_semi_suggestable = expected.iter().any(|t| match t {
|
||||
TokenType::Token(token::Semi) => true, // We expect a `;` here.
|
||||
_ => false,
|
||||
}) && ( // A `;` would be expected before the current keyword.
|
||||
self.token.is_keyword(kw::Break) ||
|
||||
self.token.is_keyword(kw::Continue) ||
|
||||
self.token.is_keyword(kw::For) ||
|
||||
self.token.is_keyword(kw::If) ||
|
||||
self.token.is_keyword(kw::Let) ||
|
||||
self.token.is_keyword(kw::Loop) ||
|
||||
self.token.is_keyword(kw::Match) ||
|
||||
self.token.is_keyword(kw::Return) ||
|
||||
self.token.is_keyword(kw::While)
|
||||
);
|
||||
let sm = self.sess.source_map();
|
||||
match (sm.lookup_line(self.token.span.lo()), sm.lookup_line(sp.lo())) {
|
||||
(Ok(ref a), Ok(ref b)) if a.line != b.line && is_semi_suggestable => {
|
||||
// The spans are in different lines, expected `;` and found `let` or `return`.
|
||||
// High likelihood that it is only a missing `;`.
|
||||
err.span_suggestion_short(
|
||||
label_sp,
|
||||
"a semicolon may be missing here",
|
||||
";".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.emit();
|
||||
return Ok(true);
|
||||
}
|
||||
(Ok(ref a), Ok(ref b)) if a.line == b.line => {
|
||||
// When the spans are in the same line, it means that the only content between
|
||||
// them is whitespace, point at the found token in that case:
|
||||
//
|
||||
// X | () => { syntax error };
|
||||
// | ^^^^^ expected one of 8 possible tokens here
|
||||
//
|
||||
// instead of having:
|
||||
//
|
||||
// X | () => { syntax error };
|
||||
// | -^^^^^ unexpected token
|
||||
// | |
|
||||
// | expected one of 8 possible tokens here
|
||||
err.span_label(self.token.span, label_exp);
|
||||
}
|
||||
_ if self.prev_span == syntax_pos::DUMMY_SP => {
|
||||
// Account for macro context where the previous span might not be
|
||||
// available to avoid incorrect output (#54841).
|
||||
err.span_label(self.token.span, "unexpected token");
|
||||
}
|
||||
_ => {
|
||||
err.span_label(sp, label_exp);
|
||||
err.span_label(self.token.span, "unexpected token");
|
||||
}
|
||||
if self.prev_span == DUMMY_SP {
|
||||
// Account for macro context where the previous span might not be
|
||||
// available to avoid incorrect output (#54841).
|
||||
err.span_label(self.token.span, label_exp);
|
||||
} else if !sm.is_multiline(self.token.span.shrink_to_hi().until(sp.shrink_to_lo())) {
|
||||
// When the spans are in the same line, it means that the only content between
|
||||
// them is whitespace, point at the found token in that case:
|
||||
//
|
||||
// X | () => { syntax error };
|
||||
// | ^^^^^ expected one of 8 possible tokens here
|
||||
//
|
||||
// instead of having:
|
||||
//
|
||||
// X | () => { syntax error };
|
||||
// | -^^^^^ unexpected token
|
||||
// | |
|
||||
// | expected one of 8 possible tokens here
|
||||
err.span_label(self.token.span, label_exp);
|
||||
} else {
|
||||
err.span_label(sp, label_exp);
|
||||
err.span_label(self.token.span, "unexpected token");
|
||||
}
|
||||
self.maybe_annotate_with_ascription(&mut err, false);
|
||||
Err(err)
|
||||
|
|
@ -902,20 +872,64 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
let sm = self.sess.source_map();
|
||||
match (sm.lookup_line(prev_sp.lo()), sm.lookup_line(sp.lo())) {
|
||||
(Ok(ref a), Ok(ref b)) if a.line == b.line => {
|
||||
// When the spans are in the same line, it means that the only content
|
||||
// between them is whitespace, point only at the found token.
|
||||
err.span_label(sp, label_exp);
|
||||
}
|
||||
_ => {
|
||||
err.span_label(prev_sp, label_exp);
|
||||
err.span_label(sp, "unexpected token");
|
||||
}
|
||||
if !sm.is_multiline(prev_sp.until(sp)) {
|
||||
// When the spans are in the same line, it means that the only content
|
||||
// between them is whitespace, point only at the found token.
|
||||
err.span_label(sp, label_exp);
|
||||
} else {
|
||||
err.span_label(prev_sp, label_exp);
|
||||
err.span_label(sp, "unexpected token");
|
||||
}
|
||||
Err(err)
|
||||
}
|
||||
|
||||
pub(super) fn expect_semi(&mut self) -> PResult<'a, ()> {
|
||||
if self.eat(&token::Semi) {
|
||||
return Ok(());
|
||||
}
|
||||
let sm = self.sess.source_map();
|
||||
let msg = format!("expected `;`, found `{}`", self.this_token_descr());
|
||||
let appl = Applicability::MachineApplicable;
|
||||
if self.token.span == DUMMY_SP || self.prev_span == DUMMY_SP {
|
||||
// Likely inside a macro, can't provide meaninful suggestions.
|
||||
return self.expect(&token::Semi).map(|_| ());
|
||||
} else if !sm.is_multiline(self.prev_span.until(self.token.span)) {
|
||||
// The current token is in the same line as the prior token, not recoverable.
|
||||
} else if self.look_ahead(1, |t| t == &token::CloseDelim(token::Brace)
|
||||
|| token_can_begin_expr(t) && t.kind != token::Colon
|
||||
) && [token::Comma, token::Colon].contains(&self.token.kind) {
|
||||
// Likely typo: `,` → `;` or `:` → `;`. This is triggered if the current token is
|
||||
// either `,` or `:`, and the next token could either start a new statement or is a
|
||||
// block close. For example:
|
||||
//
|
||||
// let x = 32:
|
||||
// let y = 42;
|
||||
self.bump();
|
||||
let sp = self.prev_span;
|
||||
self.struct_span_err(sp, &msg)
|
||||
.span_suggestion(sp, "change this to `;`", ";".to_string(), appl)
|
||||
.emit();
|
||||
return Ok(())
|
||||
} else if self.look_ahead(0, |t| t == &token::CloseDelim(token::Brace) || (
|
||||
token_can_begin_expr(t)
|
||||
&& t != &token::Semi
|
||||
&& t != &token::Pound // Avoid triggering with too many trailing `#` in raw string.
|
||||
)) {
|
||||
// Missing semicolon typo. This is triggered if the next token could either start a
|
||||
// new statement or is a block close. For example:
|
||||
//
|
||||
// let x = 32
|
||||
// let y = 42;
|
||||
let sp = self.prev_span.shrink_to_hi();
|
||||
self.struct_span_err(sp, &msg)
|
||||
.span_label(self.token.span, "unexpected token")
|
||||
.span_suggestion_short(sp, "add `;` here", ";".to_string(), appl)
|
||||
.emit();
|
||||
return Ok(())
|
||||
}
|
||||
self.expect(&token::Semi).map(|_| ()) // Error unconditionally
|
||||
}
|
||||
|
||||
pub(super) fn parse_semi_or_incorrect_foreign_fn_body(
|
||||
&mut self,
|
||||
ident: &Ident,
|
||||
|
|
@ -943,7 +957,7 @@ impl<'a> Parser<'a> {
|
|||
Err(mut err) => {
|
||||
err.cancel();
|
||||
mem::replace(self, parser_snapshot);
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ impl<'a> Parser<'a> {
|
|||
if self.eat_keyword(kw::Use) {
|
||||
// USE ITEM
|
||||
let item_ = ItemKind::Use(P(self.parse_use_tree()?));
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
|
||||
let span = lo.to(self.prev_span);
|
||||
let item = self.mk_item(span, Ident::invalid(), item_, vis, attrs);
|
||||
|
|
@ -526,7 +526,7 @@ impl<'a> Parser<'a> {
|
|||
// eat a matched-delimiter token tree:
|
||||
let (delim, tts) = self.expect_delimited_token_tree()?;
|
||||
if delim != MacDelimiter::Brace {
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
}
|
||||
|
||||
Ok(Some(Mac {
|
||||
|
|
@ -776,7 +776,7 @@ impl<'a> Parser<'a> {
|
|||
let typ = self.parse_ty()?;
|
||||
self.expect(&token::Eq)?;
|
||||
let expr = self.parse_expr()?;
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
Ok((name, ImplItemKind::Const(typ, expr), Generics::default()))
|
||||
}
|
||||
|
||||
|
|
@ -813,7 +813,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
let bounds = self.parse_generic_bounds(None)?;
|
||||
tps.where_clause = self.parse_where_clause()?;
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
|
||||
let whole_span = lo.to(self.prev_span);
|
||||
if is_auto == IsAuto::Yes {
|
||||
|
|
@ -927,7 +927,7 @@ impl<'a> Parser<'a> {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
Ok((ident, TraitItemKind::Const(ty, default), Generics::default()))
|
||||
}
|
||||
|
||||
|
|
@ -951,7 +951,7 @@ impl<'a> Parser<'a> {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
|
||||
Ok((ident, TraitItemKind::Type(bounds, default), generics))
|
||||
}
|
||||
|
|
@ -1054,7 +1054,7 @@ impl<'a> Parser<'a> {
|
|||
} else {
|
||||
(orig_name, None)
|
||||
};
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
|
||||
let span = lo.to(self.prev_span);
|
||||
Ok(self.mk_item(span, item_name, ItemKind::ExternCrate(orig_name), visibility, attrs))
|
||||
|
|
@ -1217,7 +1217,7 @@ impl<'a> Parser<'a> {
|
|||
self.expect(&token::Colon)?;
|
||||
let ty = self.parse_ty()?;
|
||||
let hi = self.token.span;
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
Ok(ForeignItem {
|
||||
ident,
|
||||
attrs,
|
||||
|
|
@ -1235,7 +1235,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
let ident = self.parse_ident()?;
|
||||
let hi = self.token.span;
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
Ok(ast::ForeignItem {
|
||||
ident,
|
||||
attrs,
|
||||
|
|
@ -1282,7 +1282,7 @@ impl<'a> Parser<'a> {
|
|||
|
||||
self.expect(&token::Eq)?;
|
||||
let e = self.parse_expr()?;
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
let item = match m {
|
||||
Some(m) => ItemKind::Static(ty, m, e),
|
||||
None => ItemKind::Const(ty, e),
|
||||
|
|
@ -1344,7 +1344,7 @@ impl<'a> Parser<'a> {
|
|||
let ty = self.parse_ty()?;
|
||||
AliasKind::Weak(ty)
|
||||
};
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
Ok((ident, alias, tps))
|
||||
}
|
||||
|
||||
|
|
@ -1468,7 +1468,7 @@ impl<'a> Parser<'a> {
|
|||
} else if self.token == token::OpenDelim(token::Paren) {
|
||||
let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
|
||||
generics.where_clause = self.parse_where_clause()?;
|
||||
self.expect(&token::Semi)?;
|
||||
self.expect_semi()?;
|
||||
body
|
||||
} else {
|
||||
let token_str = self.this_token_descr();
|
||||
|
|
|
|||
|
|
@ -432,6 +432,7 @@ impl<'a> Parser<'a> {
|
|||
None => return Ok(None),
|
||||
};
|
||||
|
||||
let mut eat_semi = true;
|
||||
match stmt.kind {
|
||||
StmtKind::Expr(ref expr) if self.token != token::Eof => {
|
||||
// expression without semicolon
|
||||
|
|
@ -453,13 +454,14 @@ impl<'a> Parser<'a> {
|
|||
if macro_legacy_warnings && self.token != token::Semi {
|
||||
self.warn_missing_semicolon();
|
||||
} else {
|
||||
self.expect_one_of(&[], &[token::Semi])?;
|
||||
self.expect_semi()?;
|
||||
eat_semi = false;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.eat(&token::Semi) {
|
||||
if eat_semi && self.eat(&token::Semi) {
|
||||
stmt = stmt.add_trailing_semicolon();
|
||||
}
|
||||
stmt.span = stmt.span.to(self.prev_span);
|
||||
|
|
|
|||
|
|
@ -143,34 +143,35 @@ impl Lit {
|
|||
|
||||
pub(crate) fn ident_can_begin_expr(name: ast::Name, span: Span, is_raw: bool) -> bool {
|
||||
let ident_token = Token::new(Ident(name, is_raw), span);
|
||||
token_can_begin_expr(&ident_token)
|
||||
}
|
||||
|
||||
pub(crate) fn token_can_begin_expr(ident_token: &Token) -> bool {
|
||||
!ident_token.is_reserved_ident() ||
|
||||
ident_token.is_path_segment_keyword() ||
|
||||
[
|
||||
kw::Async,
|
||||
|
||||
// FIXME: remove when `await!(..)` syntax is removed
|
||||
// https://github.com/rust-lang/rust/issues/60610
|
||||
kw::Await,
|
||||
|
||||
kw::Do,
|
||||
kw::Box,
|
||||
kw::Break,
|
||||
kw::Continue,
|
||||
kw::False,
|
||||
kw::For,
|
||||
kw::If,
|
||||
kw::Let,
|
||||
kw::Loop,
|
||||
kw::Match,
|
||||
kw::Move,
|
||||
kw::Return,
|
||||
kw::True,
|
||||
kw::Unsafe,
|
||||
kw::While,
|
||||
kw::Yield,
|
||||
kw::Static,
|
||||
].contains(&name)
|
||||
match ident_token.kind {
|
||||
TokenKind::Ident(ident, _) => [
|
||||
kw::Async,
|
||||
kw::Do,
|
||||
kw::Box,
|
||||
kw::Break,
|
||||
kw::Continue,
|
||||
kw::False,
|
||||
kw::For,
|
||||
kw::If,
|
||||
kw::Let,
|
||||
kw::Loop,
|
||||
kw::Match,
|
||||
kw::Move,
|
||||
kw::Return,
|
||||
kw::True,
|
||||
kw::Unsafe,
|
||||
kw::While,
|
||||
kw::Yield,
|
||||
kw::Static,
|
||||
].contains(&ident),
|
||||
_=> false,
|
||||
}
|
||||
}
|
||||
|
||||
fn ident_can_begin_type(name: ast::Name, span: Span, is_raw: bool) -> bool {
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@
|
|||
// compile-flags: --crate-type lib
|
||||
|
||||
pub async const fn x() {}
|
||||
//~^ ERROR expected one of `fn` or `unsafe`, found `const`
|
||||
//~^ ERROR expected one of `fn` or `unsafe`, found keyword `const`
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: expected one of `fn` or `unsafe`, found `const`
|
||||
error: expected one of `fn` or `unsafe`, found keyword `const`
|
||||
--> $DIR/no-async-const.rs:5:11
|
||||
|
|
||||
LL | pub async const fn x() {}
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ struct S;
|
|||
|
||||
impl S {
|
||||
#[cfg(FALSE)]
|
||||
unsafe async fn g() {} //~ ERROR expected one of `extern` or `fn`, found `async`
|
||||
unsafe async fn g() {} //~ ERROR expected one of `extern` or `fn`, found keyword `async`
|
||||
}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
unsafe async fn f() {} //~ ERROR expected one of `extern`, `fn`, or `{`, found `async`
|
||||
unsafe async fn f() {} //~ ERROR expected one of `extern`, `fn`, or `{`, found keyword `async`
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
error: expected one of `extern` or `fn`, found `async`
|
||||
error: expected one of `extern` or `fn`, found keyword `async`
|
||||
--> $DIR/no-unsafe-async.rs:7:12
|
||||
|
|
||||
LL | unsafe async fn g() {}
|
||||
| ^^^^^ expected one of `extern` or `fn` here
|
||||
|
||||
error: expected one of `extern`, `fn`, or `{`, found `async`
|
||||
error: expected one of `extern`, `fn`, or `{`, found keyword `async`
|
||||
--> $DIR/no-unsafe-async.rs:11:8
|
||||
|
|
||||
LL | unsafe async fn f() {}
|
||||
|
|
|
|||
|
|
@ -16,5 +16,5 @@ pub fn main() {
|
|||
return break as ();
|
||||
}
|
||||
|
||||
return enum; //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `enum`
|
||||
return enum; //~ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found keyword `enum`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `enum`
|
||||
error: expected one of `.`, `;`, `?`, `}`, or an operator, found keyword `enum`
|
||||
--> $DIR/can-begin-expr-check.rs:19:12
|
||||
|
|
||||
LL | return enum;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ error: expected `|`, found `}`
|
|||
--> $DIR/issue-43196.rs:3:1
|
||||
|
|
||||
LL | |
|
||||
| - expected `|` here
|
||||
| - expected `|`
|
||||
LL | }
|
||||
| ^ unexpected token
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ error: expected `fn`, found `::`
|
|||
--> $DIR/keyword-extern-as-identifier-type.rs:1:16
|
||||
|
|
||||
LL | type A = extern::foo::bar;
|
||||
| ^^ expected `fn` here
|
||||
| ^^ expected `fn`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: expected one of `crate`, `fn`, `pub`, `static`, or `type`, found `let`
|
||||
error: expected one of `crate`, `fn`, `pub`, `static`, or `type`, found keyword `let`
|
||||
--> $DIR/issue-54441.rs:3:9
|
||||
|
|
||||
LL | let
|
||||
| ^^^ unexpected token
|
||||
| ^^^ expected one of `crate`, `fn`, `pub`, `static`, or `type` here
|
||||
...
|
||||
LL | m!();
|
||||
| ----- in this macro invocation
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, found `pub`
|
||||
error: expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, found keyword `pub`
|
||||
--> $DIR/default.rs:22:13
|
||||
|
|
||||
LL | default pub fn foo<T: Default>() -> T { T::default() }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: expected one of `(`, `fn`, `static`, or `type`, found `pub`
|
||||
error: expected one of `(`, `fn`, `static`, or `type`, found keyword `pub`
|
||||
--> $DIR/duplicate-visibility.rs:3:9
|
||||
|
|
||||
LL | pub pub fn foo();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Verifies that the expected token errors for `extern crate` are
|
||||
// raised
|
||||
|
||||
extern "C" mod foo; //~ERROR expected one of `fn` or `{`, found `mod`
|
||||
extern "C" mod foo; //~ERROR expected one of `fn` or `{`, found keyword `mod`
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: expected one of `fn` or `{`, found `mod`
|
||||
error: expected one of `fn` or `{`, found keyword `mod`
|
||||
--> $DIR/extern-expected-fn-or-brace.rs:4:12
|
||||
|
|
||||
LL | extern "C" mod foo;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ error: expected `impl`, found `FAIL`
|
|||
--> $DIR/impl-parsing.rs:11:16
|
||||
|
|
||||
LL | default unsafe FAIL
|
||||
| ^^^^ expected `impl` here
|
||||
| ^^^^ expected `impl`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ fn main(){
|
|||
}
|
||||
//~^ NOTE expected one of `.`, `=>`, `?`, or an operator here
|
||||
_ => {}
|
||||
//~^ ERROR expected one of `.`, `=>`, `?`, or an operator, found `_`
|
||||
//~^ ERROR expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_`
|
||||
//~| NOTE unexpected token
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ help: you can escape reserved keywords to use them as identifiers
|
|||
LL | r#return
|
||||
|
|
||||
|
||||
error: expected one of `.`, `=>`, `?`, or an operator, found `_`
|
||||
error: expected one of `.`, `=>`, `?`, or an operator, found reserved identifier `_`
|
||||
--> $DIR/issue-15980.rs:13:9
|
||||
|
|
||||
LL | }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
trait T {
|
||||
extern "Rust" unsafe fn foo(); //~ ERROR expected `fn`, found `unsafe`
|
||||
extern "Rust" unsafe fn foo(); //~ ERROR expected `fn`, found keyword `unsafe`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error: expected `fn`, found `unsafe`
|
||||
error: expected `fn`, found keyword `unsafe`
|
||||
--> $DIR/issue-19398.rs:2:19
|
||||
|
|
||||
LL | extern "Rust" unsafe fn foo();
|
||||
| ^^^^^^ expected `fn` here
|
||||
| ^^^^^^ expected `fn`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
fn main()
|
||||
{
|
||||
let x = 3
|
||||
} //~ ERROR: expected one of `.`, `;`, `?`, or an operator, found `}`
|
||||
let x = 3 //~ ERROR: expected `;`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
error: expected one of `.`, `;`, `?`, or an operator, found `}`
|
||||
--> $DIR/issue-3036.rs:6:1
|
||||
error: expected `;`, found ``}``
|
||||
--> $DIR/issue-3036.rs:5:14
|
||||
|
|
||||
LL | let x = 3
|
||||
| - expected one of `.`, `;`, `?`, or an operator here
|
||||
| ^ help: add `;` here
|
||||
LL | }
|
||||
| ^ unexpected token
|
||||
| - unexpected token
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ error: expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe`, fo
|
|||
--> $DIR/trait-non-item-macros.rs:2:19
|
||||
|
|
||||
LL | ($a:expr) => ($a)
|
||||
| ^^ unexpected token
|
||||
| ^^ expected one of `async`, `const`, `extern`, `fn`, `type`, or `unsafe` here
|
||||
...
|
||||
LL | bah!(2);
|
||||
| -------- in this macro invocation
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
fn test_if() {
|
||||
r#if true { } //~ ERROR found `true`
|
||||
r#if true { } //~ ERROR found keyword `true`
|
||||
}
|
||||
|
||||
fn test_struct() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `true`
|
||||
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found keyword `true`
|
||||
--> $DIR/raw-literal-keywords.rs:2:10
|
||||
|
|
||||
LL | r#if true { }
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ fn main() {
|
|||
let vec = vec![1, 2, 3];
|
||||
|
||||
for ( elem in vec ) {
|
||||
//~^ ERROR expected one of `)`, `,`, `@`, or `|`, found `in`
|
||||
//~^ ERROR expected one of `)`, `,`, `@`, or `|`, found keyword `in`
|
||||
//~| ERROR unexpected closing `)`
|
||||
const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: expected one of `)`, `,`, `@`, or `|`, found `in`
|
||||
error: expected one of `)`, `,`, `@`, or `|`, found keyword `in`
|
||||
--> $DIR/recover-for-loop-parens-around-head.rs:10:16
|
||||
|
|
||||
LL | for ( elem in vec ) {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
fn main() {
|
||||
let _: usize = ()
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR expected `;`
|
||||
let _ = 3;
|
||||
//~^ ERROR expected one of
|
||||
}
|
||||
|
||||
fn foo() -> usize {
|
||||
let _: usize = ()
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR expected `;`
|
||||
return 3;
|
||||
//~^ ERROR expected one of
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
error: expected one of `.`, `;`, `?`, or an operator, found `let`
|
||||
--> $DIR/recover-missing-semi.rs:4:5
|
||||
error: expected `;`, found `keyword `let``
|
||||
--> $DIR/recover-missing-semi.rs:2:22
|
||||
|
|
||||
LL | let _: usize = ()
|
||||
| - help: a semicolon may be missing here
|
||||
LL |
|
||||
| ^ help: add `;` here
|
||||
...
|
||||
LL | let _ = 3;
|
||||
| ^^^
|
||||
| --- unexpected token
|
||||
|
||||
error: expected one of `.`, `;`, `?`, or an operator, found `return`
|
||||
--> $DIR/recover-missing-semi.rs:11:5
|
||||
error: expected `;`, found `keyword `return``
|
||||
--> $DIR/recover-missing-semi.rs:9:22
|
||||
|
|
||||
LL | let _: usize = ()
|
||||
| - help: a semicolon may be missing here
|
||||
LL |
|
||||
| ^ help: add `;` here
|
||||
...
|
||||
LL | return 3;
|
||||
| ^^^^^^
|
||||
| ------ unexpected token
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-missing-semi.rs:2:20
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `static`
|
||||
error: expected one of `async`, `const`, `crate`, `default`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found keyword `static`
|
||||
--> $DIR/removed-syntax-static-fn.rs:4:5
|
||||
|
|
||||
LL | impl S {
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
type mut_box = Box<mut isize>; //~ ERROR expected one of `>`, const, lifetime, or type, found `mut`
|
||||
type mut_box = Box<mut isize>;
|
||||
//~^ ERROR expected one of `>`, const, lifetime, or type, found keyword `mut`
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
error: expected one of `>`, const, lifetime, or type, found `mut`
|
||||
error: expected one of `>`, const, lifetime, or type, found keyword `mut`
|
||||
--> $DIR/removed-syntax-uniq-mut-ty.rs:1:20
|
||||
|
|
||||
LL | type mut_box = Box<mut isize>;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,6 @@ use _ as g; //~ ERROR expected identifier, found reserved identifier `_`
|
|||
trait _ {} //~ ERROR expected identifier, found reserved identifier `_`
|
||||
trait _ = Copy; //~ ERROR expected identifier, found reserved identifier `_`
|
||||
macro_rules! _ { () => {} } //~ ERROR expected identifier, found reserved identifier `_`
|
||||
union _ { f: u8 } //~ ERROR expected one of `!` or `::`, found `_`
|
||||
union _ { f: u8 } //~ ERROR expected one of `!` or `::`, found reserved identifier `_`
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ error: expected identifier, found reserved identifier `_`
|
|||
LL | macro_rules! _ { () => {} }
|
||||
| ^ expected identifier, found reserved identifier
|
||||
|
||||
error: expected one of `!` or `::`, found `_`
|
||||
error: expected one of `!` or `::`, found reserved identifier `_`
|
||||
--> $DIR/underscore_item_not_const.rs:28:7
|
||||
|
|
||||
LL | union _ { f: u8 }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue