]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/errors.rs
Rollup merge of #104036 - compiler-errors:option-sugg, r=petrochenkov
[rust.git] / compiler / rustc_parse / src / errors.rs
1 use rustc_ast::token::Token;
2 use rustc_ast::Path;
3 use rustc_errors::{fluent, AddToDiagnostic, Applicability, EmissionGuarantee, IntoDiagnostic};
4 use rustc_macros::{Diagnostic, Subdiagnostic};
5 use rustc_session::errors::ExprParenthesesNeeded;
6 use rustc_span::symbol::Ident;
7 use rustc_span::{Span, Symbol};
8
9 use crate::parser::TokenDescription;
10
11 #[derive(Diagnostic)]
12 #[diag(parser_maybe_report_ambiguous_plus)]
13 pub(crate) struct AmbiguousPlus {
14     pub sum_ty: String,
15     #[primary_span]
16     #[suggestion(code = "({sum_ty})")]
17     pub span: Span,
18 }
19
20 #[derive(Diagnostic)]
21 #[diag(parser_maybe_recover_from_bad_type_plus, code = "E0178")]
22 pub(crate) struct BadTypePlus {
23     pub ty: String,
24     #[primary_span]
25     pub span: Span,
26     #[subdiagnostic]
27     pub sub: BadTypePlusSub,
28 }
29
30 #[derive(Subdiagnostic)]
31 pub(crate) enum BadTypePlusSub {
32     #[suggestion(
33         parser_add_paren,
34         code = "{sum_with_parens}",
35         applicability = "machine-applicable"
36     )]
37     AddParen {
38         sum_with_parens: String,
39         #[primary_span]
40         span: Span,
41     },
42     #[label(parser_forgot_paren)]
43     ForgotParen {
44         #[primary_span]
45         span: Span,
46     },
47     #[label(parser_expect_path)]
48     ExpectPath {
49         #[primary_span]
50         span: Span,
51     },
52 }
53
54 #[derive(Diagnostic)]
55 #[diag(parser_maybe_recover_from_bad_qpath_stage_2)]
56 pub(crate) struct BadQPathStage2 {
57     #[primary_span]
58     #[suggestion(code = "", applicability = "maybe-incorrect")]
59     pub span: Span,
60     pub ty: String,
61 }
62
63 #[derive(Diagnostic)]
64 #[diag(parser_incorrect_semicolon)]
65 pub(crate) struct IncorrectSemicolon<'a> {
66     #[primary_span]
67     #[suggestion(style = "short", code = "", applicability = "machine-applicable")]
68     pub span: Span,
69     #[help]
70     pub opt_help: Option<()>,
71     pub name: &'a str,
72 }
73
74 #[derive(Diagnostic)]
75 #[diag(parser_incorrect_use_of_await)]
76 pub(crate) struct IncorrectUseOfAwait {
77     #[primary_span]
78     #[suggestion(parentheses_suggestion, code = "", applicability = "machine-applicable")]
79     pub span: Span,
80 }
81
82 #[derive(Diagnostic)]
83 #[diag(parser_incorrect_use_of_await)]
84 pub(crate) struct IncorrectAwait {
85     #[primary_span]
86     pub span: Span,
87     #[suggestion(postfix_suggestion, code = "{expr}.await{question_mark}")]
88     pub sugg_span: (Span, Applicability),
89     pub expr: String,
90     pub question_mark: &'static str,
91 }
92
93 #[derive(Diagnostic)]
94 #[diag(parser_in_in_typo)]
95 pub(crate) struct InInTypo {
96     #[primary_span]
97     pub span: Span,
98     #[suggestion(code = "", applicability = "machine-applicable")]
99     pub sugg_span: Span,
100 }
101
102 #[derive(Diagnostic)]
103 #[diag(parser_invalid_variable_declaration)]
104 pub(crate) struct InvalidVariableDeclaration {
105     #[primary_span]
106     pub span: Span,
107     #[subdiagnostic]
108     pub sub: InvalidVariableDeclarationSub,
109 }
110
111 #[derive(Subdiagnostic)]
112 pub(crate) enum InvalidVariableDeclarationSub {
113     #[suggestion(parser_switch_mut_let_order, applicability = "maybe-incorrect", code = "let mut")]
114     SwitchMutLetOrder(#[primary_span] Span),
115     #[suggestion(
116         parser_missing_let_before_mut,
117         applicability = "machine-applicable",
118         code = "let mut"
119     )]
120     MissingLet(#[primary_span] Span),
121     #[suggestion(parser_use_let_not_auto, applicability = "machine-applicable", code = "let")]
122     UseLetNotAuto(#[primary_span] Span),
123     #[suggestion(parser_use_let_not_var, applicability = "machine-applicable", code = "let")]
124     UseLetNotVar(#[primary_span] Span),
125 }
126
127 #[derive(Diagnostic)]
128 #[diag(parser_invalid_comparison_operator)]
129 pub(crate) struct InvalidComparisonOperator {
130     #[primary_span]
131     pub span: Span,
132     pub invalid: String,
133     #[subdiagnostic]
134     pub sub: InvalidComparisonOperatorSub,
135 }
136
137 #[derive(Subdiagnostic)]
138 pub(crate) enum InvalidComparisonOperatorSub {
139     #[suggestion(
140         use_instead,
141         style = "short",
142         applicability = "machine-applicable",
143         code = "{correct}"
144     )]
145     Correctable {
146         #[primary_span]
147         span: Span,
148         invalid: String,
149         correct: String,
150     },
151     #[label(spaceship_operator_invalid)]
152     Spaceship(#[primary_span] Span),
153 }
154
155 #[derive(Diagnostic)]
156 #[diag(parser_invalid_logical_operator)]
157 #[note]
158 pub(crate) struct InvalidLogicalOperator {
159     #[primary_span]
160     pub span: Span,
161     pub incorrect: String,
162     #[subdiagnostic]
163     pub sub: InvalidLogicalOperatorSub,
164 }
165
166 #[derive(Subdiagnostic)]
167 pub(crate) enum InvalidLogicalOperatorSub {
168     #[suggestion(
169         use_amp_amp_for_conjunction,
170         style = "short",
171         applicability = "machine-applicable",
172         code = "&&"
173     )]
174     Conjunction(#[primary_span] Span),
175     #[suggestion(
176         use_pipe_pipe_for_disjunction,
177         style = "short",
178         applicability = "machine-applicable",
179         code = "||"
180     )]
181     Disjunction(#[primary_span] Span),
182 }
183
184 #[derive(Diagnostic)]
185 #[diag(parser_tilde_is_not_unary_operator)]
186 pub(crate) struct TildeAsUnaryOperator(
187     #[primary_span]
188     #[suggestion(style = "short", applicability = "machine-applicable", code = "!")]
189     pub Span,
190 );
191
192 #[derive(Diagnostic)]
193 #[diag(parser_unexpected_token_after_not)]
194 pub(crate) struct NotAsNegationOperator {
195     #[primary_span]
196     pub negated: Span,
197     pub negated_desc: String,
198     #[subdiagnostic]
199     pub sub: NotAsNegationOperatorSub,
200 }
201
202 #[derive(Subdiagnostic)]
203 pub enum NotAsNegationOperatorSub {
204     #[suggestion(
205         parser_unexpected_token_after_not_default,
206         style = "short",
207         applicability = "machine-applicable",
208         code = "!"
209     )]
210     SuggestNotDefault(#[primary_span] Span),
211
212     #[suggestion(
213         parser_unexpected_token_after_not_bitwise,
214         style = "short",
215         applicability = "machine-applicable",
216         code = "!"
217     )]
218     SuggestNotBitwise(#[primary_span] Span),
219
220     #[suggestion(
221         parser_unexpected_token_after_not_logical,
222         style = "short",
223         applicability = "machine-applicable",
224         code = "!"
225     )]
226     SuggestNotLogical(#[primary_span] Span),
227 }
228
229 #[derive(Diagnostic)]
230 #[diag(parser_malformed_loop_label)]
231 pub(crate) struct MalformedLoopLabel {
232     #[primary_span]
233     #[suggestion(applicability = "machine-applicable", code = "{correct_label}")]
234     pub span: Span,
235     pub correct_label: Ident,
236 }
237
238 #[derive(Diagnostic)]
239 #[diag(parser_lifetime_in_borrow_expression)]
240 pub(crate) struct LifetimeInBorrowExpression {
241     #[primary_span]
242     pub span: Span,
243     #[suggestion(applicability = "machine-applicable", code = "")]
244     #[label]
245     pub lifetime_span: Span,
246 }
247
248 #[derive(Diagnostic)]
249 #[diag(parser_field_expression_with_generic)]
250 pub(crate) struct FieldExpressionWithGeneric(#[primary_span] pub Span);
251
252 #[derive(Diagnostic)]
253 #[diag(parser_macro_invocation_with_qualified_path)]
254 pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span);
255
256 #[derive(Diagnostic)]
257 #[diag(parser_unexpected_token_after_label)]
258 pub(crate) struct UnexpectedTokenAfterLabel {
259     #[primary_span]
260     #[label(parser_unexpected_token_after_label)]
261     pub span: Span,
262     #[suggestion(suggestion_remove_label, style = "verbose", code = "")]
263     pub remove_label: Option<Span>,
264     #[subdiagnostic]
265     pub enclose_in_block: Option<UnexpectedTokenAfterLabelSugg>,
266 }
267
268 #[derive(Subdiagnostic)]
269 #[multipart_suggestion(suggestion_enclose_in_block, applicability = "machine-applicable")]
270 pub(crate) struct UnexpectedTokenAfterLabelSugg {
271     #[suggestion_part(code = "{{ ")]
272     pub left: Span,
273     #[suggestion_part(code = " }}")]
274     pub right: Span,
275 }
276
277 #[derive(Diagnostic)]
278 #[diag(parser_require_colon_after_labeled_expression)]
279 #[note]
280 pub(crate) struct RequireColonAfterLabeledExpression {
281     #[primary_span]
282     pub span: Span,
283     #[label]
284     pub label: Span,
285     #[suggestion(style = "short", applicability = "machine-applicable", code = ": ")]
286     pub label_end: Span,
287 }
288
289 #[derive(Diagnostic)]
290 #[diag(parser_do_catch_syntax_removed)]
291 #[note]
292 pub(crate) struct DoCatchSyntaxRemoved {
293     #[primary_span]
294     #[suggestion(applicability = "machine-applicable", code = "try")]
295     pub span: Span,
296 }
297
298 #[derive(Diagnostic)]
299 #[diag(parser_float_literal_requires_integer_part)]
300 pub(crate) struct FloatLiteralRequiresIntegerPart {
301     #[primary_span]
302     #[suggestion(applicability = "machine-applicable", code = "{correct}")]
303     pub span: Span,
304     pub correct: String,
305 }
306
307 #[derive(Diagnostic)]
308 #[diag(parser_invalid_int_literal_width)]
309 #[help]
310 pub(crate) struct InvalidIntLiteralWidth {
311     #[primary_span]
312     pub span: Span,
313     pub width: String,
314 }
315
316 #[derive(Diagnostic)]
317 #[diag(parser_invalid_num_literal_base_prefix)]
318 #[note]
319 pub(crate) struct InvalidNumLiteralBasePrefix {
320     #[primary_span]
321     #[suggestion(applicability = "maybe-incorrect", code = "{fixed}")]
322     pub span: Span,
323     pub fixed: String,
324 }
325
326 #[derive(Diagnostic)]
327 #[diag(parser_invalid_num_literal_suffix)]
328 #[help]
329 pub(crate) struct InvalidNumLiteralSuffix {
330     #[primary_span]
331     #[label]
332     pub span: Span,
333     pub suffix: String,
334 }
335
336 #[derive(Diagnostic)]
337 #[diag(parser_invalid_float_literal_width)]
338 #[help]
339 pub(crate) struct InvalidFloatLiteralWidth {
340     #[primary_span]
341     pub span: Span,
342     pub width: String,
343 }
344
345 #[derive(Diagnostic)]
346 #[diag(parser_invalid_float_literal_suffix)]
347 #[help]
348 pub(crate) struct InvalidFloatLiteralSuffix {
349     #[primary_span]
350     #[label]
351     pub span: Span,
352     pub suffix: String,
353 }
354
355 #[derive(Diagnostic)]
356 #[diag(parser_int_literal_too_large)]
357 pub(crate) struct IntLiteralTooLarge {
358     #[primary_span]
359     pub span: Span,
360 }
361
362 #[derive(Diagnostic)]
363 #[diag(parser_missing_semicolon_before_array)]
364 pub(crate) struct MissingSemicolonBeforeArray {
365     #[primary_span]
366     pub open_delim: Span,
367     #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = ";")]
368     pub semicolon: Span,
369 }
370
371 #[derive(Diagnostic)]
372 #[diag(parser_expect_dotdot_not_dotdotdot)]
373 pub(crate) struct MissingDotDot {
374     #[primary_span]
375     pub token_span: Span,
376     #[suggestion(applicability = "maybe-incorrect", code = "..", style = "verbose")]
377     pub sugg_span: Span,
378 }
379
380 #[derive(Diagnostic)]
381 #[diag(parser_invalid_block_macro_segment)]
382 pub(crate) struct InvalidBlockMacroSegment {
383     #[primary_span]
384     pub span: Span,
385     #[label]
386     pub context: Span,
387 }
388
389 #[derive(Diagnostic)]
390 #[diag(parser_if_expression_missing_then_block)]
391 pub(crate) struct IfExpressionMissingThenBlock {
392     #[primary_span]
393     pub if_span: Span,
394     #[subdiagnostic]
395     pub sub: IfExpressionMissingThenBlockSub,
396 }
397
398 #[derive(Subdiagnostic)]
399 pub(crate) enum IfExpressionMissingThenBlockSub {
400     #[help(condition_possibly_unfinished)]
401     UnfinishedCondition(#[primary_span] Span),
402     #[help(add_then_block)]
403     AddThenBlock(#[primary_span] Span),
404 }
405
406 #[derive(Diagnostic)]
407 #[diag(parser_if_expression_missing_condition)]
408 pub(crate) struct IfExpressionMissingCondition {
409     #[primary_span]
410     #[label(condition_label)]
411     pub if_span: Span,
412     #[label(block_label)]
413     pub block_span: Span,
414 }
415
416 #[derive(Diagnostic)]
417 #[diag(parser_expected_expression_found_let)]
418 pub(crate) struct ExpectedExpressionFoundLet {
419     #[primary_span]
420     pub span: Span,
421 }
422
423 #[derive(Diagnostic)]
424 #[diag(parser_expect_eq_instead_of_eqeq)]
425 pub(crate) struct ExpectedEqForLetExpr {
426     #[primary_span]
427     pub span: Span,
428     #[suggestion(applicability = "maybe-incorrect", code = "=", style = "verbose")]
429     pub sugg_span: Span,
430 }
431
432 #[derive(Diagnostic)]
433 #[diag(parser_expected_else_block)]
434 pub(crate) struct ExpectedElseBlock {
435     #[primary_span]
436     pub first_tok_span: Span,
437     pub first_tok: String,
438     #[label]
439     pub else_span: Span,
440     #[suggestion(applicability = "maybe-incorrect", code = "if ")]
441     pub condition_start: Span,
442 }
443
444 #[derive(Diagnostic)]
445 #[diag(parser_outer_attribute_not_allowed_on_if_else)]
446 pub(crate) struct OuterAttributeNotAllowedOnIfElse {
447     #[primary_span]
448     pub last: Span,
449
450     #[label(branch_label)]
451     pub branch_span: Span,
452
453     #[label(ctx_label)]
454     pub ctx_span: Span,
455     pub ctx: String,
456
457     #[suggestion(applicability = "machine-applicable", code = "")]
458     pub attributes: Span,
459 }
460
461 #[derive(Diagnostic)]
462 #[diag(parser_missing_in_in_for_loop)]
463 pub(crate) struct MissingInInForLoop {
464     #[primary_span]
465     pub span: Span,
466     #[subdiagnostic]
467     pub sub: MissingInInForLoopSub,
468 }
469
470 #[derive(Subdiagnostic)]
471 pub(crate) enum MissingInInForLoopSub {
472     // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect
473     #[suggestion(use_in_not_of, style = "short", applicability = "maybe-incorrect", code = "in")]
474     InNotOf(#[primary_span] Span),
475     #[suggestion(add_in, style = "short", applicability = "maybe-incorrect", code = " in ")]
476     AddIn(#[primary_span] Span),
477 }
478
479 #[derive(Diagnostic)]
480 #[diag(parser_missing_comma_after_match_arm)]
481 pub(crate) struct MissingCommaAfterMatchArm {
482     #[primary_span]
483     #[suggestion(applicability = "machine-applicable", code = ",")]
484     pub span: Span,
485 }
486
487 #[derive(Diagnostic)]
488 #[diag(parser_catch_after_try)]
489 #[help]
490 pub(crate) struct CatchAfterTry {
491     #[primary_span]
492     pub span: Span,
493 }
494
495 #[derive(Diagnostic)]
496 #[diag(parser_comma_after_base_struct)]
497 #[note]
498 pub(crate) struct CommaAfterBaseStruct {
499     #[primary_span]
500     pub span: Span,
501     #[suggestion(style = "short", applicability = "machine-applicable", code = "")]
502     pub comma: Span,
503 }
504
505 #[derive(Diagnostic)]
506 #[diag(parser_eq_field_init)]
507 pub(crate) struct EqFieldInit {
508     #[primary_span]
509     pub span: Span,
510     #[suggestion(applicability = "machine-applicable", code = ":")]
511     pub eq: Span,
512 }
513
514 #[derive(Diagnostic)]
515 #[diag(parser_dotdotdot)]
516 pub(crate) struct DotDotDot {
517     #[primary_span]
518     #[suggestion(suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
519     #[suggestion(suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
520     pub span: Span,
521 }
522
523 #[derive(Diagnostic)]
524 #[diag(parser_left_arrow_operator)]
525 pub(crate) struct LeftArrowOperator {
526     #[primary_span]
527     #[suggestion(applicability = "maybe-incorrect", code = "< -")]
528     pub span: Span,
529 }
530
531 #[derive(Diagnostic)]
532 #[diag(parser_remove_let)]
533 pub(crate) struct RemoveLet {
534     #[primary_span]
535     #[suggestion(applicability = "machine-applicable", code = "")]
536     pub span: Span,
537 }
538
539 #[derive(Diagnostic)]
540 #[diag(parser_use_eq_instead)]
541 pub(crate) struct UseEqInstead {
542     #[primary_span]
543     #[suggestion(style = "short", applicability = "machine-applicable", code = "=")]
544     pub span: Span,
545 }
546
547 #[derive(Diagnostic)]
548 #[diag(parser_use_empty_block_not_semi)]
549 pub(crate) struct UseEmptyBlockNotSemi {
550     #[primary_span]
551     #[suggestion(style = "hidden", applicability = "machine-applicable", code = "{{}}")]
552     pub span: Span,
553 }
554
555 #[derive(Diagnostic)]
556 #[diag(parser_comparison_interpreted_as_generic)]
557 pub(crate) struct ComparisonInterpretedAsGeneric {
558     #[primary_span]
559     #[label(label_comparison)]
560     pub comparison: Span,
561     pub r#type: Path,
562     #[label(label_args)]
563     pub args: Span,
564     #[subdiagnostic]
565     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
566 }
567
568 #[derive(Diagnostic)]
569 #[diag(parser_shift_interpreted_as_generic)]
570 pub(crate) struct ShiftInterpretedAsGeneric {
571     #[primary_span]
572     #[label(label_comparison)]
573     pub shift: Span,
574     pub r#type: Path,
575     #[label(label_args)]
576     pub args: Span,
577     #[subdiagnostic]
578     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
579 }
580
581 #[derive(Subdiagnostic)]
582 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
583 pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
584     #[suggestion_part(code = "(")]
585     pub left: Span,
586     #[suggestion_part(code = ")")]
587     pub right: Span,
588 }
589
590 #[derive(Diagnostic)]
591 #[diag(parser_found_expr_would_be_stmt)]
592 pub(crate) struct FoundExprWouldBeStmt {
593     #[primary_span]
594     #[label]
595     pub span: Span,
596     pub token: Token,
597     #[subdiagnostic]
598     pub suggestion: ExprParenthesesNeeded,
599 }
600
601 #[derive(Diagnostic)]
602 #[diag(parser_leading_plus_not_supported)]
603 pub(crate) struct LeadingPlusNotSupported {
604     #[primary_span]
605     #[label]
606     pub span: Span,
607     #[suggestion(
608         suggestion_remove_plus,
609         style = "verbose",
610         code = "",
611         applicability = "machine-applicable"
612     )]
613     pub remove_plus: Option<Span>,
614     #[subdiagnostic]
615     pub add_parentheses: Option<ExprParenthesesNeeded>,
616 }
617
618 #[derive(Diagnostic)]
619 #[diag(parser_parentheses_with_struct_fields)]
620 pub(crate) struct ParenthesesWithStructFields {
621     #[primary_span]
622     pub span: Span,
623     pub r#type: Path,
624     #[subdiagnostic]
625     pub braces_for_struct: BracesForStructLiteral,
626     #[subdiagnostic]
627     pub no_fields_for_fn: NoFieldsForFnCall,
628 }
629
630 #[derive(Subdiagnostic)]
631 #[multipart_suggestion(suggestion_braces_for_struct, applicability = "maybe-incorrect")]
632 pub(crate) struct BracesForStructLiteral {
633     #[suggestion_part(code = " {{ ")]
634     pub first: Span,
635     #[suggestion_part(code = " }}")]
636     pub second: Span,
637 }
638
639 #[derive(Subdiagnostic)]
640 #[multipart_suggestion(suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
641 pub(crate) struct NoFieldsForFnCall {
642     #[suggestion_part(code = "")]
643     pub fields: Vec<Span>,
644 }
645
646 #[derive(Diagnostic)]
647 #[diag(parser_labeled_loop_in_break)]
648 pub(crate) struct LabeledLoopInBreak {
649     #[primary_span]
650     pub span: Span,
651     #[subdiagnostic]
652     pub sub: WrapExpressionInParentheses,
653 }
654
655 #[derive(Subdiagnostic)]
656 #[multipart_suggestion(
657     parser_sugg_wrap_expression_in_parentheses,
658     applicability = "machine-applicable"
659 )]
660 pub(crate) struct WrapExpressionInParentheses {
661     #[suggestion_part(code = "(")]
662     pub left: Span,
663     #[suggestion_part(code = ")")]
664     pub right: Span,
665 }
666
667 #[derive(Diagnostic)]
668 #[diag(parser_array_brackets_instead_of_braces)]
669 pub(crate) struct ArrayBracketsInsteadOfSpaces {
670     #[primary_span]
671     pub span: Span,
672     #[subdiagnostic]
673     pub sub: ArrayBracketsInsteadOfSpacesSugg,
674 }
675
676 #[derive(Subdiagnostic)]
677 #[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
678 pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
679     #[suggestion_part(code = "[")]
680     pub left: Span,
681     #[suggestion_part(code = "]")]
682     pub right: Span,
683 }
684
685 #[derive(Diagnostic)]
686 #[diag(parser_match_arm_body_without_braces)]
687 pub(crate) struct MatchArmBodyWithoutBraces {
688     #[primary_span]
689     #[label(label_statements)]
690     pub statements: Span,
691     #[label(label_arrow)]
692     pub arrow: Span,
693     pub num_statements: usize,
694     #[subdiagnostic]
695     pub sub: MatchArmBodyWithoutBracesSugg,
696 }
697
698 #[derive(Subdiagnostic)]
699 pub(crate) enum MatchArmBodyWithoutBracesSugg {
700     #[multipart_suggestion(suggestion_add_braces, applicability = "machine-applicable")]
701     AddBraces {
702         #[suggestion_part(code = "{{ ")]
703         left: Span,
704         #[suggestion_part(code = " }}")]
705         right: Span,
706     },
707     #[suggestion(
708         suggestion_use_comma_not_semicolon,
709         code = ",",
710         applicability = "machine-applicable"
711     )]
712     UseComma {
713         #[primary_span]
714         semicolon: Span,
715     },
716 }
717
718 #[derive(Diagnostic)]
719 #[diag(parser_struct_literal_not_allowed_here)]
720 pub(crate) struct StructLiteralNotAllowedHere {
721     #[primary_span]
722     pub span: Span,
723     #[subdiagnostic]
724     pub sub: StructLiteralNotAllowedHereSugg,
725 }
726
727 #[derive(Subdiagnostic)]
728 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
729 pub(crate) struct StructLiteralNotAllowedHereSugg {
730     #[suggestion_part(code = "(")]
731     pub left: Span,
732     #[suggestion_part(code = ")")]
733     pub right: Span,
734 }
735
736 #[derive(Diagnostic)]
737 #[diag(parser_invalid_interpolated_expression)]
738 pub(crate) struct InvalidInterpolatedExpression {
739     #[primary_span]
740     pub span: Span,
741 }
742
743 #[derive(Diagnostic)]
744 #[diag(parser_hexadecimal_float_literal_not_supported)]
745 pub(crate) struct HexadecimalFloatLiteralNotSupported {
746     #[primary_span]
747     #[label(parser_not_supported)]
748     pub span: Span,
749 }
750
751 #[derive(Diagnostic)]
752 #[diag(parser_octal_float_literal_not_supported)]
753 pub(crate) struct OctalFloatLiteralNotSupported {
754     #[primary_span]
755     #[label(parser_not_supported)]
756     pub span: Span,
757 }
758
759 #[derive(Diagnostic)]
760 #[diag(parser_binary_float_literal_not_supported)]
761 pub(crate) struct BinaryFloatLiteralNotSupported {
762     #[primary_span]
763     #[label(parser_not_supported)]
764     pub span: Span,
765 }
766
767 #[derive(Diagnostic)]
768 #[diag(parser_invalid_literal_suffix)]
769 pub(crate) struct InvalidLiteralSuffix {
770     #[primary_span]
771     #[label]
772     pub span: Span,
773     // FIXME(#100717)
774     pub kind: String,
775     pub suffix: Symbol,
776 }
777
778 #[derive(Diagnostic)]
779 #[diag(parser_invalid_literal_suffix_on_tuple_index)]
780 pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
781     #[primary_span]
782     #[label]
783     pub span: Span,
784     pub suffix: Symbol,
785     #[help(tuple_exception_line_1)]
786     #[help(tuple_exception_line_2)]
787     #[help(tuple_exception_line_3)]
788     pub exception: Option<()>,
789 }
790
791 #[derive(Diagnostic)]
792 #[diag(parser_non_string_abi_literal)]
793 pub(crate) struct NonStringAbiLiteral {
794     #[primary_span]
795     #[suggestion(code = "\"C\"", applicability = "maybe-incorrect")]
796     pub span: Span,
797 }
798
799 #[derive(Diagnostic)]
800 #[diag(parser_mismatched_closing_delimiter)]
801 pub(crate) struct MismatchedClosingDelimiter {
802     #[primary_span]
803     pub spans: Vec<Span>,
804     pub delimiter: String,
805     #[label(label_unmatched)]
806     pub unmatched: Span,
807     #[label(label_opening_candidate)]
808     pub opening_candidate: Option<Span>,
809     #[label(label_unclosed)]
810     pub unclosed: Option<Span>,
811 }
812
813 #[derive(Diagnostic)]
814 #[diag(parser_incorrect_visibility_restriction, code = "E0704")]
815 #[help]
816 pub(crate) struct IncorrectVisibilityRestriction {
817     #[primary_span]
818     #[suggestion(code = "in {inner_str}", applicability = "machine-applicable")]
819     pub span: Span,
820     pub inner_str: String,
821 }
822
823 #[derive(Diagnostic)]
824 #[diag(parser_assignment_else_not_allowed)]
825 pub(crate) struct AssignmentElseNotAllowed {
826     #[primary_span]
827     pub span: Span,
828 }
829
830 #[derive(Diagnostic)]
831 #[diag(parser_expected_statement_after_outer_attr)]
832 pub(crate) struct ExpectedStatementAfterOuterAttr {
833     #[primary_span]
834     pub span: Span,
835 }
836
837 #[derive(Diagnostic)]
838 #[diag(parser_doc_comment_does_not_document_anything, code = "E0585")]
839 #[help]
840 pub(crate) struct DocCommentDoesNotDocumentAnything {
841     #[primary_span]
842     pub span: Span,
843     #[suggestion(code = ",", applicability = "machine-applicable")]
844     pub missing_comma: Option<Span>,
845 }
846
847 #[derive(Diagnostic)]
848 #[diag(parser_const_let_mutually_exclusive)]
849 pub(crate) struct ConstLetMutuallyExclusive {
850     #[primary_span]
851     #[suggestion(code = "const", applicability = "maybe-incorrect")]
852     pub span: Span,
853 }
854
855 #[derive(Diagnostic)]
856 #[diag(parser_invalid_expression_in_let_else)]
857 pub(crate) struct InvalidExpressionInLetElse {
858     #[primary_span]
859     pub span: Span,
860     pub operator: &'static str,
861     #[subdiagnostic]
862     pub sugg: WrapExpressionInParentheses,
863 }
864
865 #[derive(Diagnostic)]
866 #[diag(parser_invalid_curly_in_let_else)]
867 pub(crate) struct InvalidCurlyInLetElse {
868     #[primary_span]
869     pub span: Span,
870     #[subdiagnostic]
871     pub sugg: WrapExpressionInParentheses,
872 }
873
874 #[derive(Diagnostic)]
875 #[diag(parser_compound_assignment_expression_in_let)]
876 #[help]
877 pub(crate) struct CompoundAssignmentExpressionInLet {
878     #[primary_span]
879     #[suggestion(style = "short", code = "=", applicability = "maybe-incorrect")]
880     pub span: Span,
881 }
882
883 #[derive(Diagnostic)]
884 #[diag(parser_suffixed_literal_in_attribute)]
885 #[help]
886 pub(crate) struct SuffixedLiteralInAttribute {
887     #[primary_span]
888     pub span: Span,
889 }
890
891 #[derive(Diagnostic)]
892 #[diag(parser_invalid_meta_item)]
893 pub(crate) struct InvalidMetaItem {
894     #[primary_span]
895     pub span: Span,
896     pub token: Token,
897 }
898
899 #[derive(Subdiagnostic)]
900 #[suggestion(
901     parser_sugg_escape_to_use_as_identifier,
902     style = "verbose",
903     applicability = "maybe-incorrect",
904     code = "r#"
905 )]
906 pub(crate) struct SuggEscapeToUseAsIdentifier {
907     #[primary_span]
908     pub span: Span,
909     pub ident_name: String,
910 }
911
912 #[derive(Subdiagnostic)]
913 #[suggestion(parser_sugg_remove_comma, applicability = "machine-applicable", code = "")]
914 pub(crate) struct SuggRemoveComma {
915     #[primary_span]
916     pub span: Span,
917 }
918
919 #[derive(Subdiagnostic)]
920 pub(crate) enum ExpectedIdentifierFound {
921     #[label(parser_expected_identifier_found_reserved_identifier)]
922     ReservedIdentifier(#[primary_span] Span),
923     #[label(parser_expected_identifier_found_keyword)]
924     Keyword(#[primary_span] Span),
925     #[label(parser_expected_identifier_found_reserved_keyword)]
926     ReservedKeyword(#[primary_span] Span),
927     #[label(parser_expected_identifier_found_doc_comment)]
928     DocComment(#[primary_span] Span),
929     #[label(parser_expected_identifier)]
930     Other(#[primary_span] Span),
931 }
932
933 impl ExpectedIdentifierFound {
934     pub fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
935         (match token_descr {
936             Some(TokenDescription::ReservedIdentifier) => {
937                 ExpectedIdentifierFound::ReservedIdentifier
938             }
939             Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword,
940             Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
941             Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment,
942             None => ExpectedIdentifierFound::Other,
943         })(span)
944     }
945 }
946
947 pub(crate) struct ExpectedIdentifier {
948     pub span: Span,
949     pub token: Token,
950     pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>,
951     pub suggest_remove_comma: Option<SuggRemoveComma>,
952 }
953
954 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
955     #[track_caller]
956     fn into_diagnostic(
957         self,
958         handler: &'a rustc_errors::Handler,
959     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
960         let token_descr = super::parser::TokenDescription::from_token(&self.token);
961
962         let mut diag = handler.struct_diagnostic(match token_descr {
963             Some(TokenDescription::ReservedIdentifier) => {
964                 fluent::parser_expected_identifier_found_reserved_identifier_str
965             }
966             Some(TokenDescription::Keyword) => fluent::parser_expected_identifier_found_keyword_str,
967             Some(TokenDescription::ReservedKeyword) => {
968                 fluent::parser_expected_identifier_found_reserved_keyword_str
969             }
970             Some(TokenDescription::DocComment) => {
971                 fluent::parser_expected_identifier_found_doc_comment_str
972             }
973             None => fluent::parser_expected_identifier_found_str,
974         });
975         diag.set_span(self.span);
976         diag.set_arg("token", self.token);
977
978         if let Some(sugg) = self.suggest_raw {
979             sugg.add_to_diagnostic(&mut diag);
980         }
981
982         ExpectedIdentifierFound::new(token_descr, self.span).add_to_diagnostic(&mut diag);
983
984         if let Some(sugg) = self.suggest_remove_comma {
985             sugg.add_to_diagnostic(&mut diag);
986         }
987
988         diag
989     }
990 }
991
992 pub(crate) struct ExpectedSemi {
993     pub span: Span,
994     pub token: Token,
995
996     pub unexpected_token_label: Option<Span>,
997     pub sugg: ExpectedSemiSugg,
998 }
999
1000 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
1001     #[track_caller]
1002     fn into_diagnostic(
1003         self,
1004         handler: &'a rustc_errors::Handler,
1005     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
1006         let token_descr = super::parser::TokenDescription::from_token(&self.token);
1007
1008         let mut diag = handler.struct_diagnostic(match token_descr {
1009             Some(TokenDescription::ReservedIdentifier) => {
1010                 fluent::parser_expected_semi_found_reserved_identifier_str
1011             }
1012             Some(TokenDescription::Keyword) => fluent::parser_expected_semi_found_keyword_str,
1013             Some(TokenDescription::ReservedKeyword) => {
1014                 fluent::parser_expected_semi_found_reserved_keyword_str
1015             }
1016             Some(TokenDescription::DocComment) => {
1017                 fluent::parser_expected_semi_found_doc_comment_str
1018             }
1019             None => fluent::parser_expected_semi_found_str,
1020         });
1021         diag.set_span(self.span);
1022         diag.set_arg("token", self.token);
1023
1024         if let Some(unexpected_token_label) = self.unexpected_token_label {
1025             diag.span_label(unexpected_token_label, fluent::parser_label_unexpected_token);
1026         }
1027
1028         self.sugg.add_to_diagnostic(&mut diag);
1029
1030         diag
1031     }
1032 }
1033
1034 #[derive(Subdiagnostic)]
1035 pub(crate) enum ExpectedSemiSugg {
1036     #[suggestion(
1037         parser_sugg_change_this_to_semi,
1038         code = ";",
1039         applicability = "machine-applicable"
1040     )]
1041     ChangeToSemi(#[primary_span] Span),
1042     #[suggestion(
1043         parser_sugg_add_semi,
1044         style = "short",
1045         code = ";",
1046         applicability = "machine-applicable"
1047     )]
1048     AddSemi(#[primary_span] Span),
1049 }
1050
1051 #[derive(Diagnostic)]
1052 #[diag(parser_struct_literal_body_without_path)]
1053 pub(crate) struct StructLiteralBodyWithoutPath {
1054     #[primary_span]
1055     pub span: Span,
1056     #[subdiagnostic]
1057     pub sugg: StructLiteralBodyWithoutPathSugg,
1058 }
1059
1060 #[derive(Subdiagnostic)]
1061 #[multipart_suggestion(suggestion, applicability = "has-placeholders")]
1062 pub(crate) struct StructLiteralBodyWithoutPathSugg {
1063     #[suggestion_part(code = "{{ SomeStruct ")]
1064     pub before: Span,
1065     #[suggestion_part(code = " }}")]
1066     pub after: Span,
1067 }
1068
1069 #[derive(Diagnostic)]
1070 #[diag(parser_unmatched_angle_brackets)]
1071 pub(crate) struct UnmatchedAngleBrackets {
1072     #[primary_span]
1073     #[suggestion(code = "", applicability = "machine-applicable")]
1074     pub span: Span,
1075     pub num_extra_brackets: usize,
1076 }
1077
1078 #[derive(Diagnostic)]
1079 #[diag(parser_generic_parameters_without_angle_brackets)]
1080 pub(crate) struct GenericParamsWithoutAngleBrackets {
1081     #[primary_span]
1082     pub span: Span,
1083     #[subdiagnostic]
1084     pub sugg: GenericParamsWithoutAngleBracketsSugg,
1085 }
1086
1087 #[derive(Subdiagnostic)]
1088 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1089 pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
1090     #[suggestion_part(code = "<")]
1091     pub left: Span,
1092     #[suggestion_part(code = ">")]
1093     pub right: Span,
1094 }
1095
1096 #[derive(Diagnostic)]
1097 #[diag(parser_comparison_operators_cannot_be_chained)]
1098 pub(crate) struct ComparisonOperatorsCannotBeChained {
1099     #[primary_span]
1100     pub span: Vec<Span>,
1101     #[suggestion(
1102         parser_sugg_turbofish_syntax,
1103         style = "verbose",
1104         code = "::",
1105         applicability = "maybe-incorrect"
1106     )]
1107     pub suggest_turbofish: Option<Span>,
1108     #[help(parser_sugg_turbofish_syntax)]
1109     #[help(sugg_parentheses_for_function_args)]
1110     pub help_turbofish: Option<()>,
1111     #[subdiagnostic]
1112     pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
1113 }
1114
1115 #[derive(Subdiagnostic)]
1116 pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
1117     #[suggestion(
1118         sugg_split_comparison,
1119         style = "verbose",
1120         code = " && {middle_term}",
1121         applicability = "maybe-incorrect"
1122     )]
1123     SplitComparison {
1124         #[primary_span]
1125         span: Span,
1126         middle_term: String,
1127     },
1128     #[multipart_suggestion(sugg_parenthesize, applicability = "maybe-incorrect")]
1129     Parenthesize {
1130         #[suggestion_part(code = "(")]
1131         left: Span,
1132         #[suggestion_part(code = ")")]
1133         right: Span,
1134     },
1135 }
1136
1137 #[derive(Diagnostic)]
1138 #[diag(parser_question_mark_in_type)]
1139 pub(crate) struct QuestionMarkInType {
1140     #[primary_span]
1141     #[label]
1142     pub span: Span,
1143     #[subdiagnostic]
1144     pub sugg: QuestionMarkInTypeSugg,
1145 }
1146
1147 #[derive(Subdiagnostic)]
1148 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1149 pub(crate) struct QuestionMarkInTypeSugg {
1150     #[suggestion_part(code = "Option<")]
1151     pub left: Span,
1152     #[suggestion_part(code = ">")]
1153     pub right: Span,
1154 }
1155
1156 #[derive(Diagnostic)]
1157 #[diag(parser_unexpected_parentheses_in_for_head)]
1158 pub(crate) struct ParenthesesInForHead {
1159     #[primary_span]
1160     pub span: Vec<Span>,
1161     #[subdiagnostic]
1162     pub sugg: ParenthesesInForHeadSugg,
1163 }
1164
1165 #[derive(Subdiagnostic)]
1166 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1167 pub(crate) struct ParenthesesInForHeadSugg {
1168     #[suggestion_part(code = "")]
1169     pub left: Span,
1170     #[suggestion_part(code = "")]
1171     pub right: Span,
1172 }
1173
1174 #[derive(Diagnostic)]
1175 #[diag(parser_doc_comment_on_param_type)]
1176 pub(crate) struct DocCommentOnParamType {
1177     #[primary_span]
1178     #[label]
1179     pub span: Span,
1180 }
1181
1182 #[derive(Diagnostic)]
1183 #[diag(parser_attribute_on_param_type)]
1184 pub(crate) struct AttributeOnParamType {
1185     #[primary_span]
1186     #[label]
1187     pub span: Span,
1188 }
1189
1190 #[derive(Diagnostic)]
1191 #[diag(parser_pattern_method_param_without_body, code = "E0642")]
1192 pub(crate) struct PatternMethodParamWithoutBody {
1193     #[primary_span]
1194     #[suggestion(code = "_", applicability = "machine-applicable")]
1195     pub span: Span,
1196 }
1197
1198 #[derive(Diagnostic)]
1199 #[diag(parser_self_param_not_first)]
1200 pub(crate) struct SelfParamNotFirst {
1201     #[primary_span]
1202     #[label]
1203     pub span: Span,
1204 }
1205
1206 #[derive(Diagnostic)]
1207 #[diag(parser_const_generic_without_braces)]
1208 pub(crate) struct ConstGenericWithoutBraces {
1209     #[primary_span]
1210     pub span: Span,
1211     #[subdiagnostic]
1212     pub sugg: ConstGenericWithoutBracesSugg,
1213 }
1214
1215 #[derive(Subdiagnostic)]
1216 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1217 pub(crate) struct ConstGenericWithoutBracesSugg {
1218     #[suggestion_part(code = "{{ ")]
1219     pub left: Span,
1220     #[suggestion_part(code = " }}")]
1221     pub right: Span,
1222 }
1223
1224 #[derive(Diagnostic)]
1225 #[diag(parser_unexpected_const_param_declaration)]
1226 pub(crate) struct UnexpectedConstParamDeclaration {
1227     #[primary_span]
1228     #[label]
1229     pub span: Span,
1230     #[subdiagnostic]
1231     pub sugg: Option<UnexpectedConstParamDeclarationSugg>,
1232 }
1233
1234 #[derive(Subdiagnostic)]
1235 pub(crate) enum UnexpectedConstParamDeclarationSugg {
1236     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1237     AddParam {
1238         #[suggestion_part(code = "<{snippet}>")]
1239         impl_generics: Span,
1240         #[suggestion_part(code = "{ident}")]
1241         incorrect_decl: Span,
1242         snippet: String,
1243         ident: String,
1244     },
1245     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1246     AppendParam {
1247         #[suggestion_part(code = ", {snippet}")]
1248         impl_generics_end: Span,
1249         #[suggestion_part(code = "{ident}")]
1250         incorrect_decl: Span,
1251         snippet: String,
1252         ident: String,
1253     },
1254 }
1255
1256 #[derive(Diagnostic)]
1257 #[diag(parser_unexpected_const_in_generic_param)]
1258 pub(crate) struct UnexpectedConstInGenericParam {
1259     #[primary_span]
1260     pub span: Span,
1261     #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")]
1262     pub to_remove: Option<Span>,
1263 }
1264
1265 #[derive(Diagnostic)]
1266 #[diag(parser_async_move_order_incorrect)]
1267 pub(crate) struct AsyncMoveOrderIncorrect {
1268     #[primary_span]
1269     #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")]
1270     pub span: Span,
1271 }
1272
1273 #[derive(Diagnostic)]
1274 #[diag(parser_double_colon_in_bound)]
1275 pub(crate) struct DoubleColonInBound {
1276     #[primary_span]
1277     pub span: Span,
1278     #[suggestion(code = ": ", applicability = "machine-applicable")]
1279     pub between: Span,
1280 }