]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/errors.rs
Rollup merge of #107446 - clubby789:rustc-parse-diag-migrate, r=compiler-errors
[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_unexpected_token_after_dot)]
1373 pub struct UnexpectedTokenAfterDot<'a> {
1374     #[primary_span]
1375     pub span: Span,
1376     pub actual: Cow<'a, str>,
1377 }
1378
1379 #[derive(Diagnostic)]
1380 #[diag(parse_visibility_not_followed_by_item)]
1381 #[help]
1382 pub(crate) struct VisibilityNotFollowedByItem {
1383     #[primary_span]
1384     #[label]
1385     pub span: Span,
1386     pub vis: Visibility,
1387 }
1388
1389 #[derive(Diagnostic)]
1390 #[diag(parse_default_not_followed_by_item)]
1391 #[note]
1392 pub(crate) struct DefaultNotFollowedByItem {
1393     #[primary_span]
1394     #[label]
1395     pub span: Span,
1396 }
1397
1398 #[derive(Diagnostic)]
1399 pub(crate) enum MissingKeywordForItemDefinition {
1400     #[diag(parse_missing_struct_for_struct_definition)]
1401     Struct {
1402         #[primary_span]
1403         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " struct ")]
1404         span: Span,
1405         ident: Ident,
1406     },
1407     #[diag(parse_missing_fn_for_function_definition)]
1408     Function {
1409         #[primary_span]
1410         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " fn ")]
1411         span: Span,
1412         ident: Ident,
1413     },
1414     #[diag(parse_missing_fn_for_method_definition)]
1415     Method {
1416         #[primary_span]
1417         #[suggestion(style = "short", applicability = "maybe-incorrect", code = " fn ")]
1418         span: Span,
1419         ident: Ident,
1420     },
1421     #[diag(parse_ambiguous_missing_keyword_for_item_definition)]
1422     Ambiguous {
1423         #[primary_span]
1424         span: Span,
1425         #[subdiagnostic]
1426         subdiag: Option<AmbiguousMissingKwForItemSub>,
1427     },
1428 }
1429
1430 #[derive(Subdiagnostic)]
1431 pub(crate) enum AmbiguousMissingKwForItemSub {
1432     #[suggestion(suggestion, applicability = "maybe-incorrect", code = "{snippet}!")]
1433     SuggestMacro {
1434         #[primary_span]
1435         span: Span,
1436         snippet: String,
1437     },
1438     #[help(help)]
1439     HelpMacro,
1440 }
1441
1442 #[derive(Diagnostic)]
1443 #[diag(parse_missing_trait_in_trait_impl)]
1444 pub(crate) struct MissingTraitInTraitImpl {
1445     #[primary_span]
1446     #[suggestion(suggestion_add_trait, code = " Trait ", applicability = "has-placeholders")]
1447     pub span: Span,
1448     #[suggestion(suggestion_remove_for, code = "", applicability = "maybe-incorrect")]
1449     pub for_span: Span,
1450 }
1451
1452 #[derive(Diagnostic)]
1453 #[diag(parse_missing_for_in_trait_impl)]
1454 pub(crate) struct MissingForInTraitImpl {
1455     #[primary_span]
1456     #[suggestion(style = "short", code = " for ", applicability = "machine-applicable")]
1457     pub span: Span,
1458 }
1459
1460 #[derive(Diagnostic)]
1461 #[diag(parse_expected_trait_in_trait_impl_found_type)]
1462 pub(crate) struct ExpectedTraitInTraitImplFoundType {
1463     #[primary_span]
1464     pub span: Span,
1465 }
1466
1467 #[derive(Diagnostic)]
1468 #[diag(parse_bounds_not_allowed_on_trait_aliases)]
1469 pub(crate) struct BoundsNotAllowedOnTraitAliases {
1470     #[primary_span]
1471     pub span: Span,
1472 }
1473
1474 #[derive(Diagnostic)]
1475 #[diag(parse_trait_alias_cannot_be_auto)]
1476 pub(crate) struct TraitAliasCannotBeAuto {
1477     #[primary_span]
1478     #[label(parse_trait_alias_cannot_be_auto)]
1479     pub span: Span,
1480 }
1481
1482 #[derive(Diagnostic)]
1483 #[diag(parse_trait_alias_cannot_be_unsafe)]
1484 pub(crate) struct TraitAliasCannotBeUnsafe {
1485     #[primary_span]
1486     #[label(parse_trait_alias_cannot_be_unsafe)]
1487     pub span: Span,
1488 }
1489
1490 #[derive(Diagnostic)]
1491 #[diag(parse_associated_static_item_not_allowed)]
1492 pub(crate) struct AssociatedStaticItemNotAllowed {
1493     #[primary_span]
1494     pub span: Span,
1495 }
1496
1497 #[derive(Diagnostic)]
1498 #[diag(parse_extern_crate_name_with_dashes)]
1499 pub(crate) struct ExternCrateNameWithDashes {
1500     #[primary_span]
1501     #[label]
1502     pub span: Span,
1503     #[subdiagnostic]
1504     pub sugg: ExternCrateNameWithDashesSugg,
1505 }
1506
1507 #[derive(Subdiagnostic)]
1508 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
1509 pub(crate) struct ExternCrateNameWithDashesSugg {
1510     #[suggestion_part(code = "_")]
1511     pub dashes: Vec<Span>,
1512 }
1513
1514 #[derive(Diagnostic)]
1515 #[diag(parse_extern_item_cannot_be_const)]
1516 #[note]
1517 pub(crate) struct ExternItemCannotBeConst {
1518     #[primary_span]
1519     pub ident_span: Span,
1520     #[suggestion(code = "static ", applicability = "machine-applicable")]
1521     pub const_span: Span,
1522 }
1523
1524 #[derive(Diagnostic)]
1525 #[diag(parse_const_global_cannot_be_mutable)]
1526 pub(crate) struct ConstGlobalCannotBeMutable {
1527     #[primary_span]
1528     #[label]
1529     pub ident_span: Span,
1530     #[suggestion(code = "static", applicability = "maybe-incorrect")]
1531     pub const_span: Span,
1532 }
1533
1534 #[derive(Diagnostic)]
1535 #[diag(parse_missing_const_type)]
1536 pub(crate) struct MissingConstType {
1537     #[primary_span]
1538     #[suggestion(code = "{colon} <type>", applicability = "has-placeholders")]
1539     pub span: Span,
1540
1541     pub kind: &'static str,
1542     pub colon: &'static str,
1543 }
1544
1545 #[derive(Diagnostic)]
1546 #[diag(parse_enum_struct_mutually_exclusive)]
1547 pub(crate) struct EnumStructMutuallyExclusive {
1548     #[primary_span]
1549     #[suggestion(code = "enum", applicability = "machine-applicable")]
1550     pub span: Span,
1551 }
1552
1553 #[derive(Diagnostic)]
1554 pub(crate) enum UnexpectedTokenAfterStructName {
1555     #[diag(parse_unexpected_token_after_struct_name_found_reserved_identifier)]
1556     ReservedIdentifier {
1557         #[primary_span]
1558         #[label(parse_unexpected_token_after_struct_name)]
1559         span: Span,
1560         token: Token,
1561     },
1562     #[diag(parse_unexpected_token_after_struct_name_found_keyword)]
1563     Keyword {
1564         #[primary_span]
1565         #[label(parse_unexpected_token_after_struct_name)]
1566         span: Span,
1567         token: Token,
1568     },
1569     #[diag(parse_unexpected_token_after_struct_name_found_reserved_keyword)]
1570     ReservedKeyword {
1571         #[primary_span]
1572         #[label(parse_unexpected_token_after_struct_name)]
1573         span: Span,
1574         token: Token,
1575     },
1576     #[diag(parse_unexpected_token_after_struct_name_found_doc_comment)]
1577     DocComment {
1578         #[primary_span]
1579         #[label(parse_unexpected_token_after_struct_name)]
1580         span: Span,
1581         token: Token,
1582     },
1583     #[diag(parse_unexpected_token_after_struct_name_found_other)]
1584     Other {
1585         #[primary_span]
1586         #[label(parse_unexpected_token_after_struct_name)]
1587         span: Span,
1588         token: Token,
1589     },
1590 }
1591
1592 impl UnexpectedTokenAfterStructName {
1593     pub fn new(span: Span, token: Token) -> Self {
1594         match TokenDescription::from_token(&token) {
1595             Some(TokenDescription::ReservedIdentifier) => Self::ReservedIdentifier { span, token },
1596             Some(TokenDescription::Keyword) => Self::Keyword { span, token },
1597             Some(TokenDescription::ReservedKeyword) => Self::ReservedKeyword { span, token },
1598             Some(TokenDescription::DocComment) => Self::DocComment { span, token },
1599             None => Self::Other { span, token },
1600         }
1601     }
1602 }
1603
1604 #[derive(Diagnostic)]
1605 #[diag(parse_unexpected_self_in_generic_parameters)]
1606 #[note]
1607 pub(crate) struct UnexpectedSelfInGenericParameters {
1608     #[primary_span]
1609     pub span: Span,
1610 }
1611
1612 #[derive(Diagnostic)]
1613 #[diag(parse_unexpected_default_value_for_lifetime_in_generic_parameters)]
1614 pub(crate) struct UnexpectedDefaultValueForLifetimeInGenericParameters {
1615     #[primary_span]
1616     #[label]
1617     pub span: Span,
1618 }
1619
1620 #[derive(Diagnostic)]
1621 #[diag(parse_multiple_where_clauses)]
1622 pub(crate) struct MultipleWhereClauses {
1623     #[primary_span]
1624     pub span: Span,
1625     #[label]
1626     pub previous: Span,
1627     #[suggestion(style = "verbose", code = ",", applicability = "maybe-incorrect")]
1628     pub between: Span,
1629 }
1630
1631 #[derive(Diagnostic)]
1632 pub(crate) enum UnexpectedNonterminal {
1633     #[diag(parse_nonterminal_expected_item_keyword)]
1634     Item(#[primary_span] Span),
1635     #[diag(parse_nonterminal_expected_statement)]
1636     Statement(#[primary_span] Span),
1637     #[diag(parse_nonterminal_expected_ident)]
1638     Ident {
1639         #[primary_span]
1640         span: Span,
1641         token: Token,
1642     },
1643     #[diag(parse_nonterminal_expected_lifetime)]
1644     Lifetime {
1645         #[primary_span]
1646         span: Span,
1647         token: Token,
1648     },
1649 }
1650
1651 #[derive(Diagnostic)]
1652 pub(crate) enum TopLevelOrPatternNotAllowed {
1653     #[diag(parse_or_pattern_not_allowed_in_let_binding)]
1654     LetBinding {
1655         #[primary_span]
1656         span: Span,
1657         #[subdiagnostic]
1658         sub: Option<TopLevelOrPatternNotAllowedSugg>,
1659     },
1660     #[diag(parse_or_pattern_not_allowed_in_fn_parameters)]
1661     FunctionParameter {
1662         #[primary_span]
1663         span: Span,
1664         #[subdiagnostic]
1665         sub: Option<TopLevelOrPatternNotAllowedSugg>,
1666     },
1667 }
1668
1669 #[derive(Diagnostic)]
1670 #[diag(parse_cannot_be_raw_ident)]
1671 pub struct CannotBeRawIdent {
1672     #[primary_span]
1673     pub span: Span,
1674     pub ident: Symbol,
1675 }
1676
1677 #[derive(Diagnostic)]
1678 #[diag(parse_cr_doc_comment)]
1679 pub struct CrDocComment {
1680     #[primary_span]
1681     pub span: Span,
1682     pub block: bool,
1683 }
1684
1685 #[derive(Diagnostic)]
1686 #[diag(parse_no_digits_literal, code = "E0768")]
1687 pub struct NoDigitsLiteral {
1688     #[primary_span]
1689     pub span: Span,
1690 }
1691
1692 #[derive(Diagnostic)]
1693 #[diag(parse_invalid_digit_literal)]
1694 pub struct InvalidDigitLiteral {
1695     #[primary_span]
1696     pub span: Span,
1697     pub base: u32,
1698 }
1699
1700 #[derive(Diagnostic)]
1701 #[diag(parse_empty_exponent_float)]
1702 pub struct EmptyExponentFloat {
1703     #[primary_span]
1704     pub span: Span,
1705 }
1706
1707 #[derive(Diagnostic)]
1708 #[diag(parse_float_literal_unsupported_base)]
1709 pub struct FloatLiteralUnsupportedBase {
1710     #[primary_span]
1711     pub span: Span,
1712     pub base: &'static str,
1713 }
1714
1715 #[derive(Diagnostic)]
1716 #[diag(parse_unknown_prefix)]
1717 #[note]
1718 pub struct UnknownPrefix<'a> {
1719     #[primary_span]
1720     #[label]
1721     pub span: Span,
1722     pub prefix: &'a str,
1723     #[subdiagnostic]
1724     pub sugg: Option<UnknownPrefixSugg>,
1725 }
1726
1727 #[derive(Subdiagnostic)]
1728 pub enum UnknownPrefixSugg {
1729     #[suggestion(suggestion_br, code = "br", applicability = "maybe-incorrect", style = "verbose")]
1730     UseBr(#[primary_span] Span),
1731     #[suggestion(
1732         suggestion_whitespace,
1733         code = " ",
1734         applicability = "maybe-incorrect",
1735         style = "verbose"
1736     )]
1737     Whitespace(#[primary_span] Span),
1738 }
1739
1740 #[derive(Diagnostic)]
1741 #[diag(parse_too_many_hashes)]
1742 pub struct TooManyHashes {
1743     #[primary_span]
1744     pub span: Span,
1745     pub num: u32,
1746 }
1747
1748 #[derive(Diagnostic)]
1749 #[diag(parse_unknown_start_of_token)]
1750 pub struct UnknownTokenStart {
1751     #[primary_span]
1752     pub span: Span,
1753     pub escaped: String,
1754     #[subdiagnostic]
1755     pub sugg: Option<TokenSubstitution>,
1756     #[subdiagnostic]
1757     pub null: Option<UnknownTokenNull>,
1758     #[subdiagnostic]
1759     pub repeat: Option<UnknownTokenRepeat>,
1760 }
1761
1762 #[derive(Subdiagnostic)]
1763 pub enum TokenSubstitution {
1764     #[suggestion(sugg_quotes, code = "{suggestion}", applicability = "maybe-incorrect")]
1765     DirectedQuotes {
1766         #[primary_span]
1767         span: Span,
1768         suggestion: String,
1769         ascii_str: &'static str,
1770         ascii_name: &'static str,
1771     },
1772     #[suggestion(sugg_other, code = "{suggestion}", applicability = "maybe-incorrect")]
1773     Other {
1774         #[primary_span]
1775         span: Span,
1776         suggestion: String,
1777         ch: String,
1778         u_name: &'static str,
1779         ascii_str: &'static str,
1780         ascii_name: &'static str,
1781     },
1782 }
1783
1784 #[derive(Subdiagnostic)]
1785 #[note(note_repeats)]
1786 pub struct UnknownTokenRepeat {
1787     pub repeats: usize,
1788 }
1789
1790 #[derive(Subdiagnostic)]
1791 #[help(help_null)]
1792 pub struct UnknownTokenNull;
1793
1794 #[derive(Diagnostic)]
1795 pub enum UnescapeError {
1796     #[diag(parse_invalid_unicode_escape)]
1797     #[help]
1798     InvalidUnicodeEscape {
1799         #[primary_span]
1800         #[label]
1801         span: Span,
1802         surrogate: bool,
1803     },
1804     #[diag(parse_escape_only_char)]
1805     EscapeOnlyChar {
1806         #[primary_span]
1807         span: Span,
1808         #[suggestion(escape, applicability = "machine-applicable", code = "{escaped_sugg}")]
1809         char_span: Span,
1810         escaped_sugg: String,
1811         escaped_msg: String,
1812         byte: bool,
1813     },
1814     #[diag(parse_bare_cr)]
1815     BareCr {
1816         #[primary_span]
1817         #[suggestion(escape, applicability = "machine-applicable", code = "\\r")]
1818         span: Span,
1819         double_quotes: bool,
1820     },
1821     #[diag(parse_bare_cr_in_raw_string)]
1822     BareCrRawString(#[primary_span] Span),
1823     #[diag(parse_too_short_hex_escape)]
1824     TooShortHexEscape(#[primary_span] Span),
1825     #[diag(parse_invalid_char_in_escape)]
1826     InvalidCharInEscape {
1827         #[primary_span]
1828         #[label]
1829         span: Span,
1830         is_hex: bool,
1831         ch: String,
1832     },
1833     #[diag(parse_out_of_range_hex_escape)]
1834     OutOfRangeHexEscape(
1835         #[primary_span]
1836         #[label]
1837         Span,
1838     ),
1839     #[diag(parse_leading_underscore_unicode_escape)]
1840     LeadingUnderscoreUnicodeEscape {
1841         #[primary_span]
1842         #[label(parse_leading_underscore_unicode_escape_label)]
1843         span: Span,
1844         ch: String,
1845     },
1846     #[diag(parse_overlong_unicode_escape)]
1847     OverlongUnicodeEscape(
1848         #[primary_span]
1849         #[label]
1850         Span,
1851     ),
1852     #[diag(parse_unclosed_unicode_escape)]
1853     UnclosedUnicodeEscape(
1854         #[primary_span]
1855         #[label]
1856         Span,
1857         #[suggestion(terminate, code = "}}", applicability = "maybe-incorrect", style = "verbose")]
1858         Span,
1859     ),
1860     #[diag(parse_no_brace_unicode_escape)]
1861     NoBraceInUnicodeEscape {
1862         #[primary_span]
1863         span: Span,
1864         #[label]
1865         label: Option<Span>,
1866         #[subdiagnostic]
1867         sub: NoBraceUnicodeSub,
1868     },
1869     #[diag(parse_unicode_escape_in_byte)]
1870     #[help]
1871     UnicodeEscapeInByte(
1872         #[primary_span]
1873         #[label]
1874         Span,
1875     ),
1876     #[diag(parse_empty_unicode_escape)]
1877     EmptyUnicodeEscape(
1878         #[primary_span]
1879         #[label]
1880         Span,
1881     ),
1882     #[diag(parse_zero_chars)]
1883     ZeroChars(
1884         #[primary_span]
1885         #[label]
1886         Span,
1887     ),
1888     #[diag(parse_lone_slash)]
1889     LoneSlash(
1890         #[primary_span]
1891         #[label]
1892         Span,
1893     ),
1894     #[diag(parse_unskipped_whitespace)]
1895     UnskippedWhitespace {
1896         #[primary_span]
1897         span: Span,
1898         #[label]
1899         char_span: Span,
1900         ch: String,
1901     },
1902     #[diag(parse_multiple_skipped_lines)]
1903     MultipleSkippedLinesWarning(
1904         #[primary_span]
1905         #[label]
1906         Span,
1907     ),
1908     #[diag(parse_more_than_one_char)]
1909     MoreThanOneChar {
1910         #[primary_span]
1911         span: Span,
1912         #[subdiagnostic]
1913         note: Option<MoreThanOneCharNote>,
1914         #[subdiagnostic]
1915         suggestion: MoreThanOneCharSugg,
1916     },
1917 }
1918
1919 #[derive(Subdiagnostic)]
1920 pub enum MoreThanOneCharSugg {
1921     #[suggestion(consider_normalized, code = "{normalized}", applicability = "machine-applicable")]
1922     NormalizedForm {
1923         #[primary_span]
1924         span: Span,
1925         ch: String,
1926         normalized: String,
1927     },
1928     #[suggestion(remove_non, code = "{ch}", applicability = "maybe-incorrect")]
1929     RemoveNonPrinting {
1930         #[primary_span]
1931         span: Span,
1932         ch: String,
1933     },
1934     #[suggestion(use_double_quotes, code = "{sugg}", applicability = "machine-applicable")]
1935     Quotes {
1936         #[primary_span]
1937         span: Span,
1938         is_byte: bool,
1939         sugg: String,
1940     },
1941 }
1942
1943 #[derive(Subdiagnostic)]
1944 pub enum MoreThanOneCharNote {
1945     #[note(followed_by)]
1946     AllCombining {
1947         #[primary_span]
1948         span: Span,
1949         chr: String,
1950         len: usize,
1951         escaped_marks: String,
1952     },
1953     #[note(non_printing)]
1954     NonPrinting {
1955         #[primary_span]
1956         span: Span,
1957         escaped: String,
1958     },
1959 }
1960
1961 #[derive(Subdiagnostic)]
1962 pub enum NoBraceUnicodeSub {
1963     #[suggestion(use_braces, code = "{suggestion}", applicability = "maybe-incorrect")]
1964     Suggestion {
1965         #[primary_span]
1966         span: Span,
1967         suggestion: String,
1968     },
1969     #[help(format_of_unicode)]
1970     Help,
1971 }
1972
1973 #[derive(Subdiagnostic)]
1974 pub(crate) enum TopLevelOrPatternNotAllowedSugg {
1975     #[suggestion(
1976         parse_sugg_remove_leading_vert_in_pattern,
1977         code = "{pat}",
1978         applicability = "machine-applicable"
1979     )]
1980     RemoveLeadingVert {
1981         #[primary_span]
1982         span: Span,
1983         pat: String,
1984     },
1985     #[suggestion(
1986         parse_sugg_wrap_pattern_in_parens,
1987         code = "({pat})",
1988         applicability = "machine-applicable"
1989     )]
1990     WrapInParens {
1991         #[primary_span]
1992         span: Span,
1993         pat: String,
1994     },
1995 }
1996
1997 #[derive(Diagnostic)]
1998 #[diag(parse_unexpected_vert_vert_before_function_parameter)]
1999 #[note(parse_note_pattern_alternatives_use_single_vert)]
2000 pub(crate) struct UnexpectedVertVertBeforeFunctionParam {
2001     #[primary_span]
2002     #[suggestion(code = "", applicability = "machine-applicable")]
2003     pub span: Span,
2004 }
2005
2006 #[derive(Diagnostic)]
2007 #[diag(parse_unexpected_vert_vert_in_pattern)]
2008 pub(crate) struct UnexpectedVertVertInPattern {
2009     #[primary_span]
2010     #[suggestion(code = "|", applicability = "machine-applicable")]
2011     pub span: Span,
2012     #[label(parse_label_while_parsing_or_pattern_here)]
2013     pub start: Option<Span>,
2014 }
2015
2016 #[derive(Diagnostic)]
2017 #[diag(parse_trailing_vert_not_allowed)]
2018 pub(crate) struct TrailingVertNotAllowed {
2019     #[primary_span]
2020     #[suggestion(code = "", applicability = "machine-applicable")]
2021     pub span: Span,
2022     #[label(parse_label_while_parsing_or_pattern_here)]
2023     pub start: Option<Span>,
2024     pub token: Token,
2025     #[note(parse_note_pattern_alternatives_use_single_vert)]
2026     pub note_double_vert: Option<()>,
2027 }
2028
2029 #[derive(Diagnostic)]
2030 #[diag(parse_dotdotdot_rest_pattern)]
2031 pub(crate) struct DotDotDotRestPattern {
2032     #[primary_span]
2033     #[suggestion(style = "short", code = "..", applicability = "machine-applicable")]
2034     #[label]
2035     pub span: Span,
2036 }
2037
2038 #[derive(Diagnostic)]
2039 #[diag(parse_pattern_on_wrong_side_of_at)]
2040 pub(crate) struct PatternOnWrongSideOfAt {
2041     #[primary_span]
2042     #[suggestion(code = "{whole_pat}", applicability = "machine-applicable")]
2043     pub whole_span: Span,
2044     pub whole_pat: String,
2045     #[label(label_pattern)]
2046     pub pattern: Span,
2047     #[label(label_binding)]
2048     pub binding: Span,
2049 }
2050
2051 #[derive(Diagnostic)]
2052 #[diag(parse_expected_binding_left_of_at)]
2053 #[note]
2054 pub(crate) struct ExpectedBindingLeftOfAt {
2055     #[primary_span]
2056     pub whole_span: Span,
2057     #[label(label_lhs)]
2058     pub lhs: Span,
2059     #[label(label_rhs)]
2060     pub rhs: Span,
2061 }
2062
2063 #[derive(Diagnostic)]
2064 #[diag(parse_ambiguous_range_pattern)]
2065 pub(crate) struct AmbiguousRangePattern {
2066     #[primary_span]
2067     #[suggestion(code = "({pat})", applicability = "maybe-incorrect")]
2068     pub span: Span,
2069     pub pat: String,
2070 }
2071
2072 #[derive(Diagnostic)]
2073 #[diag(parse_unexpected_lifetime_in_pattern)]
2074 pub(crate) struct UnexpectedLifetimeInPattern {
2075     #[primary_span]
2076     #[suggestion(code = "", applicability = "machine-applicable")]
2077     pub span: Span,
2078     pub symbol: Symbol,
2079 }
2080
2081 #[derive(Diagnostic)]
2082 #[diag(parse_ref_mut_order_incorrect)]
2083 pub(crate) struct RefMutOrderIncorrect {
2084     #[primary_span]
2085     #[suggestion(code = "ref mut", applicability = "machine-applicable")]
2086     pub span: Span,
2087 }
2088
2089 #[derive(Diagnostic)]
2090 pub(crate) enum InvalidMutInPattern {
2091     #[diag(parse_mut_on_nested_ident_pattern)]
2092     #[note(parse_note_mut_pattern_usage)]
2093     NestedIdent {
2094         #[primary_span]
2095         #[suggestion(code = "{pat}", applicability = "machine-applicable")]
2096         span: Span,
2097         pat: String,
2098     },
2099     #[diag(parse_mut_on_non_ident_pattern)]
2100     #[note(parse_note_mut_pattern_usage)]
2101     NonIdent {
2102         #[primary_span]
2103         #[suggestion(code = "{pat}", applicability = "machine-applicable")]
2104         span: Span,
2105         pat: String,
2106     },
2107 }
2108
2109 #[derive(Diagnostic)]
2110 #[diag(parse_repeated_mut_in_pattern)]
2111 pub(crate) struct RepeatedMutInPattern {
2112     #[primary_span]
2113     #[suggestion(code = "", applicability = "machine-applicable")]
2114     pub span: Span,
2115 }
2116
2117 #[derive(Diagnostic)]
2118 #[diag(parse_dot_dot_dot_range_to_pattern_not_allowed)]
2119 pub(crate) struct DotDotDotRangeToPatternNotAllowed {
2120     #[primary_span]
2121     #[suggestion(style = "short", code = "..=", applicability = "machine-applicable")]
2122     pub span: Span,
2123 }
2124
2125 #[derive(Diagnostic)]
2126 #[diag(parse_enum_pattern_instead_of_identifier)]
2127 pub(crate) struct EnumPatternInsteadOfIdentifier {
2128     #[primary_span]
2129     pub span: Span,
2130 }
2131
2132 #[derive(Diagnostic)]
2133 #[diag(parse_dot_dot_dot_for_remaining_fields)]
2134 pub(crate) struct DotDotDotForRemainingFields {
2135     #[primary_span]
2136     #[suggestion(code = "..", style = "verbose", applicability = "machine-applicable")]
2137     pub span: Span,
2138     pub token_str: Cow<'static, str>,
2139 }
2140
2141 #[derive(Diagnostic)]
2142 #[diag(parse_expected_comma_after_pattern_field)]
2143 pub(crate) struct ExpectedCommaAfterPatternField {
2144     #[primary_span]
2145     pub span: Span,
2146 }
2147
2148 #[derive(Diagnostic)]
2149 #[diag(parse_return_types_use_thin_arrow)]
2150 pub(crate) struct ReturnTypesUseThinArrow {
2151     #[primary_span]
2152     #[suggestion(style = "short", code = "->", applicability = "machine-applicable")]
2153     pub span: Span,
2154 }
2155
2156 #[derive(Diagnostic)]
2157 #[diag(parse_need_plus_after_trait_object_lifetime)]
2158 pub(crate) struct NeedPlusAfterTraitObjectLifetime {
2159     #[primary_span]
2160     pub span: Span,
2161 }
2162
2163 #[derive(Diagnostic)]
2164 #[diag(parse_expected_mut_or_const_in_raw_pointer_type)]
2165 pub(crate) struct ExpectedMutOrConstInRawPointerType {
2166     #[primary_span]
2167     pub span: Span,
2168     #[suggestion(code("mut ", "const "), applicability = "has-placeholders")]
2169     pub after_asterisk: Span,
2170 }
2171
2172 #[derive(Diagnostic)]
2173 #[diag(parse_lifetime_after_mut)]
2174 pub(crate) struct LifetimeAfterMut {
2175     #[primary_span]
2176     pub span: Span,
2177     #[suggestion(code = "&{snippet} mut", applicability = "maybe-incorrect")]
2178     pub suggest_lifetime: Option<Span>,
2179     pub snippet: String,
2180 }
2181
2182 #[derive(Diagnostic)]
2183 #[diag(parse_dyn_after_mut)]
2184 pub(crate) struct DynAfterMut {
2185     #[primary_span]
2186     #[suggestion(code = "&mut dyn", applicability = "machine-applicable")]
2187     pub span: Span,
2188 }
2189
2190 #[derive(Diagnostic)]
2191 #[diag(parse_fn_pointer_cannot_be_const)]
2192 pub(crate) struct FnPointerCannotBeConst {
2193     #[primary_span]
2194     pub span: Span,
2195     #[suggestion(code = "", applicability = "maybe-incorrect")]
2196     #[label]
2197     pub qualifier: Span,
2198 }
2199
2200 #[derive(Diagnostic)]
2201 #[diag(parse_fn_pointer_cannot_be_async)]
2202 pub(crate) struct FnPointerCannotBeAsync {
2203     #[primary_span]
2204     pub span: Span,
2205     #[suggestion(code = "", applicability = "maybe-incorrect")]
2206     #[label]
2207     pub qualifier: Span,
2208 }
2209
2210 #[derive(Diagnostic)]
2211 #[diag(parse_nested_c_variadic_type, code = "E0743")]
2212 pub(crate) struct NestedCVariadicType {
2213     #[primary_span]
2214     pub span: Span,
2215 }
2216
2217 #[derive(Diagnostic)]
2218 #[diag(parse_invalid_dyn_keyword)]
2219 #[help]
2220 pub(crate) struct InvalidDynKeyword {
2221     #[primary_span]
2222     #[suggestion(code = "", applicability = "machine-applicable")]
2223     pub span: Span,
2224 }
2225
2226 #[derive(Diagnostic)]
2227 #[diag(parse_negative_bounds_not_supported)]
2228 pub(crate) struct NegativeBoundsNotSupported {
2229     #[primary_span]
2230     pub negative_bounds: Vec<Span>,
2231     #[label]
2232     pub last_span: Span,
2233     #[subdiagnostic]
2234     pub sub: Option<NegativeBoundsNotSupportedSugg>,
2235 }
2236
2237 #[derive(Subdiagnostic)]
2238 #[suggestion(
2239     suggestion,
2240     style = "tool-only",
2241     code = "{fixed}",
2242     applicability = "machine-applicable"
2243 )]
2244 pub(crate) struct NegativeBoundsNotSupportedSugg {
2245     #[primary_span]
2246     pub bound_list: Span,
2247     pub num_bounds: usize,
2248     pub fixed: String,
2249 }
2250
2251 #[derive(Subdiagnostic)]
2252 pub enum HelpUseLatestEdition {
2253     #[help(parse_help_set_edition_cargo)]
2254     #[note(parse_note_edition_guide)]
2255     Cargo { edition: Edition },
2256     #[help(parse_help_set_edition_standalone)]
2257     #[note(parse_note_edition_guide)]
2258     Standalone { edition: Edition },
2259 }
2260
2261 impl HelpUseLatestEdition {
2262     pub fn new() -> Self {
2263         let edition = LATEST_STABLE_EDITION;
2264         if std::env::var_os("CARGO").is_some() {
2265             Self::Cargo { edition }
2266         } else {
2267             Self::Standalone { edition }
2268         }
2269     }
2270 }