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