]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/errors.rs
Update strip-ansi-escapes and vte
[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_expression_in_for_loop)]
438 pub(crate) struct MissingExpressionInForLoop {
439     #[primary_span]
440     #[suggestion(
441         code = "/* expression */ ",
442         applicability = "has-placeholders",
443         style = "verbose"
444     )]
445     pub span: Span,
446 }
447
448 #[derive(Diagnostic)]
449 #[diag(parse_missing_comma_after_match_arm)]
450 pub(crate) struct MissingCommaAfterMatchArm {
451     #[primary_span]
452     #[suggestion(applicability = "machine-applicable", code = ",")]
453     pub span: Span,
454 }
455
456 #[derive(Diagnostic)]
457 #[diag(parse_catch_after_try)]
458 #[help]
459 pub(crate) struct CatchAfterTry {
460     #[primary_span]
461     pub span: Span,
462 }
463
464 #[derive(Diagnostic)]
465 #[diag(parse_comma_after_base_struct)]
466 #[note]
467 pub(crate) struct CommaAfterBaseStruct {
468     #[primary_span]
469     pub span: Span,
470     #[suggestion(style = "short", applicability = "machine-applicable", code = "")]
471     pub comma: Span,
472 }
473
474 #[derive(Diagnostic)]
475 #[diag(parse_eq_field_init)]
476 pub(crate) struct EqFieldInit {
477     #[primary_span]
478     pub span: Span,
479     #[suggestion(applicability = "machine-applicable", code = ":")]
480     pub eq: Span,
481 }
482
483 #[derive(Diagnostic)]
484 #[diag(parse_dotdotdot)]
485 pub(crate) struct DotDotDot {
486     #[primary_span]
487     #[suggestion(suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
488     #[suggestion(suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
489     pub span: Span,
490 }
491
492 #[derive(Diagnostic)]
493 #[diag(parse_left_arrow_operator)]
494 pub(crate) struct LeftArrowOperator {
495     #[primary_span]
496     #[suggestion(applicability = "maybe-incorrect", code = "< -")]
497     pub span: Span,
498 }
499
500 #[derive(Diagnostic)]
501 #[diag(parse_remove_let)]
502 pub(crate) struct RemoveLet {
503     #[primary_span]
504     #[suggestion(applicability = "machine-applicable", code = "")]
505     pub span: Span,
506 }
507
508 #[derive(Diagnostic)]
509 #[diag(parse_use_eq_instead)]
510 pub(crate) struct UseEqInstead {
511     #[primary_span]
512     #[suggestion(style = "short", applicability = "machine-applicable", code = "=")]
513     pub span: Span,
514 }
515
516 #[derive(Diagnostic)]
517 #[diag(parse_use_empty_block_not_semi)]
518 pub(crate) struct UseEmptyBlockNotSemi {
519     #[primary_span]
520     #[suggestion(style = "hidden", applicability = "machine-applicable", code = "{{}}")]
521     pub span: Span,
522 }
523
524 #[derive(Diagnostic)]
525 #[diag(parse_comparison_interpreted_as_generic)]
526 pub(crate) struct ComparisonInterpretedAsGeneric {
527     #[primary_span]
528     #[label(label_comparison)]
529     pub comparison: Span,
530     pub r#type: Path,
531     #[label(label_args)]
532     pub args: Span,
533     #[subdiagnostic]
534     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
535 }
536
537 #[derive(Diagnostic)]
538 #[diag(parse_shift_interpreted_as_generic)]
539 pub(crate) struct ShiftInterpretedAsGeneric {
540     #[primary_span]
541     #[label(label_comparison)]
542     pub shift: Span,
543     pub r#type: Path,
544     #[label(label_args)]
545     pub args: Span,
546     #[subdiagnostic]
547     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
548 }
549
550 #[derive(Subdiagnostic)]
551 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
552 pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
553     #[suggestion_part(code = "(")]
554     pub left: Span,
555     #[suggestion_part(code = ")")]
556     pub right: Span,
557 }
558
559 #[derive(Diagnostic)]
560 #[diag(parse_found_expr_would_be_stmt)]
561 pub(crate) struct FoundExprWouldBeStmt {
562     #[primary_span]
563     #[label]
564     pub span: Span,
565     pub token: Token,
566     #[subdiagnostic]
567     pub suggestion: ExprParenthesesNeeded,
568 }
569
570 #[derive(Diagnostic)]
571 #[diag(parse_leading_plus_not_supported)]
572 pub(crate) struct LeadingPlusNotSupported {
573     #[primary_span]
574     #[label]
575     pub span: Span,
576     #[suggestion(
577         suggestion_remove_plus,
578         style = "verbose",
579         code = "",
580         applicability = "machine-applicable"
581     )]
582     pub remove_plus: Option<Span>,
583     #[subdiagnostic]
584     pub add_parentheses: Option<ExprParenthesesNeeded>,
585 }
586
587 #[derive(Diagnostic)]
588 #[diag(parse_parentheses_with_struct_fields)]
589 pub(crate) struct ParenthesesWithStructFields {
590     #[primary_span]
591     pub span: Span,
592     pub r#type: Path,
593     #[subdiagnostic]
594     pub braces_for_struct: BracesForStructLiteral,
595     #[subdiagnostic]
596     pub no_fields_for_fn: NoFieldsForFnCall,
597 }
598
599 #[derive(Subdiagnostic)]
600 #[multipart_suggestion(suggestion_braces_for_struct, applicability = "maybe-incorrect")]
601 pub(crate) struct BracesForStructLiteral {
602     #[suggestion_part(code = " {{ ")]
603     pub first: Span,
604     #[suggestion_part(code = " }}")]
605     pub second: Span,
606 }
607
608 #[derive(Subdiagnostic)]
609 #[multipart_suggestion(suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
610 pub(crate) struct NoFieldsForFnCall {
611     #[suggestion_part(code = "")]
612     pub fields: Vec<Span>,
613 }
614
615 #[derive(Diagnostic)]
616 #[diag(parse_labeled_loop_in_break)]
617 pub(crate) struct LabeledLoopInBreak {
618     #[primary_span]
619     pub span: Span,
620     #[subdiagnostic]
621     pub sub: WrapExpressionInParentheses,
622 }
623
624 #[derive(Subdiagnostic)]
625 #[multipart_suggestion(
626     parse_sugg_wrap_expression_in_parentheses,
627     applicability = "machine-applicable"
628 )]
629 pub(crate) struct WrapExpressionInParentheses {
630     #[suggestion_part(code = "(")]
631     pub left: Span,
632     #[suggestion_part(code = ")")]
633     pub right: Span,
634 }
635
636 #[derive(Diagnostic)]
637 #[diag(parse_array_brackets_instead_of_braces)]
638 pub(crate) struct ArrayBracketsInsteadOfSpaces {
639     #[primary_span]
640     pub span: Span,
641     #[subdiagnostic]
642     pub sub: ArrayBracketsInsteadOfSpacesSugg,
643 }
644
645 #[derive(Subdiagnostic)]
646 #[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
647 pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
648     #[suggestion_part(code = "[")]
649     pub left: Span,
650     #[suggestion_part(code = "]")]
651     pub right: Span,
652 }
653
654 #[derive(Diagnostic)]
655 #[diag(parse_match_arm_body_without_braces)]
656 pub(crate) struct MatchArmBodyWithoutBraces {
657     #[primary_span]
658     #[label(label_statements)]
659     pub statements: Span,
660     #[label(label_arrow)]
661     pub arrow: Span,
662     pub num_statements: usize,
663     #[subdiagnostic]
664     pub sub: MatchArmBodyWithoutBracesSugg,
665 }
666
667 #[derive(Diagnostic)]
668 #[diag(parse_inclusive_range_extra_equals)]
669 #[note]
670 pub(crate) struct InclusiveRangeExtraEquals {
671     #[primary_span]
672     #[suggestion(
673         suggestion_remove_eq,
674         style = "short",
675         code = "..=",
676         applicability = "maybe-incorrect"
677     )]
678     pub span: Span,
679 }
680
681 #[derive(Diagnostic)]
682 #[diag(parse_inclusive_range_match_arrow)]
683 pub(crate) struct InclusiveRangeMatchArrow {
684     #[primary_span]
685     pub arrow: Span,
686     #[label]
687     pub span: Span,
688     #[suggestion(style = "verbose", code = " ", applicability = "machine-applicable")]
689     pub after_pat: Span,
690 }
691
692 #[derive(Diagnostic)]
693 #[diag(parse_inclusive_range_no_end, code = "E0586")]
694 #[note]
695 pub(crate) struct InclusiveRangeNoEnd {
696     #[primary_span]
697     #[suggestion(
698         suggestion_open_range,
699         code = "..",
700         applicability = "machine-applicable",
701         style = "short"
702     )]
703     pub span: Span,
704 }
705
706 #[derive(Subdiagnostic)]
707 pub(crate) enum MatchArmBodyWithoutBracesSugg {
708     #[multipart_suggestion(suggestion_add_braces, applicability = "machine-applicable")]
709     AddBraces {
710         #[suggestion_part(code = "{{ ")]
711         left: Span,
712         #[suggestion_part(code = " }}")]
713         right: Span,
714     },
715     #[suggestion(
716         suggestion_use_comma_not_semicolon,
717         code = ",",
718         applicability = "machine-applicable"
719     )]
720     UseComma {
721         #[primary_span]
722         semicolon: Span,
723     },
724 }
725
726 #[derive(Diagnostic)]
727 #[diag(parse_struct_literal_not_allowed_here)]
728 pub(crate) struct StructLiteralNotAllowedHere {
729     #[primary_span]
730     pub span: Span,
731     #[subdiagnostic]
732     pub sub: StructLiteralNotAllowedHereSugg,
733 }
734
735 #[derive(Subdiagnostic)]
736 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
737 pub(crate) struct StructLiteralNotAllowedHereSugg {
738     #[suggestion_part(code = "(")]
739     pub left: Span,
740     #[suggestion_part(code = ")")]
741     pub right: Span,
742 }
743
744 #[derive(Diagnostic)]
745 #[diag(parse_invalid_interpolated_expression)]
746 pub(crate) struct InvalidInterpolatedExpression {
747     #[primary_span]
748     pub span: Span,
749 }
750
751 #[derive(Diagnostic)]
752 #[diag(parse_invalid_literal_suffix_on_tuple_index)]
753 pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
754     #[primary_span]
755     #[label]
756     pub span: Span,
757     pub suffix: Symbol,
758     #[help(tuple_exception_line_1)]
759     #[help(tuple_exception_line_2)]
760     #[help(tuple_exception_line_3)]
761     pub exception: Option<()>,
762 }
763
764 #[derive(Diagnostic)]
765 #[diag(parse_non_string_abi_literal)]
766 pub(crate) struct NonStringAbiLiteral {
767     #[primary_span]
768     #[suggestion(code = "\"C\"", applicability = "maybe-incorrect")]
769     pub span: Span,
770 }
771
772 #[derive(Diagnostic)]
773 #[diag(parse_mismatched_closing_delimiter)]
774 pub(crate) struct MismatchedClosingDelimiter {
775     #[primary_span]
776     pub spans: Vec<Span>,
777     pub delimiter: String,
778     #[label(label_unmatched)]
779     pub unmatched: Span,
780     #[label(label_opening_candidate)]
781     pub opening_candidate: Option<Span>,
782     #[label(label_unclosed)]
783     pub unclosed: Option<Span>,
784 }
785
786 #[derive(Diagnostic)]
787 #[diag(parse_incorrect_visibility_restriction, code = "E0704")]
788 #[help]
789 pub(crate) struct IncorrectVisibilityRestriction {
790     #[primary_span]
791     #[suggestion(code = "in {inner_str}", applicability = "machine-applicable")]
792     pub span: Span,
793     pub inner_str: String,
794 }
795
796 #[derive(Diagnostic)]
797 #[diag(parse_assignment_else_not_allowed)]
798 pub(crate) struct AssignmentElseNotAllowed {
799     #[primary_span]
800     pub span: Span,
801 }
802
803 #[derive(Diagnostic)]
804 #[diag(parse_expected_statement_after_outer_attr)]
805 pub(crate) struct ExpectedStatementAfterOuterAttr {
806     #[primary_span]
807     pub span: Span,
808 }
809
810 #[derive(Diagnostic)]
811 #[diag(parse_doc_comment_does_not_document_anything, code = "E0585")]
812 #[help]
813 pub(crate) struct DocCommentDoesNotDocumentAnything {
814     #[primary_span]
815     pub span: Span,
816     #[suggestion(code = ",", applicability = "machine-applicable")]
817     pub missing_comma: Option<Span>,
818 }
819
820 #[derive(Diagnostic)]
821 #[diag(parse_const_let_mutually_exclusive)]
822 pub(crate) struct ConstLetMutuallyExclusive {
823     #[primary_span]
824     #[suggestion(code = "const", applicability = "maybe-incorrect")]
825     pub span: Span,
826 }
827
828 #[derive(Diagnostic)]
829 #[diag(parse_invalid_expression_in_let_else)]
830 pub(crate) struct InvalidExpressionInLetElse {
831     #[primary_span]
832     pub span: Span,
833     pub operator: &'static str,
834     #[subdiagnostic]
835     pub sugg: WrapExpressionInParentheses,
836 }
837
838 #[derive(Diagnostic)]
839 #[diag(parse_invalid_curly_in_let_else)]
840 pub(crate) struct InvalidCurlyInLetElse {
841     #[primary_span]
842     pub span: Span,
843     #[subdiagnostic]
844     pub sugg: WrapExpressionInParentheses,
845 }
846
847 #[derive(Diagnostic)]
848 #[diag(parse_compound_assignment_expression_in_let)]
849 #[help]
850 pub(crate) struct CompoundAssignmentExpressionInLet {
851     #[primary_span]
852     #[suggestion(style = "short", code = "=", applicability = "maybe-incorrect")]
853     pub span: Span,
854 }
855
856 #[derive(Diagnostic)]
857 #[diag(parse_suffixed_literal_in_attribute)]
858 #[help]
859 pub(crate) struct SuffixedLiteralInAttribute {
860     #[primary_span]
861     pub span: Span,
862 }
863
864 #[derive(Diagnostic)]
865 #[diag(parse_invalid_meta_item)]
866 pub(crate) struct InvalidMetaItem {
867     #[primary_span]
868     pub span: Span,
869     pub token: Token,
870 }
871
872 #[derive(Subdiagnostic)]
873 #[suggestion(
874     parse_sugg_escape_to_use_as_identifier,
875     style = "verbose",
876     applicability = "maybe-incorrect",
877     code = "r#"
878 )]
879 pub(crate) struct SuggEscapeToUseAsIdentifier {
880     #[primary_span]
881     pub span: Span,
882     pub ident_name: String,
883 }
884
885 #[derive(Subdiagnostic)]
886 #[suggestion(parse_sugg_remove_comma, applicability = "machine-applicable", code = "")]
887 pub(crate) struct SuggRemoveComma {
888     #[primary_span]
889     pub span: Span,
890 }
891
892 #[derive(Subdiagnostic)]
893 pub(crate) enum ExpectedIdentifierFound {
894     #[label(parse_expected_identifier_found_reserved_identifier)]
895     ReservedIdentifier(#[primary_span] Span),
896     #[label(parse_expected_identifier_found_keyword)]
897     Keyword(#[primary_span] Span),
898     #[label(parse_expected_identifier_found_reserved_keyword)]
899     ReservedKeyword(#[primary_span] Span),
900     #[label(parse_expected_identifier_found_doc_comment)]
901     DocComment(#[primary_span] Span),
902     #[label(parse_expected_identifier)]
903     Other(#[primary_span] Span),
904 }
905
906 impl ExpectedIdentifierFound {
907     pub fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
908         (match token_descr {
909             Some(TokenDescription::ReservedIdentifier) => {
910                 ExpectedIdentifierFound::ReservedIdentifier
911             }
912             Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword,
913             Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
914             Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment,
915             None => ExpectedIdentifierFound::Other,
916         })(span)
917     }
918 }
919
920 pub(crate) struct ExpectedIdentifier {
921     pub span: Span,
922     pub token: Token,
923     pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>,
924     pub suggest_remove_comma: Option<SuggRemoveComma>,
925 }
926
927 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
928     #[track_caller]
929     fn into_diagnostic(
930         self,
931         handler: &'a rustc_errors::Handler,
932     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
933         let token_descr = super::parser::TokenDescription::from_token(&self.token);
934
935         let mut diag = handler.struct_diagnostic(match token_descr {
936             Some(TokenDescription::ReservedIdentifier) => {
937                 fluent::parse_expected_identifier_found_reserved_identifier_str
938             }
939             Some(TokenDescription::Keyword) => fluent::parse_expected_identifier_found_keyword_str,
940             Some(TokenDescription::ReservedKeyword) => {
941                 fluent::parse_expected_identifier_found_reserved_keyword_str
942             }
943             Some(TokenDescription::DocComment) => {
944                 fluent::parse_expected_identifier_found_doc_comment_str
945             }
946             None => fluent::parse_expected_identifier_found_str,
947         });
948         diag.set_span(self.span);
949         diag.set_arg("token", self.token);
950
951         if let Some(sugg) = self.suggest_raw {
952             sugg.add_to_diagnostic(&mut diag);
953         }
954
955         ExpectedIdentifierFound::new(token_descr, self.span).add_to_diagnostic(&mut diag);
956
957         if let Some(sugg) = self.suggest_remove_comma {
958             sugg.add_to_diagnostic(&mut diag);
959         }
960
961         diag
962     }
963 }
964
965 pub(crate) struct ExpectedSemi {
966     pub span: Span,
967     pub token: Token,
968
969     pub unexpected_token_label: Option<Span>,
970     pub sugg: ExpectedSemiSugg,
971 }
972
973 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
974     #[track_caller]
975     fn into_diagnostic(
976         self,
977         handler: &'a rustc_errors::Handler,
978     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
979         let token_descr = super::parser::TokenDescription::from_token(&self.token);
980
981         let mut diag = handler.struct_diagnostic(match token_descr {
982             Some(TokenDescription::ReservedIdentifier) => {
983                 fluent::parse_expected_semi_found_reserved_identifier_str
984             }
985             Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str,
986             Some(TokenDescription::ReservedKeyword) => {
987                 fluent::parse_expected_semi_found_reserved_keyword_str
988             }
989             Some(TokenDescription::DocComment) => fluent::parse_expected_semi_found_doc_comment_str,
990             None => fluent::parse_expected_semi_found_str,
991         });
992         diag.set_span(self.span);
993         diag.set_arg("token", self.token);
994
995         if let Some(unexpected_token_label) = self.unexpected_token_label {
996             diag.span_label(unexpected_token_label, fluent::parse_label_unexpected_token);
997         }
998
999         self.sugg.add_to_diagnostic(&mut diag);
1000
1001         diag
1002     }
1003 }
1004
1005 #[derive(Subdiagnostic)]
1006 pub(crate) enum ExpectedSemiSugg {
1007     #[suggestion(parse_sugg_change_this_to_semi, code = ";", applicability = "machine-applicable")]
1008     ChangeToSemi(#[primary_span] Span),
1009     #[suggestion(
1010         parse_sugg_add_semi,
1011         style = "short",
1012         code = ";",
1013         applicability = "machine-applicable"
1014     )]
1015     AddSemi(#[primary_span] Span),
1016 }
1017
1018 #[derive(Diagnostic)]
1019 #[diag(parse_struct_literal_body_without_path)]
1020 pub(crate) struct StructLiteralBodyWithoutPath {
1021     #[primary_span]
1022     pub span: Span,
1023     #[subdiagnostic]
1024     pub sugg: StructLiteralBodyWithoutPathSugg,
1025 }
1026
1027 #[derive(Subdiagnostic)]
1028 #[multipart_suggestion(suggestion, applicability = "has-placeholders")]
1029 pub(crate) struct StructLiteralBodyWithoutPathSugg {
1030     #[suggestion_part(code = "{{ SomeStruct ")]
1031     pub before: Span,
1032     #[suggestion_part(code = " }}")]
1033     pub after: Span,
1034 }
1035
1036 #[derive(Diagnostic)]
1037 #[diag(parse_struct_literal_needing_parens)]
1038 pub(crate) struct StructLiteralNeedingParens {
1039     #[primary_span]
1040     pub span: Span,
1041     #[subdiagnostic]
1042     pub sugg: StructLiteralNeedingParensSugg,
1043 }
1044
1045 #[derive(Subdiagnostic)]
1046 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1047 pub(crate) struct StructLiteralNeedingParensSugg {
1048     #[suggestion_part(code = "(")]
1049     pub before: Span,
1050     #[suggestion_part(code = ")")]
1051     pub after: Span,
1052 }
1053
1054 #[derive(Diagnostic)]
1055 #[diag(parse_unmatched_angle_brackets)]
1056 pub(crate) struct UnmatchedAngleBrackets {
1057     #[primary_span]
1058     #[suggestion(code = "", applicability = "machine-applicable")]
1059     pub span: Span,
1060     pub num_extra_brackets: usize,
1061 }
1062
1063 #[derive(Diagnostic)]
1064 #[diag(parse_generic_parameters_without_angle_brackets)]
1065 pub(crate) struct GenericParamsWithoutAngleBrackets {
1066     #[primary_span]
1067     pub span: Span,
1068     #[subdiagnostic]
1069     pub sugg: GenericParamsWithoutAngleBracketsSugg,
1070 }
1071
1072 #[derive(Subdiagnostic)]
1073 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1074 pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
1075     #[suggestion_part(code = "<")]
1076     pub left: Span,
1077     #[suggestion_part(code = ">")]
1078     pub right: Span,
1079 }
1080
1081 #[derive(Diagnostic)]
1082 #[diag(parse_comparison_operators_cannot_be_chained)]
1083 pub(crate) struct ComparisonOperatorsCannotBeChained {
1084     #[primary_span]
1085     pub span: Vec<Span>,
1086     #[suggestion(
1087         parse_sugg_turbofish_syntax,
1088         style = "verbose",
1089         code = "::",
1090         applicability = "maybe-incorrect"
1091     )]
1092     pub suggest_turbofish: Option<Span>,
1093     #[help(parse_sugg_turbofish_syntax)]
1094     #[help(sugg_parentheses_for_function_args)]
1095     pub help_turbofish: Option<()>,
1096     #[subdiagnostic]
1097     pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
1098 }
1099
1100 #[derive(Subdiagnostic)]
1101 pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
1102     #[suggestion(
1103         sugg_split_comparison,
1104         style = "verbose",
1105         code = " && {middle_term}",
1106         applicability = "maybe-incorrect"
1107     )]
1108     SplitComparison {
1109         #[primary_span]
1110         span: Span,
1111         middle_term: String,
1112     },
1113     #[multipart_suggestion(sugg_parenthesize, applicability = "maybe-incorrect")]
1114     Parenthesize {
1115         #[suggestion_part(code = "(")]
1116         left: Span,
1117         #[suggestion_part(code = ")")]
1118         right: Span,
1119     },
1120 }
1121
1122 #[derive(Diagnostic)]
1123 #[diag(parse_question_mark_in_type)]
1124 pub(crate) struct QuestionMarkInType {
1125     #[primary_span]
1126     #[label]
1127     pub span: Span,
1128     #[subdiagnostic]
1129     pub sugg: QuestionMarkInTypeSugg,
1130 }
1131
1132 #[derive(Subdiagnostic)]
1133 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1134 pub(crate) struct QuestionMarkInTypeSugg {
1135     #[suggestion_part(code = "Option<")]
1136     pub left: Span,
1137     #[suggestion_part(code = ">")]
1138     pub right: Span,
1139 }
1140
1141 #[derive(Diagnostic)]
1142 #[diag(parse_unexpected_parentheses_in_for_head)]
1143 pub(crate) struct ParenthesesInForHead {
1144     #[primary_span]
1145     pub span: Vec<Span>,
1146     #[subdiagnostic]
1147     pub sugg: ParenthesesInForHeadSugg,
1148 }
1149
1150 #[derive(Subdiagnostic)]
1151 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1152 pub(crate) struct ParenthesesInForHeadSugg {
1153     #[suggestion_part(code = "{left_snippet}")]
1154     pub left: Span,
1155     pub left_snippet: String,
1156     #[suggestion_part(code = "{right_snippet}")]
1157     pub right: Span,
1158     pub right_snippet: String,
1159 }
1160
1161 #[derive(Diagnostic)]
1162 #[diag(parse_doc_comment_on_param_type)]
1163 pub(crate) struct DocCommentOnParamType {
1164     #[primary_span]
1165     #[label]
1166     pub span: Span,
1167 }
1168
1169 #[derive(Diagnostic)]
1170 #[diag(parse_attribute_on_param_type)]
1171 pub(crate) struct AttributeOnParamType {
1172     #[primary_span]
1173     #[label]
1174     pub span: Span,
1175 }
1176
1177 #[derive(Diagnostic)]
1178 #[diag(parse_pattern_method_param_without_body, code = "E0642")]
1179 pub(crate) struct PatternMethodParamWithoutBody {
1180     #[primary_span]
1181     #[suggestion(code = "_", applicability = "machine-applicable")]
1182     pub span: Span,
1183 }
1184
1185 #[derive(Diagnostic)]
1186 #[diag(parse_self_param_not_first)]
1187 pub(crate) struct SelfParamNotFirst {
1188     #[primary_span]
1189     #[label]
1190     pub span: Span,
1191 }
1192
1193 #[derive(Diagnostic)]
1194 #[diag(parse_invalid_identifier_with_leading_number)]
1195 pub(crate) struct InvalidIdentiferStartsWithNumber {
1196     #[primary_span]
1197     #[label]
1198     pub span: Span,
1199 }
1200
1201 #[derive(Diagnostic)]
1202 #[diag(parse_const_generic_without_braces)]
1203 pub(crate) struct ConstGenericWithoutBraces {
1204     #[primary_span]
1205     pub span: Span,
1206     #[subdiagnostic]
1207     pub sugg: ConstGenericWithoutBracesSugg,
1208 }
1209
1210 #[derive(Subdiagnostic)]
1211 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1212 pub(crate) struct ConstGenericWithoutBracesSugg {
1213     #[suggestion_part(code = "{{ ")]
1214     pub left: Span,
1215     #[suggestion_part(code = " }}")]
1216     pub right: Span,
1217 }
1218
1219 #[derive(Diagnostic)]
1220 #[diag(parse_unexpected_const_param_declaration)]
1221 pub(crate) struct UnexpectedConstParamDeclaration {
1222     #[primary_span]
1223     #[label]
1224     pub span: Span,
1225     #[subdiagnostic]
1226     pub sugg: Option<UnexpectedConstParamDeclarationSugg>,
1227 }
1228
1229 #[derive(Subdiagnostic)]
1230 pub(crate) enum UnexpectedConstParamDeclarationSugg {
1231     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1232     AddParam {
1233         #[suggestion_part(code = "<{snippet}>")]
1234         impl_generics: Span,
1235         #[suggestion_part(code = "{ident}")]
1236         incorrect_decl: Span,
1237         snippet: String,
1238         ident: String,
1239     },
1240     #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1241     AppendParam {
1242         #[suggestion_part(code = ", {snippet}")]
1243         impl_generics_end: Span,
1244         #[suggestion_part(code = "{ident}")]
1245         incorrect_decl: Span,
1246         snippet: String,
1247         ident: String,
1248     },
1249 }
1250
1251 #[derive(Diagnostic)]
1252 #[diag(parse_unexpected_const_in_generic_param)]
1253 pub(crate) struct UnexpectedConstInGenericParam {
1254     #[primary_span]
1255     pub span: Span,
1256     #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")]
1257     pub to_remove: Option<Span>,
1258 }
1259
1260 #[derive(Diagnostic)]
1261 #[diag(parse_async_move_order_incorrect)]
1262 pub(crate) struct AsyncMoveOrderIncorrect {
1263     #[primary_span]
1264     #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")]
1265     pub span: Span,
1266 }
1267
1268 #[derive(Diagnostic)]
1269 #[diag(parse_double_colon_in_bound)]
1270 pub(crate) struct DoubleColonInBound {
1271     #[primary_span]
1272     pub span: Span,
1273     #[suggestion(code = ": ", applicability = "machine-applicable")]
1274     pub between: Span,
1275 }
1276
1277 #[derive(Diagnostic)]
1278 #[diag(parse_fn_ptr_with_generics)]
1279 pub(crate) struct FnPtrWithGenerics {
1280     #[primary_span]
1281     pub span: Span,
1282     #[subdiagnostic]
1283     pub sugg: Option<FnPtrWithGenericsSugg>,
1284 }
1285
1286 #[derive(Subdiagnostic)]
1287 #[multipart_suggestion(suggestion, applicability = "maybe-incorrect")]
1288 pub(crate) struct FnPtrWithGenericsSugg {
1289     #[suggestion_part(code = "{snippet}")]
1290     pub left: Span,
1291     pub snippet: String,
1292     #[suggestion_part(code = "")]
1293     pub right: Span,
1294     pub arity: usize,
1295     pub for_param_list_exists: bool,
1296 }
1297
1298 #[derive(Diagnostic)]
1299 #[diag(parse_unexpected_if_with_if)]
1300 pub(crate) struct UnexpectedIfWithIf(
1301     #[primary_span]
1302     #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
1303     pub Span,
1304 );
1305
1306 #[derive(Diagnostic)]
1307 #[diag(parse_maybe_fn_typo_with_impl)]
1308 pub(crate) struct FnTypoWithImpl {
1309     #[primary_span]
1310     #[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
1311     pub fn_span: Span,
1312 }
1313
1314 #[derive(Diagnostic)]
1315 #[diag(parse_expected_fn_path_found_fn_keyword)]
1316 pub(crate) struct ExpectedFnPathFoundFnKeyword {
1317     #[primary_span]
1318     #[suggestion(applicability = "machine-applicable", code = "Fn", style = "verbose")]
1319     pub fn_token_span: Span,
1320 }
1321
1322 #[derive(Diagnostic)]
1323 #[diag(parse_where_clause_before_tuple_struct_body)]
1324 pub(crate) struct WhereClauseBeforeTupleStructBody {
1325     #[primary_span]
1326     #[label]
1327     pub span: Span,
1328     #[label(name_label)]
1329     pub name: Span,
1330     #[label(body_label)]
1331     pub body: Span,
1332     #[subdiagnostic]
1333     pub sugg: Option<WhereClauseBeforeTupleStructBodySugg>,
1334 }
1335
1336 #[derive(Subdiagnostic)]
1337 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1338 pub(crate) struct WhereClauseBeforeTupleStructBodySugg {
1339     #[suggestion_part(code = "{snippet}")]
1340     pub left: Span,
1341     pub snippet: String,
1342     #[suggestion_part(code = "")]
1343     pub right: Span,
1344 }
1345
1346 #[derive(Diagnostic)]
1347 #[diag(parse_async_fn_in_2015, code = "E0670")]
1348 pub(crate) struct AsyncFnIn2015 {
1349     #[primary_span]
1350     #[label]
1351     pub span: Span,
1352     #[subdiagnostic]
1353     pub help: HelpUseLatestEdition,
1354 }
1355
1356 #[derive(Subdiagnostic)]
1357 #[label(parse_async_block_in_2015)]
1358 pub(crate) struct AsyncBlockIn2015 {
1359     #[primary_span]
1360     pub span: Span,
1361 }
1362
1363 #[derive(Diagnostic)]
1364 #[diag(parse_self_argument_pointer)]
1365 pub(crate) struct SelfArgumentPointer {
1366     #[primary_span]
1367     #[label]
1368     pub span: Span,
1369 }
1370
1371 #[derive(Diagnostic)]
1372 #[diag(parse_visibility_not_followed_by_item)]
1373 #[help]
1374 pub(crate) struct VisibilityNotFollowedByItem {
1375     #[primary_span]
1376     #[label]
1377     pub span: Span,
1378     pub vis: Visibility,
1379 }
1380
1381 #[derive(Diagnostic)]
1382 #[diag(parse_default_not_followed_by_item)]
1383 #[note]
1384 pub(crate) struct DefaultNotFollowedByItem {
1385     #[primary_span]
1386     #[label]
1387     pub span: Span,
1388 }
1389
1390 #[derive(Diagnostic)]
1391 pub(crate) enum MissingKeywordForItemDefinition {
1392     #[diag(parse_missing_struct_for_struct_definition)]
1393     Struct {
1394         #[primary_span]
1395         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " struct ")]
1396         span: Span,
1397         ident: Ident,
1398     },
1399     #[diag(parse_missing_fn_for_function_definition)]
1400     Function {
1401         #[primary_span]
1402         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " fn ")]
1403         span: Span,
1404         ident: Ident,
1405     },
1406     #[diag(parse_missing_fn_for_method_definition)]
1407     Method {
1408         #[primary_span]
1409         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " fn ")]
1410         span: Span,
1411         ident: Ident,
1412     },
1413     #[diag(parse_ambiguous_missing_keyword_for_item_definition)]
1414     Ambiguous {
1415         #[primary_span]
1416         span: Span,
1417         #[subdiagnostic]
1418         subdiag: Option<AmbiguousMissingKwForItemSub>,
1419     },
1420 }
1421
1422 #[derive(Subdiagnostic)]
1423 pub(crate) enum AmbiguousMissingKwForItemSub {
1424     #[suggestion(suggestion, applicability = "maybe-incorrect", code = "{snippet}!")]
1425     SuggestMacro {
1426         #[primary_span]
1427         span: Span,
1428         snippet: String,
1429     },
1430     #[help(help)]
1431     HelpMacro,
1432 }
1433
1434 #[derive(Diagnostic)]
1435 #[diag(parse_missing_trait_in_trait_impl)]
1436 pub(crate) struct MissingTraitInTraitImpl {
1437     #[primary_span]
1438     #[suggestion(suggestion_add_trait, code = " Trait ", applicability = "has-placeholders")]
1439     pub span: Span,
1440     #[suggestion(suggestion_remove_for, code = "", applicability = "maybe-incorrect")]
1441     pub for_span: Span,
1442 }
1443
1444 #[derive(Diagnostic)]
1445 #[diag(parse_missing_for_in_trait_impl)]
1446 pub(crate) struct MissingForInTraitImpl {
1447     #[primary_span]
1448     #[suggestion(style = "short", code = " for ", applicability = "machine-applicable")]
1449     pub span: Span,
1450 }
1451
1452 #[derive(Diagnostic)]
1453 #[diag(parse_expected_trait_in_trait_impl_found_type)]
1454 pub(crate) struct ExpectedTraitInTraitImplFoundType {
1455     #[primary_span]
1456     pub span: Span,
1457 }
1458
1459 #[derive(Diagnostic)]
1460 #[diag(parse_bounds_not_allowed_on_trait_aliases)]
1461 pub(crate) struct BoundsNotAllowedOnTraitAliases {
1462     #[primary_span]
1463     pub span: Span,
1464 }
1465
1466 #[derive(Diagnostic)]
1467 #[diag(parse_trait_alias_cannot_be_auto)]
1468 pub(crate) struct TraitAliasCannotBeAuto {
1469     #[primary_span]
1470     #[label(parse_trait_alias_cannot_be_auto)]
1471     pub span: Span,
1472 }
1473
1474 #[derive(Diagnostic)]
1475 #[diag(parse_trait_alias_cannot_be_unsafe)]
1476 pub(crate) struct TraitAliasCannotBeUnsafe {
1477     #[primary_span]
1478     #[label(parse_trait_alias_cannot_be_unsafe)]
1479     pub span: Span,
1480 }
1481
1482 #[derive(Diagnostic)]
1483 #[diag(parse_associated_static_item_not_allowed)]
1484 pub(crate) struct AssociatedStaticItemNotAllowed {
1485     #[primary_span]
1486     pub span: Span,
1487 }
1488
1489 #[derive(Diagnostic)]
1490 #[diag(parse_extern_crate_name_with_dashes)]
1491 pub(crate) struct ExternCrateNameWithDashes {
1492     #[primary_span]
1493     #[label]
1494     pub span: Span,
1495     #[subdiagnostic]
1496     pub sugg: ExternCrateNameWithDashesSugg,
1497 }
1498
1499 #[derive(Subdiagnostic)]
1500 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1501 pub(crate) struct ExternCrateNameWithDashesSugg {
1502     #[suggestion_part(code = "_")]
1503     pub dashes: Vec<Span>,
1504 }
1505
1506 #[derive(Diagnostic)]
1507 #[diag(parse_extern_item_cannot_be_const)]
1508 #[note]
1509 pub(crate) struct ExternItemCannotBeConst {
1510     #[primary_span]
1511     pub ident_span: Span,
1512     #[suggestion(code = "static ", applicability = "machine-applicable")]
1513     pub const_span: Span,
1514 }
1515
1516 #[derive(Diagnostic)]
1517 #[diag(parse_const_global_cannot_be_mutable)]
1518 pub(crate) struct ConstGlobalCannotBeMutable {
1519     #[primary_span]
1520     #[label]
1521     pub ident_span: Span,
1522     #[suggestion(code = "static", applicability = "maybe-incorrect")]
1523     pub const_span: Span,
1524 }
1525
1526 #[derive(Diagnostic)]
1527 #[diag(parse_missing_const_type)]
1528 pub(crate) struct MissingConstType {
1529     #[primary_span]
1530     #[suggestion(code = "{colon} <type>", applicability = "has-placeholders")]
1531     pub span: Span,
1532
1533     pub kind: &'static str,
1534     pub colon: &'static str,
1535 }
1536
1537 #[derive(Diagnostic)]
1538 #[diag(parse_enum_struct_mutually_exclusive)]
1539 pub(crate) struct EnumStructMutuallyExclusive {
1540     #[primary_span]
1541     #[suggestion(code = "enum", applicability = "machine-applicable")]
1542     pub span: Span,
1543 }
1544
1545 #[derive(Diagnostic)]
1546 pub(crate) enum UnexpectedTokenAfterStructName {
1547     #[diag(parse_unexpected_token_after_struct_name_found_reserved_identifier)]
1548     ReservedIdentifier {
1549         #[primary_span]
1550         #[label(parse_unexpected_token_after_struct_name)]
1551         span: Span,
1552         token: Token,
1553     },
1554     #[diag(parse_unexpected_token_after_struct_name_found_keyword)]
1555     Keyword {
1556         #[primary_span]
1557         #[label(parse_unexpected_token_after_struct_name)]
1558         span: Span,
1559         token: Token,
1560     },
1561     #[diag(parse_unexpected_token_after_struct_name_found_reserved_keyword)]
1562     ReservedKeyword {
1563         #[primary_span]
1564         #[label(parse_unexpected_token_after_struct_name)]
1565         span: Span,
1566         token: Token,
1567     },
1568     #[diag(parse_unexpected_token_after_struct_name_found_doc_comment)]
1569     DocComment {
1570         #[primary_span]
1571         #[label(parse_unexpected_token_after_struct_name)]
1572         span: Span,
1573         token: Token,
1574     },
1575     #[diag(parse_unexpected_token_after_struct_name_found_other)]
1576     Other {
1577         #[primary_span]
1578         #[label(parse_unexpected_token_after_struct_name)]
1579         span: Span,
1580         token: Token,
1581     },
1582 }
1583
1584 impl UnexpectedTokenAfterStructName {
1585     pub fn new(span: Span, token: Token) -> Self {
1586         match TokenDescription::from_token(&token) {
1587             Some(TokenDescription::ReservedIdentifier) => Self::ReservedIdentifier { span, token },
1588             Some(TokenDescription::Keyword) => Self::Keyword { span, token },
1589             Some(TokenDescription::ReservedKeyword) => Self::ReservedKeyword { span, token },
1590             Some(TokenDescription::DocComment) => Self::DocComment { span, token },
1591             None => Self::Other { span, token },
1592         }
1593     }
1594 }
1595
1596 #[derive(Diagnostic)]
1597 #[diag(parse_unexpected_self_in_generic_parameters)]
1598 #[note]
1599 pub(crate) struct UnexpectedSelfInGenericParameters {
1600     #[primary_span]
1601     pub span: Span,
1602 }
1603
1604 #[derive(Diagnostic)]
1605 #[diag(parse_multiple_where_clauses)]
1606 pub(crate) struct MultipleWhereClauses {
1607     #[primary_span]
1608     pub span: Span,
1609     #[label]
1610     pub previous: Span,
1611     #[suggestion(style = "verbose", code = ",", applicability = "maybe-incorrect")]
1612     pub between: Span,
1613 }
1614
1615 #[derive(Diagnostic)]
1616 pub(crate) enum UnexpectedNonterminal {
1617     #[diag(parse_nonterminal_expected_item_keyword)]
1618     Item(#[primary_span] Span),
1619     #[diag(parse_nonterminal_expected_statement)]
1620     Statement(#[primary_span] Span),
1621     #[diag(parse_nonterminal_expected_ident)]
1622     Ident {
1623         #[primary_span]
1624         span: Span,
1625         token: Token,
1626     },
1627     #[diag(parse_nonterminal_expected_lifetime)]
1628     Lifetime {
1629         #[primary_span]
1630         span: Span,
1631         token: Token,
1632     },
1633 }
1634
1635 #[derive(Diagnostic)]
1636 pub(crate) enum TopLevelOrPatternNotAllowed {
1637     #[diag(parse_or_pattern_not_allowed_in_let_binding)]
1638     LetBinding {
1639         #[primary_span]
1640         span: Span,
1641         #[subdiagnostic]
1642         sub: Option<TopLevelOrPatternNotAllowedSugg>,
1643     },
1644     #[diag(parse_or_pattern_not_allowed_in_fn_parameters)]
1645     FunctionParameter {
1646         #[primary_span]
1647         span: Span,
1648         #[subdiagnostic]
1649         sub: Option<TopLevelOrPatternNotAllowedSugg>,
1650     },
1651 }
1652
1653 #[derive(Subdiagnostic)]
1654 pub(crate) enum TopLevelOrPatternNotAllowedSugg {
1655     #[suggestion(
1656         parse_sugg_remove_leading_vert_in_pattern,
1657         code = "{pat}",
1658         applicability = "machine-applicable"
1659     )]
1660     RemoveLeadingVert {
1661         #[primary_span]
1662         span: Span,
1663         pat: String,
1664     },
1665     #[suggestion(
1666         parse_sugg_wrap_pattern_in_parens,
1667         code = "({pat})",
1668         applicability = "machine-applicable"
1669     )]
1670     WrapInParens {
1671         #[primary_span]
1672         span: Span,
1673         pat: String,
1674     },
1675 }
1676
1677 #[derive(Diagnostic)]
1678 #[diag(parse_unexpected_vert_vert_before_function_parameter)]
1679 #[note(parse_note_pattern_alternatives_use_single_vert)]
1680 pub(crate) struct UnexpectedVertVertBeforeFunctionParam {
1681     #[primary_span]
1682     #[suggestion(code = "", applicability = "machine-applicable")]
1683     pub span: Span,
1684 }
1685
1686 #[derive(Diagnostic)]
1687 #[diag(parse_unexpected_vert_vert_in_pattern)]
1688 pub(crate) struct UnexpectedVertVertInPattern {
1689     #[primary_span]
1690     #[suggestion(code = "|", applicability = "machine-applicable")]
1691     pub span: Span,
1692     #[label(parse_label_while_parsing_or_pattern_here)]
1693     pub start: Option<Span>,
1694 }
1695
1696 #[derive(Diagnostic)]
1697 #[diag(parse_trailing_vert_not_allowed)]
1698 pub(crate) struct TrailingVertNotAllowed {
1699     #[primary_span]
1700     #[suggestion(code = "", applicability = "machine-applicable")]
1701     pub span: Span,
1702     #[label(parse_label_while_parsing_or_pattern_here)]
1703     pub start: Option<Span>,
1704     pub token: Token,
1705     #[note(parse_note_pattern_alternatives_use_single_vert)]
1706     pub note_double_vert: Option<()>,
1707 }
1708
1709 #[derive(Diagnostic)]
1710 #[diag(parse_dotdotdot_rest_pattern)]
1711 pub(crate) struct DotDotDotRestPattern {
1712     #[primary_span]
1713     #[suggestion(style = "short", code = "..", applicability = "machine-applicable")]
1714     #[label]
1715     pub span: Span,
1716 }
1717
1718 #[derive(Diagnostic)]
1719 #[diag(parse_pattern_on_wrong_side_of_at)]
1720 pub(crate) struct PatternOnWrongSideOfAt {
1721     #[primary_span]
1722     #[suggestion(code = "{whole_pat}", applicability = "machine-applicable")]
1723     pub whole_span: Span,
1724     pub whole_pat: String,
1725     #[label(label_pattern)]
1726     pub pattern: Span,
1727     #[label(label_binding)]
1728     pub binding: Span,
1729 }
1730
1731 #[derive(Diagnostic)]
1732 #[diag(parse_expected_binding_left_of_at)]
1733 #[note]
1734 pub(crate) struct ExpectedBindingLeftOfAt {
1735     #[primary_span]
1736     pub whole_span: Span,
1737     #[label(label_lhs)]
1738     pub lhs: Span,
1739     #[label(label_rhs)]
1740     pub rhs: Span,
1741 }
1742
1743 #[derive(Diagnostic)]
1744 #[diag(parse_ambiguous_range_pattern)]
1745 pub(crate) struct AmbiguousRangePattern {
1746     #[primary_span]
1747     #[suggestion(code = "({pat})", applicability = "maybe-incorrect")]
1748     pub span: Span,
1749     pub pat: String,
1750 }
1751
1752 #[derive(Diagnostic)]
1753 #[diag(parse_unexpected_lifetime_in_pattern)]
1754 pub(crate) struct UnexpectedLifetimeInPattern {
1755     #[primary_span]
1756     #[suggestion(code = "", applicability = "machine-applicable")]
1757     pub span: Span,
1758     pub symbol: Symbol,
1759 }
1760
1761 #[derive(Diagnostic)]
1762 #[diag(parse_ref_mut_order_incorrect)]
1763 pub(crate) struct RefMutOrderIncorrect {
1764     #[primary_span]
1765     #[suggestion(code = "ref mut", applicability = "machine-applicable")]
1766     pub span: Span,
1767 }
1768
1769 #[derive(Diagnostic)]
1770 pub(crate) enum InvalidMutInPattern {
1771     #[diag(parse_mut_on_nested_ident_pattern)]
1772     #[note(parse_note_mut_pattern_usage)]
1773     NestedIdent {
1774         #[primary_span]
1775         #[suggestion(code = "{pat}", applicability = "machine-applicable")]
1776         span: Span,
1777         pat: String,
1778     },
1779     #[diag(parse_mut_on_non_ident_pattern)]
1780     #[note(parse_note_mut_pattern_usage)]
1781     NonIdent {
1782         #[primary_span]
1783         #[suggestion(code = "{pat}", applicability = "machine-applicable")]
1784         span: Span,
1785         pat: String,
1786     },
1787 }
1788
1789 #[derive(Diagnostic)]
1790 #[diag(parse_repeated_mut_in_pattern)]
1791 pub(crate) struct RepeatedMutInPattern {
1792     #[primary_span]
1793     #[suggestion(code = "", applicability = "machine-applicable")]
1794     pub span: Span,
1795 }
1796
1797 #[derive(Diagnostic)]
1798 #[diag(parse_dot_dot_dot_range_to_pattern_not_allowed)]
1799 pub(crate) struct DotDotDotRangeToPatternNotAllowed {
1800     #[primary_span]
1801     #[suggestion(style = "short", code = "..=", applicability = "machine-applicable")]
1802     pub span: Span,
1803 }
1804
1805 #[derive(Diagnostic)]
1806 #[diag(parse_enum_pattern_instead_of_identifier)]
1807 pub(crate) struct EnumPatternInsteadOfIdentifier {
1808     #[primary_span]
1809     pub span: Span,
1810 }
1811
1812 #[derive(Diagnostic)]
1813 #[diag(parse_dot_dot_dot_for_remaining_fields)]
1814 pub(crate) struct DotDotDotForRemainingFields {
1815     #[primary_span]
1816     #[suggestion(code = "..", style = "verbose", applicability = "machine-applicable")]
1817     pub span: Span,
1818     pub token_str: Cow<'static, str>,
1819 }
1820
1821 #[derive(Diagnostic)]
1822 #[diag(parse_expected_comma_after_pattern_field)]
1823 pub(crate) struct ExpectedCommaAfterPatternField {
1824     #[primary_span]
1825     pub span: Span,
1826 }
1827
1828 #[derive(Diagnostic)]
1829 #[diag(parse_return_types_use_thin_arrow)]
1830 pub(crate) struct ReturnTypesUseThinArrow {
1831     #[primary_span]
1832     #[suggestion(style = "short", code = "->", applicability = "machine-applicable")]
1833     pub span: Span,
1834 }
1835
1836 #[derive(Diagnostic)]
1837 #[diag(parse_need_plus_after_trait_object_lifetime)]
1838 pub(crate) struct NeedPlusAfterTraitObjectLifetime {
1839     #[primary_span]
1840     pub span: Span,
1841 }
1842
1843 #[derive(Diagnostic)]
1844 #[diag(parse_expected_mut_or_const_in_raw_pointer_type)]
1845 pub(crate) struct ExpectedMutOrConstInRawPointerType {
1846     #[primary_span]
1847     pub span: Span,
1848     #[suggestion(code("mut ", "const "), applicability = "has-placeholders")]
1849     pub after_asterisk: Span,
1850 }
1851
1852 #[derive(Diagnostic)]
1853 #[diag(parse_lifetime_after_mut)]
1854 pub(crate) struct LifetimeAfterMut {
1855     #[primary_span]
1856     pub span: Span,
1857     #[suggestion(code = "&{snippet} mut", applicability = "maybe-incorrect")]
1858     pub suggest_lifetime: Option<Span>,
1859     pub snippet: String,
1860 }
1861
1862 #[derive(Diagnostic)]
1863 #[diag(parse_dyn_after_mut)]
1864 pub(crate) struct DynAfterMut {
1865     #[primary_span]
1866     #[suggestion(code = "&mut dyn", applicability = "machine-applicable")]
1867     pub span: Span,
1868 }
1869
1870 #[derive(Diagnostic)]
1871 #[diag(parse_fn_pointer_cannot_be_const)]
1872 pub(crate) struct FnPointerCannotBeConst {
1873     #[primary_span]
1874     pub span: Span,
1875     #[suggestion(code = "", applicability = "maybe-incorrect")]
1876     #[label]
1877     pub qualifier: Span,
1878 }
1879
1880 #[derive(Diagnostic)]
1881 #[diag(parse_fn_pointer_cannot_be_async)]
1882 pub(crate) struct FnPointerCannotBeAsync {
1883     #[primary_span]
1884     pub span: Span,
1885     #[suggestion(code = "", applicability = "maybe-incorrect")]
1886     #[label]
1887     pub qualifier: Span,
1888 }
1889
1890 #[derive(Diagnostic)]
1891 #[diag(parse_nested_c_variadic_type, code = "E0743")]
1892 pub(crate) struct NestedCVariadicType {
1893     #[primary_span]
1894     pub span: Span,
1895 }
1896
1897 #[derive(Diagnostic)]
1898 #[diag(parse_invalid_dyn_keyword)]
1899 #[help]
1900 pub(crate) struct InvalidDynKeyword {
1901     #[primary_span]
1902     #[suggestion(code = "", applicability = "machine-applicable")]
1903     pub span: Span,
1904 }
1905
1906 #[derive(Diagnostic)]
1907 #[diag(parse_negative_bounds_not_supported)]
1908 pub(crate) struct NegativeBoundsNotSupported {
1909     #[primary_span]
1910     pub negative_bounds: Vec<Span>,
1911     #[label]
1912     pub last_span: Span,
1913     #[subdiagnostic]
1914     pub sub: Option<NegativeBoundsNotSupportedSugg>,
1915 }
1916
1917 #[derive(Subdiagnostic)]
1918 #[suggestion(
1919     suggestion,
1920     style = "tool-only",
1921     code = "{fixed}",
1922     applicability = "machine-applicable"
1923 )]
1924 pub(crate) struct NegativeBoundsNotSupportedSugg {
1925     #[primary_span]
1926     pub bound_list: Span,
1927     pub num_bounds: usize,
1928     pub fixed: String,
1929 }
1930
1931 #[derive(Subdiagnostic)]
1932 pub enum HelpUseLatestEdition {
1933     #[help(parse_help_set_edition_cargo)]
1934     #[note(parse_note_edition_guide)]
1935     Cargo { edition: Edition },
1936     #[help(parse_help_set_edition_standalone)]
1937     #[note(parse_note_edition_guide)]
1938     Standalone { edition: Edition },
1939 }
1940
1941 impl HelpUseLatestEdition {
1942     pub fn new() -> Self {
1943         let edition = LATEST_STABLE_EDITION;
1944         if std::env::var_os("CARGO").is_some() {
1945             Self::Cargo { edition }
1946         } else {
1947             Self::Standalone { edition }
1948         }
1949     }
1950 }