@@ -285,6 +285,54 @@ pub enum BadTypePlusSub {
285
285
},
286
286
}
287
287
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
+
288
336
// SnapshotParser is used to create a snapshot of the parser
289
337
// without causing duplicate errors being emitted when the `Parser`
290
338
// is dropped.
@@ -1451,15 +1499,10 @@ impl<'a> Parser<'a> {
1451
1499
path.span = ty_span.to(self.prev_token.span);
1452
1500
1453
1501
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
+ });
1463
1506
1464
1507
let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`.
1465
1508
Ok(P(T::recovered(Some(QSelf { ty, path_span, position: 0 }), path)))
@@ -1468,13 +1511,10 @@ impl<'a> Parser<'a> {
1468
1511
pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool {
1469
1512
if self.token.kind == TokenKind::Semi {
1470
1513
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
+
1478
1518
if !items.is_empty() {
1479
1519
let previous_item = &items[items.len() - 1];
1480
1520
let previous_item_kind_name = match previous_item.kind {
@@ -1487,10 +1527,11 @@ impl<'a> Parser<'a> {
1487
1527
_ => None,
1488
1528
};
1489
1529
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;
1491
1532
}
1492
1533
}
1493
- err . emit ( ) ;
1534
+ self.sess.emit_err(err );
1494
1535
true
1495
1536
} else {
1496
1537
false
@@ -1604,18 +1645,20 @@ impl<'a> Parser<'a> {
1604
1645
}
1605
1646
1606
1647
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 {
1612
1650
ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await <expr>?`
1613
1651
_ => Applicability::MachineApplicable,
1614
1652
};
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
1619
1662
}
1620
1663
1621
1664
/// If encountering `future.await()`, consumes and emits an error.
@@ -1626,16 +1669,10 @@ impl<'a> Parser<'a> {
1626
1669
// future.await()
1627
1670
let lo = self.token.span;
1628
1671
self.bump(); // (
1629
- let sp = lo. to ( self . token . span ) ;
1672
+ let span = lo.to(self.token.span);
1630
1673
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 });
1639
1676
}
1640
1677
}
1641
1678
@@ -1907,14 +1944,10 @@ impl<'a> Parser<'a> {
1907
1944
pub(super) fn check_for_for_in_in_typo(&mut self, in_span: Span) {
1908
1945
if self.eat_keyword(kw::In) {
1909
1946
// 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
+ });
1918
1951
}
1919
1952
}
1920
1953
0 commit comments