]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/errors.rs
Rollup merge of #107559 - WaffleLapkin:is_it_2015¿, r=davidtwco
[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 arrow: Span,
674     #[label]
675     pub span: Span,
676     #[suggestion(style = "verbose", code = " ", applicability = "machine-applicable")]
677     pub after_pat: Span,
678 }
679
680 #[derive(Diagnostic)]
681 #[diag(parse_inclusive_range_no_end, code = "E0586")]
682 #[note]
683 pub(crate) struct InclusiveRangeNoEnd {
684     #[primary_span]
685     #[suggestion(
686         suggestion_open_range,
687         code = "..",
688         applicability = "machine-applicable",
689         style = "short"
690     )]
691     pub span: Span,
692 }
693
694 #[derive(Subdiagnostic)]
695 pub(crate) enum MatchArmBodyWithoutBracesSugg {
696     #[multipart_suggestion(suggestion_add_braces, applicability = "machine-applicable")]
697     AddBraces {
698         #[suggestion_part(code = "{{ ")]
699         left: Span,
700         #[suggestion_part(code = " }}")]
701         right: Span,
702     },
703     #[suggestion(
704         suggestion_use_comma_not_semicolon,
705         code = ",",
706         applicability = "machine-applicable"
707     )]
708     UseComma {
709         #[primary_span]
710         semicolon: Span,
711     },
712 }
713
714 #[derive(Diagnostic)]
715 #[diag(parse_struct_literal_not_allowed_here)]
716 pub(crate) struct StructLiteralNotAllowedHere {
717     #[primary_span]
718     pub span: Span,
719     #[subdiagnostic]
720     pub sub: StructLiteralNotAllowedHereSugg,
721 }
722
723 #[derive(Subdiagnostic)]
724 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
725 pub(crate) struct StructLiteralNotAllowedHereSugg {
726     #[suggestion_part(code = "(")]
727     pub left: Span,
728     #[suggestion_part(code = ")")]
729     pub right: Span,
730 }
731
732 #[derive(Diagnostic)]
733 #[diag(parse_invalid_interpolated_expression)]
734 pub(crate) struct InvalidInterpolatedExpression {
735     #[primary_span]
736     pub span: Span,
737 }
738
739 #[derive(Diagnostic)]
740 #[diag(parse_invalid_literal_suffix_on_tuple_index)]
741 pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
742     #[primary_span]
743     #[label]
744     pub span: Span,
745     pub suffix: Symbol,
746     #[help(tuple_exception_line_1)]
747     #[help(tuple_exception_line_2)]
748     #[help(tuple_exception_line_3)]
749     pub exception: Option<()>,
750 }
751
752 #[derive(Diagnostic)]
753 #[diag(parse_non_string_abi_literal)]
754 pub(crate) struct NonStringAbiLiteral {
755     #[primary_span]
756     #[suggestion(code = "\"C\"", applicability = "maybe-incorrect")]
757     pub span: Span,
758 }
759
760 #[derive(Diagnostic)]
761 #[diag(parse_mismatched_closing_delimiter)]
762 pub(crate) struct MismatchedClosingDelimiter {
763     #[primary_span]
764     pub spans: Vec<Span>,
765     pub delimiter: String,
766     #[label(label_unmatched)]
767     pub unmatched: Span,
768     #[label(label_opening_candidate)]
769     pub opening_candidate: Option<Span>,
770     #[label(label_unclosed)]
771     pub unclosed: Option<Span>,
772 }
773
774 #[derive(Diagnostic)]
775 #[diag(parse_incorrect_visibility_restriction, code = "E0704")]
776 #[help]
777 pub(crate) struct IncorrectVisibilityRestriction {
778     #[primary_span]
779     #[suggestion(code = "in {inner_str}", applicability = "machine-applicable")]
780     pub span: Span,
781     pub inner_str: String,
782 }
783
784 #[derive(Diagnostic)]
785 #[diag(parse_assignment_else_not_allowed)]
786 pub(crate) struct AssignmentElseNotAllowed {
787     #[primary_span]
788     pub span: Span,
789 }
790
791 #[derive(Diagnostic)]
792 #[diag(parse_expected_statement_after_outer_attr)]
793 pub(crate) struct ExpectedStatementAfterOuterAttr {
794     #[primary_span]
795     pub span: Span,
796 }
797
798 #[derive(Diagnostic)]
799 #[diag(parse_doc_comment_does_not_document_anything, code = "E0585")]
800 #[help]
801 pub(crate) struct DocCommentDoesNotDocumentAnything {
802     #[primary_span]
803     pub span: Span,
804     #[suggestion(code = ",", applicability = "machine-applicable")]
805     pub missing_comma: Option<Span>,
806 }
807
808 #[derive(Diagnostic)]
809 #[diag(parse_const_let_mutually_exclusive)]
810 pub(crate) struct ConstLetMutuallyExclusive {
811     #[primary_span]
812     #[suggestion(code = "const", applicability = "maybe-incorrect")]
813     pub span: Span,
814 }
815
816 #[derive(Diagnostic)]
817 #[diag(parse_invalid_expression_in_let_else)]
818 pub(crate) struct InvalidExpressionInLetElse {
819     #[primary_span]
820     pub span: Span,
821     pub operator: &'static str,
822     #[subdiagnostic]
823     pub sugg: WrapExpressionInParentheses,
824 }
825
826 #[derive(Diagnostic)]
827 #[diag(parse_invalid_curly_in_let_else)]
828 pub(crate) struct InvalidCurlyInLetElse {
829     #[primary_span]
830     pub span: Span,
831     #[subdiagnostic]
832     pub sugg: WrapExpressionInParentheses,
833 }
834
835 #[derive(Diagnostic)]
836 #[diag(parse_compound_assignment_expression_in_let)]
837 #[help]
838 pub(crate) struct CompoundAssignmentExpressionInLet {
839     #[primary_span]
840     #[suggestion(style = "short", code = "=", applicability = "maybe-incorrect")]
841     pub span: Span,
842 }
843
844 #[derive(Diagnostic)]
845 #[diag(parse_suffixed_literal_in_attribute)]
846 #[help]
847 pub(crate) struct SuffixedLiteralInAttribute {
848     #[primary_span]
849     pub span: Span,
850 }
851
852 #[derive(Diagnostic)]
853 #[diag(parse_invalid_meta_item)]
854 pub(crate) struct InvalidMetaItem {
855     #[primary_span]
856     pub span: Span,
857     pub token: Token,
858 }
859
860 #[derive(Subdiagnostic)]
861 #[suggestion(
862     parse_sugg_escape_to_use_as_identifier,
863     style = "verbose",
864     applicability = "maybe-incorrect",
865     code = "r#"
866 )]
867 pub(crate) struct SuggEscapeToUseAsIdentifier {
868     #[primary_span]
869     pub span: Span,
870     pub ident_name: String,
871 }
872
873 #[derive(Subdiagnostic)]
874 #[suggestion(parse_sugg_remove_comma, applicability = "machine-applicable", code = "")]
875 pub(crate) struct SuggRemoveComma {
876     #[primary_span]
877     pub span: Span,
878 }
879
880 #[derive(Subdiagnostic)]
881 pub(crate) enum ExpectedIdentifierFound {
882     #[label(parse_expected_identifier_found_reserved_identifier)]
883     ReservedIdentifier(#[primary_span] Span),
884     #[label(parse_expected_identifier_found_keyword)]
885     Keyword(#[primary_span] Span),
886     #[label(parse_expected_identifier_found_reserved_keyword)]
887     ReservedKeyword(#[primary_span] Span),
888     #[label(parse_expected_identifier_found_doc_comment)]
889     DocComment(#[primary_span] Span),
890     #[label(parse_expected_identifier)]
891     Other(#[primary_span] Span),
892 }
893
894 impl ExpectedIdentifierFound {
895     pub fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
896         (match token_descr {
897             Some(TokenDescription::ReservedIdentifier) => {
898                 ExpectedIdentifierFound::ReservedIdentifier
899             }
900             Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword,
901             Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
902             Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment,
903             None => ExpectedIdentifierFound::Other,
904         })(span)
905     }
906 }
907
908 pub(crate) struct ExpectedIdentifier {
909     pub span: Span,
910     pub token: Token,
911     pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>,
912     pub suggest_remove_comma: Option<SuggRemoveComma>,
913 }
914
915 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
916     #[track_caller]
917     fn into_diagnostic(
918         self,
919         handler: &'a rustc_errors::Handler,
920     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
921         let token_descr = super::parser::TokenDescription::from_token(&self.token);
922
923         let mut diag = handler.struct_diagnostic(match token_descr {
924             Some(TokenDescription::ReservedIdentifier) => {
925                 fluent::parse_expected_identifier_found_reserved_identifier_str
926             }
927             Some(TokenDescription::Keyword) => fluent::parse_expected_identifier_found_keyword_str,
928             Some(TokenDescription::ReservedKeyword) => {
929                 fluent::parse_expected_identifier_found_reserved_keyword_str
930             }
931             Some(TokenDescription::DocComment) => {
932                 fluent::parse_expected_identifier_found_doc_comment_str
933             }
934             None => fluent::parse_expected_identifier_found_str,
935         });
936         diag.set_span(self.span);
937         diag.set_arg("token", self.token);
938
939         if let Some(sugg) = self.suggest_raw {
940             sugg.add_to_diagnostic(&mut diag);
941         }
942
943         ExpectedIdentifierFound::new(token_descr, self.span).add_to_diagnostic(&mut diag);
944
945         if let Some(sugg) = self.suggest_remove_comma {
946             sugg.add_to_diagnostic(&mut diag);
947         }
948
949         diag
950     }
951 }
952
953 pub(crate) struct ExpectedSemi {
954     pub span: Span,
955     pub token: Token,
956
957     pub unexpected_token_label: Option<Span>,
958     pub sugg: ExpectedSemiSugg,
959 }
960
961 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
962     #[track_caller]
963     fn into_diagnostic(
964         self,
965         handler: &'a rustc_errors::Handler,
966     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
967         let token_descr = super::parser::TokenDescription::from_token(&self.token);
968
969         let mut diag = handler.struct_diagnostic(match token_descr {
970             Some(TokenDescription::ReservedIdentifier) => {
971                 fluent::parse_expected_semi_found_reserved_identifier_str
972             }
973             Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str,
974             Some(TokenDescription::ReservedKeyword) => {
975                 fluent::parse_expected_semi_found_reserved_keyword_str
976             }
977             Some(TokenDescription::DocComment) => fluent::parse_expected_semi_found_doc_comment_str,
978             None => fluent::parse_expected_semi_found_str,
979         });
980         diag.set_span(self.span);
981         diag.set_arg("token", self.token);
982
983         if let Some(unexpected_token_label) = self.unexpected_token_label {
984             diag.span_label(unexpected_token_label, fluent::parse_label_unexpected_token);
985         }
986
987         self.sugg.add_to_diagnostic(&mut diag);
988
989         diag
990     }
991 }
992
993 #[derive(Subdiagnostic)]
994 pub(crate) enum ExpectedSemiSugg {
995     #[suggestion(parse_sugg_change_this_to_semi, code = ";", applicability = "machine-applicable")]
996     ChangeToSemi(#[primary_span] Span),
997     #[suggestion(
998         parse_sugg_add_semi,
999         style = "short",
1000         code = ";",
1001         applicability = "machine-applicable"
1002     )]
1003     AddSemi(#[primary_span] Span),
1004 }
1005
1006 #[derive(Diagnostic)]
1007 #[diag(parse_struct_literal_body_without_path)]
1008 pub(crate) struct StructLiteralBodyWithoutPath {
1009     #[primary_span]
1010     pub span: Span,
1011     #[subdiagnostic]
1012     pub sugg: StructLiteralBodyWithoutPathSugg,
1013 }
1014
1015 #[derive(Subdiagnostic)]
1016 #[multipart_suggestion(suggestion, applicability = "has-placeholders")]
1017 pub(crate) struct StructLiteralBodyWithoutPathSugg {
1018     #[suggestion_part(code = "{{ SomeStruct ")]
1019     pub before: Span,
1020     #[suggestion_part(code = " }}")]
1021     pub after: Span,
1022 }
1023
1024 #[derive(Diagnostic)]
1025 #[diag(parse_struct_literal_needing_parens)]
1026 pub(crate) struct StructLiteralNeedingParens {
1027     #[primary_span]
1028     pub span: Span,
1029     #[subdiagnostic]
1030     pub sugg: StructLiteralNeedingParensSugg,
1031 }
1032
1033 #[derive(Subdiagnostic)]
1034 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1035 pub(crate) struct StructLiteralNeedingParensSugg {
1036     #[suggestion_part(code = "(")]
1037     pub before: Span,
1038     #[suggestion_part(code = ")")]
1039     pub after: Span,
1040 }
1041
1042 #[derive(Diagnostic)]
1043 #[diag(parse_unmatched_angle_brackets)]
1044 pub(crate) struct UnmatchedAngleBrackets {
1045     #[primary_span]
1046     #[suggestion(code = "", applicability = "machine-applicable")]
1047     pub span: Span,
1048     pub num_extra_brackets: usize,
1049 }
1050
1051 #[derive(Diagnostic)]
1052 #[diag(parse_generic_parameters_without_angle_brackets)]
1053 pub(crate) struct GenericParamsWithoutAngleBrackets {
1054     #[primary_span]
1055     pub span: Span,
1056     #[subdiagnostic]
1057     pub sugg: GenericParamsWithoutAngleBracketsSugg,
1058 }
1059
1060 #[derive(Subdiagnostic)]
1061 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1062 pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
1063     #[suggestion_part(code = "<")]
1064     pub left: Span,
1065     #[suggestion_part(code = ">")]
1066     pub right: Span,
1067 }
1068
1069 #[derive(Diagnostic)]
1070 #[diag(parse_comparison_operators_cannot_be_chained)]
1071 pub(crate) struct ComparisonOperatorsCannotBeChained {
1072     #[primary_span]
1073     pub span: Vec<Span>,
1074     #[suggestion(
1075         parse_sugg_turbofish_syntax,
1076         style = "verbose",
1077         code = "::",
1078         applicability = "maybe-incorrect"
1079     )]
1080     pub suggest_turbofish: Option<Span>,
1081     #[help(parse_sugg_turbofish_syntax)]
1082     #[help(sugg_parentheses_for_function_args)]
1083     pub help_turbofish: Option<()>,
1084     #[subdiagnostic]
1085     pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
1086 }
1087
1088 #[derive(Subdiagnostic)]
1089 pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
1090     #[suggestion(
1091         sugg_split_comparison,
1092         style = "verbose",
1093         code = " && {middle_term}",
1094         applicability = "maybe-incorrect"
1095     )]
1096     SplitComparison {
1097         #[primary_span]
1098         span: Span,
1099         middle_term: String,
1100     },
1101     #[multipart_suggestion(sugg_parenthesize, applicability = "maybe-incorrect")]
1102     Parenthesize {
1103         #[suggestion_part(code = "(")]
1104         left: Span,
1105         #[suggestion_part(code = ")")]
1106         right: Span,
1107     },
1108 }
1109
1110 #[derive(Diagnostic)]
1111 #[diag(parse_question_mark_in_type)]
1112 pub(crate) struct QuestionMarkInType {
1113     #[primary_span]
1114     #[label]
1115     pub span: Span,
1116     #[subdiagnostic]
1117     pub sugg: QuestionMarkInTypeSugg,
1118 }
1119
1120 #[derive(Subdiagnostic)]
1121 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1122 pub(crate) struct QuestionMarkInTypeSugg {
1123     #[suggestion_part(code = "Option<")]
1124     pub left: Span,
1125     #[suggestion_part(code = ">")]
1126     pub right: Span,
1127 }
1128
1129 #[derive(Diagnostic)]
1130 #[diag(parse_unexpected_parentheses_in_for_head)]
1131 pub(crate) struct ParenthesesInForHead {
1132     #[primary_span]
1133     pub span: Vec<Span>,
1134     #[subdiagnostic]
1135     pub sugg: ParenthesesInForHeadSugg,
1136 }
1137
1138 #[derive(Subdiagnostic)]
1139 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1140 pub(crate) struct ParenthesesInForHeadSugg {
1141     #[suggestion_part(code = "{left_snippet}")]
1142     pub left: Span,
1143     pub left_snippet: String,
1144     #[suggestion_part(code = "{right_snippet}")]
1145     pub right: Span,
1146     pub right_snippet: String,
1147 }
1148
1149 #[derive(Diagnostic)]
1150 #[diag(parse_doc_comment_on_param_type)]
1151 pub(crate) struct DocCommentOnParamType {
1152     #[primary_span]
1153     #[label]
1154     pub span: Span,
1155 }
1156
1157 #[derive(Diagnostic)]
1158 #[diag(parse_attribute_on_param_type)]
1159 pub(crate) struct AttributeOnParamType {
1160     #[primary_span]
1161     #[label]
1162     pub span: Span,
1163 }
1164
1165 #[derive(Diagnostic)]
1166 #[diag(parse_pattern_method_param_without_body, code = "E0642")]
1167 pub(crate) struct PatternMethodParamWithoutBody {
1168     #[primary_span]
1169     #[suggestion(code = "_", applicability = "machine-applicable")]
1170     pub span: Span,
1171 }
1172
1173 #[derive(Diagnostic)]
1174 #[diag(parse_self_param_not_first)]
1175 pub(crate) struct SelfParamNotFirst {
1176     #[primary_span]
1177     #[label]
1178     pub span: Span,
1179 }
1180
1181 #[derive(Diagnostic)]
1182 #[diag(parse_invalid_identifier_with_leading_number)]
1183 pub(crate) struct InvalidIdentiferStartsWithNumber {
1184     #[primary_span]
1185     #[label]
1186     pub span: Span,
1187 }
1188
1189 #[derive(Diagnostic)]
1190 #[diag(parse_const_generic_without_braces)]
1191 pub(crate) struct ConstGenericWithoutBraces {
1192     #[primary_span]
1193     pub span: Span,
1194     #[subdiagnostic]
1195     pub sugg: ConstGenericWithoutBracesSugg,
1196 }
1197
1198 #[derive(Subdiagnostic)]
1199 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1200 pub(crate) struct ConstGenericWithoutBracesSugg {
1201     #[suggestion_part(code = "{{ ")]
1202     pub left: Span,
1203     #[suggestion_part(code = " }}")]
1204     pub right: Span,
1205 }
1206
1207 #[derive(Diagnostic)]
1208 #[diag(parse_unexpected_const_param_declaration)]
1209 pub(crate) struct UnexpectedConstParamDeclaration {
1210     #[primary_span]
1211     #[label]
1212     pub span: Span,
1213     #[subdiagnostic]
1214     pub sugg: Option<UnexpectedConstParamDeclarationSugg>,
1215 }
1216
1217 #[derive(Subdiagnostic)]
1218 pub(crate) enum UnexpectedConstParamDeclarationSugg {
1219     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1220     AddParam {
1221         #[suggestion_part(code = "<{snippet}>")]
1222         impl_generics: Span,
1223         #[suggestion_part(code = "{ident}")]
1224         incorrect_decl: Span,
1225         snippet: String,
1226         ident: String,
1227     },
1228     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1229     AppendParam {
1230         #[suggestion_part(code = ", {snippet}")]
1231         impl_generics_end: Span,
1232         #[suggestion_part(code = "{ident}")]
1233         incorrect_decl: Span,
1234         snippet: String,
1235         ident: String,
1236     },
1237 }
1238
1239 #[derive(Diagnostic)]
1240 #[diag(parse_unexpected_const_in_generic_param)]
1241 pub(crate) struct UnexpectedConstInGenericParam {
1242     #[primary_span]
1243     pub span: Span,
1244     #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")]
1245     pub to_remove: Option<Span>,
1246 }
1247
1248 #[derive(Diagnostic)]
1249 #[diag(parse_async_move_order_incorrect)]
1250 pub(crate) struct AsyncMoveOrderIncorrect {
1251     #[primary_span]
1252     #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")]
1253     pub span: Span,
1254 }
1255
1256 #[derive(Diagnostic)]
1257 #[diag(parse_double_colon_in_bound)]
1258 pub(crate) struct DoubleColonInBound {
1259     #[primary_span]
1260     pub span: Span,
1261     #[suggestion(code = ": ", applicability = "machine-applicable")]
1262     pub between: Span,
1263 }
1264
1265 #[derive(Diagnostic)]
1266 #[diag(parse_fn_ptr_with_generics)]
1267 pub(crate) struct FnPtrWithGenerics {
1268     #[primary_span]
1269     pub span: Span,
1270     #[subdiagnostic]
1271     pub sugg: Option<FnPtrWithGenericsSugg>,
1272 }
1273
1274 #[derive(Subdiagnostic)]
1275 #[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
1276 pub(crate) struct FnPtrWithGenericsSugg {
1277     #[suggestion_part(code = "{snippet}")]
1278     pub left: Span,
1279     pub snippet: String,
1280     #[suggestion_part(code = "")]
1281     pub right: Span,
1282     pub arity: usize,
1283     pub for_param_list_exists: bool,
1284 }
1285
1286 #[derive(Diagnostic)]
1287 #[diag(parse_unexpected_if_with_if)]
1288 pub(crate) struct UnexpectedIfWithIf(
1289     #[primary_span]
1290     #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
1291     pub Span,
1292 );
1293
1294 #[derive(Diagnostic)]
1295 #[diag(parse_maybe_fn_typo_with_impl)]
1296 pub(crate) struct FnTypoWithImpl {
1297     #[primary_span]
1298     #[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
1299     pub fn_span: Span,
1300 }
1301
1302 #[derive(Diagnostic)]
1303 #[diag(parse_expected_fn_path_found_fn_keyword)]
1304 pub(crate) struct ExpectedFnPathFoundFnKeyword {
1305     #[primary_span]
1306     #[suggestion(applicability = "machine-applicable", code = "Fn", style = "verbose")]
1307     pub fn_token_span: Span,
1308 }
1309
1310 #[derive(Diagnostic)]
1311 #[diag(parse_where_clause_before_tuple_struct_body)]
1312 pub(crate) struct WhereClauseBeforeTupleStructBody {
1313     #[primary_span]
1314     #[label]
1315     pub span: Span,
1316     #[label(name_label)]
1317     pub name: Span,
1318     #[label(body_label)]
1319     pub body: Span,
1320     #[subdiagnostic]
1321     pub sugg: Option<WhereClauseBeforeTupleStructBodySugg>,
1322 }
1323
1324 #[derive(Subdiagnostic)]
1325 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1326 pub(crate) struct WhereClauseBeforeTupleStructBodySugg {
1327     #[suggestion_part(code = "{snippet}")]
1328     pub left: Span,
1329     pub snippet: String,
1330     #[suggestion_part(code = "")]
1331     pub right: Span,
1332 }
1333
1334 #[derive(Diagnostic)]
1335 #[diag(parse_async_fn_in_2015, code = "E0670")]
1336 pub(crate) struct AsyncFnIn2015 {
1337     #[primary_span]
1338     #[label]
1339     pub span: Span,
1340     #[subdiagnostic]
1341     pub help: HelpUseLatestEdition,
1342 }
1343
1344 #[derive(Subdiagnostic)]
1345 #[label(parse_async_block_in_2015)]
1346 pub(crate) struct AsyncBlockIn2015 {
1347     #[primary_span]
1348     pub span: Span,
1349 }
1350
1351 #[derive(Diagnostic)]
1352 #[diag(parse_self_argument_pointer)]
1353 pub(crate) struct SelfArgumentPointer {
1354     #[primary_span]
1355     #[label]
1356     pub span: Span,
1357 }
1358
1359 #[derive(Diagnostic)]
1360 #[diag(parse_visibility_not_followed_by_item)]
1361 #[help]
1362 pub(crate) struct VisibilityNotFollowedByItem {
1363     #[primary_span]
1364     #[label]
1365     pub span: Span,
1366     pub vis: Visibility,
1367 }
1368
1369 #[derive(Diagnostic)]
1370 #[diag(parse_default_not_followed_by_item)]
1371 #[note]
1372 pub(crate) struct DefaultNotFollowedByItem {
1373     #[primary_span]
1374     #[label]
1375     pub span: Span,
1376 }
1377
1378 #[derive(Diagnostic)]
1379 pub(crate) enum MissingKeywordForItemDefinition {
1380     #[diag(parse_missing_struct_for_struct_definition)]
1381     Struct {
1382         #[primary_span]
1383         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " struct ")]
1384         span: Span,
1385         ident: Ident,
1386     },
1387     #[diag(parse_missing_fn_for_function_definition)]
1388     Function {
1389         #[primary_span]
1390         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " fn ")]
1391         span: Span,
1392         ident: Ident,
1393     },
1394     #[diag(parse_missing_fn_for_method_definition)]
1395     Method {
1396         #[primary_span]
1397         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " fn ")]
1398         span: Span,
1399         ident: Ident,
1400     },
1401     #[diag(parse_ambiguous_missing_keyword_for_item_definition)]
1402     Ambiguous {
1403         #[primary_span]
1404         span: Span,
1405         #[subdiagnostic]
1406         subdiag: Option<AmbiguousMissingKwForItemSub>,
1407     },
1408 }
1409
1410 #[derive(Subdiagnostic)]
1411 pub(crate) enum AmbiguousMissingKwForItemSub {
1412     #[suggestion(suggestion, applicability = "maybe-incorrect", code = "{snippet}!")]
1413     SuggestMacro {
1414         #[primary_span]
1415         span: Span,
1416         snippet: String,
1417     },
1418     #[help(help)]
1419     HelpMacro,
1420 }
1421
1422 #[derive(Diagnostic)]
1423 #[diag(parse_missing_trait_in_trait_impl)]
1424 pub(crate) struct MissingTraitInTraitImpl {
1425     #[primary_span]
1426     #[suggestion(suggestion_add_trait, code = " Trait ", applicability = "has-placeholders")]
1427     pub span: Span,
1428     #[suggestion(suggestion_remove_for, code = "", applicability = "maybe-incorrect")]
1429     pub for_span: Span,
1430 }
1431
1432 #[derive(Diagnostic)]
1433 #[diag(parse_missing_for_in_trait_impl)]
1434 pub(crate) struct MissingForInTraitImpl {
1435     #[primary_span]
1436     #[suggestion(style = "short", code = " for ", applicability = "machine-applicable")]
1437     pub span: Span,
1438 }
1439
1440 #[derive(Diagnostic)]
1441 #[diag(parse_expected_trait_in_trait_impl_found_type)]
1442 pub(crate) struct ExpectedTraitInTraitImplFoundType {
1443     #[primary_span]
1444     pub span: Span,
1445 }
1446
1447 #[derive(Diagnostic)]
1448 #[diag(parse_bounds_not_allowed_on_trait_aliases)]
1449 pub(crate) struct BoundsNotAllowedOnTraitAliases {
1450     #[primary_span]
1451     pub span: Span,
1452 }
1453
1454 #[derive(Diagnostic)]
1455 #[diag(parse_trait_alias_cannot_be_auto)]
1456 pub(crate) struct TraitAliasCannotBeAuto {
1457     #[primary_span]
1458     #[label(parse_trait_alias_cannot_be_auto)]
1459     pub span: Span,
1460 }
1461
1462 #[derive(Diagnostic)]
1463 #[diag(parse_trait_alias_cannot_be_unsafe)]
1464 pub(crate) struct TraitAliasCannotBeUnsafe {
1465     #[primary_span]
1466     #[label(parse_trait_alias_cannot_be_unsafe)]
1467     pub span: Span,
1468 }
1469
1470 #[derive(Diagnostic)]
1471 #[diag(parse_associated_static_item_not_allowed)]
1472 pub(crate) struct AssociatedStaticItemNotAllowed {
1473     #[primary_span]
1474     pub span: Span,
1475 }
1476
1477 #[derive(Diagnostic)]
1478 #[diag(parse_extern_crate_name_with_dashes)]
1479 pub(crate) struct ExternCrateNameWithDashes {
1480     #[primary_span]
1481     #[label]
1482     pub span: Span,
1483     #[subdiagnostic]
1484     pub sugg: ExternCrateNameWithDashesSugg,
1485 }
1486
1487 #[derive(Subdiagnostic)]
1488 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1489 pub(crate) struct ExternCrateNameWithDashesSugg {
1490     #[suggestion_part(code = "_")]
1491     pub dashes: Vec<Span>,
1492 }
1493
1494 #[derive(Diagnostic)]
1495 #[diag(parse_extern_item_cannot_be_const)]
1496 #[note]
1497 pub(crate) struct ExternItemCannotBeConst {
1498     #[primary_span]
1499     pub ident_span: Span,
1500     #[suggestion(code = "static ", applicability = "machine-applicable")]
1501     pub const_span: Span,
1502 }
1503
1504 #[derive(Diagnostic)]
1505 #[diag(parse_const_global_cannot_be_mutable)]
1506 pub(crate) struct ConstGlobalCannotBeMutable {
1507     #[primary_span]
1508     #[label]
1509     pub ident_span: Span,
1510     #[suggestion(code = "static", applicability = "maybe-incorrect")]
1511     pub const_span: Span,
1512 }
1513
1514 #[derive(Diagnostic)]
1515 #[diag(parse_missing_const_type)]
1516 pub(crate) struct MissingConstType {
1517     #[primary_span]
1518     #[suggestion(code = "{colon} <type>", applicability = "has-placeholders")]
1519     pub span: Span,
1520
1521     pub kind: &'static str,
1522     pub colon: &'static str,
1523 }
1524
1525 #[derive(Diagnostic)]
1526 #[diag(parse_enum_struct_mutually_exclusive)]
1527 pub(crate) struct EnumStructMutuallyExclusive {
1528     #[primary_span]
1529     #[suggestion(code = "enum", applicability = "machine-applicable")]
1530     pub span: Span,
1531 }
1532
1533 #[derive(Diagnostic)]
1534 pub(crate) enum UnexpectedTokenAfterStructName {
1535     #[diag(parse_unexpected_token_after_struct_name_found_reserved_identifier)]
1536     ReservedIdentifier {
1537         #[primary_span]
1538         #[label(parse_unexpected_token_after_struct_name)]
1539         span: Span,
1540         token: Token,
1541     },
1542     #[diag(parse_unexpected_token_after_struct_name_found_keyword)]
1543     Keyword {
1544         #[primary_span]
1545         #[label(parse_unexpected_token_after_struct_name)]
1546         span: Span,
1547         token: Token,
1548     },
1549     #[diag(parse_unexpected_token_after_struct_name_found_reserved_keyword)]
1550     ReservedKeyword {
1551         #[primary_span]
1552         #[label(parse_unexpected_token_after_struct_name)]
1553         span: Span,
1554         token: Token,
1555     },
1556     #[diag(parse_unexpected_token_after_struct_name_found_doc_comment)]
1557     DocComment {
1558         #[primary_span]
1559         #[label(parse_unexpected_token_after_struct_name)]
1560         span: Span,
1561         token: Token,
1562     },
1563     #[diag(parse_unexpected_token_after_struct_name_found_other)]
1564     Other {
1565         #[primary_span]
1566         #[label(parse_unexpected_token_after_struct_name)]
1567         span: Span,
1568         token: Token,
1569     },
1570 }
1571
1572 impl UnexpectedTokenAfterStructName {
1573     pub fn new(span: Span, token: Token) -> Self {
1574         match TokenDescription::from_token(&token) {
1575             Some(TokenDescription::ReservedIdentifier) => Self::ReservedIdentifier { span, token },
1576             Some(TokenDescription::Keyword) => Self::Keyword { span, token },
1577             Some(TokenDescription::ReservedKeyword) => Self::ReservedKeyword { span, token },
1578             Some(TokenDescription::DocComment) => Self::DocComment { span, token },
1579             None => Self::Other { span, token },
1580         }
1581     }
1582 }
1583
1584 #[derive(Diagnostic)]
1585 #[diag(parse_unexpected_self_in_generic_parameters)]
1586 #[note]
1587 pub(crate) struct UnexpectedSelfInGenericParameters {
1588     #[primary_span]
1589     pub span: Span,
1590 }
1591
1592 #[derive(Diagnostic)]
1593 #[diag(parse_multiple_where_clauses)]
1594 pub(crate) struct MultipleWhereClauses {
1595     #[primary_span]
1596     pub span: Span,
1597     #[label]
1598     pub previous: Span,
1599     #[suggestion(style = "verbose", code = ",", applicability = "maybe-incorrect")]
1600     pub between: Span,
1601 }
1602
1603 #[derive(Diagnostic)]
1604 pub(crate) enum UnexpectedNonterminal {
1605     #[diag(parse_nonterminal_expected_item_keyword)]
1606     Item(#[primary_span] Span),
1607     #[diag(parse_nonterminal_expected_statement)]
1608     Statement(#[primary_span] Span),
1609     #[diag(parse_nonterminal_expected_ident)]
1610     Ident {
1611         #[primary_span]
1612         span: Span,
1613         token: Token,
1614     },
1615     #[diag(parse_nonterminal_expected_lifetime)]
1616     Lifetime {
1617         #[primary_span]
1618         span: Span,
1619         token: Token,
1620     },
1621 }
1622
1623 #[derive(Diagnostic)]
1624 pub(crate) enum TopLevelOrPatternNotAllowed {
1625     #[diag(parse_or_pattern_not_allowed_in_let_binding)]
1626     LetBinding {
1627         #[primary_span]
1628         span: Span,
1629         #[subdiagnostic]
1630         sub: Option<TopLevelOrPatternNotAllowedSugg>,
1631     },
1632     #[diag(parse_or_pattern_not_allowed_in_fn_parameters)]
1633     FunctionParameter {
1634         #[primary_span]
1635         span: Span,
1636         #[subdiagnostic]
1637         sub: Option<TopLevelOrPatternNotAllowedSugg>,
1638     },
1639 }
1640
1641 #[derive(Subdiagnostic)]
1642 pub(crate) enum TopLevelOrPatternNotAllowedSugg {
1643     #[suggestion(
1644         parse_sugg_remove_leading_vert_in_pattern,
1645         code = "{pat}",
1646         applicability = "machine-applicable"
1647     )]
1648     RemoveLeadingVert {
1649         #[primary_span]
1650         span: Span,
1651         pat: String,
1652     },
1653     #[suggestion(
1654         parse_sugg_wrap_pattern_in_parens,
1655         code = "({pat})",
1656         applicability = "machine-applicable"
1657     )]
1658     WrapInParens {
1659         #[primary_span]
1660         span: Span,
1661         pat: String,
1662     },
1663 }
1664
1665 #[derive(Diagnostic)]
1666 #[diag(parse_unexpected_vert_vert_before_function_parameter)]
1667 #[note(parse_note_pattern_alternatives_use_single_vert)]
1668 pub(crate) struct UnexpectedVertVertBeforeFunctionParam {
1669     #[primary_span]
1670     #[suggestion(code = "", applicability = "machine-applicable")]
1671     pub span: Span,
1672 }
1673
1674 #[derive(Diagnostic)]
1675 #[diag(parse_unexpected_vert_vert_in_pattern)]
1676 pub(crate) struct UnexpectedVertVertInPattern {
1677     #[primary_span]
1678     #[suggestion(code = "|", applicability = "machine-applicable")]
1679     pub span: Span,
1680     #[label(parse_label_while_parsing_or_pattern_here)]
1681     pub start: Option<Span>,
1682 }
1683
1684 #[derive(Diagnostic)]
1685 #[diag(parse_trailing_vert_not_allowed)]
1686 pub(crate) struct TrailingVertNotAllowed {
1687     #[primary_span]
1688     #[suggestion(code = "", applicability = "machine-applicable")]
1689     pub span: Span,
1690     #[label(parse_label_while_parsing_or_pattern_here)]
1691     pub start: Option<Span>,
1692     pub token: Token,
1693     #[note(parse_note_pattern_alternatives_use_single_vert)]
1694     pub note_double_vert: Option<()>,
1695 }
1696
1697 #[derive(Diagnostic)]
1698 #[diag(parse_dotdotdot_rest_pattern)]
1699 pub(crate) struct DotDotDotRestPattern {
1700     #[primary_span]
1701     #[suggestion(style = "short", code = "..", applicability = "machine-applicable")]
1702     #[label]
1703     pub span: Span,
1704 }
1705
1706 #[derive(Diagnostic)]
1707 #[diag(parse_pattern_on_wrong_side_of_at)]
1708 pub(crate) struct PatternOnWrongSideOfAt {
1709     #[primary_span]
1710     #[suggestion(code = "{whole_pat}", applicability = "machine-applicable")]
1711     pub whole_span: Span,
1712     pub whole_pat: String,
1713     #[label(label_pattern)]
1714     pub pattern: Span,
1715     #[label(label_binding)]
1716     pub binding: Span,
1717 }
1718
1719 #[derive(Diagnostic)]
1720 #[diag(parse_expected_binding_left_of_at)]
1721 #[note]
1722 pub(crate) struct ExpectedBindingLeftOfAt {
1723     #[primary_span]
1724     pub whole_span: Span,
1725     #[label(label_lhs)]
1726     pub lhs: Span,
1727     #[label(label_rhs)]
1728     pub rhs: Span,
1729 }
1730
1731 #[derive(Diagnostic)]
1732 #[diag(parse_ambiguous_range_pattern)]
1733 pub(crate) struct AmbiguousRangePattern {
1734     #[primary_span]
1735     #[suggestion(code = "({pat})", applicability = "maybe-incorrect")]
1736     pub span: Span,
1737     pub pat: String,
1738 }
1739
1740 #[derive(Diagnostic)]
1741 #[diag(parse_unexpected_lifetime_in_pattern)]
1742 pub(crate) struct UnexpectedLifetimeInPattern {
1743     #[primary_span]
1744     #[suggestion(code = "", applicability = "machine-applicable")]
1745     pub span: Span,
1746     pub symbol: Symbol,
1747 }
1748
1749 #[derive(Diagnostic)]
1750 #[diag(parse_ref_mut_order_incorrect)]
1751 pub(crate) struct RefMutOrderIncorrect {
1752     #[primary_span]
1753     #[suggestion(code = "ref mut", applicability = "machine-applicable")]
1754     pub span: Span,
1755 }
1756
1757 #[derive(Diagnostic)]
1758 pub(crate) enum InvalidMutInPattern {
1759     #[diag(parse_mut_on_nested_ident_pattern)]
1760     #[note(parse_note_mut_pattern_usage)]
1761     NestedIdent {
1762         #[primary_span]
1763         #[suggestion(code = "{pat}", applicability = "machine-applicable")]
1764         span: Span,
1765         pat: String,
1766     },
1767     #[diag(parse_mut_on_non_ident_pattern)]
1768     #[note(parse_note_mut_pattern_usage)]
1769     NonIdent {
1770         #[primary_span]
1771         #[suggestion(code = "{pat}", applicability = "machine-applicable")]
1772         span: Span,
1773         pat: String,
1774     },
1775 }
1776
1777 #[derive(Diagnostic)]
1778 #[diag(parse_repeated_mut_in_pattern)]
1779 pub(crate) struct RepeatedMutInPattern {
1780     #[primary_span]
1781     #[suggestion(code = "", applicability = "machine-applicable")]
1782     pub span: Span,
1783 }
1784
1785 #[derive(Diagnostic)]
1786 #[diag(parse_dot_dot_dot_range_to_pattern_not_allowed)]
1787 pub(crate) struct DotDotDotRangeToPatternNotAllowed {
1788     #[primary_span]
1789     #[suggestion(style = "short", code = "..=", applicability = "machine-applicable")]
1790     pub span: Span,
1791 }
1792
1793 #[derive(Diagnostic)]
1794 #[diag(parse_enum_pattern_instead_of_identifier)]
1795 pub(crate) struct EnumPatternInsteadOfIdentifier {
1796     #[primary_span]
1797     pub span: Span,
1798 }
1799
1800 #[derive(Diagnostic)]
1801 #[diag(parse_dot_dot_dot_for_remaining_fields)]
1802 pub(crate) struct DotDotDotForRemainingFields {
1803     #[primary_span]
1804     #[suggestion(code = "..", style = "verbose", applicability = "machine-applicable")]
1805     pub span: Span,
1806     pub token_str: Cow<'static, str>,
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 }