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