mirror of
https://github.com/rust-lang/rust
synced 2024-10-14 12:33:57 +00:00
improve maybe_consume_incorrect_semicolon
This commit is contained in:
parent
bdfd941f4d
commit
8dc6a5d145
|
@ -3250,6 +3250,7 @@ pub enum ItemKind {
|
|||
}
|
||||
|
||||
impl ItemKind {
|
||||
/// "a" or "an"
|
||||
pub fn article(&self) -> &'static str {
|
||||
use ItemKind::*;
|
||||
match self {
|
||||
|
|
|
@ -83,7 +83,7 @@ pub(crate) struct IncorrectSemicolon<'a> {
|
|||
#[suggestion(style = "short", code = "", applicability = "machine-applicable")]
|
||||
pub span: Span,
|
||||
#[help]
|
||||
pub opt_help: Option<()>,
|
||||
pub show_help: bool,
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
|
|
|
@ -1817,34 +1817,31 @@ pub(super) fn maybe_recover_from_bad_qpath_stage_2<T: RecoverQPath>(
|
|||
Ok(P(T::recovered(Some(P(QSelf { ty, path_span, position: 0 })), path)))
|
||||
}
|
||||
|
||||
pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool {
|
||||
if self.token.kind == TokenKind::Semi {
|
||||
self.bump();
|
||||
/// This function gets called in places where a semicolon is NOT expected and if there's a
|
||||
/// semicolon it emits the appropriate error and returns true.
|
||||
pub fn maybe_consume_incorrect_semicolon(&mut self, previous_item: Option<&Item>) -> bool {
|
||||
if self.token.kind != TokenKind::Semi {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut err =
|
||||
IncorrectSemicolon { span: self.prev_token.span, opt_help: None, name: "" };
|
||||
|
||||
if !items.is_empty() {
|
||||
let previous_item = &items[items.len() - 1];
|
||||
let previous_item_kind_name = match previous_item.kind {
|
||||
// Check previous item to add it to the diagnostic, for example to say
|
||||
// `enum declarations are not followed by a semicolon`
|
||||
let err = match previous_item {
|
||||
Some(previous_item) => {
|
||||
let name = match previous_item.kind {
|
||||
// Say "braced struct" because tuple-structs and
|
||||
// braceless-empty-struct declarations do take a semicolon.
|
||||
ItemKind::Struct(..) => Some("braced struct"),
|
||||
ItemKind::Enum(..) => Some("enum"),
|
||||
ItemKind::Trait(..) => Some("trait"),
|
||||
ItemKind::Union(..) => Some("union"),
|
||||
_ => None,
|
||||
ItemKind::Struct(..) => "braced struct",
|
||||
_ => previous_item.kind.descr(),
|
||||
};
|
||||
if let Some(name) = previous_item_kind_name {
|
||||
err.opt_help = Some(());
|
||||
err.name = name;
|
||||
}
|
||||
IncorrectSemicolon { span: self.token.span, name, show_help: true }
|
||||
}
|
||||
self.dcx().emit_err(err);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
None => IncorrectSemicolon { span: self.token.span, name: "", show_help: false },
|
||||
};
|
||||
self.dcx().emit_err(err);
|
||||
|
||||
self.bump();
|
||||
true
|
||||
}
|
||||
|
||||
/// Creates a `Diag` for an unexpected token `t` and tries to recover if it is a
|
||||
|
|
|
@ -59,13 +59,13 @@ pub fn parse_mod(
|
|||
let post_attr_lo = self.token.span;
|
||||
let mut items = ThinVec::new();
|
||||
while let Some(item) = self.parse_item(ForceCollect::No)? {
|
||||
self.maybe_consume_incorrect_semicolon(Some(&item));
|
||||
items.push(item);
|
||||
self.maybe_consume_incorrect_semicolon(&items);
|
||||
}
|
||||
|
||||
if !self.eat(term) {
|
||||
let token_str = super::token_descr(&self.token);
|
||||
if !self.maybe_consume_incorrect_semicolon(&items) {
|
||||
if !self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) {
|
||||
let msg = format!("expected item, found {token_str}");
|
||||
let mut err = self.dcx().struct_span_err(self.token.span, msg);
|
||||
let span = self.token.span;
|
||||
|
|
|
@ -686,9 +686,9 @@ pub(crate) fn make_test(
|
|||
}
|
||||
}
|
||||
|
||||
// The supplied slice is only used for diagnostics,
|
||||
// The supplied item is only used for diagnostics,
|
||||
// which are swallowed here anyway.
|
||||
parser.maybe_consume_incorrect_semicolon(&[]);
|
||||
parser.maybe_consume_incorrect_semicolon(None);
|
||||
}
|
||||
|
||||
// Reset errors so that they won't be reported as compiler bugs when dropping the
|
||||
|
|
|
@ -3,6 +3,8 @@ error: expected item, found `;`
|
|||
|
|
||||
LL | mod M {};
|
||||
| ^ help: remove this semicolon
|
||||
|
|
||||
= help: module declarations are not followed by a semicolon
|
||||
|
||||
error: expected item, found `;`
|
||||
--> $DIR/recover-from-semicolon-trailing-item.rs:4:12
|
||||
|
@ -17,6 +19,8 @@ error: expected item, found `;`
|
|||
|
|
||||
LL | fn foo(a: usize) {};
|
||||
| ^ help: remove this semicolon
|
||||
|
|
||||
= help: function declarations are not followed by a semicolon
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-from-semicolon-trailing-item.rs:10:20
|
||||
|
|
Loading…
Reference in a new issue