Skip to content

Commit 6ee7bd3

Browse files
authored
Rollup merge of rust-lang#97587 - pvdrz:maybe-recover-from-bad-qpath-stage-2, r=davidtwco
Migrate more diagnostics to use the `#[derive(SessionDiagnostic)]` r? `@davidtwco`
2 parents 78cd67b + 0fa70a8 commit 6ee7bd3

File tree

2 files changed

+95
-44
lines changed

2 files changed

+95
-44
lines changed

compiler/rustc_error_messages/locales/en-US/parser.ftl

+18
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,21 @@ parser-add-paren = try adding parentheses
1414
parser-forgot-paren = perhaps you forgot parentheses?
1515
1616
parser-expect-path = expected a path
17+
18+
parser-maybe-recover-from-bad-qpath-stage-2 =
19+
missing angle brackets in associated item path
20+
.suggestion = try: `{$ty}`
21+
22+
parser-incorrect-semicolon =
23+
expected item, found `;`
24+
.suggestion = remove this semicolon
25+
.help = {$name} declarations are not followed by a semicolon
26+
27+
parser-incorrect-use-of-await =
28+
incorrect use of `await`
29+
.parentheses-suggestion = `await` is not a method call, remove the parentheses
30+
.postfix-suggestion = `await` is a postfix operation
31+
32+
parser-in-in-typo =
33+
expected iterable, found keyword `in`
34+
.suggestion = remove the duplicated `in`

compiler/rustc_parse/src/parser/diagnostics.rs

+77-44
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,54 @@ pub enum BadTypePlusSub {
285285
},
286286
}
287287

288+
#[derive(SessionDiagnostic)]
289+
#[error(slug = "parser-maybe-recover-from-bad-qpath-stage-2")]
290+
struct BadQPathStage2 {
291+
#[primary_span]
292+
#[suggestion(applicability = "maybe-incorrect")]
293+
span: Span,
294+
ty: String,
295+
}
296+
297+
#[derive(SessionDiagnostic)]
298+
#[error(slug = "parser-incorrect-semicolon")]
299+
struct IncorrectSemicolon<'a> {
300+
#[primary_span]
301+
#[suggestion_short(applicability = "machine-applicable")]
302+
span: Span,
303+
#[help]
304+
opt_help: Option<()>,
305+
name: &'a str,
306+
}
307+
308+
#[derive(SessionDiagnostic)]
309+
#[error(slug = "parser-incorrect-use-of-await")]
310+
struct IncorrectUseOfAwait {
311+
#[primary_span]
312+
#[suggestion(message = "parentheses-suggestion", applicability = "machine-applicable")]
313+
span: Span,
314+
}
315+
316+
#[derive(SessionDiagnostic)]
317+
#[error(slug = "parser-incorrect-use-of-await")]
318+
struct IncorrectAwait {
319+
#[primary_span]
320+
span: Span,
321+
#[suggestion(message = "postfix-suggestion", code = "{expr}.await{question_mark}")]
322+
sugg_span: (Span, Applicability),
323+
expr: String,
324+
question_mark: &'static str,
325+
}
326+
327+
#[derive(SessionDiagnostic)]
328+
#[error(slug = "parser-in-in-typo")]
329+
struct InInTypo {
330+
#[primary_span]
331+
span: Span,
332+
#[suggestion(applicability = "machine-applicable")]
333+
sugg_span: Span,
334+
}
335+
288336
// SnapshotParser is used to create a snapshot of the parser
289337
// without causing duplicate errors being emitted when the `Parser`
290338
// is dropped.
@@ -1451,15 +1499,10 @@ impl<'a> Parser<'a> {
14511499
path.span = ty_span.to(self.prev_token.span);
14521500

14531501
let ty_str = self.span_to_snippet(ty_span).unwrap_or_else(|_| pprust::ty_to_string(&ty));
1454-
self.struct_span_err(path.span, "missing angle brackets in associated item path")
1455-
.span_suggestion(
1456-
// This is a best-effort recovery.
1457-
path.span,
1458-
"try",
1459-
format!("<{}>::{}", ty_str, pprust::path_to_string(&path)),
1460-
Applicability::MaybeIncorrect,
1461-
)
1462-
.emit();
1502+
self.sess.emit_err(BadQPathStage2 {
1503+
span: path.span,
1504+
ty: format!("<{}>::{}", ty_str, pprust::path_to_string(&path)),
1505+
});
14631506

14641507
let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`.
14651508
Ok(P(T::recovered(Some(QSelf { ty, path_span, position: 0 }), path)))
@@ -1468,13 +1511,10 @@ impl<'a> Parser<'a> {
14681511
pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool {
14691512
if self.token.kind == TokenKind::Semi {
14701513
self.bump();
1471-
let mut err = self.struct_span_err(self.prev_token.span, "expected item, found `;`");
1472-
err.span_suggestion_short(
1473-
self.prev_token.span,
1474-
"remove this semicolon",
1475-
String::new(),
1476-
Applicability::MachineApplicable,
1477-
);
1514+
1515+
let mut err =
1516+
IncorrectSemicolon { span: self.prev_token.span, opt_help: None, name: "" };
1517+
14781518
if !items.is_empty() {
14791519
let previous_item = &items[items.len() - 1];
14801520
let previous_item_kind_name = match previous_item.kind {
@@ -1487,10 +1527,11 @@ impl<'a> Parser<'a> {
14871527
_ => None,
14881528
};
14891529
if let Some(name) = previous_item_kind_name {
1490-
err.help(&format!("{name} declarations are not followed by a semicolon"));
1530+
err.opt_help = Some(());
1531+
err.name = name;
14911532
}
14921533
}
1493-
err.emit();
1534+
self.sess.emit_err(err);
14941535
true
14951536
} else {
14961537
false
@@ -1604,18 +1645,20 @@ impl<'a> Parser<'a> {
16041645
}
16051646

16061647
fn error_on_incorrect_await(&self, lo: Span, hi: Span, expr: &Expr, is_question: bool) -> Span {
1607-
let expr_str =
1608-
self.span_to_snippet(expr.span).unwrap_or_else(|_| pprust::expr_to_string(&expr));
1609-
let suggestion = format!("{}.await{}", expr_str, if is_question { "?" } else { "" });
1610-
let sp = lo.to(hi);
1611-
let app = match expr.kind {
1648+
let span = lo.to(hi);
1649+
let applicability = match expr.kind {
16121650
ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await <expr>?`
16131651
_ => Applicability::MachineApplicable,
16141652
};
1615-
self.struct_span_err(sp, "incorrect use of `await`")
1616-
.span_suggestion(sp, "`await` is a postfix operation", suggestion, app)
1617-
.emit();
1618-
sp
1653+
1654+
self.sess.emit_err(IncorrectAwait {
1655+
span,
1656+
sugg_span: (span, applicability),
1657+
expr: self.span_to_snippet(expr.span).unwrap_or_else(|_| pprust::expr_to_string(&expr)),
1658+
question_mark: if is_question { "?" } else { "" },
1659+
});
1660+
1661+
span
16191662
}
16201663

16211664
/// If encountering `future.await()`, consumes and emits an error.
@@ -1626,16 +1669,10 @@ impl<'a> Parser<'a> {
16261669
// future.await()
16271670
let lo = self.token.span;
16281671
self.bump(); // (
1629-
let sp = lo.to(self.token.span);
1672+
let span = lo.to(self.token.span);
16301673
self.bump(); // )
1631-
self.struct_span_err(sp, "incorrect use of `await`")
1632-
.span_suggestion(
1633-
sp,
1634-
"`await` is not a method call, remove the parentheses",
1635-
String::new(),
1636-
Applicability::MachineApplicable,
1637-
)
1638-
.emit();
1674+
1675+
self.sess.emit_err(IncorrectUseOfAwait { span });
16391676
}
16401677
}
16411678

@@ -1907,14 +1944,10 @@ impl<'a> Parser<'a> {
19071944
pub(super) fn check_for_for_in_in_typo(&mut self, in_span: Span) {
19081945
if self.eat_keyword(kw::In) {
19091946
// a common typo: `for _ in in bar {}`
1910-
self.struct_span_err(self.prev_token.span, "expected iterable, found keyword `in`")
1911-
.span_suggestion_short(
1912-
in_span.until(self.prev_token.span),
1913-
"remove the duplicated `in`",
1914-
String::new(),
1915-
Applicability::MachineApplicable,
1916-
)
1917-
.emit();
1947+
self.sess.emit_err(InInTypo {
1948+
span: self.prev_token.span,
1949+
sugg_span: in_span.until(self.prev_token.span),
1950+
});
19181951
}
19191952
}
19201953

0 commit comments

Comments
 (0)