]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/errors.rs
Rollup merge of #103110 - RalfJung:manual-send, r=thomcc
[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     fn into_diagnostic(
922         self,
923         handler: &'a rustc_errors::Handler,
924     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
925         let token_descr = super::parser::TokenDescription::from_token(&self.token);
926
927         let mut diag = handler.struct_diagnostic(match token_descr {
928             Some(TokenDescription::ReservedIdentifier) => {
929                 fluent::parser_expected_identifier_found_reserved_identifier_str
930             }
931             Some(TokenDescription::Keyword) => fluent::parser_expected_identifier_found_keyword_str,
932             Some(TokenDescription::ReservedKeyword) => {
933                 fluent::parser_expected_identifier_found_reserved_keyword_str
934             }
935             Some(TokenDescription::DocComment) => {
936                 fluent::parser_expected_identifier_found_doc_comment_str
937             }
938             None => fluent::parser_expected_identifier_found_str,
939         });
940         diag.set_span(self.span);
941         diag.set_arg("token", self.token);
942
943         if let Some(sugg) = self.suggest_raw {
944             sugg.add_to_diagnostic(&mut diag);
945         }
946
947         ExpectedIdentifierFound::new(token_descr, self.span).add_to_diagnostic(&mut diag);
948
949         if let Some(sugg) = self.suggest_remove_comma {
950             sugg.add_to_diagnostic(&mut diag);
951         }
952
953         diag
954     }
955 }
956
957 pub(crate) struct ExpectedSemi {
958     pub span: Span,
959     pub token: Token,
960
961     pub unexpected_token_label: Option<Span>,
962     pub sugg: ExpectedSemiSugg,
963 }
964
965 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
966     fn into_diagnostic(
967         self,
968         handler: &'a rustc_errors::Handler,
969     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
970         let token_descr = super::parser::TokenDescription::from_token(&self.token);
971
972         let mut diag = handler.struct_diagnostic(match token_descr {
973             Some(TokenDescription::ReservedIdentifier) => {
974                 fluent::parser_expected_semi_found_reserved_identifier_str
975             }
976             Some(TokenDescription::Keyword) => fluent::parser_expected_semi_found_keyword_str,
977             Some(TokenDescription::ReservedKeyword) => {
978                 fluent::parser_expected_semi_found_reserved_keyword_str
979             }
980             Some(TokenDescription::DocComment) => {
981                 fluent::parser_expected_semi_found_doc_comment_str
982             }
983             None => fluent::parser_expected_semi_found_str,
984         });
985         diag.set_span(self.span);
986         diag.set_arg("token", self.token);
987
988         if let Some(unexpected_token_label) = self.unexpected_token_label {
989             diag.span_label(unexpected_token_label, fluent::parser_label_unexpected_token);
990         }
991
992         self.sugg.add_to_diagnostic(&mut diag);
993
994         diag
995     }
996 }
997
998 #[derive(Subdiagnostic)]
999 pub(crate) enum ExpectedSemiSugg {
1000     #[suggestion(
1001         parser_sugg_change_this_to_semi,
1002         code = ";",
1003         applicability = "machine-applicable"
1004     )]
1005     ChangeToSemi(#[primary_span] Span),
1006     #[suggestion_short(parser_sugg_add_semi, code = ";", applicability = "machine-applicable")]
1007     AddSemi(#[primary_span] Span),
1008 }
1009
1010 #[derive(Diagnostic)]
1011 #[diag(parser_struct_literal_body_without_path)]
1012 pub(crate) struct StructLiteralBodyWithoutPath {
1013     #[primary_span]
1014     pub span: Span,
1015     #[subdiagnostic]
1016     pub sugg: StructLiteralBodyWithoutPathSugg,
1017 }
1018
1019 #[derive(Subdiagnostic)]
1020 #[multipart_suggestion(suggestion, applicability = "has-placeholders")]
1021 pub(crate) struct StructLiteralBodyWithoutPathSugg {
1022     #[suggestion_part(code = "{{ SomeStruct ")]
1023     pub before: Span,
1024     #[suggestion_part(code = " }}")]
1025     pub after: Span,
1026 }
1027
1028 #[derive(Diagnostic)]
1029 #[diag(parser_unmatched_angle_brackets)]
1030 pub(crate) struct UnmatchedAngleBrackets {
1031     #[primary_span]
1032     #[suggestion(code = "", applicability = "machine-applicable")]
1033     pub span: Span,
1034     pub num_extra_brackets: usize,
1035 }
1036
1037 #[derive(Diagnostic)]
1038 #[diag(parser_generic_parameters_without_angle_brackets)]
1039 pub(crate) struct GenericParamsWithoutAngleBrackets {
1040     #[primary_span]
1041     pub span: Span,
1042     #[subdiagnostic]
1043     pub sugg: GenericParamsWithoutAngleBracketsSugg,
1044 }
1045
1046 #[derive(Subdiagnostic)]
1047 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1048 pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
1049     #[suggestion_part(code = "<")]
1050     pub left: Span,
1051     #[suggestion_part(code = ">")]
1052     pub right: Span,
1053 }
1054
1055 #[derive(Diagnostic)]
1056 #[diag(parser_comparison_operators_cannot_be_chained)]
1057 pub(crate) struct ComparisonOperatorsCannotBeChained {
1058     #[primary_span]
1059     pub span: Vec<Span>,
1060     #[suggestion_verbose(
1061         parser_sugg_turbofish_syntax,
1062         code = "::",
1063         applicability = "maybe-incorrect"
1064     )]
1065     pub suggest_turbofish: Option<Span>,
1066     #[help(parser_sugg_turbofish_syntax)]
1067     #[help(sugg_parentheses_for_function_args)]
1068     pub help_turbofish: Option<()>,
1069     #[subdiagnostic]
1070     pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
1071 }
1072
1073 #[derive(Subdiagnostic)]
1074 pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
1075     #[suggestion_verbose(
1076         sugg_split_comparison,
1077         code = " && {middle_term}",
1078         applicability = "maybe-incorrect"
1079     )]
1080     SplitComparison {
1081         #[primary_span]
1082         span: Span,
1083         middle_term: String,
1084     },
1085     #[multipart_suggestion(sugg_parenthesize, applicability = "maybe-incorrect")]
1086     Parenthesize {
1087         #[suggestion_part(code = "(")]
1088         left: Span,
1089         #[suggestion_part(code = ")")]
1090         right: Span,
1091     },
1092 }
1093
1094 #[derive(Diagnostic)]
1095 #[diag(parser_question_mark_in_type)]
1096 pub(crate) struct QuestionMarkInType {
1097     #[primary_span]
1098     #[label]
1099     pub span: Span,
1100     #[subdiagnostic]
1101     pub sugg: QuestionMarkInTypeSugg,
1102 }
1103
1104 #[derive(Subdiagnostic)]
1105 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1106 pub(crate) struct QuestionMarkInTypeSugg {
1107     #[suggestion_part(code = "Option<")]
1108     pub left: Span,
1109     #[suggestion_part(code = ">")]
1110     pub right: Span,
1111 }
1112
1113 #[derive(Diagnostic)]
1114 #[diag(parser_unexpected_parentheses_in_for_head)]
1115 pub(crate) struct ParenthesesInForHead {
1116     #[primary_span]
1117     pub span: Vec<Span>,
1118     #[subdiagnostic]
1119     pub sugg: ParenthesesInForHeadSugg,
1120 }
1121
1122 #[derive(Subdiagnostic)]
1123 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1124 pub(crate) struct ParenthesesInForHeadSugg {
1125     #[suggestion_part(code = "")]
1126     pub left: Span,
1127     #[suggestion_part(code = "")]
1128     pub right: Span,
1129 }
1130
1131 #[derive(Diagnostic)]
1132 #[diag(parser_doc_comment_on_param_type)]
1133 pub(crate) struct DocCommentOnParamType {
1134     #[primary_span]
1135     #[label]
1136     pub span: Span,
1137 }
1138
1139 #[derive(Diagnostic)]
1140 #[diag(parser_attribute_on_param_type)]
1141 pub(crate) struct AttributeOnParamType {
1142     #[primary_span]
1143     #[label]
1144     pub span: Span,
1145 }
1146
1147 #[derive(Diagnostic)]
1148 #[diag(parser_pattern_method_param_without_body, code = "E0642")]
1149 pub(crate) struct PatternMethodParamWithoutBody {
1150     #[primary_span]
1151     #[suggestion(code = "_", applicability = "machine-applicable")]
1152     pub span: Span,
1153 }
1154
1155 #[derive(Diagnostic)]
1156 #[diag(parser_self_param_not_first)]
1157 pub(crate) struct SelfParamNotFirst {
1158     #[primary_span]
1159     #[label]
1160     pub span: Span,
1161 }
1162
1163 #[derive(Diagnostic)]
1164 #[diag(parser_const_generic_without_braces)]
1165 pub(crate) struct ConstGenericWithoutBraces {
1166     #[primary_span]
1167     pub span: Span,
1168     #[subdiagnostic]
1169     pub sugg: ConstGenericWithoutBracesSugg,
1170 }
1171
1172 #[derive(Subdiagnostic)]
1173 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1174 pub(crate) struct ConstGenericWithoutBracesSugg {
1175     #[suggestion_part(code = "{{ ")]
1176     pub left: Span,
1177     #[suggestion_part(code = " }}")]
1178     pub right: Span,
1179 }
1180
1181 #[derive(Diagnostic)]
1182 #[diag(parser_unexpected_const_param_declaration)]
1183 pub(crate) struct UnexpectedConstParamDeclaration {
1184     #[primary_span]
1185     #[label]
1186     pub span: Span,
1187     #[subdiagnostic]
1188     pub sugg: Option<UnexpectedConstParamDeclarationSugg>,
1189 }
1190
1191 #[derive(Subdiagnostic)]
1192 pub(crate) enum UnexpectedConstParamDeclarationSugg {
1193     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1194     AddParam {
1195         #[suggestion_part(code = "<{snippet}>")]
1196         impl_generics: Span,
1197         #[suggestion_part(code = "{ident}")]
1198         incorrect_decl: Span,
1199         snippet: String,
1200         ident: String,
1201     },
1202     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1203     AppendParam {
1204         #[suggestion_part(code = ", {snippet}")]
1205         impl_generics_end: Span,
1206         #[suggestion_part(code = "{ident}")]
1207         incorrect_decl: Span,
1208         snippet: String,
1209         ident: String,
1210     },
1211 }
1212
1213 #[derive(Diagnostic)]
1214 #[diag(parser_unexpected_const_in_generic_param)]
1215 pub(crate) struct UnexpectedConstInGenericParam {
1216     #[primary_span]
1217     pub span: Span,
1218     #[suggestion_verbose(code = "", applicability = "maybe-incorrect")]
1219     pub to_remove: Option<Span>,
1220 }
1221
1222 #[derive(Diagnostic)]
1223 #[diag(parser_async_move_order_incorrect)]
1224 pub(crate) struct AsyncMoveOrderIncorrect {
1225     #[primary_span]
1226     #[suggestion_verbose(code = "async move", applicability = "maybe-incorrect")]
1227     pub span: Span,
1228 }
1229
1230 #[derive(Diagnostic)]
1231 #[diag(parser_double_colon_in_bound)]
1232 pub(crate) struct DoubleColonInBound {
1233     #[primary_span]
1234     pub span: Span,
1235     #[suggestion(code = ": ", applicability = "machine-applicable")]
1236     pub between: Span,
1237 }