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