@@ -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