]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/errors.rs
Rollup merge of #107389 - zvavybir:master, r=estebank
[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 missing_then_block_sub: IfExpressionMissingThenBlockSub,
341     #[subdiagnostic]
342     pub let_else_sub: Option<IfExpressionLetSomeSub>,
343 }
344
345 #[derive(Subdiagnostic)]
346 pub(crate) enum IfExpressionMissingThenBlockSub {
347     #[help(condition_possibly_unfinished)]
348     UnfinishedCondition(#[primary_span] Span),
349     #[help(add_then_block)]
350     AddThenBlock(#[primary_span] Span),
351 }
352
353 #[derive(Subdiagnostic)]
354 #[help(parse_extra_if_in_let_else)]
355 pub(crate) struct IfExpressionLetSomeSub {
356     #[primary_span]
357     pub if_span: Span,
358 }
359
360 #[derive(Diagnostic)]
361 #[diag(parse_if_expression_missing_condition)]
362 pub(crate) struct IfExpressionMissingCondition {
363     #[primary_span]
364     #[label(condition_label)]
365     pub if_span: Span,
366     #[label(block_label)]
367     pub block_span: Span,
368 }
369
370 #[derive(Diagnostic)]
371 #[diag(parse_expected_expression_found_let)]
372 pub(crate) struct ExpectedExpressionFoundLet {
373     #[primary_span]
374     pub span: Span,
375 }
376
377 #[derive(Diagnostic)]
378 #[diag(parse_expect_eq_instead_of_eqeq)]
379 pub(crate) struct ExpectedEqForLetExpr {
380     #[primary_span]
381     pub span: Span,
382     #[suggestion(applicability = "maybe-incorrect", code = "=", style = "verbose")]
383     pub sugg_span: Span,
384 }
385
386 #[derive(Diagnostic)]
387 #[diag(parse_expected_else_block)]
388 pub(crate) struct ExpectedElseBlock {
389     #[primary_span]
390     pub first_tok_span: Span,
391     pub first_tok: String,
392     #[label]
393     pub else_span: Span,
394     #[suggestion(applicability = "maybe-incorrect", code = "if ")]
395     pub condition_start: Span,
396 }
397
398 #[derive(Diagnostic)]
399 #[diag(parse_outer_attribute_not_allowed_on_if_else)]
400 pub(crate) struct OuterAttributeNotAllowedOnIfElse {
401     #[primary_span]
402     pub last: Span,
403
404     #[label(branch_label)]
405     pub branch_span: Span,
406
407     #[label(ctx_label)]
408     pub ctx_span: Span,
409     pub ctx: String,
410
411     #[suggestion(applicability = "machine-applicable", code = "")]
412     pub attributes: Span,
413 }
414
415 #[derive(Diagnostic)]
416 #[diag(parse_missing_in_in_for_loop)]
417 pub(crate) struct MissingInInForLoop {
418     #[primary_span]
419     pub span: Span,
420     #[subdiagnostic]
421     pub sub: MissingInInForLoopSub,
422 }
423
424 #[derive(Subdiagnostic)]
425 pub(crate) enum MissingInInForLoopSub {
426     // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect
427     #[suggestion(use_in_not_of, style = "short", applicability = "maybe-incorrect", code = "in")]
428     InNotOf(#[primary_span] Span),
429     #[suggestion(add_in, style = "short", applicability = "maybe-incorrect", code = " in ")]
430     AddIn(#[primary_span] Span),
431 }
432
433 #[derive(Diagnostic)]
434 #[diag(parse_missing_comma_after_match_arm)]
435 pub(crate) struct MissingCommaAfterMatchArm {
436     #[primary_span]
437     #[suggestion(applicability = "machine-applicable", code = ",")]
438     pub span: Span,
439 }
440
441 #[derive(Diagnostic)]
442 #[diag(parse_catch_after_try)]
443 #[help]
444 pub(crate) struct CatchAfterTry {
445     #[primary_span]
446     pub span: Span,
447 }
448
449 #[derive(Diagnostic)]
450 #[diag(parse_comma_after_base_struct)]
451 #[note]
452 pub(crate) struct CommaAfterBaseStruct {
453     #[primary_span]
454     pub span: Span,
455     #[suggestion(style = "short", applicability = "machine-applicable", code = "")]
456     pub comma: Span,
457 }
458
459 #[derive(Diagnostic)]
460 #[diag(parse_eq_field_init)]
461 pub(crate) struct EqFieldInit {
462     #[primary_span]
463     pub span: Span,
464     #[suggestion(applicability = "machine-applicable", code = ":")]
465     pub eq: Span,
466 }
467
468 #[derive(Diagnostic)]
469 #[diag(parse_dotdotdot)]
470 pub(crate) struct DotDotDot {
471     #[primary_span]
472     #[suggestion(suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
473     #[suggestion(suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
474     pub span: Span,
475 }
476
477 #[derive(Diagnostic)]
478 #[diag(parse_left_arrow_operator)]
479 pub(crate) struct LeftArrowOperator {
480     #[primary_span]
481     #[suggestion(applicability = "maybe-incorrect", code = "< -")]
482     pub span: Span,
483 }
484
485 #[derive(Diagnostic)]
486 #[diag(parse_remove_let)]
487 pub(crate) struct RemoveLet {
488     #[primary_span]
489     #[suggestion(applicability = "machine-applicable", code = "")]
490     pub span: Span,
491 }
492
493 #[derive(Diagnostic)]
494 #[diag(parse_use_eq_instead)]
495 pub(crate) struct UseEqInstead {
496     #[primary_span]
497     #[suggestion(style = "short", applicability = "machine-applicable", code = "=")]
498     pub span: Span,
499 }
500
501 #[derive(Diagnostic)]
502 #[diag(parse_use_empty_block_not_semi)]
503 pub(crate) struct UseEmptyBlockNotSemi {
504     #[primary_span]
505     #[suggestion(style = "hidden", applicability = "machine-applicable", code = "{{}}")]
506     pub span: Span,
507 }
508
509 #[derive(Diagnostic)]
510 #[diag(parse_comparison_interpreted_as_generic)]
511 pub(crate) struct ComparisonInterpretedAsGeneric {
512     #[primary_span]
513     #[label(label_comparison)]
514     pub comparison: Span,
515     pub r#type: Path,
516     #[label(label_args)]
517     pub args: Span,
518     #[subdiagnostic]
519     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
520 }
521
522 #[derive(Diagnostic)]
523 #[diag(parse_shift_interpreted_as_generic)]
524 pub(crate) struct ShiftInterpretedAsGeneric {
525     #[primary_span]
526     #[label(label_comparison)]
527     pub shift: Span,
528     pub r#type: Path,
529     #[label(label_args)]
530     pub args: Span,
531     #[subdiagnostic]
532     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
533 }
534
535 #[derive(Subdiagnostic)]
536 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
537 pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
538     #[suggestion_part(code = "(")]
539     pub left: Span,
540     #[suggestion_part(code = ")")]
541     pub right: Span,
542 }
543
544 #[derive(Diagnostic)]
545 #[diag(parse_found_expr_would_be_stmt)]
546 pub(crate) struct FoundExprWouldBeStmt {
547     #[primary_span]
548     #[label]
549     pub span: Span,
550     pub token: Token,
551     #[subdiagnostic]
552     pub suggestion: ExprParenthesesNeeded,
553 }
554
555 #[derive(Diagnostic)]
556 #[diag(parse_leading_plus_not_supported)]
557 pub(crate) struct LeadingPlusNotSupported {
558     #[primary_span]
559     #[label]
560     pub span: Span,
561     #[suggestion(
562         suggestion_remove_plus,
563         style = "verbose",
564         code = "",
565         applicability = "machine-applicable"
566     )]
567     pub remove_plus: Option<Span>,
568     #[subdiagnostic]
569     pub add_parentheses: Option<ExprParenthesesNeeded>,
570 }
571
572 #[derive(Diagnostic)]
573 #[diag(parse_parentheses_with_struct_fields)]
574 pub(crate) struct ParenthesesWithStructFields {
575     #[primary_span]
576     pub span: Span,
577     pub r#type: Path,
578     #[subdiagnostic]
579     pub braces_for_struct: BracesForStructLiteral,
580     #[subdiagnostic]
581     pub no_fields_for_fn: NoFieldsForFnCall,
582 }
583
584 #[derive(Subdiagnostic)]
585 #[multipart_suggestion(suggestion_braces_for_struct, applicability = "maybe-incorrect")]
586 pub(crate) struct BracesForStructLiteral {
587     #[suggestion_part(code = " {{ ")]
588     pub first: Span,
589     #[suggestion_part(code = " }}")]
590     pub second: Span,
591 }
592
593 #[derive(Subdiagnostic)]
594 #[multipart_suggestion(suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
595 pub(crate) struct NoFieldsForFnCall {
596     #[suggestion_part(code = "")]
597     pub fields: Vec<Span>,
598 }
599
600 #[derive(Diagnostic)]
601 #[diag(parse_labeled_loop_in_break)]
602 pub(crate) struct LabeledLoopInBreak {
603     #[primary_span]
604     pub span: Span,
605     #[subdiagnostic]
606     pub sub: WrapExpressionInParentheses,
607 }
608
609 #[derive(Subdiagnostic)]
610 #[multipart_suggestion(
611     parse_sugg_wrap_expression_in_parentheses,
612     applicability = "machine-applicable"
613 )]
614 pub(crate) struct WrapExpressionInParentheses {
615     #[suggestion_part(code = "(")]
616     pub left: Span,
617     #[suggestion_part(code = ")")]
618     pub right: Span,
619 }
620
621 #[derive(Diagnostic)]
622 #[diag(parse_array_brackets_instead_of_braces)]
623 pub(crate) struct ArrayBracketsInsteadOfSpaces {
624     #[primary_span]
625     pub span: Span,
626     #[subdiagnostic]
627     pub sub: ArrayBracketsInsteadOfSpacesSugg,
628 }
629
630 #[derive(Subdiagnostic)]
631 #[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
632 pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
633     #[suggestion_part(code = "[")]
634     pub left: Span,
635     #[suggestion_part(code = "]")]
636     pub right: Span,
637 }
638
639 #[derive(Diagnostic)]
640 #[diag(parse_match_arm_body_without_braces)]
641 pub(crate) struct MatchArmBodyWithoutBraces {
642     #[primary_span]
643     #[label(label_statements)]
644     pub statements: Span,
645     #[label(label_arrow)]
646     pub arrow: Span,
647     pub num_statements: usize,
648     #[subdiagnostic]
649     pub sub: MatchArmBodyWithoutBracesSugg,
650 }
651
652 #[derive(Diagnostic)]
653 #[diag(parse_inclusive_range_extra_equals)]
654 #[note]
655 pub(crate) struct InclusiveRangeExtraEquals {
656     #[primary_span]
657     #[suggestion(
658         suggestion_remove_eq,
659         style = "short",
660         code = "..=",
661         applicability = "maybe-incorrect"
662     )]
663     pub span: Span,
664 }
665
666 #[derive(Diagnostic)]
667 #[diag(parse_inclusive_range_match_arrow)]
668 pub(crate) struct InclusiveRangeMatchArrow {
669     #[primary_span]
670     pub span: Span,
671     #[suggestion(
672         suggestion_add_space,
673         style = "verbose",
674         code = " ",
675         applicability = "machine-applicable"
676     )]
677     pub after_pat: Span,
678 }
679
680 #[derive(Diagnostic)]
681 #[diag(parse_inclusive_range_no_end, code = "E0586")]
682 #[note]
683 pub(crate) struct InclusiveRangeNoEnd {
684     #[primary_span]
685     #[suggestion(
686         suggestion_open_range,
687         code = "..",
688         applicability = "machine-applicable",
689         style = "short"
690     )]
691     pub span: Span,
692 }
693
694 #[derive(Subdiagnostic)]
695 pub(crate) enum MatchArmBodyWithoutBracesSugg {
696     #[multipart_suggestion(suggestion_add_braces, applicability = "machine-applicable")]
697     AddBraces {
698         #[suggestion_part(code = "{{ ")]
699         left: Span,
700         #[suggestion_part(code = " }}")]
701         right: Span,
702     },
703     #[suggestion(
704         suggestion_use_comma_not_semicolon,
705         code = ",",
706         applicability = "machine-applicable"
707     )]
708     UseComma {
709         #[primary_span]
710         semicolon: Span,
711     },
712 }
713
714 #[derive(Diagnostic)]
715 #[diag(parse_struct_literal_not_allowed_here)]
716 pub(crate) struct StructLiteralNotAllowedHere {
717     #[primary_span]
718     pub span: Span,
719     #[subdiagnostic]
720     pub sub: StructLiteralNotAllowedHereSugg,
721 }
722
723 #[derive(Subdiagnostic)]
724 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
725 pub(crate) struct StructLiteralNotAllowedHereSugg {
726     #[suggestion_part(code = "(")]
727     pub left: Span,
728     #[suggestion_part(code = ")")]
729     pub right: Span,
730 }
731
732 #[derive(Diagnostic)]
733 #[diag(parse_invalid_interpolated_expression)]
734 pub(crate) struct InvalidInterpolatedExpression {
735     #[primary_span]
736     pub span: Span,
737 }
738
739 #[derive(Diagnostic)]
740 #[diag(parse_invalid_literal_suffix_on_tuple_index)]
741 pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
742     #[primary_span]
743     #[label]
744     pub span: Span,
745     pub suffix: Symbol,
746     #[help(tuple_exception_line_1)]
747     #[help(tuple_exception_line_2)]
748     #[help(tuple_exception_line_3)]
749     pub exception: Option<()>,
750 }
751
752 #[derive(Diagnostic)]
753 #[diag(parse_non_string_abi_literal)]
754 pub(crate) struct NonStringAbiLiteral {
755     #[primary_span]
756     #[suggestion(code = "\"C\"", applicability = "maybe-incorrect")]
757     pub span: Span,
758 }
759
760 #[derive(Diagnostic)]
761 #[diag(parse_mismatched_closing_delimiter)]
762 pub(crate) struct MismatchedClosingDelimiter {
763     #[primary_span]
764     pub spans: Vec<Span>,
765     pub delimiter: String,
766     #[label(label_unmatched)]
767     pub unmatched: Span,
768     #[label(label_opening_candidate)]
769     pub opening_candidate: Option<Span>,
770     #[label(label_unclosed)]
771     pub unclosed: Option<Span>,
772 }
773
774 #[derive(Diagnostic)]
775 #[diag(parse_incorrect_visibility_restriction, code = "E0704")]
776 #[help]
777 pub(crate) struct IncorrectVisibilityRestriction {
778     #[primary_span]
779     #[suggestion(code = "in {inner_str}", applicability = "machine-applicable")]
780     pub span: Span,
781     pub inner_str: String,
782 }
783
784 #[derive(Diagnostic)]
785 #[diag(parse_assignment_else_not_allowed)]
786 pub(crate) struct AssignmentElseNotAllowed {
787     #[primary_span]
788     pub span: Span,
789 }
790
791 #[derive(Diagnostic)]
792 #[diag(parse_expected_statement_after_outer_attr)]
793 pub(crate) struct ExpectedStatementAfterOuterAttr {
794     #[primary_span]
795     pub span: Span,
796 }
797
798 #[derive(Diagnostic)]
799 #[diag(parse_doc_comment_does_not_document_anything, code = "E0585")]
800 #[help]
801 pub(crate) struct DocCommentDoesNotDocumentAnything {
802     #[primary_span]
803     pub span: Span,
804     #[suggestion(code = ",", applicability = "machine-applicable")]
805     pub missing_comma: Option<Span>,
806 }
807
808 #[derive(Diagnostic)]
809 #[diag(parse_const_let_mutually_exclusive)]
810 pub(crate) struct ConstLetMutuallyExclusive {
811     #[primary_span]
812     #[suggestion(code = "const", applicability = "maybe-incorrect")]
813     pub span: Span,
814 }
815
816 #[derive(Diagnostic)]
817 #[diag(parse_invalid_expression_in_let_else)]
818 pub(crate) struct InvalidExpressionInLetElse {
819     #[primary_span]
820     pub span: Span,
821     pub operator: &'static str,
822     #[subdiagnostic]
823     pub sugg: WrapExpressionInParentheses,
824 }
825
826 #[derive(Diagnostic)]
827 #[diag(parse_invalid_curly_in_let_else)]
828 pub(crate) struct InvalidCurlyInLetElse {
829     #[primary_span]
830     pub span: Span,
831     #[subdiagnostic]
832     pub sugg: WrapExpressionInParentheses,
833 }
834
835 #[derive(Diagnostic)]
836 #[diag(parse_compound_assignment_expression_in_let)]
837 #[help]
838 pub(crate) struct CompoundAssignmentExpressionInLet {
839     #[primary_span]
840     #[suggestion(style = "short", code = "=", applicability = "maybe-incorrect")]
841     pub span: Span,
842 }
843
844 #[derive(Diagnostic)]
845 #[diag(parse_suffixed_literal_in_attribute)]
846 #[help]
847 pub(crate) struct SuffixedLiteralInAttribute {
848     #[primary_span]
849     pub span: Span,
850 }
851
852 #[derive(Diagnostic)]
853 #[diag(parse_invalid_meta_item)]
854 pub(crate) struct InvalidMetaItem {
855     #[primary_span]
856     pub span: Span,
857     pub token: Token,
858 }
859
860 #[derive(Subdiagnostic)]
861 #[suggestion(
862     parse_sugg_escape_to_use_as_identifier,
863     style = "verbose",
864     applicability = "maybe-incorrect",
865     code = "r#"
866 )]
867 pub(crate) struct SuggEscapeToUseAsIdentifier {
868     #[primary_span]
869     pub span: Span,
870     pub ident_name: String,
871 }
872
873 #[derive(Subdiagnostic)]
874 #[suggestion(parse_sugg_remove_comma, applicability = "machine-applicable", code = "")]
875 pub(crate) struct SuggRemoveComma {
876     #[primary_span]
877     pub span: Span,
878 }
879
880 #[derive(Subdiagnostic)]
881 pub(crate) enum ExpectedIdentifierFound {
882     #[label(parse_expected_identifier_found_reserved_identifier)]
883     ReservedIdentifier(#[primary_span] Span),
884     #[label(parse_expected_identifier_found_keyword)]
885     Keyword(#[primary_span] Span),
886     #[label(parse_expected_identifier_found_reserved_keyword)]
887     ReservedKeyword(#[primary_span] Span),
888     #[label(parse_expected_identifier_found_doc_comment)]
889     DocComment(#[primary_span] Span),
890     #[label(parse_expected_identifier)]
891     Other(#[primary_span] Span),
892 }
893
894 impl ExpectedIdentifierFound {
895     pub fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
896         (match token_descr {
897             Some(TokenDescription::ReservedIdentifier) => {
898                 ExpectedIdentifierFound::ReservedIdentifier
899             }
900             Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword,
901             Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
902             Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment,
903             None => ExpectedIdentifierFound::Other,
904         })(span)
905     }
906 }
907
908 pub(crate) struct ExpectedIdentifier {
909     pub span: Span,
910     pub token: Token,
911     pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>,
912     pub suggest_remove_comma: Option<SuggRemoveComma>,
913 }
914
915 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
916     #[track_caller]
917     fn into_diagnostic(
918         self,
919         handler: &'a rustc_errors::Handler,
920     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
921         let token_descr = super::parser::TokenDescription::from_token(&self.token);
922
923         let mut diag = handler.struct_diagnostic(match token_descr {
924             Some(TokenDescription::ReservedIdentifier) => {
925                 fluent::parse_expected_identifier_found_reserved_identifier_str
926             }
927             Some(TokenDescription::Keyword) => fluent::parse_expected_identifier_found_keyword_str,
928             Some(TokenDescription::ReservedKeyword) => {
929                 fluent::parse_expected_identifier_found_reserved_keyword_str
930             }
931             Some(TokenDescription::DocComment) => {
932                 fluent::parse_expected_identifier_found_doc_comment_str
933             }
934             None => fluent::parse_expected_identifier_found_str,
935         });
936         diag.set_span(self.span);
937         diag.set_arg("token", self.token);
938
939         if let Some(sugg) = self.suggest_raw {
940             sugg.add_to_diagnostic(&mut diag);
941         }
942
943         ExpectedIdentifierFound::new(token_descr, self.span).add_to_diagnostic(&mut diag);
944
945         if let Some(sugg) = self.suggest_remove_comma {
946             sugg.add_to_diagnostic(&mut diag);
947         }
948
949         diag
950     }
951 }
952
953 pub(crate) struct ExpectedSemi {
954     pub span: Span,
955     pub token: Token,
956
957     pub unexpected_token_label: Option<Span>,
958     pub sugg: ExpectedSemiSugg,
959 }
960
961 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
962     #[track_caller]
963     fn into_diagnostic(
964         self,
965         handler: &'a rustc_errors::Handler,
966     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
967         let token_descr = super::parser::TokenDescription::from_token(&self.token);
968
969         let mut diag = handler.struct_diagnostic(match token_descr {
970             Some(TokenDescription::ReservedIdentifier) => {
971                 fluent::parse_expected_semi_found_reserved_identifier_str
972             }
973             Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str,
974             Some(TokenDescription::ReservedKeyword) => {
975                 fluent::parse_expected_semi_found_reserved_keyword_str
976             }
977             Some(TokenDescription::DocComment) => fluent::parse_expected_semi_found_doc_comment_str,
978             None => fluent::parse_expected_semi_found_str,
979         });
980         diag.set_span(self.span);
981         diag.set_arg("token", self.token);
982
983         if let Some(unexpected_token_label) = self.unexpected_token_label {
984             diag.span_label(unexpected_token_label, fluent::parse_label_unexpected_token);
985         }
986
987         self.sugg.add_to_diagnostic(&mut diag);
988
989         diag
990     }
991 }
992
993 #[derive(Subdiagnostic)]
994 pub(crate) enum ExpectedSemiSugg {
995     #[suggestion(parse_sugg_change_this_to_semi, code = ";", applicability = "machine-applicable")]
996     ChangeToSemi(#[primary_span] Span),
997     #[suggestion(
998         parse_sugg_add_semi,
999         style = "short",
1000         code = ";",
1001         applicability = "machine-applicable"
1002     )]
1003     AddSemi(#[primary_span] Span),
1004 }
1005
1006 #[derive(Diagnostic)]
1007 #[diag(parse_struct_literal_body_without_path)]
1008 pub(crate) struct StructLiteralBodyWithoutPath {
1009     #[primary_span]
1010     pub span: Span,
1011     #[subdiagnostic]
1012     pub sugg: StructLiteralBodyWithoutPathSugg,
1013 }
1014
1015 #[derive(Subdiagnostic)]
1016 #[multipart_suggestion(suggestion, applicability = "has-placeholders")]
1017 pub(crate) struct StructLiteralBodyWithoutPathSugg {
1018     #[suggestion_part(code = "{{ SomeStruct ")]
1019     pub before: Span,
1020     #[suggestion_part(code = " }}")]
1021     pub after: Span,
1022 }
1023
1024 #[derive(Diagnostic)]
1025 #[diag(parse_struct_literal_needing_parens)]
1026 pub(crate) struct StructLiteralNeedingParens {
1027     #[primary_span]
1028     pub span: Span,
1029     #[subdiagnostic]
1030     pub sugg: StructLiteralNeedingParensSugg,
1031 }
1032
1033 #[derive(Subdiagnostic)]
1034 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1035 pub(crate) struct StructLiteralNeedingParensSugg {
1036     #[suggestion_part(code = "(")]
1037     pub before: Span,
1038     #[suggestion_part(code = ")")]
1039     pub after: Span,
1040 }
1041
1042 #[derive(Diagnostic)]
1043 #[diag(parse_unmatched_angle_brackets)]
1044 pub(crate) struct UnmatchedAngleBrackets {
1045     #[primary_span]
1046     #[suggestion(code = "", applicability = "machine-applicable")]
1047     pub span: Span,
1048     pub num_extra_brackets: usize,
1049 }
1050
1051 #[derive(Diagnostic)]
1052 #[diag(parse_generic_parameters_without_angle_brackets)]
1053 pub(crate) struct GenericParamsWithoutAngleBrackets {
1054     #[primary_span]
1055     pub span: Span,
1056     #[subdiagnostic]
1057     pub sugg: GenericParamsWithoutAngleBracketsSugg,
1058 }
1059
1060 #[derive(Subdiagnostic)]
1061 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1062 pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
1063     #[suggestion_part(code = "<")]
1064     pub left: Span,
1065     #[suggestion_part(code = ">")]
1066     pub right: Span,
1067 }
1068
1069 #[derive(Diagnostic)]
1070 #[diag(parse_comparison_operators_cannot_be_chained)]
1071 pub(crate) struct ComparisonOperatorsCannotBeChained {
1072     #[primary_span]
1073     pub span: Vec<Span>,
1074     #[suggestion(
1075         parse_sugg_turbofish_syntax,
1076         style = "verbose",
1077         code = "::",
1078         applicability = "maybe-incorrect"
1079     )]
1080     pub suggest_turbofish: Option<Span>,
1081     #[help(parse_sugg_turbofish_syntax)]
1082     #[help(sugg_parentheses_for_function_args)]
1083     pub help_turbofish: Option<()>,
1084     #[subdiagnostic]
1085     pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
1086 }
1087
1088 #[derive(Subdiagnostic)]
1089 pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
1090     #[suggestion(
1091         sugg_split_comparison,
1092         style = "verbose",
1093         code = " && {middle_term}",
1094         applicability = "maybe-incorrect"
1095     )]
1096     SplitComparison {
1097         #[primary_span]
1098         span: Span,
1099         middle_term: String,
1100     },
1101     #[multipart_suggestion(sugg_parenthesize, applicability = "maybe-incorrect")]
1102     Parenthesize {
1103         #[suggestion_part(code = "(")]
1104         left: Span,
1105         #[suggestion_part(code = ")")]
1106         right: Span,
1107     },
1108 }
1109
1110 #[derive(Diagnostic)]
1111 #[diag(parse_question_mark_in_type)]
1112 pub(crate) struct QuestionMarkInType {
1113     #[primary_span]
1114     #[label]
1115     pub span: Span,
1116     #[subdiagnostic]
1117     pub sugg: QuestionMarkInTypeSugg,
1118 }
1119
1120 #[derive(Subdiagnostic)]
1121 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1122 pub(crate) struct QuestionMarkInTypeSugg {
1123     #[suggestion_part(code = "Option<")]
1124     pub left: Span,
1125     #[suggestion_part(code = ">")]
1126     pub right: Span,
1127 }
1128
1129 #[derive(Diagnostic)]
1130 #[diag(parse_unexpected_parentheses_in_for_head)]
1131 pub(crate) struct ParenthesesInForHead {
1132     #[primary_span]
1133     pub span: Vec<Span>,
1134     #[subdiagnostic]
1135     pub sugg: ParenthesesInForHeadSugg,
1136 }
1137
1138 #[derive(Subdiagnostic)]
1139 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1140 pub(crate) struct ParenthesesInForHeadSugg {
1141     #[suggestion_part(code = "{left_snippet}")]
1142     pub left: Span,
1143     pub left_snippet: String,
1144     #[suggestion_part(code = "{right_snippet}")]
1145     pub right: Span,
1146     pub right_snippet: String,
1147 }
1148
1149 #[derive(Diagnostic)]
1150 #[diag(parse_doc_comment_on_param_type)]
1151 pub(crate) struct DocCommentOnParamType {
1152     #[primary_span]
1153     #[label]
1154     pub span: Span,
1155 }
1156
1157 #[derive(Diagnostic)]
1158 #[diag(parse_attribute_on_param_type)]
1159 pub(crate) struct AttributeOnParamType {
1160     #[primary_span]
1161     #[label]
1162     pub span: Span,
1163 }
1164
1165 #[derive(Diagnostic)]
1166 #[diag(parse_pattern_method_param_without_body, code = "E0642")]
1167 pub(crate) struct PatternMethodParamWithoutBody {
1168     #[primary_span]
1169     #[suggestion(code = "_", applicability = "machine-applicable")]
1170     pub span: Span,
1171 }
1172
1173 #[derive(Diagnostic)]
1174 #[diag(parse_self_param_not_first)]
1175 pub(crate) struct SelfParamNotFirst {
1176     #[primary_span]
1177     #[label]
1178     pub span: Span,
1179 }
1180
1181 #[derive(Diagnostic)]
1182 #[diag(parse_invalid_identifier_with_leading_number)]
1183 pub(crate) struct InvalidIdentiferStartsWithNumber {
1184     #[primary_span]
1185     #[label]
1186     pub span: Span,
1187 }
1188
1189 #[derive(Diagnostic)]
1190 #[diag(parse_const_generic_without_braces)]
1191 pub(crate) struct ConstGenericWithoutBraces {
1192     #[primary_span]
1193     pub span: Span,
1194     #[subdiagnostic]
1195     pub sugg: ConstGenericWithoutBracesSugg,
1196 }
1197
1198 #[derive(Subdiagnostic)]
1199 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1200 pub(crate) struct ConstGenericWithoutBracesSugg {
1201     #[suggestion_part(code = "{{ ")]
1202     pub left: Span,
1203     #[suggestion_part(code = " }}")]
1204     pub right: Span,
1205 }
1206
1207 #[derive(Diagnostic)]
1208 #[diag(parse_unexpected_const_param_declaration)]
1209 pub(crate) struct UnexpectedConstParamDeclaration {
1210     #[primary_span]
1211     #[label]
1212     pub span: Span,
1213     #[subdiagnostic]
1214     pub sugg: Option<UnexpectedConstParamDeclarationSugg>,
1215 }
1216
1217 #[derive(Subdiagnostic)]
1218 pub(crate) enum UnexpectedConstParamDeclarationSugg {
1219     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1220     AddParam {
1221         #[suggestion_part(code = "<{snippet}>")]
1222         impl_generics: Span,
1223         #[suggestion_part(code = "{ident}")]
1224         incorrect_decl: Span,
1225         snippet: String,
1226         ident: String,
1227     },
1228     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1229     AppendParam {
1230         #[suggestion_part(code = ", {snippet}")]
1231         impl_generics_end: Span,
1232         #[suggestion_part(code = "{ident}")]
1233         incorrect_decl: Span,
1234         snippet: String,
1235         ident: String,
1236     },
1237 }
1238
1239 #[derive(Diagnostic)]
1240 #[diag(parse_unexpected_const_in_generic_param)]
1241 pub(crate) struct UnexpectedConstInGenericParam {
1242     #[primary_span]
1243     pub span: Span,
1244     #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")]
1245     pub to_remove: Option<Span>,
1246 }
1247
1248 #[derive(Diagnostic)]
1249 #[diag(parse_async_move_order_incorrect)]
1250 pub(crate) struct AsyncMoveOrderIncorrect {
1251     #[primary_span]
1252     #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")]
1253     pub span: Span,
1254 }
1255
1256 #[derive(Diagnostic)]
1257 #[diag(parse_double_colon_in_bound)]
1258 pub(crate) struct DoubleColonInBound {
1259     #[primary_span]
1260     pub span: Span,
1261     #[suggestion(code = ": ", applicability = "machine-applicable")]
1262     pub between: Span,
1263 }
1264
1265 #[derive(Diagnostic)]
1266 #[diag(parse_fn_ptr_with_generics)]
1267 pub(crate) struct FnPtrWithGenerics {
1268     #[primary_span]
1269     pub span: Span,
1270     #[subdiagnostic]
1271     pub sugg: Option<FnPtrWithGenericsSugg>,
1272 }
1273
1274 #[derive(Subdiagnostic)]
1275 #[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
1276 pub(crate) struct FnPtrWithGenericsSugg {
1277     #[suggestion_part(code = "{snippet}")]
1278     pub left: Span,
1279     pub snippet: String,
1280     #[suggestion_part(code = "")]
1281     pub right: Span,
1282     pub arity: usize,
1283     pub for_param_list_exists: bool,
1284 }
1285
1286 #[derive(Diagnostic)]
1287 #[diag(parse_unexpected_if_with_if)]
1288 pub(crate) struct UnexpectedIfWithIf(
1289     #[primary_span]
1290     #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
1291     pub Span,
1292 );
1293
1294 #[derive(Diagnostic)]
1295 #[diag(parse_maybe_fn_typo_with_impl)]
1296 pub(crate) struct FnTypoWithImpl {
1297     #[primary_span]
1298     #[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
1299     pub fn_span: Span,
1300 }
1301
1302 #[derive(Diagnostic)]
1303 #[diag(parse_expected_fn_path_found_fn_keyword)]
1304 pub(crate) struct ExpectedFnPathFoundFnKeyword {
1305     #[primary_span]
1306     #[suggestion(applicability = "machine-applicable", code = "Fn", style = "verbose")]
1307     pub fn_token_span: Span,
1308 }
1309
1310 #[derive(Diagnostic)]
1311 #[diag(parse_where_clause_before_tuple_struct_body)]
1312 pub(crate) struct WhereClauseBeforeTupleStructBody {
1313     #[primary_span]
1314     #[label]
1315     pub span: Span,
1316     #[label(name_label)]
1317     pub name: Span,
1318     #[label(body_label)]
1319     pub body: Span,
1320     #[subdiagnostic]
1321     pub sugg: Option<WhereClauseBeforeTupleStructBodySugg>,
1322 }
1323
1324 #[derive(Subdiagnostic)]
1325 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1326 pub(crate) struct WhereClauseBeforeTupleStructBodySugg {
1327     #[suggestion_part(code = "{snippet}")]
1328     pub left: Span,
1329     pub snippet: String,
1330     #[suggestion_part(code = "")]
1331     pub right: Span,
1332 }