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