]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/errors.rs
Rollup merge of #106175 - compiler-errors:bad-import-sugg, r=oli-obk
[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(parse_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(parse_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         parse_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(parse_forgot_paren)]
43     ForgotParen {
44         #[primary_span]
45         span: Span,
46     },
47     #[label(parse_expect_path)]
48     ExpectPath {
49         #[primary_span]
50         span: Span,
51     },
52 }
53
54 #[derive(Diagnostic)]
55 #[diag(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_switch_mut_let_order, applicability = "maybe-incorrect", code = "let mut")]
114     SwitchMutLetOrder(#[primary_span] Span),
115     #[suggestion(
116         parse_missing_let_before_mut,
117         applicability = "machine-applicable",
118         code = "let mut"
119     )]
120     MissingLet(#[primary_span] Span),
121     #[suggestion(parse_use_let_not_auto, applicability = "machine-applicable", code = "let")]
122     UseLetNotAuto(#[primary_span] Span),
123     #[suggestion(parse_use_let_not_var, applicability = "machine-applicable", code = "let")]
124     UseLetNotVar(#[primary_span] Span),
125 }
126
127 #[derive(Diagnostic)]
128 #[diag(parse_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(parse_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(parse_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(parse_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         parse_unexpected_token_after_not_default,
206         style = "short",
207         applicability = "machine-applicable",
208         code = "!"
209     )]
210     SuggestNotDefault(#[primary_span] Span),
211
212     #[suggestion(
213         parse_unexpected_token_after_not_bitwise,
214         style = "short",
215         applicability = "machine-applicable",
216         code = "!"
217     )]
218     SuggestNotBitwise(#[primary_span] Span),
219
220     #[suggestion(
221         parse_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(parse_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(parse_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(parse_field_expression_with_generic)]
250 pub(crate) struct FieldExpressionWithGeneric(#[primary_span] pub Span);
251
252 #[derive(Diagnostic)]
253 #[diag(parse_macro_invocation_with_qualified_path)]
254 pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span);
255
256 #[derive(Diagnostic)]
257 #[diag(parse_unexpected_token_after_label)]
258 pub(crate) struct UnexpectedTokenAfterLabel {
259     #[primary_span]
260     #[label(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_expected_expression_found_let)]
363 pub(crate) struct ExpectedExpressionFoundLet {
364     #[primary_span]
365     pub span: Span,
366 }
367
368 #[derive(Diagnostic)]
369 #[diag(parse_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(parse_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(parse_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(parse_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(parse_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(parse_catch_after_try)]
434 #[help]
435 pub(crate) struct CatchAfterTry {
436     #[primary_span]
437     pub span: Span,
438 }
439
440 #[derive(Diagnostic)]
441 #[diag(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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     parse_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(parse_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(parse_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(parse_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(parse_invalid_interpolated_expression)]
683 pub(crate) struct InvalidInterpolatedExpression {
684     #[primary_span]
685     pub span: Span,
686 }
687
688 #[derive(Diagnostic)]
689 #[diag(parse_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(parse_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(parse_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(parse_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(parse_assignment_else_not_allowed)]
735 pub(crate) struct AssignmentElseNotAllowed {
736     #[primary_span]
737     pub span: Span,
738 }
739
740 #[derive(Diagnostic)]
741 #[diag(parse_expected_statement_after_outer_attr)]
742 pub(crate) struct ExpectedStatementAfterOuterAttr {
743     #[primary_span]
744     pub span: Span,
745 }
746
747 #[derive(Diagnostic)]
748 #[diag(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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(parse_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     parse_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(parse_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(parse_expected_identifier_found_reserved_identifier)]
832     ReservedIdentifier(#[primary_span] Span),
833     #[label(parse_expected_identifier_found_keyword)]
834     Keyword(#[primary_span] Span),
835     #[label(parse_expected_identifier_found_reserved_keyword)]
836     ReservedKeyword(#[primary_span] Span),
837     #[label(parse_expected_identifier_found_doc_comment)]
838     DocComment(#[primary_span] Span),
839     #[label(parse_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::parse_expected_identifier_found_reserved_identifier_str
875             }
876             Some(TokenDescription::Keyword) => fluent::parse_expected_identifier_found_keyword_str,
877             Some(TokenDescription::ReservedKeyword) => {
878                 fluent::parse_expected_identifier_found_reserved_keyword_str
879             }
880             Some(TokenDescription::DocComment) => {
881                 fluent::parse_expected_identifier_found_doc_comment_str
882             }
883             None => fluent::parse_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::parse_expected_semi_found_reserved_identifier_str
921             }
922             Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str,
923             Some(TokenDescription::ReservedKeyword) => {
924                 fluent::parse_expected_semi_found_reserved_keyword_str
925             }
926             Some(TokenDescription::DocComment) => fluent::parse_expected_semi_found_doc_comment_str,
927             None => fluent::parse_expected_semi_found_str,
928         });
929         diag.set_span(self.span);
930         diag.set_arg("token", self.token);
931
932         if let Some(unexpected_token_label) = self.unexpected_token_label {
933             diag.span_label(unexpected_token_label, fluent::parse_label_unexpected_token);
934         }
935
936         self.sugg.add_to_diagnostic(&mut diag);
937
938         diag
939     }
940 }
941
942 #[derive(Subdiagnostic)]
943 pub(crate) enum ExpectedSemiSugg {
944     #[suggestion(parse_sugg_change_this_to_semi, code = ";", applicability = "machine-applicable")]
945     ChangeToSemi(#[primary_span] Span),
946     #[suggestion(
947         parse_sugg_add_semi,
948         style = "short",
949         code = ";",
950         applicability = "machine-applicable"
951     )]
952     AddSemi(#[primary_span] Span),
953 }
954
955 #[derive(Diagnostic)]
956 #[diag(parse_struct_literal_body_without_path)]
957 pub(crate) struct StructLiteralBodyWithoutPath {
958     #[primary_span]
959     pub span: Span,
960     #[subdiagnostic]
961     pub sugg: StructLiteralBodyWithoutPathSugg,
962 }
963
964 #[derive(Subdiagnostic)]
965 #[multipart_suggestion(suggestion, applicability = "has-placeholders")]
966 pub(crate) struct StructLiteralBodyWithoutPathSugg {
967     #[suggestion_part(code = "{{ SomeStruct ")]
968     pub before: Span,
969     #[suggestion_part(code = " }}")]
970     pub after: Span,
971 }
972
973 #[derive(Diagnostic)]
974 #[diag(parse_unmatched_angle_brackets)]
975 pub(crate) struct UnmatchedAngleBrackets {
976     #[primary_span]
977     #[suggestion(code = "", applicability = "machine-applicable")]
978     pub span: Span,
979     pub num_extra_brackets: usize,
980 }
981
982 #[derive(Diagnostic)]
983 #[diag(parse_generic_parameters_without_angle_brackets)]
984 pub(crate) struct GenericParamsWithoutAngleBrackets {
985     #[primary_span]
986     pub span: Span,
987     #[subdiagnostic]
988     pub sugg: GenericParamsWithoutAngleBracketsSugg,
989 }
990
991 #[derive(Subdiagnostic)]
992 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
993 pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
994     #[suggestion_part(code = "<")]
995     pub left: Span,
996     #[suggestion_part(code = ">")]
997     pub right: Span,
998 }
999
1000 #[derive(Diagnostic)]
1001 #[diag(parse_comparison_operators_cannot_be_chained)]
1002 pub(crate) struct ComparisonOperatorsCannotBeChained {
1003     #[primary_span]
1004     pub span: Vec<Span>,
1005     #[suggestion(
1006         parse_sugg_turbofish_syntax,
1007         style = "verbose",
1008         code = "::",
1009         applicability = "maybe-incorrect"
1010     )]
1011     pub suggest_turbofish: Option<Span>,
1012     #[help(parse_sugg_turbofish_syntax)]
1013     #[help(sugg_parentheses_for_function_args)]
1014     pub help_turbofish: Option<()>,
1015     #[subdiagnostic]
1016     pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
1017 }
1018
1019 #[derive(Subdiagnostic)]
1020 pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
1021     #[suggestion(
1022         sugg_split_comparison,
1023         style = "verbose",
1024         code = " && {middle_term}",
1025         applicability = "maybe-incorrect"
1026     )]
1027     SplitComparison {
1028         #[primary_span]
1029         span: Span,
1030         middle_term: String,
1031     },
1032     #[multipart_suggestion(sugg_parenthesize, applicability = "maybe-incorrect")]
1033     Parenthesize {
1034         #[suggestion_part(code = "(")]
1035         left: Span,
1036         #[suggestion_part(code = ")")]
1037         right: Span,
1038     },
1039 }
1040
1041 #[derive(Diagnostic)]
1042 #[diag(parse_question_mark_in_type)]
1043 pub(crate) struct QuestionMarkInType {
1044     #[primary_span]
1045     #[label]
1046     pub span: Span,
1047     #[subdiagnostic]
1048     pub sugg: QuestionMarkInTypeSugg,
1049 }
1050
1051 #[derive(Subdiagnostic)]
1052 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1053 pub(crate) struct QuestionMarkInTypeSugg {
1054     #[suggestion_part(code = "Option<")]
1055     pub left: Span,
1056     #[suggestion_part(code = ">")]
1057     pub right: Span,
1058 }
1059
1060 #[derive(Diagnostic)]
1061 #[diag(parse_unexpected_parentheses_in_for_head)]
1062 pub(crate) struct ParenthesesInForHead {
1063     #[primary_span]
1064     pub span: Vec<Span>,
1065     #[subdiagnostic]
1066     pub sugg: ParenthesesInForHeadSugg,
1067 }
1068
1069 #[derive(Subdiagnostic)]
1070 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1071 pub(crate) struct ParenthesesInForHeadSugg {
1072     #[suggestion_part(code = "{left_snippet}")]
1073     pub left: Span,
1074     pub left_snippet: String,
1075     #[suggestion_part(code = "{right_snippet}")]
1076     pub right: Span,
1077     pub right_snippet: String,
1078 }
1079
1080 #[derive(Diagnostic)]
1081 #[diag(parse_doc_comment_on_param_type)]
1082 pub(crate) struct DocCommentOnParamType {
1083     #[primary_span]
1084     #[label]
1085     pub span: Span,
1086 }
1087
1088 #[derive(Diagnostic)]
1089 #[diag(parse_attribute_on_param_type)]
1090 pub(crate) struct AttributeOnParamType {
1091     #[primary_span]
1092     #[label]
1093     pub span: Span,
1094 }
1095
1096 #[derive(Diagnostic)]
1097 #[diag(parse_pattern_method_param_without_body, code = "E0642")]
1098 pub(crate) struct PatternMethodParamWithoutBody {
1099     #[primary_span]
1100     #[suggestion(code = "_", applicability = "machine-applicable")]
1101     pub span: Span,
1102 }
1103
1104 #[derive(Diagnostic)]
1105 #[diag(parse_self_param_not_first)]
1106 pub(crate) struct SelfParamNotFirst {
1107     #[primary_span]
1108     #[label]
1109     pub span: Span,
1110 }
1111
1112 #[derive(Diagnostic)]
1113 #[diag(parse_invalid_identifier_with_leading_number)]
1114 pub(crate) struct InvalidIdentiferStartsWithNumber {
1115     #[primary_span]
1116     #[label]
1117     pub span: Span,
1118 }
1119
1120 #[derive(Diagnostic)]
1121 #[diag(parse_const_generic_without_braces)]
1122 pub(crate) struct ConstGenericWithoutBraces {
1123     #[primary_span]
1124     pub span: Span,
1125     #[subdiagnostic]
1126     pub sugg: ConstGenericWithoutBracesSugg,
1127 }
1128
1129 #[derive(Subdiagnostic)]
1130 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1131 pub(crate) struct ConstGenericWithoutBracesSugg {
1132     #[suggestion_part(code = "{{ ")]
1133     pub left: Span,
1134     #[suggestion_part(code = " }}")]
1135     pub right: Span,
1136 }
1137
1138 #[derive(Diagnostic)]
1139 #[diag(parse_unexpected_const_param_declaration)]
1140 pub(crate) struct UnexpectedConstParamDeclaration {
1141     #[primary_span]
1142     #[label]
1143     pub span: Span,
1144     #[subdiagnostic]
1145     pub sugg: Option<UnexpectedConstParamDeclarationSugg>,
1146 }
1147
1148 #[derive(Subdiagnostic)]
1149 pub(crate) enum UnexpectedConstParamDeclarationSugg {
1150     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1151     AddParam {
1152         #[suggestion_part(code = "<{snippet}>")]
1153         impl_generics: Span,
1154         #[suggestion_part(code = "{ident}")]
1155         incorrect_decl: Span,
1156         snippet: String,
1157         ident: String,
1158     },
1159     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1160     AppendParam {
1161         #[suggestion_part(code = ", {snippet}")]
1162         impl_generics_end: Span,
1163         #[suggestion_part(code = "{ident}")]
1164         incorrect_decl: Span,
1165         snippet: String,
1166         ident: String,
1167     },
1168 }
1169
1170 #[derive(Diagnostic)]
1171 #[diag(parse_unexpected_const_in_generic_param)]
1172 pub(crate) struct UnexpectedConstInGenericParam {
1173     #[primary_span]
1174     pub span: Span,
1175     #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")]
1176     pub to_remove: Option<Span>,
1177 }
1178
1179 #[derive(Diagnostic)]
1180 #[diag(parse_async_move_order_incorrect)]
1181 pub(crate) struct AsyncMoveOrderIncorrect {
1182     #[primary_span]
1183     #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")]
1184     pub span: Span,
1185 }
1186
1187 #[derive(Diagnostic)]
1188 #[diag(parse_double_colon_in_bound)]
1189 pub(crate) struct DoubleColonInBound {
1190     #[primary_span]
1191     pub span: Span,
1192     #[suggestion(code = ": ", applicability = "machine-applicable")]
1193     pub between: Span,
1194 }
1195
1196 #[derive(Diagnostic)]
1197 #[diag(parse_fn_ptr_with_generics)]
1198 pub(crate) struct FnPtrWithGenerics {
1199     #[primary_span]
1200     pub span: Span,
1201     #[subdiagnostic]
1202     pub sugg: Option<FnPtrWithGenericsSugg>,
1203 }
1204
1205 #[derive(Subdiagnostic)]
1206 #[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
1207 pub(crate) struct FnPtrWithGenericsSugg {
1208     #[suggestion_part(code = "{snippet}")]
1209     pub left: Span,
1210     pub snippet: String,
1211     #[suggestion_part(code = "")]
1212     pub right: Span,
1213     pub arity: usize,
1214     pub for_param_list_exists: bool,
1215 }
1216
1217 #[derive(Diagnostic)]
1218 #[diag(parse_unexpected_if_with_if)]
1219 pub(crate) struct UnexpectedIfWithIf(
1220     #[primary_span]
1221     #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
1222     pub Span,
1223 );
1224
1225 #[derive(Diagnostic)]
1226 #[diag(parse_maybe_fn_typo_with_impl)]
1227 pub(crate) struct FnTypoWithImpl {
1228     #[primary_span]
1229     #[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
1230     pub fn_span: Span,
1231 }
1232
1233 #[derive(Diagnostic)]
1234 #[diag(parse_expected_fn_path_found_fn_keyword)]
1235 pub(crate) struct ExpectedFnPathFoundFnKeyword {
1236     #[primary_span]
1237     #[suggestion(applicability = "machine-applicable", code = "Fn", style = "verbose")]
1238     pub fn_token_span: Span,
1239 }