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