]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/errors.rs
Rollup merge of #107312 - calebcartwright:style-let-else, r=joshtriplett
[rust.git] / compiler / rustc_parse / src / errors.rs
1 use rustc_ast::token::Token;
2 use rustc_ast::{Path, Visibility};
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::edition::{Edition, LATEST_STABLE_EDITION};
7 use rustc_span::symbol::Ident;
8 use rustc_span::{Span, Symbol};
9
10 use crate::parser::TokenDescription;
11
12 #[derive(Diagnostic)]
13 #[diag(parse_maybe_report_ambiguous_plus)]
14 pub(crate) struct AmbiguousPlus {
15     pub sum_ty: String,
16     #[primary_span]
17     #[suggestion(code = "({sum_ty})")]
18     pub span: Span,
19 }
20
21 #[derive(Diagnostic)]
22 #[diag(parse_maybe_recover_from_bad_type_plus, code = "E0178")]
23 pub(crate) struct BadTypePlus {
24     pub ty: String,
25     #[primary_span]
26     pub span: Span,
27     #[subdiagnostic]
28     pub sub: BadTypePlusSub,
29 }
30
31 #[derive(Subdiagnostic)]
32 pub(crate) enum BadTypePlusSub {
33     #[suggestion(
34         parse_add_paren,
35         code = "{sum_with_parens}",
36         applicability = "machine-applicable"
37     )]
38     AddParen {
39         sum_with_parens: String,
40         #[primary_span]
41         span: Span,
42     },
43     #[label(parse_forgot_paren)]
44     ForgotParen {
45         #[primary_span]
46         span: Span,
47     },
48     #[label(parse_expect_path)]
49     ExpectPath {
50         #[primary_span]
51         span: Span,
52     },
53 }
54
55 #[derive(Diagnostic)]
56 #[diag(parse_maybe_recover_from_bad_qpath_stage_2)]
57 pub(crate) struct BadQPathStage2 {
58     #[primary_span]
59     #[suggestion(code = "", applicability = "maybe-incorrect")]
60     pub span: Span,
61     pub ty: String,
62 }
63
64 #[derive(Diagnostic)]
65 #[diag(parse_incorrect_semicolon)]
66 pub(crate) struct IncorrectSemicolon<'a> {
67     #[primary_span]
68     #[suggestion(style = "short", code = "", applicability = "machine-applicable")]
69     pub span: Span,
70     #[help]
71     pub opt_help: Option<()>,
72     pub name: &'a str,
73 }
74
75 #[derive(Diagnostic)]
76 #[diag(parse_incorrect_use_of_await)]
77 pub(crate) struct IncorrectUseOfAwait {
78     #[primary_span]
79     #[suggestion(parentheses_suggestion, code = "", applicability = "machine-applicable")]
80     pub span: Span,
81 }
82
83 #[derive(Diagnostic)]
84 #[diag(parse_incorrect_use_of_await)]
85 pub(crate) struct IncorrectAwait {
86     #[primary_span]
87     pub span: Span,
88     #[suggestion(postfix_suggestion, code = "{expr}.await{question_mark}")]
89     pub sugg_span: (Span, Applicability),
90     pub expr: String,
91     pub question_mark: &'static str,
92 }
93
94 #[derive(Diagnostic)]
95 #[diag(parse_in_in_typo)]
96 pub(crate) struct InInTypo {
97     #[primary_span]
98     pub span: Span,
99     #[suggestion(code = "", applicability = "machine-applicable")]
100     pub sugg_span: Span,
101 }
102
103 #[derive(Diagnostic)]
104 #[diag(parse_invalid_variable_declaration)]
105 pub(crate) struct InvalidVariableDeclaration {
106     #[primary_span]
107     pub span: Span,
108     #[subdiagnostic]
109     pub sub: InvalidVariableDeclarationSub,
110 }
111
112 #[derive(Subdiagnostic)]
113 pub(crate) enum InvalidVariableDeclarationSub {
114     #[suggestion(parse_switch_mut_let_order, applicability = "maybe-incorrect", code = "let mut")]
115     SwitchMutLetOrder(#[primary_span] Span),
116     #[suggestion(
117         parse_missing_let_before_mut,
118         applicability = "machine-applicable",
119         code = "let mut"
120     )]
121     MissingLet(#[primary_span] Span),
122     #[suggestion(parse_use_let_not_auto, applicability = "machine-applicable", code = "let")]
123     UseLetNotAuto(#[primary_span] Span),
124     #[suggestion(parse_use_let_not_var, applicability = "machine-applicable", code = "let")]
125     UseLetNotVar(#[primary_span] Span),
126 }
127
128 #[derive(Diagnostic)]
129 #[diag(parse_invalid_comparison_operator)]
130 pub(crate) struct InvalidComparisonOperator {
131     #[primary_span]
132     pub span: Span,
133     pub invalid: String,
134     #[subdiagnostic]
135     pub sub: InvalidComparisonOperatorSub,
136 }
137
138 #[derive(Subdiagnostic)]
139 pub(crate) enum InvalidComparisonOperatorSub {
140     #[suggestion(
141         use_instead,
142         style = "short",
143         applicability = "machine-applicable",
144         code = "{correct}"
145     )]
146     Correctable {
147         #[primary_span]
148         span: Span,
149         invalid: String,
150         correct: String,
151     },
152     #[label(spaceship_operator_invalid)]
153     Spaceship(#[primary_span] Span),
154 }
155
156 #[derive(Diagnostic)]
157 #[diag(parse_invalid_logical_operator)]
158 #[note]
159 pub(crate) struct InvalidLogicalOperator {
160     #[primary_span]
161     pub span: Span,
162     pub incorrect: String,
163     #[subdiagnostic]
164     pub sub: InvalidLogicalOperatorSub,
165 }
166
167 #[derive(Subdiagnostic)]
168 pub(crate) enum InvalidLogicalOperatorSub {
169     #[suggestion(
170         use_amp_amp_for_conjunction,
171         style = "short",
172         applicability = "machine-applicable",
173         code = "&&"
174     )]
175     Conjunction(#[primary_span] Span),
176     #[suggestion(
177         use_pipe_pipe_for_disjunction,
178         style = "short",
179         applicability = "machine-applicable",
180         code = "||"
181     )]
182     Disjunction(#[primary_span] Span),
183 }
184
185 #[derive(Diagnostic)]
186 #[diag(parse_tilde_is_not_unary_operator)]
187 pub(crate) struct TildeAsUnaryOperator(
188     #[primary_span]
189     #[suggestion(style = "short", applicability = "machine-applicable", code = "!")]
190     pub Span,
191 );
192
193 #[derive(Diagnostic)]
194 #[diag(parse_unexpected_token_after_not)]
195 pub(crate) struct NotAsNegationOperator {
196     #[primary_span]
197     pub negated: Span,
198     pub negated_desc: String,
199     #[subdiagnostic]
200     pub sub: NotAsNegationOperatorSub,
201 }
202
203 #[derive(Subdiagnostic)]
204 pub enum NotAsNegationOperatorSub {
205     #[suggestion(
206         parse_unexpected_token_after_not_default,
207         style = "short",
208         applicability = "machine-applicable",
209         code = "!"
210     )]
211     SuggestNotDefault(#[primary_span] Span),
212
213     #[suggestion(
214         parse_unexpected_token_after_not_bitwise,
215         style = "short",
216         applicability = "machine-applicable",
217         code = "!"
218     )]
219     SuggestNotBitwise(#[primary_span] Span),
220
221     #[suggestion(
222         parse_unexpected_token_after_not_logical,
223         style = "short",
224         applicability = "machine-applicable",
225         code = "!"
226     )]
227     SuggestNotLogical(#[primary_span] Span),
228 }
229
230 #[derive(Diagnostic)]
231 #[diag(parse_malformed_loop_label)]
232 pub(crate) struct MalformedLoopLabel {
233     #[primary_span]
234     #[suggestion(applicability = "machine-applicable", code = "{correct_label}")]
235     pub span: Span,
236     pub correct_label: Ident,
237 }
238
239 #[derive(Diagnostic)]
240 #[diag(parse_lifetime_in_borrow_expression)]
241 pub(crate) struct LifetimeInBorrowExpression {
242     #[primary_span]
243     pub span: Span,
244     #[suggestion(applicability = "machine-applicable", code = "")]
245     #[label]
246     pub lifetime_span: Span,
247 }
248
249 #[derive(Diagnostic)]
250 #[diag(parse_field_expression_with_generic)]
251 pub(crate) struct FieldExpressionWithGeneric(#[primary_span] pub Span);
252
253 #[derive(Diagnostic)]
254 #[diag(parse_macro_invocation_with_qualified_path)]
255 pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span);
256
257 #[derive(Diagnostic)]
258 #[diag(parse_unexpected_token_after_label)]
259 pub(crate) struct UnexpectedTokenAfterLabel {
260     #[primary_span]
261     #[label(parse_unexpected_token_after_label)]
262     pub span: Span,
263     #[suggestion(suggestion_remove_label, style = "verbose", code = "")]
264     pub remove_label: Option<Span>,
265     #[subdiagnostic]
266     pub enclose_in_block: Option<UnexpectedTokenAfterLabelSugg>,
267 }
268
269 #[derive(Subdiagnostic)]
270 #[multipart_suggestion(suggestion_enclose_in_block, applicability = "machine-applicable")]
271 pub(crate) struct UnexpectedTokenAfterLabelSugg {
272     #[suggestion_part(code = "{{ ")]
273     pub left: Span,
274     #[suggestion_part(code = " }}")]
275     pub right: Span,
276 }
277
278 #[derive(Diagnostic)]
279 #[diag(parse_require_colon_after_labeled_expression)]
280 #[note]
281 pub(crate) struct RequireColonAfterLabeledExpression {
282     #[primary_span]
283     pub span: Span,
284     #[label]
285     pub label: Span,
286     #[suggestion(style = "short", applicability = "machine-applicable", code = ": ")]
287     pub label_end: Span,
288 }
289
290 #[derive(Diagnostic)]
291 #[diag(parse_do_catch_syntax_removed)]
292 #[note]
293 pub(crate) struct DoCatchSyntaxRemoved {
294     #[primary_span]
295     #[suggestion(applicability = "machine-applicable", code = "try")]
296     pub span: Span,
297 }
298
299 #[derive(Diagnostic)]
300 #[diag(parse_float_literal_requires_integer_part)]
301 pub(crate) struct FloatLiteralRequiresIntegerPart {
302     #[primary_span]
303     #[suggestion(applicability = "machine-applicable", code = "{correct}")]
304     pub span: Span,
305     pub correct: String,
306 }
307
308 #[derive(Diagnostic)]
309 #[diag(parse_missing_semicolon_before_array)]
310 pub(crate) struct MissingSemicolonBeforeArray {
311     #[primary_span]
312     pub open_delim: Span,
313     #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = ";")]
314     pub semicolon: Span,
315 }
316
317 #[derive(Diagnostic)]
318 #[diag(parse_expect_dotdot_not_dotdotdot)]
319 pub(crate) struct MissingDotDot {
320     #[primary_span]
321     pub token_span: Span,
322     #[suggestion(applicability = "maybe-incorrect", code = "..", style = "verbose")]
323     pub sugg_span: Span,
324 }
325
326 #[derive(Diagnostic)]
327 #[diag(parse_invalid_block_macro_segment)]
328 pub(crate) struct InvalidBlockMacroSegment {
329     #[primary_span]
330     pub span: Span,
331     #[label]
332     pub context: Span,
333 }
334
335 #[derive(Diagnostic)]
336 #[diag(parse_if_expression_missing_then_block)]
337 pub(crate) struct IfExpressionMissingThenBlock {
338     #[primary_span]
339     pub if_span: Span,
340     #[subdiagnostic]
341     pub missing_then_block_sub: IfExpressionMissingThenBlockSub,
342     #[subdiagnostic]
343     pub let_else_sub: Option<IfExpressionLetSomeSub>,
344 }
345
346 #[derive(Subdiagnostic)]
347 pub(crate) enum IfExpressionMissingThenBlockSub {
348     #[help(condition_possibly_unfinished)]
349     UnfinishedCondition(#[primary_span] Span),
350     #[help(add_then_block)]
351     AddThenBlock(#[primary_span] Span),
352 }
353
354 #[derive(Subdiagnostic)]
355 #[suggestion(parse_extra_if_in_let_else, applicability = "maybe-incorrect", code = "")]
356 pub(crate) struct IfExpressionLetSomeSub {
357     #[primary_span]
358     pub if_span: Span,
359 }
360
361 #[derive(Diagnostic)]
362 #[diag(parse_if_expression_missing_condition)]
363 pub(crate) struct IfExpressionMissingCondition {
364     #[primary_span]
365     #[label(condition_label)]
366     pub if_span: Span,
367     #[label(block_label)]
368     pub block_span: Span,
369 }
370
371 #[derive(Diagnostic)]
372 #[diag(parse_expected_expression_found_let)]
373 pub(crate) struct ExpectedExpressionFoundLet {
374     #[primary_span]
375     pub span: Span,
376 }
377
378 #[derive(Diagnostic)]
379 #[diag(parse_expect_eq_instead_of_eqeq)]
380 pub(crate) struct ExpectedEqForLetExpr {
381     #[primary_span]
382     pub span: Span,
383     #[suggestion(applicability = "maybe-incorrect", code = "=", style = "verbose")]
384     pub sugg_span: Span,
385 }
386
387 #[derive(Diagnostic)]
388 #[diag(parse_expected_else_block)]
389 pub(crate) struct ExpectedElseBlock {
390     #[primary_span]
391     pub first_tok_span: Span,
392     pub first_tok: String,
393     #[label]
394     pub else_span: Span,
395     #[suggestion(applicability = "maybe-incorrect", code = "if ")]
396     pub condition_start: Span,
397 }
398
399 #[derive(Diagnostic)]
400 #[diag(parse_outer_attribute_not_allowed_on_if_else)]
401 pub(crate) struct OuterAttributeNotAllowedOnIfElse {
402     #[primary_span]
403     pub last: Span,
404
405     #[label(branch_label)]
406     pub branch_span: Span,
407
408     #[label(ctx_label)]
409     pub ctx_span: Span,
410     pub ctx: String,
411
412     #[suggestion(applicability = "machine-applicable", code = "")]
413     pub attributes: Span,
414 }
415
416 #[derive(Diagnostic)]
417 #[diag(parse_missing_in_in_for_loop)]
418 pub(crate) struct MissingInInForLoop {
419     #[primary_span]
420     pub span: Span,
421     #[subdiagnostic]
422     pub sub: MissingInInForLoopSub,
423 }
424
425 #[derive(Subdiagnostic)]
426 pub(crate) enum MissingInInForLoopSub {
427     // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect
428     #[suggestion(use_in_not_of, style = "short", applicability = "maybe-incorrect", code = "in")]
429     InNotOf(#[primary_span] Span),
430     #[suggestion(add_in, style = "short", applicability = "maybe-incorrect", code = " in ")]
431     AddIn(#[primary_span] Span),
432 }
433
434 #[derive(Diagnostic)]
435 #[diag(parse_missing_comma_after_match_arm)]
436 pub(crate) struct MissingCommaAfterMatchArm {
437     #[primary_span]
438     #[suggestion(applicability = "machine-applicable", code = ",")]
439     pub span: Span,
440 }
441
442 #[derive(Diagnostic)]
443 #[diag(parse_catch_after_try)]
444 #[help]
445 pub(crate) struct CatchAfterTry {
446     #[primary_span]
447     pub span: Span,
448 }
449
450 #[derive(Diagnostic)]
451 #[diag(parse_comma_after_base_struct)]
452 #[note]
453 pub(crate) struct CommaAfterBaseStruct {
454     #[primary_span]
455     pub span: Span,
456     #[suggestion(style = "short", applicability = "machine-applicable", code = "")]
457     pub comma: Span,
458 }
459
460 #[derive(Diagnostic)]
461 #[diag(parse_eq_field_init)]
462 pub(crate) struct EqFieldInit {
463     #[primary_span]
464     pub span: Span,
465     #[suggestion(applicability = "machine-applicable", code = ":")]
466     pub eq: Span,
467 }
468
469 #[derive(Diagnostic)]
470 #[diag(parse_dotdotdot)]
471 pub(crate) struct DotDotDot {
472     #[primary_span]
473     #[suggestion(suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
474     #[suggestion(suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
475     pub span: Span,
476 }
477
478 #[derive(Diagnostic)]
479 #[diag(parse_left_arrow_operator)]
480 pub(crate) struct LeftArrowOperator {
481     #[primary_span]
482     #[suggestion(applicability = "maybe-incorrect", code = "< -")]
483     pub span: Span,
484 }
485
486 #[derive(Diagnostic)]
487 #[diag(parse_remove_let)]
488 pub(crate) struct RemoveLet {
489     #[primary_span]
490     #[suggestion(applicability = "machine-applicable", code = "")]
491     pub span: Span,
492 }
493
494 #[derive(Diagnostic)]
495 #[diag(parse_use_eq_instead)]
496 pub(crate) struct UseEqInstead {
497     #[primary_span]
498     #[suggestion(style = "short", applicability = "machine-applicable", code = "=")]
499     pub span: Span,
500 }
501
502 #[derive(Diagnostic)]
503 #[diag(parse_use_empty_block_not_semi)]
504 pub(crate) struct UseEmptyBlockNotSemi {
505     #[primary_span]
506     #[suggestion(style = "hidden", applicability = "machine-applicable", code = "{{}}")]
507     pub span: Span,
508 }
509
510 #[derive(Diagnostic)]
511 #[diag(parse_comparison_interpreted_as_generic)]
512 pub(crate) struct ComparisonInterpretedAsGeneric {
513     #[primary_span]
514     #[label(label_comparison)]
515     pub comparison: Span,
516     pub r#type: Path,
517     #[label(label_args)]
518     pub args: Span,
519     #[subdiagnostic]
520     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
521 }
522
523 #[derive(Diagnostic)]
524 #[diag(parse_shift_interpreted_as_generic)]
525 pub(crate) struct ShiftInterpretedAsGeneric {
526     #[primary_span]
527     #[label(label_comparison)]
528     pub shift: Span,
529     pub r#type: Path,
530     #[label(label_args)]
531     pub args: Span,
532     #[subdiagnostic]
533     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
534 }
535
536 #[derive(Subdiagnostic)]
537 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
538 pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
539     #[suggestion_part(code = "(")]
540     pub left: Span,
541     #[suggestion_part(code = ")")]
542     pub right: Span,
543 }
544
545 #[derive(Diagnostic)]
546 #[diag(parse_found_expr_would_be_stmt)]
547 pub(crate) struct FoundExprWouldBeStmt {
548     #[primary_span]
549     #[label]
550     pub span: Span,
551     pub token: Token,
552     #[subdiagnostic]
553     pub suggestion: ExprParenthesesNeeded,
554 }
555
556 #[derive(Diagnostic)]
557 #[diag(parse_leading_plus_not_supported)]
558 pub(crate) struct LeadingPlusNotSupported {
559     #[primary_span]
560     #[label]
561     pub span: Span,
562     #[suggestion(
563         suggestion_remove_plus,
564         style = "verbose",
565         code = "",
566         applicability = "machine-applicable"
567     )]
568     pub remove_plus: Option<Span>,
569     #[subdiagnostic]
570     pub add_parentheses: Option<ExprParenthesesNeeded>,
571 }
572
573 #[derive(Diagnostic)]
574 #[diag(parse_parentheses_with_struct_fields)]
575 pub(crate) struct ParenthesesWithStructFields {
576     #[primary_span]
577     pub span: Span,
578     pub r#type: Path,
579     #[subdiagnostic]
580     pub braces_for_struct: BracesForStructLiteral,
581     #[subdiagnostic]
582     pub no_fields_for_fn: NoFieldsForFnCall,
583 }
584
585 #[derive(Subdiagnostic)]
586 #[multipart_suggestion(suggestion_braces_for_struct, applicability = "maybe-incorrect")]
587 pub(crate) struct BracesForStructLiteral {
588     #[suggestion_part(code = " {{ ")]
589     pub first: Span,
590     #[suggestion_part(code = " }}")]
591     pub second: Span,
592 }
593
594 #[derive(Subdiagnostic)]
595 #[multipart_suggestion(suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
596 pub(crate) struct NoFieldsForFnCall {
597     #[suggestion_part(code = "")]
598     pub fields: Vec<Span>,
599 }
600
601 #[derive(Diagnostic)]
602 #[diag(parse_labeled_loop_in_break)]
603 pub(crate) struct LabeledLoopInBreak {
604     #[primary_span]
605     pub span: Span,
606     #[subdiagnostic]
607     pub sub: WrapExpressionInParentheses,
608 }
609
610 #[derive(Subdiagnostic)]
611 #[multipart_suggestion(
612     parse_sugg_wrap_expression_in_parentheses,
613     applicability = "machine-applicable"
614 )]
615 pub(crate) struct WrapExpressionInParentheses {
616     #[suggestion_part(code = "(")]
617     pub left: Span,
618     #[suggestion_part(code = ")")]
619     pub right: Span,
620 }
621
622 #[derive(Diagnostic)]
623 #[diag(parse_array_brackets_instead_of_braces)]
624 pub(crate) struct ArrayBracketsInsteadOfSpaces {
625     #[primary_span]
626     pub span: Span,
627     #[subdiagnostic]
628     pub sub: ArrayBracketsInsteadOfSpacesSugg,
629 }
630
631 #[derive(Subdiagnostic)]
632 #[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
633 pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
634     #[suggestion_part(code = "[")]
635     pub left: Span,
636     #[suggestion_part(code = "]")]
637     pub right: Span,
638 }
639
640 #[derive(Diagnostic)]
641 #[diag(parse_match_arm_body_without_braces)]
642 pub(crate) struct MatchArmBodyWithoutBraces {
643     #[primary_span]
644     #[label(label_statements)]
645     pub statements: Span,
646     #[label(label_arrow)]
647     pub arrow: Span,
648     pub num_statements: usize,
649     #[subdiagnostic]
650     pub sub: MatchArmBodyWithoutBracesSugg,
651 }
652
653 #[derive(Diagnostic)]
654 #[diag(parse_inclusive_range_extra_equals)]
655 #[note]
656 pub(crate) struct InclusiveRangeExtraEquals {
657     #[primary_span]
658     #[suggestion(
659         suggestion_remove_eq,
660         style = "short",
661         code = "..=",
662         applicability = "maybe-incorrect"
663     )]
664     pub span: Span,
665 }
666
667 #[derive(Diagnostic)]
668 #[diag(parse_inclusive_range_match_arrow)]
669 pub(crate) struct InclusiveRangeMatchArrow {
670     #[primary_span]
671     pub span: Span,
672     #[suggestion(
673         suggestion_add_space,
674         style = "verbose",
675         code = " ",
676         applicability = "machine-applicable"
677     )]
678     pub after_pat: Span,
679 }
680
681 #[derive(Diagnostic)]
682 #[diag(parse_inclusive_range_no_end, code = "E0586")]
683 #[note]
684 pub(crate) struct InclusiveRangeNoEnd {
685     #[primary_span]
686     #[suggestion(
687         suggestion_open_range,
688         code = "..",
689         applicability = "machine-applicable",
690         style = "short"
691     )]
692     pub span: Span,
693 }
694
695 #[derive(Subdiagnostic)]
696 pub(crate) enum MatchArmBodyWithoutBracesSugg {
697     #[multipart_suggestion(suggestion_add_braces, applicability = "machine-applicable")]
698     AddBraces {
699         #[suggestion_part(code = "{{ ")]
700         left: Span,
701         #[suggestion_part(code = " }}")]
702         right: Span,
703     },
704     #[suggestion(
705         suggestion_use_comma_not_semicolon,
706         code = ",",
707         applicability = "machine-applicable"
708     )]
709     UseComma {
710         #[primary_span]
711         semicolon: Span,
712     },
713 }
714
715 #[derive(Diagnostic)]
716 #[diag(parse_struct_literal_not_allowed_here)]
717 pub(crate) struct StructLiteralNotAllowedHere {
718     #[primary_span]
719     pub span: Span,
720     #[subdiagnostic]
721     pub sub: StructLiteralNotAllowedHereSugg,
722 }
723
724 #[derive(Subdiagnostic)]
725 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
726 pub(crate) struct StructLiteralNotAllowedHereSugg {
727     #[suggestion_part(code = "(")]
728     pub left: Span,
729     #[suggestion_part(code = ")")]
730     pub right: Span,
731 }
732
733 #[derive(Diagnostic)]
734 #[diag(parse_invalid_interpolated_expression)]
735 pub(crate) struct InvalidInterpolatedExpression {
736     #[primary_span]
737     pub span: Span,
738 }
739
740 #[derive(Diagnostic)]
741 #[diag(parse_invalid_literal_suffix_on_tuple_index)]
742 pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
743     #[primary_span]
744     #[label]
745     pub span: Span,
746     pub suffix: Symbol,
747     #[help(tuple_exception_line_1)]
748     #[help(tuple_exception_line_2)]
749     #[help(tuple_exception_line_3)]
750     pub exception: Option<()>,
751 }
752
753 #[derive(Diagnostic)]
754 #[diag(parse_non_string_abi_literal)]
755 pub(crate) struct NonStringAbiLiteral {
756     #[primary_span]
757     #[suggestion(code = "\"C\"", applicability = "maybe-incorrect")]
758     pub span: Span,
759 }
760
761 #[derive(Diagnostic)]
762 #[diag(parse_mismatched_closing_delimiter)]
763 pub(crate) struct MismatchedClosingDelimiter {
764     #[primary_span]
765     pub spans: Vec<Span>,
766     pub delimiter: String,
767     #[label(label_unmatched)]
768     pub unmatched: Span,
769     #[label(label_opening_candidate)]
770     pub opening_candidate: Option<Span>,
771     #[label(label_unclosed)]
772     pub unclosed: Option<Span>,
773 }
774
775 #[derive(Diagnostic)]
776 #[diag(parse_incorrect_visibility_restriction, code = "E0704")]
777 #[help]
778 pub(crate) struct IncorrectVisibilityRestriction {
779     #[primary_span]
780     #[suggestion(code = "in {inner_str}", applicability = "machine-applicable")]
781     pub span: Span,
782     pub inner_str: String,
783 }
784
785 #[derive(Diagnostic)]
786 #[diag(parse_assignment_else_not_allowed)]
787 pub(crate) struct AssignmentElseNotAllowed {
788     #[primary_span]
789     pub span: Span,
790 }
791
792 #[derive(Diagnostic)]
793 #[diag(parse_expected_statement_after_outer_attr)]
794 pub(crate) struct ExpectedStatementAfterOuterAttr {
795     #[primary_span]
796     pub span: Span,
797 }
798
799 #[derive(Diagnostic)]
800 #[diag(parse_doc_comment_does_not_document_anything, code = "E0585")]
801 #[help]
802 pub(crate) struct DocCommentDoesNotDocumentAnything {
803     #[primary_span]
804     pub span: Span,
805     #[suggestion(code = ",", applicability = "machine-applicable")]
806     pub missing_comma: Option<Span>,
807 }
808
809 #[derive(Diagnostic)]
810 #[diag(parse_const_let_mutually_exclusive)]
811 pub(crate) struct ConstLetMutuallyExclusive {
812     #[primary_span]
813     #[suggestion(code = "const", applicability = "maybe-incorrect")]
814     pub span: Span,
815 }
816
817 #[derive(Diagnostic)]
818 #[diag(parse_invalid_expression_in_let_else)]
819 pub(crate) struct InvalidExpressionInLetElse {
820     #[primary_span]
821     pub span: Span,
822     pub operator: &'static str,
823     #[subdiagnostic]
824     pub sugg: WrapExpressionInParentheses,
825 }
826
827 #[derive(Diagnostic)]
828 #[diag(parse_invalid_curly_in_let_else)]
829 pub(crate) struct InvalidCurlyInLetElse {
830     #[primary_span]
831     pub span: Span,
832     #[subdiagnostic]
833     pub sugg: WrapExpressionInParentheses,
834 }
835
836 #[derive(Diagnostic)]
837 #[diag(parse_compound_assignment_expression_in_let)]
838 #[help]
839 pub(crate) struct CompoundAssignmentExpressionInLet {
840     #[primary_span]
841     #[suggestion(style = "short", code = "=", applicability = "maybe-incorrect")]
842     pub span: Span,
843 }
844
845 #[derive(Diagnostic)]
846 #[diag(parse_suffixed_literal_in_attribute)]
847 #[help]
848 pub(crate) struct SuffixedLiteralInAttribute {
849     #[primary_span]
850     pub span: Span,
851 }
852
853 #[derive(Diagnostic)]
854 #[diag(parse_invalid_meta_item)]
855 pub(crate) struct InvalidMetaItem {
856     #[primary_span]
857     pub span: Span,
858     pub token: Token,
859 }
860
861 #[derive(Subdiagnostic)]
862 #[suggestion(
863     parse_sugg_escape_to_use_as_identifier,
864     style = "verbose",
865     applicability = "maybe-incorrect",
866     code = "r#"
867 )]
868 pub(crate) struct SuggEscapeToUseAsIdentifier {
869     #[primary_span]
870     pub span: Span,
871     pub ident_name: String,
872 }
873
874 #[derive(Subdiagnostic)]
875 #[suggestion(parse_sugg_remove_comma, applicability = "machine-applicable", code = "")]
876 pub(crate) struct SuggRemoveComma {
877     #[primary_span]
878     pub span: Span,
879 }
880
881 #[derive(Subdiagnostic)]
882 pub(crate) enum ExpectedIdentifierFound {
883     #[label(parse_expected_identifier_found_reserved_identifier)]
884     ReservedIdentifier(#[primary_span] Span),
885     #[label(parse_expected_identifier_found_keyword)]
886     Keyword(#[primary_span] Span),
887     #[label(parse_expected_identifier_found_reserved_keyword)]
888     ReservedKeyword(#[primary_span] Span),
889     #[label(parse_expected_identifier_found_doc_comment)]
890     DocComment(#[primary_span] Span),
891     #[label(parse_expected_identifier)]
892     Other(#[primary_span] Span),
893 }
894
895 impl ExpectedIdentifierFound {
896     pub fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
897         (match token_descr {
898             Some(TokenDescription::ReservedIdentifier) => {
899                 ExpectedIdentifierFound::ReservedIdentifier
900             }
901             Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword,
902             Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
903             Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment,
904             None => ExpectedIdentifierFound::Other,
905         })(span)
906     }
907 }
908
909 pub(crate) struct ExpectedIdentifier {
910     pub span: Span,
911     pub token: Token,
912     pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>,
913     pub suggest_remove_comma: Option<SuggRemoveComma>,
914 }
915
916 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
917     #[track_caller]
918     fn into_diagnostic(
919         self,
920         handler: &'a rustc_errors::Handler,
921     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
922         let token_descr = super::parser::TokenDescription::from_token(&self.token);
923
924         let mut diag = handler.struct_diagnostic(match token_descr {
925             Some(TokenDescription::ReservedIdentifier) => {
926                 fluent::parse_expected_identifier_found_reserved_identifier_str
927             }
928             Some(TokenDescription::Keyword) => fluent::parse_expected_identifier_found_keyword_str,
929             Some(TokenDescription::ReservedKeyword) => {
930                 fluent::parse_expected_identifier_found_reserved_keyword_str
931             }
932             Some(TokenDescription::DocComment) => {
933                 fluent::parse_expected_identifier_found_doc_comment_str
934             }
935             None => fluent::parse_expected_identifier_found_str,
936         });
937         diag.set_span(self.span);
938         diag.set_arg("token", self.token);
939
940         if let Some(sugg) = self.suggest_raw {
941             sugg.add_to_diagnostic(&mut diag);
942         }
943
944         ExpectedIdentifierFound::new(token_descr, self.span).add_to_diagnostic(&mut diag);
945
946         if let Some(sugg) = self.suggest_remove_comma {
947             sugg.add_to_diagnostic(&mut diag);
948         }
949
950         diag
951     }
952 }
953
954 pub(crate) struct ExpectedSemi {
955     pub span: Span,
956     pub token: Token,
957
958     pub unexpected_token_label: Option<Span>,
959     pub sugg: ExpectedSemiSugg,
960 }
961
962 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
963     #[track_caller]
964     fn into_diagnostic(
965         self,
966         handler: &'a rustc_errors::Handler,
967     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
968         let token_descr = super::parser::TokenDescription::from_token(&self.token);
969
970         let mut diag = handler.struct_diagnostic(match token_descr {
971             Some(TokenDescription::ReservedIdentifier) => {
972                 fluent::parse_expected_semi_found_reserved_identifier_str
973             }
974             Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str,
975             Some(TokenDescription::ReservedKeyword) => {
976                 fluent::parse_expected_semi_found_reserved_keyword_str
977             }
978             Some(TokenDescription::DocComment) => fluent::parse_expected_semi_found_doc_comment_str,
979             None => fluent::parse_expected_semi_found_str,
980         });
981         diag.set_span(self.span);
982         diag.set_arg("token", self.token);
983
984         if let Some(unexpected_token_label) = self.unexpected_token_label {
985             diag.span_label(unexpected_token_label, fluent::parse_label_unexpected_token);
986         }
987
988         self.sugg.add_to_diagnostic(&mut diag);
989
990         diag
991     }
992 }
993
994 #[derive(Subdiagnostic)]
995 pub(crate) enum ExpectedSemiSugg {
996     #[suggestion(parse_sugg_change_this_to_semi, code = ";", applicability = "machine-applicable")]
997     ChangeToSemi(#[primary_span] Span),
998     #[suggestion(
999         parse_sugg_add_semi,
1000         style = "short",
1001         code = ";",
1002         applicability = "machine-applicable"
1003     )]
1004     AddSemi(#[primary_span] Span),
1005 }
1006
1007 #[derive(Diagnostic)]
1008 #[diag(parse_struct_literal_body_without_path)]
1009 pub(crate) struct StructLiteralBodyWithoutPath {
1010     #[primary_span]
1011     pub span: Span,
1012     #[subdiagnostic]
1013     pub sugg: StructLiteralBodyWithoutPathSugg,
1014 }
1015
1016 #[derive(Subdiagnostic)]
1017 #[multipart_suggestion(suggestion, applicability = "has-placeholders")]
1018 pub(crate) struct StructLiteralBodyWithoutPathSugg {
1019     #[suggestion_part(code = "{{ SomeStruct ")]
1020     pub before: Span,
1021     #[suggestion_part(code = " }}")]
1022     pub after: Span,
1023 }
1024
1025 #[derive(Diagnostic)]
1026 #[diag(parse_struct_literal_needing_parens)]
1027 pub(crate) struct StructLiteralNeedingParens {
1028     #[primary_span]
1029     pub span: Span,
1030     #[subdiagnostic]
1031     pub sugg: StructLiteralNeedingParensSugg,
1032 }
1033
1034 #[derive(Subdiagnostic)]
1035 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1036 pub(crate) struct StructLiteralNeedingParensSugg {
1037     #[suggestion_part(code = "(")]
1038     pub before: Span,
1039     #[suggestion_part(code = ")")]
1040     pub after: Span,
1041 }
1042
1043 #[derive(Diagnostic)]
1044 #[diag(parse_unmatched_angle_brackets)]
1045 pub(crate) struct UnmatchedAngleBrackets {
1046     #[primary_span]
1047     #[suggestion(code = "", applicability = "machine-applicable")]
1048     pub span: Span,
1049     pub num_extra_brackets: usize,
1050 }
1051
1052 #[derive(Diagnostic)]
1053 #[diag(parse_generic_parameters_without_angle_brackets)]
1054 pub(crate) struct GenericParamsWithoutAngleBrackets {
1055     #[primary_span]
1056     pub span: Span,
1057     #[subdiagnostic]
1058     pub sugg: GenericParamsWithoutAngleBracketsSugg,
1059 }
1060
1061 #[derive(Subdiagnostic)]
1062 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1063 pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
1064     #[suggestion_part(code = "<")]
1065     pub left: Span,
1066     #[suggestion_part(code = ">")]
1067     pub right: Span,
1068 }
1069
1070 #[derive(Diagnostic)]
1071 #[diag(parse_comparison_operators_cannot_be_chained)]
1072 pub(crate) struct ComparisonOperatorsCannotBeChained {
1073     #[primary_span]
1074     pub span: Vec<Span>,
1075     #[suggestion(
1076         parse_sugg_turbofish_syntax,
1077         style = "verbose",
1078         code = "::",
1079         applicability = "maybe-incorrect"
1080     )]
1081     pub suggest_turbofish: Option<Span>,
1082     #[help(parse_sugg_turbofish_syntax)]
1083     #[help(sugg_parentheses_for_function_args)]
1084     pub help_turbofish: Option<()>,
1085     #[subdiagnostic]
1086     pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
1087 }
1088
1089 #[derive(Subdiagnostic)]
1090 pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
1091     #[suggestion(
1092         sugg_split_comparison,
1093         style = "verbose",
1094         code = " && {middle_term}",
1095         applicability = "maybe-incorrect"
1096     )]
1097     SplitComparison {
1098         #[primary_span]
1099         span: Span,
1100         middle_term: String,
1101     },
1102     #[multipart_suggestion(sugg_parenthesize, applicability = "maybe-incorrect")]
1103     Parenthesize {
1104         #[suggestion_part(code = "(")]
1105         left: Span,
1106         #[suggestion_part(code = ")")]
1107         right: Span,
1108     },
1109 }
1110
1111 #[derive(Diagnostic)]
1112 #[diag(parse_question_mark_in_type)]
1113 pub(crate) struct QuestionMarkInType {
1114     #[primary_span]
1115     #[label]
1116     pub span: Span,
1117     #[subdiagnostic]
1118     pub sugg: QuestionMarkInTypeSugg,
1119 }
1120
1121 #[derive(Subdiagnostic)]
1122 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1123 pub(crate) struct QuestionMarkInTypeSugg {
1124     #[suggestion_part(code = "Option<")]
1125     pub left: Span,
1126     #[suggestion_part(code = ">")]
1127     pub right: Span,
1128 }
1129
1130 #[derive(Diagnostic)]
1131 #[diag(parse_unexpected_parentheses_in_for_head)]
1132 pub(crate) struct ParenthesesInForHead {
1133     #[primary_span]
1134     pub span: Vec<Span>,
1135     #[subdiagnostic]
1136     pub sugg: ParenthesesInForHeadSugg,
1137 }
1138
1139 #[derive(Subdiagnostic)]
1140 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1141 pub(crate) struct ParenthesesInForHeadSugg {
1142     #[suggestion_part(code = "{left_snippet}")]
1143     pub left: Span,
1144     pub left_snippet: String,
1145     #[suggestion_part(code = "{right_snippet}")]
1146     pub right: Span,
1147     pub right_snippet: String,
1148 }
1149
1150 #[derive(Diagnostic)]
1151 #[diag(parse_doc_comment_on_param_type)]
1152 pub(crate) struct DocCommentOnParamType {
1153     #[primary_span]
1154     #[label]
1155     pub span: Span,
1156 }
1157
1158 #[derive(Diagnostic)]
1159 #[diag(parse_attribute_on_param_type)]
1160 pub(crate) struct AttributeOnParamType {
1161     #[primary_span]
1162     #[label]
1163     pub span: Span,
1164 }
1165
1166 #[derive(Diagnostic)]
1167 #[diag(parse_pattern_method_param_without_body, code = "E0642")]
1168 pub(crate) struct PatternMethodParamWithoutBody {
1169     #[primary_span]
1170     #[suggestion(code = "_", applicability = "machine-applicable")]
1171     pub span: Span,
1172 }
1173
1174 #[derive(Diagnostic)]
1175 #[diag(parse_self_param_not_first)]
1176 pub(crate) struct SelfParamNotFirst {
1177     #[primary_span]
1178     #[label]
1179     pub span: Span,
1180 }
1181
1182 #[derive(Diagnostic)]
1183 #[diag(parse_invalid_identifier_with_leading_number)]
1184 pub(crate) struct InvalidIdentiferStartsWithNumber {
1185     #[primary_span]
1186     #[label]
1187     pub span: Span,
1188 }
1189
1190 #[derive(Diagnostic)]
1191 #[diag(parse_const_generic_without_braces)]
1192 pub(crate) struct ConstGenericWithoutBraces {
1193     #[primary_span]
1194     pub span: Span,
1195     #[subdiagnostic]
1196     pub sugg: ConstGenericWithoutBracesSugg,
1197 }
1198
1199 #[derive(Subdiagnostic)]
1200 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1201 pub(crate) struct ConstGenericWithoutBracesSugg {
1202     #[suggestion_part(code = "{{ ")]
1203     pub left: Span,
1204     #[suggestion_part(code = " }}")]
1205     pub right: Span,
1206 }
1207
1208 #[derive(Diagnostic)]
1209 #[diag(parse_unexpected_const_param_declaration)]
1210 pub(crate) struct UnexpectedConstParamDeclaration {
1211     #[primary_span]
1212     #[label]
1213     pub span: Span,
1214     #[subdiagnostic]
1215     pub sugg: Option<UnexpectedConstParamDeclarationSugg>,
1216 }
1217
1218 #[derive(Subdiagnostic)]
1219 pub(crate) enum UnexpectedConstParamDeclarationSugg {
1220     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1221     AddParam {
1222         #[suggestion_part(code = "<{snippet}>")]
1223         impl_generics: Span,
1224         #[suggestion_part(code = "{ident}")]
1225         incorrect_decl: Span,
1226         snippet: String,
1227         ident: String,
1228     },
1229     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1230     AppendParam {
1231         #[suggestion_part(code = ", {snippet}")]
1232         impl_generics_end: Span,
1233         #[suggestion_part(code = "{ident}")]
1234         incorrect_decl: Span,
1235         snippet: String,
1236         ident: String,
1237     },
1238 }
1239
1240 #[derive(Diagnostic)]
1241 #[diag(parse_unexpected_const_in_generic_param)]
1242 pub(crate) struct UnexpectedConstInGenericParam {
1243     #[primary_span]
1244     pub span: Span,
1245     #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")]
1246     pub to_remove: Option<Span>,
1247 }
1248
1249 #[derive(Diagnostic)]
1250 #[diag(parse_async_move_order_incorrect)]
1251 pub(crate) struct AsyncMoveOrderIncorrect {
1252     #[primary_span]
1253     #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")]
1254     pub span: Span,
1255 }
1256
1257 #[derive(Diagnostic)]
1258 #[diag(parse_double_colon_in_bound)]
1259 pub(crate) struct DoubleColonInBound {
1260     #[primary_span]
1261     pub span: Span,
1262     #[suggestion(code = ": ", applicability = "machine-applicable")]
1263     pub between: Span,
1264 }
1265
1266 #[derive(Diagnostic)]
1267 #[diag(parse_fn_ptr_with_generics)]
1268 pub(crate) struct FnPtrWithGenerics {
1269     #[primary_span]
1270     pub span: Span,
1271     #[subdiagnostic]
1272     pub sugg: Option<FnPtrWithGenericsSugg>,
1273 }
1274
1275 #[derive(Subdiagnostic)]
1276 #[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
1277 pub(crate) struct FnPtrWithGenericsSugg {
1278     #[suggestion_part(code = "{snippet}")]
1279     pub left: Span,
1280     pub snippet: String,
1281     #[suggestion_part(code = "")]
1282     pub right: Span,
1283     pub arity: usize,
1284     pub for_param_list_exists: bool,
1285 }
1286
1287 #[derive(Diagnostic)]
1288 #[diag(parse_unexpected_if_with_if)]
1289 pub(crate) struct UnexpectedIfWithIf(
1290     #[primary_span]
1291     #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
1292     pub Span,
1293 );
1294
1295 #[derive(Diagnostic)]
1296 #[diag(parse_maybe_fn_typo_with_impl)]
1297 pub(crate) struct FnTypoWithImpl {
1298     #[primary_span]
1299     #[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
1300     pub fn_span: Span,
1301 }
1302
1303 #[derive(Diagnostic)]
1304 #[diag(parse_expected_fn_path_found_fn_keyword)]
1305 pub(crate) struct ExpectedFnPathFoundFnKeyword {
1306     #[primary_span]
1307     #[suggestion(applicability = "machine-applicable", code = "Fn", style = "verbose")]
1308     pub fn_token_span: Span,
1309 }
1310
1311 #[derive(Diagnostic)]
1312 #[diag(parse_where_clause_before_tuple_struct_body)]
1313 pub(crate) struct WhereClauseBeforeTupleStructBody {
1314     #[primary_span]
1315     #[label]
1316     pub span: Span,
1317     #[label(name_label)]
1318     pub name: Span,
1319     #[label(body_label)]
1320     pub body: Span,
1321     #[subdiagnostic]
1322     pub sugg: Option<WhereClauseBeforeTupleStructBodySugg>,
1323 }
1324
1325 #[derive(Subdiagnostic)]
1326 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1327 pub(crate) struct WhereClauseBeforeTupleStructBodySugg {
1328     #[suggestion_part(code = "{snippet}")]
1329     pub left: Span,
1330     pub snippet: String,
1331     #[suggestion_part(code = "")]
1332     pub right: Span,
1333 }
1334
1335 #[derive(Diagnostic)]
1336 #[diag(parse_async_fn_in_2015, code = "E0670")]
1337 pub(crate) struct AsyncFnIn2015 {
1338     #[primary_span]
1339     #[label]
1340     pub span: Span,
1341     #[subdiagnostic]
1342     pub help: HelpUseLatestEdition,
1343 }
1344
1345 #[derive(Subdiagnostic)]
1346 #[label(parse_async_block_in_2015)]
1347 pub(crate) struct AsyncBlockIn2015 {
1348     #[primary_span]
1349     pub span: Span,
1350 }
1351
1352 #[derive(Diagnostic)]
1353 #[diag(parse_self_argument_pointer)]
1354 pub(crate) struct SelfArgumentPointer {
1355     #[primary_span]
1356     #[label]
1357     pub span: Span,
1358 }
1359
1360 #[derive(Diagnostic)]
1361 #[diag(parse_visibility_not_followed_by_item)]
1362 #[help]
1363 pub(crate) struct VisibilityNotFollowedByItem {
1364     #[primary_span]
1365     #[label]
1366     pub span: Span,
1367     pub vis: Visibility,
1368 }
1369
1370 #[derive(Diagnostic)]
1371 #[diag(parse_default_not_followed_by_item)]
1372 #[note]
1373 pub(crate) struct DefaultNotFollowedByItem {
1374     #[primary_span]
1375     #[label]
1376     pub span: Span,
1377 }
1378
1379 #[derive(Diagnostic)]
1380 pub(crate) enum MissingKeywordForItemDefinition {
1381     #[diag(parse_missing_struct_for_struct_definition)]
1382     Struct {
1383         #[primary_span]
1384         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " struct ")]
1385         span: Span,
1386         ident: Ident,
1387     },
1388     #[diag(parse_missing_fn_for_function_definition)]
1389     Function {
1390         #[primary_span]
1391         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " fn ")]
1392         span: Span,
1393         ident: Ident,
1394     },
1395     #[diag(parse_missing_fn_for_method_definition)]
1396     Method {
1397         #[primary_span]
1398         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " fn ")]
1399         span: Span,
1400         ident: Ident,
1401     },
1402     #[diag(parse_ambiguous_missing_keyword_for_item_definition)]
1403     Ambiguous {
1404         #[primary_span]
1405         span: Span,
1406         #[subdiagnostic]
1407         subdiag: Option<AmbiguousMissingKwForItemSub>,
1408     },
1409 }
1410
1411 #[derive(Subdiagnostic)]
1412 pub(crate) enum AmbiguousMissingKwForItemSub {
1413     #[suggestion(suggestion, applicability = "maybe-incorrect", code = "{snippet}!")]
1414     SuggestMacro {
1415         #[primary_span]
1416         span: Span,
1417         snippet: String,
1418     },
1419     #[help(help)]
1420     HelpMacro,
1421 }
1422
1423 #[derive(Diagnostic)]
1424 #[diag(parse_missing_trait_in_trait_impl)]
1425 pub(crate) struct MissingTraitInTraitImpl {
1426     #[primary_span]
1427     #[suggestion(suggestion_add_trait, code = " Trait ", applicability = "has-placeholders")]
1428     pub span: Span,
1429     #[suggestion(suggestion_remove_for, code = "", applicability = "maybe-incorrect")]
1430     pub for_span: Span,
1431 }
1432
1433 #[derive(Diagnostic)]
1434 #[diag(parse_missing_for_in_trait_impl)]
1435 pub(crate) struct MissingForInTraitImpl {
1436     #[primary_span]
1437     #[suggestion(style = "short", code = " for ", applicability = "machine-applicable")]
1438     pub span: Span,
1439 }
1440
1441 #[derive(Diagnostic)]
1442 #[diag(parse_expected_trait_in_trait_impl_found_type)]
1443 pub(crate) struct ExpectedTraitInTraitImplFoundType {
1444     #[primary_span]
1445     pub span: Span,
1446 }
1447
1448 #[derive(Diagnostic)]
1449 #[diag(parse_bounds_not_allowed_on_trait_aliases)]
1450 pub(crate) struct BoundsNotAllowedOnTraitAliases {
1451     #[primary_span]
1452     pub span: Span,
1453 }
1454
1455 #[derive(Diagnostic)]
1456 #[diag(parse_trait_alias_cannot_be_auto)]
1457 pub(crate) struct TraitAliasCannotBeAuto {
1458     #[primary_span]
1459     #[label(parse_trait_alias_cannot_be_auto)]
1460     pub span: Span,
1461 }
1462
1463 #[derive(Diagnostic)]
1464 #[diag(parse_trait_alias_cannot_be_unsafe)]
1465 pub(crate) struct TraitAliasCannotBeUnsafe {
1466     #[primary_span]
1467     #[label(parse_trait_alias_cannot_be_unsafe)]
1468     pub span: Span,
1469 }
1470
1471 #[derive(Diagnostic)]
1472 #[diag(parse_associated_static_item_not_allowed)]
1473 pub(crate) struct AssociatedStaticItemNotAllowed {
1474     #[primary_span]
1475     pub span: Span,
1476 }
1477
1478 #[derive(Diagnostic)]
1479 #[diag(parse_extern_crate_name_with_dashes)]
1480 pub(crate) struct ExternCrateNameWithDashes {
1481     #[primary_span]
1482     #[label]
1483     pub span: Span,
1484     #[subdiagnostic]
1485     pub sugg: ExternCrateNameWithDashesSugg,
1486 }
1487
1488 #[derive(Subdiagnostic)]
1489 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1490 pub(crate) struct ExternCrateNameWithDashesSugg {
1491     #[suggestion_part(code = "_")]
1492     pub dashes: Vec<Span>,
1493 }
1494
1495 #[derive(Diagnostic)]
1496 #[diag(parse_extern_item_cannot_be_const)]
1497 #[note]
1498 pub(crate) struct ExternItemCannotBeConst {
1499     #[primary_span]
1500     pub ident_span: Span,
1501     #[suggestion(code = "static ", applicability = "machine-applicable")]
1502     pub const_span: Span,
1503 }
1504
1505 #[derive(Diagnostic)]
1506 #[diag(parse_const_global_cannot_be_mutable)]
1507 pub(crate) struct ConstGlobalCannotBeMutable {
1508     #[primary_span]
1509     #[label]
1510     pub ident_span: Span,
1511     #[suggestion(code = "static", applicability = "maybe-incorrect")]
1512     pub const_span: Span,
1513 }
1514
1515 #[derive(Diagnostic)]
1516 #[diag(parse_missing_const_type)]
1517 pub(crate) struct MissingConstType {
1518     #[primary_span]
1519     #[suggestion(code = "{colon} <type>", applicability = "has-placeholders")]
1520     pub span: Span,
1521
1522     pub kind: &'static str,
1523     pub colon: &'static str,
1524 }
1525
1526 #[derive(Diagnostic)]
1527 #[diag(parse_enum_struct_mutually_exclusive)]
1528 pub(crate) struct EnumStructMutuallyExclusive {
1529     #[primary_span]
1530     #[suggestion(code = "enum", applicability = "machine-applicable")]
1531     pub span: Span,
1532 }
1533
1534 #[derive(Diagnostic)]
1535 pub(crate) enum UnexpectedTokenAfterStructName {
1536     #[diag(parse_unexpected_token_after_struct_name_found_reserved_identifier)]
1537     ReservedIdentifier {
1538         #[primary_span]
1539         #[label(parse_unexpected_token_after_struct_name)]
1540         span: Span,
1541         token: Token,
1542     },
1543     #[diag(parse_unexpected_token_after_struct_name_found_keyword)]
1544     Keyword {
1545         #[primary_span]
1546         #[label(parse_unexpected_token_after_struct_name)]
1547         span: Span,
1548         token: Token,
1549     },
1550     #[diag(parse_unexpected_token_after_struct_name_found_reserved_keyword)]
1551     ReservedKeyword {
1552         #[primary_span]
1553         #[label(parse_unexpected_token_after_struct_name)]
1554         span: Span,
1555         token: Token,
1556     },
1557     #[diag(parse_unexpected_token_after_struct_name_found_doc_comment)]
1558     DocComment {
1559         #[primary_span]
1560         #[label(parse_unexpected_token_after_struct_name)]
1561         span: Span,
1562         token: Token,
1563     },
1564     #[diag(parse_unexpected_token_after_struct_name_found_other)]
1565     Other {
1566         #[primary_span]
1567         #[label(parse_unexpected_token_after_struct_name)]
1568         span: Span,
1569         token: Token,
1570     },
1571 }
1572
1573 impl UnexpectedTokenAfterStructName {
1574     pub fn new(span: Span, token: Token) -> Self {
1575         match TokenDescription::from_token(&token) {
1576             Some(TokenDescription::ReservedIdentifier) => Self::ReservedIdentifier { span, token },
1577             Some(TokenDescription::Keyword) => Self::Keyword { span, token },
1578             Some(TokenDescription::ReservedKeyword) => Self::ReservedKeyword { span, token },
1579             Some(TokenDescription::DocComment) => Self::DocComment { span, token },
1580             None => Self::Other { span, token },
1581         }
1582     }
1583 }
1584
1585 #[derive(Diagnostic)]
1586 #[diag(parse_unexpected_self_in_generic_parameters)]
1587 #[note]
1588 pub(crate) struct UnexpectedSelfInGenericParameters {
1589     #[primary_span]
1590     pub span: Span,
1591 }
1592
1593 #[derive(Diagnostic)]
1594 #[diag(parse_multiple_where_clauses)]
1595 pub(crate) struct MultipleWhereClauses {
1596     #[primary_span]
1597     pub span: Span,
1598     #[label]
1599     pub previous: Span,
1600     #[suggestion(style = "verbose", code = ",", applicability = "maybe-incorrect")]
1601     pub between: Span,
1602 }
1603
1604 #[derive(Diagnostic)]
1605 pub(crate) enum UnexpectedNonterminal {
1606     #[diag(parse_nonterminal_expected_item_keyword)]
1607     Item(#[primary_span] Span),
1608     #[diag(parse_nonterminal_expected_statement)]
1609     Statement(#[primary_span] Span),
1610     #[diag(parse_nonterminal_expected_ident)]
1611     Ident {
1612         #[primary_span]
1613         span: Span,
1614         token: Token,
1615     },
1616     #[diag(parse_nonterminal_expected_lifetime)]
1617     Lifetime {
1618         #[primary_span]
1619         span: Span,
1620         token: Token,
1621     },
1622 }
1623
1624 #[derive(Diagnostic)]
1625 pub(crate) enum TopLevelOrPatternNotAllowed {
1626     #[diag(parse_or_pattern_not_allowed_in_let_binding)]
1627     LetBinding {
1628         #[primary_span]
1629         span: Span,
1630         #[subdiagnostic]
1631         sub: Option<TopLevelOrPatternNotAllowedSugg>,
1632     },
1633     #[diag(parse_or_pattern_not_allowed_in_fn_parameters)]
1634     FunctionParameter {
1635         #[primary_span]
1636         span: Span,
1637         #[subdiagnostic]
1638         sub: Option<TopLevelOrPatternNotAllowedSugg>,
1639     },
1640 }
1641
1642 #[derive(Subdiagnostic)]
1643 pub(crate) enum TopLevelOrPatternNotAllowedSugg {
1644     #[suggestion(
1645         parse_sugg_remove_leading_vert_in_pattern,
1646         code = "{pat}",
1647         applicability = "machine-applicable"
1648     )]
1649     RemoveLeadingVert {
1650         #[primary_span]
1651         span: Span,
1652         pat: String,
1653     },
1654     #[suggestion(
1655         parse_sugg_wrap_pattern_in_parens,
1656         code = "({pat})",
1657         applicability = "machine-applicable"
1658     )]
1659     WrapInParens {
1660         #[primary_span]
1661         span: Span,
1662         pat: String,
1663     },
1664 }
1665
1666 #[derive(Diagnostic)]
1667 #[diag(parse_unexpected_vert_vert_before_function_parameter)]
1668 #[note(parse_note_pattern_alternatives_use_single_vert)]
1669 pub(crate) struct UnexpectedVertVertBeforeFunctionParam {
1670     #[primary_span]
1671     #[suggestion(code = "", applicability = "machine-applicable")]
1672     pub span: Span,
1673 }
1674
1675 #[derive(Diagnostic)]
1676 #[diag(parse_unexpected_vert_vert_in_pattern)]
1677 pub(crate) struct UnexpectedVertVertInPattern {
1678     #[primary_span]
1679     #[suggestion(code = "|", applicability = "machine-applicable")]
1680     pub span: Span,
1681     #[label(parse_label_while_parsing_or_pattern_here)]
1682     pub start: Option<Span>,
1683 }
1684
1685 #[derive(Diagnostic)]
1686 #[diag(parse_trailing_vert_not_allowed)]
1687 pub(crate) struct TrailingVertNotAllowed {
1688     #[primary_span]
1689     #[suggestion(code = "", applicability = "machine-applicable")]
1690     pub span: Span,
1691     #[label(parse_label_while_parsing_or_pattern_here)]
1692     pub start: Option<Span>,
1693     pub token: Token,
1694     #[note(parse_note_pattern_alternatives_use_single_vert)]
1695     pub note_double_vert: Option<()>,
1696 }
1697
1698 #[derive(Diagnostic)]
1699 #[diag(parse_dotdotdot_rest_pattern)]
1700 pub(crate) struct DotDotDotRestPattern {
1701     #[primary_span]
1702     #[suggestion(style = "short", code = "..", applicability = "machine-applicable")]
1703     #[label]
1704     pub span: Span,
1705 }
1706
1707 #[derive(Diagnostic)]
1708 #[diag(parse_pattern_on_wrong_side_of_at)]
1709 pub(crate) struct PatternOnWrongSideOfAt {
1710     #[primary_span]
1711     #[suggestion(code = "{whole_pat}", applicability = "machine-applicable")]
1712     pub whole_span: Span,
1713     pub whole_pat: String,
1714     #[label(label_pattern)]
1715     pub pattern: Span,
1716     #[label(label_binding)]
1717     pub binding: Span,
1718 }
1719
1720 #[derive(Diagnostic)]
1721 #[diag(parse_expected_binding_left_of_at)]
1722 #[note]
1723 pub(crate) struct ExpectedBindingLeftOfAt {
1724     #[primary_span]
1725     pub whole_span: Span,
1726     #[label(label_lhs)]
1727     pub lhs: Span,
1728     #[label(label_rhs)]
1729     pub rhs: Span,
1730 }
1731
1732 #[derive(Diagnostic)]
1733 #[diag(parse_ambiguous_range_pattern)]
1734 pub(crate) struct AmbiguousRangePattern {
1735     #[primary_span]
1736     #[suggestion(code = "({pat})", applicability = "maybe-incorrect")]
1737     pub span: Span,
1738     pub pat: String,
1739 }
1740
1741 #[derive(Diagnostic)]
1742 #[diag(parse_unexpected_lifetime_in_pattern)]
1743 pub(crate) struct UnexpectedLifetimeInPattern {
1744     #[primary_span]
1745     #[suggestion(code = "", applicability = "machine-applicable")]
1746     pub span: Span,
1747     pub symbol: Symbol,
1748 }
1749
1750 #[derive(Diagnostic)]
1751 #[diag(parse_ref_mut_order_incorrect)]
1752 pub(crate) struct RefMutOrderIncorrect {
1753     #[primary_span]
1754     #[suggestion(code = "ref mut", applicability = "machine-applicable")]
1755     pub span: Span,
1756 }
1757
1758 #[derive(Diagnostic)]
1759 pub(crate) enum InvalidMutInPattern {
1760     #[diag(parse_mut_on_nested_ident_pattern)]
1761     #[note(parse_note_mut_pattern_usage)]
1762     NestedIdent {
1763         #[primary_span]
1764         #[suggestion(code = "{pat}", applicability = "machine-applicable")]
1765         span: Span,
1766         pat: String,
1767     },
1768     #[diag(parse_mut_on_non_ident_pattern)]
1769     #[note(parse_note_mut_pattern_usage)]
1770     NonIdent {
1771         #[primary_span]
1772         #[suggestion(code = "{pat}", applicability = "machine-applicable")]
1773         span: Span,
1774         pat: String,
1775     },
1776 }
1777
1778 #[derive(Diagnostic)]
1779 #[diag(parse_repeated_mut_in_pattern)]
1780 pub(crate) struct RepeatedMutInPattern {
1781     #[primary_span]
1782     #[suggestion(code = "", applicability = "machine-applicable")]
1783     pub span: Span,
1784 }
1785
1786 #[derive(Diagnostic)]
1787 #[diag(parse_dot_dot_dot_range_to_pattern_not_allowed)]
1788 pub(crate) struct DotDotDotRangeToPatternNotAllowed {
1789     #[primary_span]
1790     #[suggestion(style = "short", code = "..=", applicability = "machine-applicable")]
1791     pub span: Span,
1792 }
1793
1794 #[derive(Diagnostic)]
1795 #[diag(parse_enum_pattern_instead_of_identifier)]
1796 pub(crate) struct EnumPatternInsteadOfIdentifier {
1797     #[primary_span]
1798     pub span: Span,
1799 }
1800
1801 #[derive(Diagnostic)]
1802 #[diag(parse_dot_dot_dot_for_remaining_fields)]
1803 pub(crate) struct DotDotDotForRemainingFields {
1804     #[primary_span]
1805     #[suggestion(code = "..", applicability = "machine-applicable")]
1806     pub span: Span,
1807 }
1808
1809 #[derive(Diagnostic)]
1810 #[diag(parse_expected_comma_after_pattern_field)]
1811 pub(crate) struct ExpectedCommaAfterPatternField {
1812     #[primary_span]
1813     pub span: Span,
1814 }
1815
1816 #[derive(Diagnostic)]
1817 #[diag(parse_return_types_use_thin_arrow)]
1818 pub(crate) struct ReturnTypesUseThinArrow {
1819     #[primary_span]
1820     #[suggestion(style = "short", code = "->", applicability = "machine-applicable")]
1821     pub span: Span,
1822 }
1823
1824 #[derive(Diagnostic)]
1825 #[diag(parse_need_plus_after_trait_object_lifetime)]
1826 pub(crate) struct NeedPlusAfterTraitObjectLifetime {
1827     #[primary_span]
1828     pub span: Span,
1829 }
1830
1831 #[derive(Diagnostic)]
1832 #[diag(parse_expected_mut_or_const_in_raw_pointer_type)]
1833 pub(crate) struct ExpectedMutOrConstInRawPointerType {
1834     #[primary_span]
1835     pub span: Span,
1836     #[suggestion(code("mut ", "const "), applicability = "has-placeholders")]
1837     pub after_asterisk: Span,
1838 }
1839
1840 #[derive(Diagnostic)]
1841 #[diag(parse_lifetime_after_mut)]
1842 pub(crate) struct LifetimeAfterMut {
1843     #[primary_span]
1844     pub span: Span,
1845     #[suggestion(code = "&{snippet} mut", applicability = "maybe-incorrect")]
1846     pub suggest_lifetime: Option<Span>,
1847     pub snippet: String,
1848 }
1849
1850 #[derive(Diagnostic)]
1851 #[diag(parse_dyn_after_mut)]
1852 pub(crate) struct DynAfterMut {
1853     #[primary_span]
1854     #[suggestion(code = "&mut dyn", applicability = "machine-applicable")]
1855     pub span: Span,
1856 }
1857
1858 #[derive(Diagnostic)]
1859 #[diag(parse_fn_pointer_cannot_be_const)]
1860 pub(crate) struct FnPointerCannotBeConst {
1861     #[primary_span]
1862     pub span: Span,
1863     #[suggestion(code = "", applicability = "maybe-incorrect")]
1864     #[label]
1865     pub qualifier: Span,
1866 }
1867
1868 #[derive(Diagnostic)]
1869 #[diag(parse_fn_pointer_cannot_be_async)]
1870 pub(crate) struct FnPointerCannotBeAsync {
1871     #[primary_span]
1872     pub span: Span,
1873     #[suggestion(code = "", applicability = "maybe-incorrect")]
1874     #[label]
1875     pub qualifier: Span,
1876 }
1877
1878 #[derive(Diagnostic)]
1879 #[diag(parse_nested_c_variadic_type, code = "E0743")]
1880 pub(crate) struct NestedCVariadicType {
1881     #[primary_span]
1882     pub span: Span,
1883 }
1884
1885 #[derive(Diagnostic)]
1886 #[diag(parse_invalid_dyn_keyword)]
1887 #[help]
1888 pub(crate) struct InvalidDynKeyword {
1889     #[primary_span]
1890     #[suggestion(code = "", applicability = "machine-applicable")]
1891     pub span: Span,
1892 }
1893
1894 #[derive(Diagnostic)]
1895 #[diag(parse_negative_bounds_not_supported)]
1896 pub(crate) struct NegativeBoundsNotSupported {
1897     #[primary_span]
1898     pub negative_bounds: Vec<Span>,
1899     #[label]
1900     pub last_span: Span,
1901     #[subdiagnostic]
1902     pub sub: Option<NegativeBoundsNotSupportedSugg>,
1903 }
1904
1905 #[derive(Subdiagnostic)]
1906 #[suggestion(
1907     suggestion,
1908     style = "tool-only",
1909     code = "{fixed}",
1910     applicability = "machine-applicable"
1911 )]
1912 pub(crate) struct NegativeBoundsNotSupportedSugg {
1913     #[primary_span]
1914     pub bound_list: Span,
1915     pub num_bounds: usize,
1916     pub fixed: String,
1917 }
1918
1919 #[derive(Subdiagnostic)]
1920 pub enum HelpUseLatestEdition {
1921     #[help(parse_help_set_edition_cargo)]
1922     #[note(parse_note_edition_guide)]
1923     Cargo { edition: Edition },
1924     #[help(parse_help_set_edition_standalone)]
1925     #[note(parse_note_edition_guide)]
1926     Standalone { edition: Edition },
1927 }
1928
1929 impl HelpUseLatestEdition {
1930     pub fn new() -> Self {
1931         let edition = LATEST_STABLE_EDITION;
1932         if std::env::var_os("CARGO").is_some() {
1933             Self::Cargo { edition }
1934         } else {
1935             Self::Standalone { edition }
1936         }
1937     }
1938 }