]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/errors.rs
Convert all #[suggestion_*] attributes to #[suggestion(style = "...")]
[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_invalid_block_macro_segment)]
373 pub(crate) struct InvalidBlockMacroSegment {
374     #[primary_span]
375     pub span: Span,
376     #[label]
377     pub context: Span,
378 }
379
380 #[derive(Diagnostic)]
381 #[diag(parser_if_expression_missing_then_block)]
382 pub(crate) struct IfExpressionMissingThenBlock {
383     #[primary_span]
384     pub if_span: Span,
385     #[subdiagnostic]
386     pub sub: IfExpressionMissingThenBlockSub,
387 }
388
389 #[derive(Subdiagnostic)]
390 pub(crate) enum IfExpressionMissingThenBlockSub {
391     #[help(condition_possibly_unfinished)]
392     UnfinishedCondition(#[primary_span] Span),
393     #[help(add_then_block)]
394     AddThenBlock(#[primary_span] Span),
395 }
396
397 #[derive(Diagnostic)]
398 #[diag(parser_if_expression_missing_condition)]
399 pub(crate) struct IfExpressionMissingCondition {
400     #[primary_span]
401     #[label(condition_label)]
402     pub if_span: Span,
403     #[label(block_label)]
404     pub block_span: Span,
405 }
406
407 #[derive(Diagnostic)]
408 #[diag(parser_expected_expression_found_let)]
409 pub(crate) struct ExpectedExpressionFoundLet {
410     #[primary_span]
411     pub span: Span,
412 }
413
414 #[derive(Diagnostic)]
415 #[diag(parser_expected_else_block)]
416 pub(crate) struct ExpectedElseBlock {
417     #[primary_span]
418     pub first_tok_span: Span,
419     pub first_tok: String,
420     #[label]
421     pub else_span: Span,
422     #[suggestion(applicability = "maybe-incorrect", code = "if ")]
423     pub condition_start: Span,
424 }
425
426 #[derive(Diagnostic)]
427 #[diag(parser_outer_attribute_not_allowed_on_if_else)]
428 pub(crate) struct OuterAttributeNotAllowedOnIfElse {
429     #[primary_span]
430     pub last: Span,
431
432     #[label(branch_label)]
433     pub branch_span: Span,
434
435     #[label(ctx_label)]
436     pub ctx_span: Span,
437     pub ctx: String,
438
439     #[suggestion(applicability = "machine-applicable", code = "")]
440     pub attributes: Span,
441 }
442
443 #[derive(Diagnostic)]
444 #[diag(parser_missing_in_in_for_loop)]
445 pub(crate) struct MissingInInForLoop {
446     #[primary_span]
447     pub span: Span,
448     #[subdiagnostic]
449     pub sub: MissingInInForLoopSub,
450 }
451
452 #[derive(Subdiagnostic)]
453 pub(crate) enum MissingInInForLoopSub {
454     // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect
455     #[suggestion(use_in_not_of, style = "short", applicability = "maybe-incorrect", code = "in")]
456     InNotOf(#[primary_span] Span),
457     #[suggestion(add_in, style = "short", applicability = "maybe-incorrect", code = " in ")]
458     AddIn(#[primary_span] Span),
459 }
460
461 #[derive(Diagnostic)]
462 #[diag(parser_missing_comma_after_match_arm)]
463 pub(crate) struct MissingCommaAfterMatchArm {
464     #[primary_span]
465     #[suggestion(applicability = "machine-applicable", code = ",")]
466     pub span: Span,
467 }
468
469 #[derive(Diagnostic)]
470 #[diag(parser_catch_after_try)]
471 #[help]
472 pub(crate) struct CatchAfterTry {
473     #[primary_span]
474     pub span: Span,
475 }
476
477 #[derive(Diagnostic)]
478 #[diag(parser_comma_after_base_struct)]
479 #[note]
480 pub(crate) struct CommaAfterBaseStruct {
481     #[primary_span]
482     pub span: Span,
483     #[suggestion(style = "short", applicability = "machine-applicable", code = "")]
484     pub comma: Span,
485 }
486
487 #[derive(Diagnostic)]
488 #[diag(parser_eq_field_init)]
489 pub(crate) struct EqFieldInit {
490     #[primary_span]
491     pub span: Span,
492     #[suggestion(applicability = "machine-applicable", code = ":")]
493     pub eq: Span,
494 }
495
496 #[derive(Diagnostic)]
497 #[diag(parser_dotdotdot)]
498 pub(crate) struct DotDotDot {
499     #[primary_span]
500     #[suggestion(suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
501     #[suggestion(suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
502     pub span: Span,
503 }
504
505 #[derive(Diagnostic)]
506 #[diag(parser_left_arrow_operator)]
507 pub(crate) struct LeftArrowOperator {
508     #[primary_span]
509     #[suggestion(applicability = "maybe-incorrect", code = "< -")]
510     pub span: Span,
511 }
512
513 #[derive(Diagnostic)]
514 #[diag(parser_remove_let)]
515 pub(crate) struct RemoveLet {
516     #[primary_span]
517     #[suggestion(applicability = "machine-applicable", code = "")]
518     pub span: Span,
519 }
520
521 #[derive(Diagnostic)]
522 #[diag(parser_use_eq_instead)]
523 pub(crate) struct UseEqInstead {
524     #[primary_span]
525     #[suggestion(style = "short", applicability = "machine-applicable", code = "=")]
526     pub span: Span,
527 }
528
529 #[derive(Diagnostic)]
530 #[diag(parser_use_empty_block_not_semi)]
531 pub(crate) struct UseEmptyBlockNotSemi {
532     #[primary_span]
533     #[suggestion(style = "hidden", applicability = "machine-applicable", code = "{{}}")]
534     pub span: Span,
535 }
536
537 #[derive(Diagnostic)]
538 #[diag(parser_comparison_interpreted_as_generic)]
539 pub(crate) struct ComparisonInterpretedAsGeneric {
540     #[primary_span]
541     #[label(label_comparison)]
542     pub comparison: Span,
543     pub r#type: Path,
544     #[label(label_args)]
545     pub args: Span,
546     #[subdiagnostic]
547     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
548 }
549
550 #[derive(Diagnostic)]
551 #[diag(parser_shift_interpreted_as_generic)]
552 pub(crate) struct ShiftInterpretedAsGeneric {
553     #[primary_span]
554     #[label(label_comparison)]
555     pub shift: Span,
556     pub r#type: Path,
557     #[label(label_args)]
558     pub args: Span,
559     #[subdiagnostic]
560     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
561 }
562
563 #[derive(Subdiagnostic)]
564 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
565 pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
566     #[suggestion_part(code = "(")]
567     pub left: Span,
568     #[suggestion_part(code = ")")]
569     pub right: Span,
570 }
571
572 #[derive(Diagnostic)]
573 #[diag(parser_found_expr_would_be_stmt)]
574 pub(crate) struct FoundExprWouldBeStmt {
575     #[primary_span]
576     #[label]
577     pub span: Span,
578     pub token: Token,
579     #[subdiagnostic]
580     pub suggestion: ExprParenthesesNeeded,
581 }
582
583 #[derive(Diagnostic)]
584 #[diag(parser_leading_plus_not_supported)]
585 pub(crate) struct LeadingPlusNotSupported {
586     #[primary_span]
587     #[label]
588     pub span: Span,
589     #[suggestion(
590         suggestion_remove_plus,
591         style = "verbose",
592         code = "",
593         applicability = "machine-applicable"
594     )]
595     pub remove_plus: Option<Span>,
596     #[subdiagnostic]
597     pub add_parentheses: Option<ExprParenthesesNeeded>,
598 }
599
600 #[derive(Diagnostic)]
601 #[diag(parser_parentheses_with_struct_fields)]
602 pub(crate) struct ParenthesesWithStructFields {
603     #[primary_span]
604     pub span: Span,
605     pub r#type: Path,
606     #[subdiagnostic]
607     pub braces_for_struct: BracesForStructLiteral,
608     #[subdiagnostic]
609     pub no_fields_for_fn: NoFieldsForFnCall,
610 }
611
612 #[derive(Subdiagnostic)]
613 #[multipart_suggestion(suggestion_braces_for_struct, applicability = "maybe-incorrect")]
614 pub(crate) struct BracesForStructLiteral {
615     #[suggestion_part(code = " {{ ")]
616     pub first: Span,
617     #[suggestion_part(code = " }}")]
618     pub second: Span,
619 }
620
621 #[derive(Subdiagnostic)]
622 #[multipart_suggestion(suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
623 pub(crate) struct NoFieldsForFnCall {
624     #[suggestion_part(code = "")]
625     pub fields: Vec<Span>,
626 }
627
628 #[derive(Diagnostic)]
629 #[diag(parser_labeled_loop_in_break)]
630 pub(crate) struct LabeledLoopInBreak {
631     #[primary_span]
632     pub span: Span,
633     #[subdiagnostic]
634     pub sub: WrapExpressionInParentheses,
635 }
636
637 #[derive(Subdiagnostic)]
638 #[multipart_suggestion(
639     parser_sugg_wrap_expression_in_parentheses,
640     applicability = "machine-applicable"
641 )]
642 pub(crate) struct WrapExpressionInParentheses {
643     #[suggestion_part(code = "(")]
644     pub left: Span,
645     #[suggestion_part(code = ")")]
646     pub right: Span,
647 }
648
649 #[derive(Diagnostic)]
650 #[diag(parser_array_brackets_instead_of_braces)]
651 pub(crate) struct ArrayBracketsInsteadOfSpaces {
652     #[primary_span]
653     pub span: Span,
654     #[subdiagnostic]
655     pub sub: ArrayBracketsInsteadOfSpacesSugg,
656 }
657
658 #[derive(Subdiagnostic)]
659 #[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
660 pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
661     #[suggestion_part(code = "[")]
662     pub left: Span,
663     #[suggestion_part(code = "]")]
664     pub right: Span,
665 }
666
667 #[derive(Diagnostic)]
668 #[diag(parser_match_arm_body_without_braces)]
669 pub(crate) struct MatchArmBodyWithoutBraces {
670     #[primary_span]
671     #[label(label_statements)]
672     pub statements: Span,
673     #[label(label_arrow)]
674     pub arrow: Span,
675     pub num_statements: usize,
676     #[subdiagnostic]
677     pub sub: MatchArmBodyWithoutBracesSugg,
678 }
679
680 #[derive(Subdiagnostic)]
681 pub(crate) enum MatchArmBodyWithoutBracesSugg {
682     #[multipart_suggestion(suggestion_add_braces, applicability = "machine-applicable")]
683     AddBraces {
684         #[suggestion_part(code = "{{ ")]
685         left: Span,
686         #[suggestion_part(code = " }}")]
687         right: Span,
688     },
689     #[suggestion(
690         suggestion_use_comma_not_semicolon,
691         code = ",",
692         applicability = "machine-applicable"
693     )]
694     UseComma {
695         #[primary_span]
696         semicolon: Span,
697     },
698 }
699
700 #[derive(Diagnostic)]
701 #[diag(parser_struct_literal_not_allowed_here)]
702 pub(crate) struct StructLiteralNotAllowedHere {
703     #[primary_span]
704     pub span: Span,
705     #[subdiagnostic]
706     pub sub: StructLiteralNotAllowedHereSugg,
707 }
708
709 #[derive(Subdiagnostic)]
710 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
711 pub(crate) struct StructLiteralNotAllowedHereSugg {
712     #[suggestion_part(code = "(")]
713     pub left: Span,
714     #[suggestion_part(code = ")")]
715     pub right: Span,
716 }
717
718 #[derive(Diagnostic)]
719 #[diag(parser_invalid_interpolated_expression)]
720 pub(crate) struct InvalidInterpolatedExpression {
721     #[primary_span]
722     pub span: Span,
723 }
724
725 #[derive(Diagnostic)]
726 #[diag(parser_hexadecimal_float_literal_not_supported)]
727 pub(crate) struct HexadecimalFloatLiteralNotSupported {
728     #[primary_span]
729     #[label(parser_not_supported)]
730     pub span: Span,
731 }
732
733 #[derive(Diagnostic)]
734 #[diag(parser_octal_float_literal_not_supported)]
735 pub(crate) struct OctalFloatLiteralNotSupported {
736     #[primary_span]
737     #[label(parser_not_supported)]
738     pub span: Span,
739 }
740
741 #[derive(Diagnostic)]
742 #[diag(parser_binary_float_literal_not_supported)]
743 pub(crate) struct BinaryFloatLiteralNotSupported {
744     #[primary_span]
745     #[label(parser_not_supported)]
746     pub span: Span,
747 }
748
749 #[derive(Diagnostic)]
750 #[diag(parser_invalid_literal_suffix)]
751 pub(crate) struct InvalidLiteralSuffix {
752     #[primary_span]
753     #[label]
754     pub span: Span,
755     // FIXME(#100717)
756     pub kind: String,
757     pub suffix: Symbol,
758 }
759
760 #[derive(Diagnostic)]
761 #[diag(parser_invalid_literal_suffix_on_tuple_index)]
762 pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
763     #[primary_span]
764     #[label]
765     pub span: Span,
766     pub suffix: Symbol,
767     #[help(tuple_exception_line_1)]
768     #[help(tuple_exception_line_2)]
769     #[help(tuple_exception_line_3)]
770     pub exception: Option<()>,
771 }
772
773 #[derive(Diagnostic)]
774 #[diag(parser_non_string_abi_literal)]
775 pub(crate) struct NonStringAbiLiteral {
776     #[primary_span]
777     #[suggestion(code = "\"C\"", applicability = "maybe-incorrect")]
778     pub span: Span,
779 }
780
781 #[derive(Diagnostic)]
782 #[diag(parser_mismatched_closing_delimiter)]
783 pub(crate) struct MismatchedClosingDelimiter {
784     #[primary_span]
785     pub spans: Vec<Span>,
786     pub delimiter: String,
787     #[label(label_unmatched)]
788     pub unmatched: Span,
789     #[label(label_opening_candidate)]
790     pub opening_candidate: Option<Span>,
791     #[label(label_unclosed)]
792     pub unclosed: Option<Span>,
793 }
794
795 #[derive(Diagnostic)]
796 #[diag(parser_incorrect_visibility_restriction, code = "E0704")]
797 #[help]
798 pub(crate) struct IncorrectVisibilityRestriction {
799     #[primary_span]
800     #[suggestion(code = "in {inner_str}", applicability = "machine-applicable")]
801     pub span: Span,
802     pub inner_str: String,
803 }
804
805 #[derive(Diagnostic)]
806 #[diag(parser_assignment_else_not_allowed)]
807 pub(crate) struct AssignmentElseNotAllowed {
808     #[primary_span]
809     pub span: Span,
810 }
811
812 #[derive(Diagnostic)]
813 #[diag(parser_expected_statement_after_outer_attr)]
814 pub(crate) struct ExpectedStatementAfterOuterAttr {
815     #[primary_span]
816     pub span: Span,
817 }
818
819 #[derive(Diagnostic)]
820 #[diag(parser_doc_comment_does_not_document_anything, code = "E0585")]
821 #[help]
822 pub(crate) struct DocCommentDoesNotDocumentAnything {
823     #[primary_span]
824     pub span: Span,
825     #[suggestion(code = ",", applicability = "machine-applicable")]
826     pub missing_comma: Option<Span>,
827 }
828
829 #[derive(Diagnostic)]
830 #[diag(parser_const_let_mutually_exclusive)]
831 pub(crate) struct ConstLetMutuallyExclusive {
832     #[primary_span]
833     #[suggestion(code = "const", applicability = "maybe-incorrect")]
834     pub span: Span,
835 }
836
837 #[derive(Diagnostic)]
838 #[diag(parser_invalid_expression_in_let_else)]
839 pub(crate) struct InvalidExpressionInLetElse {
840     #[primary_span]
841     pub span: Span,
842     pub operator: &'static str,
843     #[subdiagnostic]
844     pub sugg: WrapExpressionInParentheses,
845 }
846
847 #[derive(Diagnostic)]
848 #[diag(parser_invalid_curly_in_let_else)]
849 pub(crate) struct InvalidCurlyInLetElse {
850     #[primary_span]
851     pub span: Span,
852     #[subdiagnostic]
853     pub sugg: WrapExpressionInParentheses,
854 }
855
856 #[derive(Diagnostic)]
857 #[diag(parser_compound_assignment_expression_in_let)]
858 #[help]
859 pub(crate) struct CompoundAssignmentExpressionInLet {
860     #[primary_span]
861     #[suggestion(style = "short", code = "=", applicability = "maybe-incorrect")]
862     pub span: Span,
863 }
864
865 #[derive(Diagnostic)]
866 #[diag(parser_suffixed_literal_in_attribute)]
867 #[help]
868 pub(crate) struct SuffixedLiteralInAttribute {
869     #[primary_span]
870     pub span: Span,
871 }
872
873 #[derive(Diagnostic)]
874 #[diag(parser_invalid_meta_item)]
875 pub(crate) struct InvalidMetaItem {
876     #[primary_span]
877     pub span: Span,
878     pub token: Token,
879 }
880
881 #[derive(Subdiagnostic)]
882 #[suggestion(
883     parser_sugg_escape_to_use_as_identifier,
884     style = "verbose",
885     applicability = "maybe-incorrect",
886     code = "r#"
887 )]
888 pub(crate) struct SuggEscapeToUseAsIdentifier {
889     #[primary_span]
890     pub span: Span,
891     pub ident_name: String,
892 }
893
894 #[derive(Subdiagnostic)]
895 #[suggestion(parser_sugg_remove_comma, applicability = "machine-applicable", code = "")]
896 pub(crate) struct SuggRemoveComma {
897     #[primary_span]
898     pub span: Span,
899 }
900
901 #[derive(Subdiagnostic)]
902 pub(crate) enum ExpectedIdentifierFound {
903     #[label(parser_expected_identifier_found_reserved_identifier)]
904     ReservedIdentifier(#[primary_span] Span),
905     #[label(parser_expected_identifier_found_keyword)]
906     Keyword(#[primary_span] Span),
907     #[label(parser_expected_identifier_found_reserved_keyword)]
908     ReservedKeyword(#[primary_span] Span),
909     #[label(parser_expected_identifier_found_doc_comment)]
910     DocComment(#[primary_span] Span),
911     #[label(parser_expected_identifier)]
912     Other(#[primary_span] Span),
913 }
914
915 impl ExpectedIdentifierFound {
916     pub fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
917         (match token_descr {
918             Some(TokenDescription::ReservedIdentifier) => {
919                 ExpectedIdentifierFound::ReservedIdentifier
920             }
921             Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword,
922             Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
923             Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment,
924             None => ExpectedIdentifierFound::Other,
925         })(span)
926     }
927 }
928
929 pub(crate) struct ExpectedIdentifier {
930     pub span: Span,
931     pub token: Token,
932     pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>,
933     pub suggest_remove_comma: Option<SuggRemoveComma>,
934 }
935
936 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
937     fn into_diagnostic(
938         self,
939         handler: &'a rustc_errors::Handler,
940     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
941         let token_descr = super::parser::TokenDescription::from_token(&self.token);
942
943         let mut diag = handler.struct_diagnostic(match token_descr {
944             Some(TokenDescription::ReservedIdentifier) => {
945                 fluent::parser_expected_identifier_found_reserved_identifier_str
946             }
947             Some(TokenDescription::Keyword) => fluent::parser_expected_identifier_found_keyword_str,
948             Some(TokenDescription::ReservedKeyword) => {
949                 fluent::parser_expected_identifier_found_reserved_keyword_str
950             }
951             Some(TokenDescription::DocComment) => {
952                 fluent::parser_expected_identifier_found_doc_comment_str
953             }
954             None => fluent::parser_expected_identifier_found_str,
955         });
956         diag.set_span(self.span);
957         diag.set_arg("token", self.token);
958
959         if let Some(sugg) = self.suggest_raw {
960             sugg.add_to_diagnostic(&mut diag);
961         }
962
963         ExpectedIdentifierFound::new(token_descr, self.span).add_to_diagnostic(&mut diag);
964
965         if let Some(sugg) = self.suggest_remove_comma {
966             sugg.add_to_diagnostic(&mut diag);
967         }
968
969         diag
970     }
971 }
972
973 pub(crate) struct ExpectedSemi {
974     pub span: Span,
975     pub token: Token,
976
977     pub unexpected_token_label: Option<Span>,
978     pub sugg: ExpectedSemiSugg,
979 }
980
981 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
982     fn into_diagnostic(
983         self,
984         handler: &'a rustc_errors::Handler,
985     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
986         let token_descr = super::parser::TokenDescription::from_token(&self.token);
987
988         let mut diag = handler.struct_diagnostic(match token_descr {
989             Some(TokenDescription::ReservedIdentifier) => {
990                 fluent::parser_expected_semi_found_reserved_identifier_str
991             }
992             Some(TokenDescription::Keyword) => fluent::parser_expected_semi_found_keyword_str,
993             Some(TokenDescription::ReservedKeyword) => {
994                 fluent::parser_expected_semi_found_reserved_keyword_str
995             }
996             Some(TokenDescription::DocComment) => {
997                 fluent::parser_expected_semi_found_doc_comment_str
998             }
999             None => fluent::parser_expected_semi_found_str,
1000         });
1001         diag.set_span(self.span);
1002         diag.set_arg("token", self.token);
1003
1004         if let Some(unexpected_token_label) = self.unexpected_token_label {
1005             diag.span_label(unexpected_token_label, fluent::parser_label_unexpected_token);
1006         }
1007
1008         self.sugg.add_to_diagnostic(&mut diag);
1009
1010         diag
1011     }
1012 }
1013
1014 #[derive(Subdiagnostic)]
1015 pub(crate) enum ExpectedSemiSugg {
1016     #[suggestion(
1017         parser_sugg_change_this_to_semi,
1018         code = ";",
1019         applicability = "machine-applicable"
1020     )]
1021     ChangeToSemi(#[primary_span] Span),
1022     #[suggestion(
1023         parser_sugg_add_semi,
1024         style = "short",
1025         code = ";",
1026         applicability = "machine-applicable"
1027     )]
1028     AddSemi(#[primary_span] Span),
1029 }
1030
1031 #[derive(Diagnostic)]
1032 #[diag(parser_struct_literal_body_without_path)]
1033 pub(crate) struct StructLiteralBodyWithoutPath {
1034     #[primary_span]
1035     pub span: Span,
1036     #[subdiagnostic]
1037     pub sugg: StructLiteralBodyWithoutPathSugg,
1038 }
1039
1040 #[derive(Subdiagnostic)]
1041 #[multipart_suggestion(suggestion, applicability = "has-placeholders")]
1042 pub(crate) struct StructLiteralBodyWithoutPathSugg {
1043     #[suggestion_part(code = "{{ SomeStruct ")]
1044     pub before: Span,
1045     #[suggestion_part(code = " }}")]
1046     pub after: Span,
1047 }
1048
1049 #[derive(Diagnostic)]
1050 #[diag(parser_unmatched_angle_brackets)]
1051 pub(crate) struct UnmatchedAngleBrackets {
1052     #[primary_span]
1053     #[suggestion(code = "", applicability = "machine-applicable")]
1054     pub span: Span,
1055     pub num_extra_brackets: usize,
1056 }
1057
1058 #[derive(Diagnostic)]
1059 #[diag(parser_generic_parameters_without_angle_brackets)]
1060 pub(crate) struct GenericParamsWithoutAngleBrackets {
1061     #[primary_span]
1062     pub span: Span,
1063     #[subdiagnostic]
1064     pub sugg: GenericParamsWithoutAngleBracketsSugg,
1065 }
1066
1067 #[derive(Subdiagnostic)]
1068 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1069 pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
1070     #[suggestion_part(code = "<")]
1071     pub left: Span,
1072     #[suggestion_part(code = ">")]
1073     pub right: Span,
1074 }
1075
1076 #[derive(Diagnostic)]
1077 #[diag(parser_comparison_operators_cannot_be_chained)]
1078 pub(crate) struct ComparisonOperatorsCannotBeChained {
1079     #[primary_span]
1080     pub span: Vec<Span>,
1081     #[suggestion(
1082         parser_sugg_turbofish_syntax,
1083         style = "verbose",
1084         code = "::",
1085         applicability = "maybe-incorrect"
1086     )]
1087     pub suggest_turbofish: Option<Span>,
1088     #[help(parser_sugg_turbofish_syntax)]
1089     #[help(sugg_parentheses_for_function_args)]
1090     pub help_turbofish: Option<()>,
1091     #[subdiagnostic]
1092     pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
1093 }
1094
1095 #[derive(Subdiagnostic)]
1096 pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
1097     #[suggestion(
1098         sugg_split_comparison,
1099         style = "verbose",
1100         code = " && {middle_term}",
1101         applicability = "maybe-incorrect"
1102     )]
1103     SplitComparison {
1104         #[primary_span]
1105         span: Span,
1106         middle_term: String,
1107     },
1108     #[multipart_suggestion(sugg_parenthesize, applicability = "maybe-incorrect")]
1109     Parenthesize {
1110         #[suggestion_part(code = "(")]
1111         left: Span,
1112         #[suggestion_part(code = ")")]
1113         right: Span,
1114     },
1115 }
1116
1117 #[derive(Diagnostic)]
1118 #[diag(parser_question_mark_in_type)]
1119 pub(crate) struct QuestionMarkInType {
1120     #[primary_span]
1121     #[label]
1122     pub span: Span,
1123     #[subdiagnostic]
1124     pub sugg: QuestionMarkInTypeSugg,
1125 }
1126
1127 #[derive(Subdiagnostic)]
1128 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1129 pub(crate) struct QuestionMarkInTypeSugg {
1130     #[suggestion_part(code = "Option<")]
1131     pub left: Span,
1132     #[suggestion_part(code = ">")]
1133     pub right: Span,
1134 }
1135
1136 #[derive(Diagnostic)]
1137 #[diag(parser_unexpected_parentheses_in_for_head)]
1138 pub(crate) struct ParenthesesInForHead {
1139     #[primary_span]
1140     pub span: Vec<Span>,
1141     #[subdiagnostic]
1142     pub sugg: ParenthesesInForHeadSugg,
1143 }
1144
1145 #[derive(Subdiagnostic)]
1146 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1147 pub(crate) struct ParenthesesInForHeadSugg {
1148     #[suggestion_part(code = "")]
1149     pub left: Span,
1150     #[suggestion_part(code = "")]
1151     pub right: Span,
1152 }
1153
1154 #[derive(Diagnostic)]
1155 #[diag(parser_doc_comment_on_param_type)]
1156 pub(crate) struct DocCommentOnParamType {
1157     #[primary_span]
1158     #[label]
1159     pub span: Span,
1160 }
1161
1162 #[derive(Diagnostic)]
1163 #[diag(parser_attribute_on_param_type)]
1164 pub(crate) struct AttributeOnParamType {
1165     #[primary_span]
1166     #[label]
1167     pub span: Span,
1168 }
1169
1170 #[derive(Diagnostic)]
1171 #[diag(parser_pattern_method_param_without_body, code = "E0642")]
1172 pub(crate) struct PatternMethodParamWithoutBody {
1173     #[primary_span]
1174     #[suggestion(code = "_", applicability = "machine-applicable")]
1175     pub span: Span,
1176 }
1177
1178 #[derive(Diagnostic)]
1179 #[diag(parser_self_param_not_first)]
1180 pub(crate) struct SelfParamNotFirst {
1181     #[primary_span]
1182     #[label]
1183     pub span: Span,
1184 }
1185
1186 #[derive(Diagnostic)]
1187 #[diag(parser_const_generic_without_braces)]
1188 pub(crate) struct ConstGenericWithoutBraces {
1189     #[primary_span]
1190     pub span: Span,
1191     #[subdiagnostic]
1192     pub sugg: ConstGenericWithoutBracesSugg,
1193 }
1194
1195 #[derive(Subdiagnostic)]
1196 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1197 pub(crate) struct ConstGenericWithoutBracesSugg {
1198     #[suggestion_part(code = "{{ ")]
1199     pub left: Span,
1200     #[suggestion_part(code = " }}")]
1201     pub right: Span,
1202 }
1203
1204 #[derive(Diagnostic)]
1205 #[diag(parser_unexpected_const_param_declaration)]
1206 pub(crate) struct UnexpectedConstParamDeclaration {
1207     #[primary_span]
1208     #[label]
1209     pub span: Span,
1210     #[subdiagnostic]
1211     pub sugg: Option<UnexpectedConstParamDeclarationSugg>,
1212 }
1213
1214 #[derive(Subdiagnostic)]
1215 pub(crate) enum UnexpectedConstParamDeclarationSugg {
1216     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1217     AddParam {
1218         #[suggestion_part(code = "<{snippet}>")]
1219         impl_generics: Span,
1220         #[suggestion_part(code = "{ident}")]
1221         incorrect_decl: Span,
1222         snippet: String,
1223         ident: String,
1224     },
1225     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1226     AppendParam {
1227         #[suggestion_part(code = ", {snippet}")]
1228         impl_generics_end: Span,
1229         #[suggestion_part(code = "{ident}")]
1230         incorrect_decl: Span,
1231         snippet: String,
1232         ident: String,
1233     },
1234 }
1235
1236 #[derive(Diagnostic)]
1237 #[diag(parser_unexpected_const_in_generic_param)]
1238 pub(crate) struct UnexpectedConstInGenericParam {
1239     #[primary_span]
1240     pub span: Span,
1241     #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")]
1242     pub to_remove: Option<Span>,
1243 }
1244
1245 #[derive(Diagnostic)]
1246 #[diag(parser_async_move_order_incorrect)]
1247 pub(crate) struct AsyncMoveOrderIncorrect {
1248     #[primary_span]
1249     #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")]
1250     pub span: Span,
1251 }
1252
1253 #[derive(Diagnostic)]
1254 #[diag(parser_double_colon_in_bound)]
1255 pub(crate) struct DoubleColonInBound {
1256     #[primary_span]
1257     pub span: Span,
1258     #[suggestion(code = ": ", applicability = "machine-applicable")]
1259     pub between: Span,
1260 }