rustc_parse/
errors.rs

1// ignore-tidy-filelength
2
3use std::borrow::Cow;
4use std::path::PathBuf;
5
6use rustc_ast::token::Token;
7use rustc_ast::util::parser::ExprPrecedence;
8use rustc_ast::{Path, Visibility};
9use rustc_errors::codes::*;
10use rustc_errors::{
11    Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg,
12    Level, Subdiagnostic, SuggestionStyle,
13};
14use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
15use rustc_session::errors::ExprParenthesesNeeded;
16use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
17use rustc_span::{Ident, Span, Symbol};
18
19use crate::fluent_generated as fluent;
20use crate::parser::{ForbiddenLetReason, TokenDescription};
21
22#[derive(Diagnostic)]
23#[diag(parse_maybe_report_ambiguous_plus)]
24pub(crate) struct AmbiguousPlus {
25    #[primary_span]
26    pub span: Span,
27    #[subdiagnostic]
28    pub suggestion: AddParen,
29}
30
31#[derive(Diagnostic)]
32#[diag(parse_maybe_recover_from_bad_type_plus, code = E0178)]
33pub(crate) struct BadTypePlus {
34    #[primary_span]
35    pub span: Span,
36    #[subdiagnostic]
37    pub sub: BadTypePlusSub,
38}
39
40#[derive(Subdiagnostic)]
41#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")]
42pub(crate) struct AddParen {
43    #[suggestion_part(code = "(")]
44    pub lo: Span,
45    #[suggestion_part(code = ")")]
46    pub hi: Span,
47}
48
49#[derive(Subdiagnostic)]
50pub(crate) enum BadTypePlusSub {
51    AddParen {
52        #[subdiagnostic]
53        suggestion: AddParen,
54    },
55    #[label(parse_forgot_paren)]
56    ForgotParen {
57        #[primary_span]
58        span: Span,
59    },
60    #[label(parse_expect_path)]
61    ExpectPath {
62        #[primary_span]
63        span: Span,
64    },
65}
66
67#[derive(Diagnostic)]
68#[diag(parse_maybe_recover_from_bad_qpath_stage_2)]
69pub(crate) struct BadQPathStage2 {
70    #[primary_span]
71    pub span: Span,
72    #[subdiagnostic]
73    pub wrap: WrapType,
74}
75
76#[derive(Diagnostic)]
77#[diag(parse_trait_impl_modifier_in_inherent_impl)]
78#[note]
79pub(crate) struct TraitImplModifierInInherentImpl {
80    #[primary_span]
81    pub span: Span,
82    pub modifier: &'static str,
83    pub modifier_name: &'static str,
84    #[label(parse_because)]
85    pub modifier_span: Span,
86    #[label(parse_type)]
87    pub self_ty: Span,
88}
89
90#[derive(Subdiagnostic)]
91#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
92pub(crate) struct WrapType {
93    #[suggestion_part(code = "<")]
94    pub lo: Span,
95    #[suggestion_part(code = ">")]
96    pub hi: Span,
97}
98
99#[derive(Diagnostic)]
100#[diag(parse_incorrect_semicolon)]
101pub(crate) struct IncorrectSemicolon<'a> {
102    #[primary_span]
103    #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
104    pub span: Span,
105    #[help]
106    pub show_help: bool,
107    pub name: &'a str,
108}
109
110#[derive(Diagnostic)]
111#[diag(parse_incorrect_use_of_await)]
112pub(crate) struct IncorrectUseOfAwait {
113    #[primary_span]
114    #[suggestion(
115        parse_parentheses_suggestion,
116        style = "verbose",
117        code = "",
118        applicability = "machine-applicable"
119    )]
120    pub span: Span,
121}
122
123#[derive(Diagnostic)]
124#[diag(parse_incorrect_use_of_use)]
125pub(crate) struct IncorrectUseOfUse {
126    #[primary_span]
127    #[suggestion(
128        parse_parentheses_suggestion,
129        style = "verbose",
130        code = "",
131        applicability = "machine-applicable"
132    )]
133    pub span: Span,
134}
135
136#[derive(Subdiagnostic)]
137#[multipart_suggestion(
138    parse_incorrect_use_of_await_postfix_suggestion,
139    applicability = "machine-applicable"
140)]
141pub(crate) struct AwaitSuggestion {
142    #[suggestion_part(code = "")]
143    pub removal: Span,
144    #[suggestion_part(code = ".await{question_mark}")]
145    pub dot_await: Span,
146    pub question_mark: &'static str,
147}
148
149#[derive(Diagnostic)]
150#[diag(parse_incorrect_use_of_await)]
151pub(crate) struct IncorrectAwait {
152    #[primary_span]
153    pub span: Span,
154    #[subdiagnostic]
155    pub suggestion: AwaitSuggestion,
156}
157
158#[derive(Diagnostic)]
159#[diag(parse_in_in_typo)]
160pub(crate) struct InInTypo {
161    #[primary_span]
162    pub span: Span,
163    #[suggestion(code = "", style = "verbose", applicability = "machine-applicable")]
164    pub sugg_span: Span,
165}
166
167#[derive(Diagnostic)]
168#[diag(parse_invalid_variable_declaration)]
169pub(crate) struct InvalidVariableDeclaration {
170    #[primary_span]
171    pub span: Span,
172    #[subdiagnostic]
173    pub sub: InvalidVariableDeclarationSub,
174}
175
176#[derive(Subdiagnostic)]
177pub(crate) enum InvalidVariableDeclarationSub {
178    #[suggestion(
179        parse_switch_mut_let_order,
180        style = "verbose",
181        applicability = "maybe-incorrect",
182        code = "let mut"
183    )]
184    SwitchMutLetOrder(#[primary_span] Span),
185    #[suggestion(
186        parse_missing_let_before_mut,
187        applicability = "machine-applicable",
188        style = "verbose",
189        code = "let mut"
190    )]
191    MissingLet(#[primary_span] Span),
192    #[suggestion(
193        parse_use_let_not_auto,
194        style = "verbose",
195        applicability = "machine-applicable",
196        code = "let"
197    )]
198    UseLetNotAuto(#[primary_span] Span),
199    #[suggestion(
200        parse_use_let_not_var,
201        style = "verbose",
202        applicability = "machine-applicable",
203        code = "let"
204    )]
205    UseLetNotVar(#[primary_span] Span),
206}
207
208#[derive(Diagnostic)]
209#[diag(parse_switch_ref_box_order)]
210pub(crate) struct SwitchRefBoxOrder {
211    #[primary_span]
212    #[suggestion(applicability = "machine-applicable", style = "verbose", code = "box ref")]
213    pub span: Span,
214}
215
216#[derive(Diagnostic)]
217#[diag(parse_invalid_comparison_operator)]
218pub(crate) struct InvalidComparisonOperator {
219    #[primary_span]
220    pub span: Span,
221    pub invalid: String,
222    #[subdiagnostic]
223    pub sub: InvalidComparisonOperatorSub,
224}
225
226#[derive(Subdiagnostic)]
227pub(crate) enum InvalidComparisonOperatorSub {
228    #[suggestion(
229        parse_use_instead,
230        style = "verbose",
231        applicability = "machine-applicable",
232        code = "{correct}"
233    )]
234    Correctable {
235        #[primary_span]
236        span: Span,
237        invalid: String,
238        correct: String,
239    },
240    #[label(parse_spaceship_operator_invalid)]
241    Spaceship(#[primary_span] Span),
242}
243
244#[derive(Diagnostic)]
245#[diag(parse_invalid_logical_operator)]
246#[note]
247pub(crate) struct InvalidLogicalOperator {
248    #[primary_span]
249    pub span: Span,
250    pub incorrect: String,
251    #[subdiagnostic]
252    pub sub: InvalidLogicalOperatorSub,
253}
254
255#[derive(Subdiagnostic)]
256pub(crate) enum InvalidLogicalOperatorSub {
257    #[suggestion(
258        parse_use_amp_amp_for_conjunction,
259        style = "verbose",
260        applicability = "machine-applicable",
261        code = "&&"
262    )]
263    Conjunction(#[primary_span] Span),
264    #[suggestion(
265        parse_use_pipe_pipe_for_disjunction,
266        style = "verbose",
267        applicability = "machine-applicable",
268        code = "||"
269    )]
270    Disjunction(#[primary_span] Span),
271}
272
273#[derive(Diagnostic)]
274#[diag(parse_tilde_is_not_unary_operator)]
275pub(crate) struct TildeAsUnaryOperator(
276    #[primary_span]
277    #[suggestion(style = "verbose", applicability = "machine-applicable", code = "!")]
278    pub Span,
279);
280
281#[derive(Diagnostic)]
282#[diag(parse_unexpected_token_after_not)]
283pub(crate) struct NotAsNegationOperator {
284    #[primary_span]
285    pub negated: Span,
286    pub negated_desc: String,
287    #[subdiagnostic]
288    pub sub: NotAsNegationOperatorSub,
289}
290
291#[derive(Subdiagnostic)]
292pub(crate) enum NotAsNegationOperatorSub {
293    #[suggestion(
294        parse_unexpected_token_after_not_default,
295        style = "verbose",
296        applicability = "machine-applicable",
297        code = "!"
298    )]
299    SuggestNotDefault(#[primary_span] Span),
300
301    #[suggestion(
302        parse_unexpected_token_after_not_bitwise,
303        style = "verbose",
304        applicability = "machine-applicable",
305        code = "!"
306    )]
307    SuggestNotBitwise(#[primary_span] Span),
308
309    #[suggestion(
310        parse_unexpected_token_after_not_logical,
311        style = "verbose",
312        applicability = "machine-applicable",
313        code = "!"
314    )]
315    SuggestNotLogical(#[primary_span] Span),
316}
317
318#[derive(Diagnostic)]
319#[diag(parse_malformed_loop_label)]
320pub(crate) struct MalformedLoopLabel {
321    #[primary_span]
322    pub span: Span,
323    #[suggestion(applicability = "machine-applicable", code = "'", style = "verbose")]
324    pub suggestion: Span,
325}
326
327#[derive(Diagnostic)]
328#[diag(parse_lifetime_in_borrow_expression)]
329pub(crate) struct LifetimeInBorrowExpression {
330    #[primary_span]
331    pub span: Span,
332    #[suggestion(applicability = "machine-applicable", code = "", style = "verbose")]
333    #[label]
334    pub lifetime_span: Span,
335}
336
337#[derive(Diagnostic)]
338#[diag(parse_field_expression_with_generic)]
339pub(crate) struct FieldExpressionWithGeneric(#[primary_span] pub Span);
340
341#[derive(Diagnostic)]
342#[diag(parse_macro_invocation_with_qualified_path)]
343pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span);
344
345#[derive(Diagnostic)]
346#[diag(parse_unexpected_token_after_label)]
347pub(crate) struct UnexpectedTokenAfterLabel {
348    #[primary_span]
349    #[label(parse_unexpected_token_after_label)]
350    pub span: Span,
351    #[suggestion(parse_suggestion_remove_label, style = "verbose", code = "")]
352    pub remove_label: Option<Span>,
353    #[subdiagnostic]
354    pub enclose_in_block: Option<UnexpectedTokenAfterLabelSugg>,
355}
356
357#[derive(Subdiagnostic)]
358#[multipart_suggestion(parse_suggestion_enclose_in_block, applicability = "machine-applicable")]
359pub(crate) struct UnexpectedTokenAfterLabelSugg {
360    #[suggestion_part(code = "{{ ")]
361    pub left: Span,
362    #[suggestion_part(code = " }}")]
363    pub right: Span,
364}
365
366#[derive(Diagnostic)]
367#[diag(parse_require_colon_after_labeled_expression)]
368#[note]
369pub(crate) struct RequireColonAfterLabeledExpression {
370    #[primary_span]
371    pub span: Span,
372    #[label]
373    pub label: Span,
374    #[suggestion(style = "verbose", applicability = "machine-applicable", code = ": ")]
375    pub label_end: Span,
376}
377
378#[derive(Diagnostic)]
379#[diag(parse_do_catch_syntax_removed)]
380#[note]
381pub(crate) struct DoCatchSyntaxRemoved {
382    #[primary_span]
383    #[suggestion(applicability = "machine-applicable", code = "try", style = "verbose")]
384    pub span: Span,
385}
386
387#[derive(Diagnostic)]
388#[diag(parse_float_literal_requires_integer_part)]
389pub(crate) struct FloatLiteralRequiresIntegerPart {
390    #[primary_span]
391    pub span: Span,
392    #[suggestion(applicability = "machine-applicable", code = "0", style = "verbose")]
393    pub suggestion: Span,
394}
395
396#[derive(Diagnostic)]
397#[diag(parse_missing_semicolon_before_array)]
398pub(crate) struct MissingSemicolonBeforeArray {
399    #[primary_span]
400    pub open_delim: Span,
401    #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = ";")]
402    pub semicolon: Span,
403}
404
405#[derive(Diagnostic)]
406#[diag(parse_expect_dotdot_not_dotdotdot)]
407pub(crate) struct MissingDotDot {
408    #[primary_span]
409    pub token_span: Span,
410    #[suggestion(applicability = "maybe-incorrect", code = "..", style = "verbose")]
411    pub sugg_span: Span,
412}
413
414#[derive(Diagnostic)]
415#[diag(parse_invalid_block_macro_segment)]
416pub(crate) struct InvalidBlockMacroSegment {
417    #[primary_span]
418    pub span: Span,
419    #[label]
420    pub context: Span,
421    #[subdiagnostic]
422    pub wrap: WrapInExplicitBlock,
423}
424
425#[derive(Subdiagnostic)]
426#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
427pub(crate) struct WrapInExplicitBlock {
428    #[suggestion_part(code = "{{ ")]
429    pub lo: Span,
430    #[suggestion_part(code = " }}")]
431    pub hi: Span,
432}
433
434#[derive(Diagnostic)]
435#[diag(parse_if_expression_missing_then_block)]
436pub(crate) struct IfExpressionMissingThenBlock {
437    #[primary_span]
438    pub if_span: Span,
439    #[subdiagnostic]
440    pub missing_then_block_sub: IfExpressionMissingThenBlockSub,
441    #[subdiagnostic]
442    pub let_else_sub: Option<IfExpressionLetSomeSub>,
443}
444
445#[derive(Subdiagnostic)]
446pub(crate) enum IfExpressionMissingThenBlockSub {
447    #[help(parse_condition_possibly_unfinished)]
448    UnfinishedCondition(#[primary_span] Span),
449    #[help(parse_add_then_block)]
450    AddThenBlock(#[primary_span] Span),
451}
452
453#[derive(Diagnostic)]
454#[diag(parse_ternary_operator)]
455pub(crate) struct TernaryOperator {
456    #[primary_span]
457    pub span: Span,
458    /// If we have a span for the condition expression, suggest the if/else
459    #[subdiagnostic]
460    pub sugg: Option<TernaryOperatorSuggestion>,
461    /// Otherwise, just print the suggestion message
462    #[help(parse_use_if_else)]
463    pub no_sugg: bool,
464}
465
466#[derive(Subdiagnostic, Copy, Clone)]
467#[multipart_suggestion(parse_use_if_else, applicability = "maybe-incorrect", style = "verbose")]
468pub(crate) struct TernaryOperatorSuggestion {
469    #[suggestion_part(code = "if ")]
470    pub before_cond: Span,
471    #[suggestion_part(code = "{{")]
472    pub question: Span,
473    #[suggestion_part(code = "}} else {{")]
474    pub colon: Span,
475    #[suggestion_part(code = " }}")]
476    pub end: Span,
477}
478
479#[derive(Subdiagnostic)]
480#[suggestion(
481    parse_extra_if_in_let_else,
482    applicability = "maybe-incorrect",
483    code = "",
484    style = "verbose"
485)]
486pub(crate) struct IfExpressionLetSomeSub {
487    #[primary_span]
488    pub if_span: Span,
489}
490
491#[derive(Diagnostic)]
492#[diag(parse_if_expression_missing_condition)]
493pub(crate) struct IfExpressionMissingCondition {
494    #[primary_span]
495    #[label(parse_condition_label)]
496    pub if_span: Span,
497    #[label(parse_block_label)]
498    pub block_span: Span,
499}
500
501#[derive(Diagnostic)]
502#[diag(parse_expected_expression_found_let)]
503#[note]
504pub(crate) struct ExpectedExpressionFoundLet {
505    #[primary_span]
506    pub span: Span,
507    #[subdiagnostic]
508    pub reason: ForbiddenLetReason,
509    #[subdiagnostic]
510    pub missing_let: Option<MaybeMissingLet>,
511    #[subdiagnostic]
512    pub comparison: Option<MaybeComparison>,
513}
514
515#[derive(Diagnostic)]
516#[diag(parse_or_in_let_chain)]
517pub(crate) struct OrInLetChain {
518    #[primary_span]
519    pub span: Span,
520}
521
522#[derive(Subdiagnostic, Clone, Copy)]
523#[multipart_suggestion(
524    parse_maybe_missing_let,
525    applicability = "maybe-incorrect",
526    style = "verbose"
527)]
528pub(crate) struct MaybeMissingLet {
529    #[suggestion_part(code = "let ")]
530    pub span: Span,
531}
532
533#[derive(Subdiagnostic, Clone, Copy)]
534#[multipart_suggestion(
535    parse_maybe_comparison,
536    applicability = "maybe-incorrect",
537    style = "verbose"
538)]
539pub(crate) struct MaybeComparison {
540    #[suggestion_part(code = "=")]
541    pub span: Span,
542}
543
544#[derive(Diagnostic)]
545#[diag(parse_expect_eq_instead_of_eqeq)]
546pub(crate) struct ExpectedEqForLetExpr {
547    #[primary_span]
548    pub span: Span,
549    #[suggestion(applicability = "maybe-incorrect", code = "=", style = "verbose")]
550    pub sugg_span: Span,
551}
552
553#[derive(Diagnostic)]
554#[diag(parse_expected_else_block)]
555pub(crate) struct ExpectedElseBlock {
556    #[primary_span]
557    pub first_tok_span: Span,
558    pub first_tok: String,
559    #[label]
560    pub else_span: Span,
561    #[suggestion(applicability = "maybe-incorrect", code = "if ", style = "verbose")]
562    pub condition_start: Span,
563}
564
565#[derive(Diagnostic)]
566#[diag(parse_expected_struct_field)]
567pub(crate) struct ExpectedStructField {
568    #[primary_span]
569    #[label]
570    pub span: Span,
571    pub token: Token,
572    #[label(parse_ident_label)]
573    pub ident_span: Span,
574}
575
576#[derive(Diagnostic)]
577#[diag(parse_outer_attribute_not_allowed_on_if_else)]
578pub(crate) struct OuterAttributeNotAllowedOnIfElse {
579    #[primary_span]
580    pub last: Span,
581
582    #[label(parse_branch_label)]
583    pub branch_span: Span,
584
585    #[label(parse_ctx_label)]
586    pub ctx_span: Span,
587    pub ctx: String,
588
589    #[suggestion(applicability = "machine-applicable", code = "", style = "verbose")]
590    pub attributes: Span,
591}
592
593#[derive(Diagnostic)]
594#[diag(parse_missing_in_in_for_loop)]
595pub(crate) struct MissingInInForLoop {
596    #[primary_span]
597    pub span: Span,
598    #[subdiagnostic]
599    pub sub: MissingInInForLoopSub,
600}
601
602#[derive(Subdiagnostic)]
603pub(crate) enum MissingInInForLoopSub {
604    // User wrote `for pat of expr {}`
605    // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect
606    #[suggestion(parse_use_in, style = "verbose", applicability = "maybe-incorrect", code = "in")]
607    InNotOf(#[primary_span] Span),
608    // User wrote `for pat = expr {}`
609    #[suggestion(parse_use_in, style = "verbose", applicability = "maybe-incorrect", code = "in")]
610    InNotEq(#[primary_span] Span),
611    #[suggestion(parse_add_in, style = "verbose", applicability = "maybe-incorrect", code = " in ")]
612    AddIn(#[primary_span] Span),
613}
614
615#[derive(Diagnostic)]
616#[diag(parse_missing_expression_in_for_loop)]
617pub(crate) struct MissingExpressionInForLoop {
618    #[primary_span]
619    #[suggestion(
620        code = "/* expression */ ",
621        applicability = "has-placeholders",
622        style = "verbose"
623    )]
624    pub span: Span,
625}
626
627#[derive(Diagnostic)]
628#[diag(parse_loop_else)]
629#[note]
630pub(crate) struct LoopElseNotSupported {
631    #[primary_span]
632    pub span: Span,
633    pub loop_kind: &'static str,
634    #[label(parse_loop_keyword)]
635    pub loop_kw: Span,
636}
637
638#[derive(Diagnostic)]
639#[diag(parse_missing_comma_after_match_arm)]
640pub(crate) struct MissingCommaAfterMatchArm {
641    #[primary_span]
642    #[suggestion(applicability = "machine-applicable", code = ",", style = "verbose")]
643    pub span: Span,
644}
645
646#[derive(Diagnostic)]
647#[diag(parse_catch_after_try)]
648#[help]
649pub(crate) struct CatchAfterTry {
650    #[primary_span]
651    pub span: Span,
652}
653
654#[derive(Diagnostic)]
655#[diag(parse_comma_after_base_struct)]
656#[note]
657pub(crate) struct CommaAfterBaseStruct {
658    #[primary_span]
659    pub span: Span,
660    #[suggestion(style = "verbose", applicability = "machine-applicable", code = "")]
661    pub comma: Span,
662}
663
664#[derive(Diagnostic)]
665#[diag(parse_eq_field_init)]
666pub(crate) struct EqFieldInit {
667    #[primary_span]
668    pub span: Span,
669    #[suggestion(applicability = "machine-applicable", code = ":", style = "verbose")]
670    pub eq: Span,
671}
672
673#[derive(Diagnostic)]
674#[diag(parse_dotdotdot)]
675pub(crate) struct DotDotDot {
676    #[primary_span]
677    #[suggestion(
678        parse_suggest_exclusive_range,
679        applicability = "maybe-incorrect",
680        code = "..",
681        style = "verbose"
682    )]
683    #[suggestion(
684        parse_suggest_inclusive_range,
685        applicability = "maybe-incorrect",
686        code = "..=",
687        style = "verbose"
688    )]
689    pub span: Span,
690}
691
692#[derive(Diagnostic)]
693#[diag(parse_left_arrow_operator)]
694pub(crate) struct LeftArrowOperator {
695    #[primary_span]
696    #[suggestion(applicability = "maybe-incorrect", code = "< -", style = "verbose")]
697    pub span: Span,
698}
699
700#[derive(Diagnostic)]
701#[diag(parse_remove_let)]
702pub(crate) struct RemoveLet {
703    #[primary_span]
704    pub span: Span,
705    #[suggestion(applicability = "machine-applicable", code = "", style = "verbose")]
706    pub suggestion: Span,
707}
708
709#[derive(Diagnostic)]
710#[diag(parse_use_eq_instead)]
711pub(crate) struct UseEqInstead {
712    #[primary_span]
713    #[suggestion(style = "verbose", applicability = "machine-applicable", code = "=")]
714    pub span: Span,
715}
716
717#[derive(Diagnostic)]
718#[diag(parse_use_empty_block_not_semi)]
719pub(crate) struct UseEmptyBlockNotSemi {
720    #[primary_span]
721    #[suggestion(style = "hidden", applicability = "machine-applicable", code = "{{}}")]
722    pub span: Span,
723}
724
725#[derive(Diagnostic)]
726#[diag(parse_comparison_interpreted_as_generic)]
727pub(crate) struct ComparisonInterpretedAsGeneric {
728    #[primary_span]
729    #[label(parse_label_comparison)]
730    pub comparison: Span,
731    pub r#type: Path,
732    #[label(parse_label_args)]
733    pub args: Span,
734    #[subdiagnostic]
735    pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
736}
737
738#[derive(Diagnostic)]
739#[diag(parse_shift_interpreted_as_generic)]
740pub(crate) struct ShiftInterpretedAsGeneric {
741    #[primary_span]
742    #[label(parse_label_comparison)]
743    pub shift: Span,
744    pub r#type: Path,
745    #[label(parse_label_args)]
746    pub args: Span,
747    #[subdiagnostic]
748    pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
749}
750
751#[derive(Subdiagnostic)]
752#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
753pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
754    #[suggestion_part(code = "(")]
755    pub left: Span,
756    #[suggestion_part(code = ")")]
757    pub right: Span,
758}
759
760#[derive(Diagnostic)]
761#[diag(parse_found_expr_would_be_stmt)]
762pub(crate) struct FoundExprWouldBeStmt {
763    #[primary_span]
764    #[label]
765    pub span: Span,
766    pub token: Token,
767    #[subdiagnostic]
768    pub suggestion: ExprParenthesesNeeded,
769}
770
771#[derive(Diagnostic)]
772#[diag(parse_frontmatter_extra_characters_after_close)]
773pub(crate) struct FrontmatterExtraCharactersAfterClose {
774    #[primary_span]
775    pub span: Span,
776}
777
778#[derive(Diagnostic)]
779#[diag(parse_frontmatter_invalid_infostring)]
780#[note]
781pub(crate) struct FrontmatterInvalidInfostring {
782    #[primary_span]
783    pub span: Span,
784}
785
786#[derive(Diagnostic)]
787#[diag(parse_frontmatter_invalid_opening_preceding_whitespace)]
788pub(crate) struct FrontmatterInvalidOpeningPrecedingWhitespace {
789    #[primary_span]
790    pub span: Span,
791    #[note]
792    pub note_span: Span,
793}
794
795#[derive(Diagnostic)]
796#[diag(parse_frontmatter_unclosed)]
797pub(crate) struct FrontmatterUnclosed {
798    #[primary_span]
799    pub span: Span,
800    #[note]
801    pub note_span: Span,
802}
803
804#[derive(Diagnostic)]
805#[diag(parse_frontmatter_invalid_close_preceding_whitespace)]
806pub(crate) struct FrontmatterInvalidClosingPrecedingWhitespace {
807    #[primary_span]
808    pub span: Span,
809    #[note]
810    pub note_span: Span,
811}
812
813#[derive(Diagnostic)]
814#[diag(parse_frontmatter_length_mismatch)]
815pub(crate) struct FrontmatterLengthMismatch {
816    #[primary_span]
817    pub span: Span,
818    #[label(parse_label_opening)]
819    pub opening: Span,
820    #[label(parse_label_close)]
821    pub close: Span,
822    pub len_opening: usize,
823    pub len_close: usize,
824}
825
826#[derive(Diagnostic)]
827#[diag(parse_frontmatter_too_many_dashes)]
828pub(crate) struct FrontmatterTooManyDashes {
829    pub len_opening: usize,
830}
831
832#[derive(Diagnostic)]
833#[diag(parse_leading_plus_not_supported)]
834pub(crate) struct LeadingPlusNotSupported {
835    #[primary_span]
836    #[label]
837    pub span: Span,
838    #[suggestion(
839        parse_suggestion_remove_plus,
840        style = "verbose",
841        code = "",
842        applicability = "machine-applicable"
843    )]
844    pub remove_plus: Option<Span>,
845    #[subdiagnostic]
846    pub add_parentheses: Option<ExprParenthesesNeeded>,
847}
848
849#[derive(Diagnostic)]
850#[diag(parse_parentheses_with_struct_fields)]
851pub(crate) struct ParenthesesWithStructFields {
852    #[primary_span]
853    pub span: Span,
854    pub r#type: Path,
855    #[subdiagnostic]
856    pub braces_for_struct: BracesForStructLiteral,
857    #[subdiagnostic]
858    pub no_fields_for_fn: NoFieldsForFnCall,
859}
860
861#[derive(Subdiagnostic)]
862#[multipart_suggestion(parse_suggestion_braces_for_struct, applicability = "maybe-incorrect")]
863pub(crate) struct BracesForStructLiteral {
864    #[suggestion_part(code = " {{ ")]
865    pub first: Span,
866    #[suggestion_part(code = " }}")]
867    pub second: Span,
868}
869
870#[derive(Subdiagnostic)]
871#[multipart_suggestion(parse_suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
872pub(crate) struct NoFieldsForFnCall {
873    #[suggestion_part(code = "")]
874    pub fields: Vec<Span>,
875}
876
877#[derive(Diagnostic)]
878#[diag(parse_labeled_loop_in_break)]
879pub(crate) struct LabeledLoopInBreak {
880    #[primary_span]
881    pub span: Span,
882    #[subdiagnostic]
883    pub sub: WrapInParentheses,
884}
885
886#[derive(Subdiagnostic)]
887pub(crate) enum WrapInParentheses {
888    #[multipart_suggestion(
889        parse_sugg_wrap_expression_in_parentheses,
890        applicability = "machine-applicable"
891    )]
892    Expression {
893        #[suggestion_part(code = "(")]
894        left: Span,
895        #[suggestion_part(code = ")")]
896        right: Span,
897    },
898    #[multipart_suggestion(
899        parse_sugg_wrap_macro_in_parentheses,
900        applicability = "machine-applicable"
901    )]
902    MacroArgs {
903        #[suggestion_part(code = "(")]
904        left: Span,
905        #[suggestion_part(code = ")")]
906        right: Span,
907    },
908}
909
910#[derive(Diagnostic)]
911#[diag(parse_array_brackets_instead_of_braces)]
912pub(crate) struct ArrayBracketsInsteadOfBraces {
913    #[primary_span]
914    pub span: Span,
915    #[subdiagnostic]
916    pub sub: ArrayBracketsInsteadOfBracesSugg,
917}
918
919#[derive(Subdiagnostic)]
920#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")]
921pub(crate) struct ArrayBracketsInsteadOfBracesSugg {
922    #[suggestion_part(code = "[")]
923    pub left: Span,
924    #[suggestion_part(code = "]")]
925    pub right: Span,
926}
927
928#[derive(Diagnostic)]
929#[diag(parse_match_arm_body_without_braces)]
930pub(crate) struct MatchArmBodyWithoutBraces {
931    #[primary_span]
932    #[label(parse_label_statements)]
933    pub statements: Span,
934    #[label(parse_label_arrow)]
935    pub arrow: Span,
936    pub num_statements: usize,
937    #[subdiagnostic]
938    pub sub: MatchArmBodyWithoutBracesSugg,
939}
940
941#[derive(Diagnostic)]
942#[diag(parse_inclusive_range_extra_equals)]
943#[note]
944pub(crate) struct InclusiveRangeExtraEquals {
945    #[primary_span]
946    #[suggestion(
947        parse_suggestion_remove_eq,
948        style = "verbose",
949        code = "..=",
950        applicability = "maybe-incorrect"
951    )]
952    pub span: Span,
953}
954
955#[derive(Diagnostic)]
956#[diag(parse_inclusive_range_match_arrow)]
957pub(crate) struct InclusiveRangeMatchArrow {
958    #[primary_span]
959    pub arrow: Span,
960    #[label]
961    pub span: Span,
962    #[suggestion(style = "verbose", code = " ", applicability = "machine-applicable")]
963    pub after_pat: Span,
964}
965
966#[derive(Diagnostic)]
967#[diag(parse_inclusive_range_no_end, code = E0586)]
968#[note]
969pub(crate) struct InclusiveRangeNoEnd {
970    #[primary_span]
971    pub span: Span,
972    #[suggestion(
973        parse_suggestion_open_range,
974        code = "",
975        applicability = "machine-applicable",
976        style = "verbose"
977    )]
978    pub suggestion: Span,
979}
980
981#[derive(Subdiagnostic)]
982pub(crate) enum MatchArmBodyWithoutBracesSugg {
983    #[multipart_suggestion(parse_suggestion_add_braces, applicability = "machine-applicable")]
984    AddBraces {
985        #[suggestion_part(code = "{{ ")]
986        left: Span,
987        #[suggestion_part(code = " }}")]
988        right: Span,
989    },
990    #[suggestion(
991        parse_suggestion_use_comma_not_semicolon,
992        code = ",",
993        applicability = "machine-applicable",
994        style = "verbose"
995    )]
996    UseComma {
997        #[primary_span]
998        semicolon: Span,
999    },
1000}
1001
1002#[derive(Diagnostic)]
1003#[diag(parse_struct_literal_not_allowed_here)]
1004pub(crate) struct StructLiteralNotAllowedHere {
1005    #[primary_span]
1006    pub span: Span,
1007    #[subdiagnostic]
1008    pub sub: StructLiteralNotAllowedHereSugg,
1009}
1010
1011#[derive(Subdiagnostic)]
1012#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1013pub(crate) struct StructLiteralNotAllowedHereSugg {
1014    #[suggestion_part(code = "(")]
1015    pub left: Span,
1016    #[suggestion_part(code = ")")]
1017    pub right: Span,
1018}
1019
1020#[derive(Diagnostic)]
1021#[diag(parse_invalid_literal_suffix_on_tuple_index)]
1022pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
1023    #[primary_span]
1024    #[label]
1025    pub span: Span,
1026    pub suffix: Symbol,
1027}
1028
1029#[derive(Diagnostic)]
1030#[diag(parse_non_string_abi_literal)]
1031pub(crate) struct NonStringAbiLiteral {
1032    #[primary_span]
1033    #[suggestion(code = "\"C\"", applicability = "maybe-incorrect", style = "verbose")]
1034    pub span: Span,
1035}
1036
1037#[derive(Diagnostic)]
1038#[diag(parse_mismatched_closing_delimiter)]
1039pub(crate) struct MismatchedClosingDelimiter {
1040    #[primary_span]
1041    pub spans: Vec<Span>,
1042    pub delimiter: String,
1043    #[label(parse_label_unmatched)]
1044    pub unmatched: Span,
1045    #[label(parse_label_opening_candidate)]
1046    pub opening_candidate: Option<Span>,
1047    #[label(parse_label_unclosed)]
1048    pub unclosed: Option<Span>,
1049}
1050
1051#[derive(Diagnostic)]
1052#[diag(parse_incorrect_visibility_restriction, code = E0704)]
1053#[help]
1054pub(crate) struct IncorrectVisibilityRestriction {
1055    #[primary_span]
1056    #[suggestion(code = "in {inner_str}", applicability = "machine-applicable", style = "verbose")]
1057    pub span: Span,
1058    pub inner_str: String,
1059}
1060
1061#[derive(Diagnostic)]
1062#[diag(parse_assignment_else_not_allowed)]
1063pub(crate) struct AssignmentElseNotAllowed {
1064    #[primary_span]
1065    pub span: Span,
1066}
1067
1068#[derive(Diagnostic)]
1069#[diag(parse_expected_statement_after_outer_attr)]
1070pub(crate) struct ExpectedStatementAfterOuterAttr {
1071    #[primary_span]
1072    pub span: Span,
1073}
1074
1075#[derive(Diagnostic)]
1076#[diag(parse_doc_comment_does_not_document_anything, code = E0585)]
1077#[help]
1078pub(crate) struct DocCommentDoesNotDocumentAnything {
1079    #[primary_span]
1080    pub span: Span,
1081    #[suggestion(code = ",", applicability = "machine-applicable", style = "verbose")]
1082    pub missing_comma: Option<Span>,
1083}
1084
1085#[derive(Diagnostic)]
1086#[diag(parse_const_let_mutually_exclusive)]
1087pub(crate) struct ConstLetMutuallyExclusive {
1088    #[primary_span]
1089    #[suggestion(code = "const", applicability = "maybe-incorrect", style = "verbose")]
1090    pub span: Span,
1091}
1092
1093#[derive(Diagnostic)]
1094#[diag(parse_invalid_expression_in_let_else)]
1095pub(crate) struct InvalidExpressionInLetElse {
1096    #[primary_span]
1097    pub span: Span,
1098    pub operator: &'static str,
1099    #[subdiagnostic]
1100    pub sugg: WrapInParentheses,
1101}
1102
1103#[derive(Diagnostic)]
1104#[diag(parse_invalid_curly_in_let_else)]
1105pub(crate) struct InvalidCurlyInLetElse {
1106    #[primary_span]
1107    pub span: Span,
1108    #[subdiagnostic]
1109    pub sugg: WrapInParentheses,
1110}
1111
1112#[derive(Diagnostic)]
1113#[diag(parse_compound_assignment_expression_in_let)]
1114#[help]
1115pub(crate) struct CompoundAssignmentExpressionInLet {
1116    #[primary_span]
1117    pub span: Span,
1118    #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")]
1119    pub suggestion: Span,
1120}
1121
1122#[derive(Diagnostic)]
1123#[diag(parse_suffixed_literal_in_attribute)]
1124#[help]
1125pub(crate) struct SuffixedLiteralInAttribute {
1126    #[primary_span]
1127    pub span: Span,
1128}
1129
1130#[derive(Diagnostic)]
1131#[diag(parse_invalid_meta_item)]
1132pub(crate) struct InvalidMetaItem {
1133    #[primary_span]
1134    pub span: Span,
1135    pub descr: String,
1136    #[subdiagnostic]
1137    pub quote_ident_sugg: Option<InvalidMetaItemQuoteIdentSugg>,
1138}
1139
1140#[derive(Subdiagnostic)]
1141#[multipart_suggestion(parse_quote_ident_sugg, applicability = "machine-applicable")]
1142pub(crate) struct InvalidMetaItemQuoteIdentSugg {
1143    #[suggestion_part(code = "\"")]
1144    pub before: Span,
1145    #[suggestion_part(code = "\"")]
1146    pub after: Span,
1147}
1148
1149#[derive(Subdiagnostic)]
1150#[suggestion(
1151    parse_sugg_escape_identifier,
1152    style = "verbose",
1153    applicability = "maybe-incorrect",
1154    code = "r#"
1155)]
1156pub(crate) struct SuggEscapeIdentifier {
1157    #[primary_span]
1158    pub span: Span,
1159    pub ident_name: String,
1160}
1161
1162#[derive(Subdiagnostic)]
1163#[suggestion(
1164    parse_sugg_remove_comma,
1165    applicability = "machine-applicable",
1166    code = "",
1167    style = "verbose"
1168)]
1169pub(crate) struct SuggRemoveComma {
1170    #[primary_span]
1171    pub span: Span,
1172}
1173
1174#[derive(Subdiagnostic)]
1175#[suggestion(
1176    parse_sugg_add_let_for_stmt,
1177    style = "verbose",
1178    applicability = "maybe-incorrect",
1179    code = "let "
1180)]
1181pub(crate) struct SuggAddMissingLetStmt {
1182    #[primary_span]
1183    pub span: Span,
1184}
1185
1186#[derive(Subdiagnostic)]
1187pub(crate) enum ExpectedIdentifierFound {
1188    #[label(parse_expected_identifier_found_reserved_identifier)]
1189    ReservedIdentifier(#[primary_span] Span),
1190    #[label(parse_expected_identifier_found_keyword)]
1191    Keyword(#[primary_span] Span),
1192    #[label(parse_expected_identifier_found_reserved_keyword)]
1193    ReservedKeyword(#[primary_span] Span),
1194    #[label(parse_expected_identifier_found_doc_comment)]
1195    DocComment(#[primary_span] Span),
1196    #[label(parse_expected_identifier_found_metavar)]
1197    MetaVar(#[primary_span] Span),
1198    #[label(parse_expected_identifier)]
1199    Other(#[primary_span] Span),
1200}
1201
1202impl ExpectedIdentifierFound {
1203    pub(crate) fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
1204        (match token_descr {
1205            Some(TokenDescription::ReservedIdentifier) => {
1206                ExpectedIdentifierFound::ReservedIdentifier
1207            }
1208            Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword,
1209            Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
1210            Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment,
1211            Some(TokenDescription::MetaVar(_)) => ExpectedIdentifierFound::MetaVar,
1212            None => ExpectedIdentifierFound::Other,
1213        })(span)
1214    }
1215}
1216
1217pub(crate) struct ExpectedIdentifier {
1218    pub span: Span,
1219    pub token: Token,
1220    pub suggest_raw: Option<SuggEscapeIdentifier>,
1221    pub suggest_remove_comma: Option<SuggRemoveComma>,
1222    pub help_cannot_start_number: Option<HelpIdentifierStartsWithNumber>,
1223}
1224
1225impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedIdentifier {
1226    #[track_caller]
1227    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
1228        let token_descr = TokenDescription::from_token(&self.token);
1229
1230        let mut add_token = true;
1231        let mut diag = Diag::new(
1232            dcx,
1233            level,
1234            match token_descr {
1235                Some(TokenDescription::ReservedIdentifier) => {
1236                    fluent::parse_expected_identifier_found_reserved_identifier_str
1237                }
1238                Some(TokenDescription::Keyword) => {
1239                    fluent::parse_expected_identifier_found_keyword_str
1240                }
1241                Some(TokenDescription::ReservedKeyword) => {
1242                    fluent::parse_expected_identifier_found_reserved_keyword_str
1243                }
1244                Some(TokenDescription::DocComment) => {
1245                    fluent::parse_expected_identifier_found_doc_comment_str
1246                }
1247                Some(TokenDescription::MetaVar(_)) => {
1248                    add_token = false;
1249                    fluent::parse_expected_identifier_found_metavar_str
1250                }
1251                None => fluent::parse_expected_identifier_found_str,
1252            },
1253        );
1254        diag.span(self.span);
1255        if add_token {
1256            diag.arg("token", self.token);
1257        }
1258
1259        if let Some(sugg) = self.suggest_raw {
1260            sugg.add_to_diag(&mut diag);
1261        }
1262
1263        ExpectedIdentifierFound::new(token_descr, self.span).add_to_diag(&mut diag);
1264
1265        if let Some(sugg) = self.suggest_remove_comma {
1266            sugg.add_to_diag(&mut diag);
1267        }
1268
1269        if let Some(help) = self.help_cannot_start_number {
1270            help.add_to_diag(&mut diag);
1271        }
1272
1273        diag
1274    }
1275}
1276
1277#[derive(Subdiagnostic)]
1278#[help(parse_invalid_identifier_with_leading_number)]
1279pub(crate) struct HelpIdentifierStartsWithNumber {
1280    #[primary_span]
1281    pub num_span: Span,
1282}
1283
1284pub(crate) struct ExpectedSemi {
1285    pub span: Span,
1286    pub token: Token,
1287
1288    pub unexpected_token_label: Option<Span>,
1289    pub sugg: ExpectedSemiSugg,
1290}
1291
1292impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedSemi {
1293    #[track_caller]
1294    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
1295        let token_descr = TokenDescription::from_token(&self.token);
1296
1297        let mut add_token = true;
1298        let mut diag = Diag::new(
1299            dcx,
1300            level,
1301            match token_descr {
1302                Some(TokenDescription::ReservedIdentifier) => {
1303                    fluent::parse_expected_semi_found_reserved_identifier_str
1304                }
1305                Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str,
1306                Some(TokenDescription::ReservedKeyword) => {
1307                    fluent::parse_expected_semi_found_reserved_keyword_str
1308                }
1309                Some(TokenDescription::DocComment) => {
1310                    fluent::parse_expected_semi_found_doc_comment_str
1311                }
1312                Some(TokenDescription::MetaVar(_)) => {
1313                    add_token = false;
1314                    fluent::parse_expected_semi_found_metavar_str
1315                }
1316                None => fluent::parse_expected_semi_found_str,
1317            },
1318        );
1319        diag.span(self.span);
1320        if add_token {
1321            diag.arg("token", self.token);
1322        }
1323
1324        if let Some(unexpected_token_label) = self.unexpected_token_label {
1325            diag.span_label(unexpected_token_label, fluent::parse_label_unexpected_token);
1326        }
1327
1328        self.sugg.add_to_diag(&mut diag);
1329
1330        diag
1331    }
1332}
1333
1334#[derive(Subdiagnostic)]
1335pub(crate) enum ExpectedSemiSugg {
1336    #[suggestion(
1337        parse_sugg_change_this_to_semi,
1338        code = ";",
1339        applicability = "machine-applicable",
1340        style = "short"
1341    )]
1342    ChangeToSemi(#[primary_span] Span),
1343    #[suggestion(
1344        parse_sugg_add_semi,
1345        code = ";",
1346        applicability = "machine-applicable",
1347        style = "short"
1348    )]
1349    AddSemi(#[primary_span] Span),
1350}
1351
1352#[derive(Diagnostic)]
1353#[diag(parse_struct_literal_body_without_path)]
1354pub(crate) struct StructLiteralBodyWithoutPath {
1355    #[primary_span]
1356    pub span: Span,
1357    #[subdiagnostic]
1358    pub sugg: StructLiteralBodyWithoutPathSugg,
1359}
1360
1361#[derive(Subdiagnostic)]
1362#[multipart_suggestion(parse_suggestion, applicability = "has-placeholders")]
1363pub(crate) struct StructLiteralBodyWithoutPathSugg {
1364    #[suggestion_part(code = "{{ SomeStruct ")]
1365    pub before: Span,
1366    #[suggestion_part(code = " }}")]
1367    pub after: Span,
1368}
1369
1370#[derive(Diagnostic)]
1371#[diag(parse_unmatched_angle_brackets)]
1372pub(crate) struct UnmatchedAngleBrackets {
1373    #[primary_span]
1374    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
1375    pub span: Span,
1376    pub num_extra_brackets: usize,
1377}
1378
1379#[derive(Diagnostic)]
1380#[diag(parse_generic_parameters_without_angle_brackets)]
1381pub(crate) struct GenericParamsWithoutAngleBrackets {
1382    #[primary_span]
1383    pub span: Span,
1384    #[subdiagnostic]
1385    pub sugg: GenericParamsWithoutAngleBracketsSugg,
1386}
1387
1388#[derive(Subdiagnostic)]
1389#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1390pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
1391    #[suggestion_part(code = "<")]
1392    pub left: Span,
1393    #[suggestion_part(code = ">")]
1394    pub right: Span,
1395}
1396
1397#[derive(Diagnostic)]
1398#[diag(parse_comparison_operators_cannot_be_chained)]
1399pub(crate) struct ComparisonOperatorsCannotBeChained {
1400    #[primary_span]
1401    pub span: Vec<Span>,
1402    #[suggestion(
1403        parse_sugg_turbofish_syntax,
1404        style = "verbose",
1405        code = "::",
1406        applicability = "maybe-incorrect"
1407    )]
1408    pub suggest_turbofish: Option<Span>,
1409    #[help(parse_sugg_turbofish_syntax)]
1410    #[help(parse_sugg_parentheses_for_function_args)]
1411    pub help_turbofish: bool,
1412    #[subdiagnostic]
1413    pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
1414}
1415
1416#[derive(Subdiagnostic)]
1417pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
1418    #[suggestion(
1419        parse_sugg_split_comparison,
1420        style = "verbose",
1421        code = " && {middle_term}",
1422        applicability = "maybe-incorrect"
1423    )]
1424    SplitComparison {
1425        #[primary_span]
1426        span: Span,
1427        middle_term: String,
1428    },
1429    #[multipart_suggestion(parse_sugg_parenthesize, applicability = "maybe-incorrect")]
1430    Parenthesize {
1431        #[suggestion_part(code = "(")]
1432        left: Span,
1433        #[suggestion_part(code = ")")]
1434        right: Span,
1435    },
1436}
1437
1438#[derive(Diagnostic)]
1439#[diag(parse_question_mark_in_type)]
1440pub(crate) struct QuestionMarkInType {
1441    #[primary_span]
1442    #[label]
1443    pub span: Span,
1444    #[subdiagnostic]
1445    pub sugg: QuestionMarkInTypeSugg,
1446}
1447
1448#[derive(Subdiagnostic)]
1449#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1450pub(crate) struct QuestionMarkInTypeSugg {
1451    #[suggestion_part(code = "Option<")]
1452    pub left: Span,
1453    #[suggestion_part(code = ">")]
1454    pub right: Span,
1455}
1456
1457#[derive(Diagnostic)]
1458#[diag(parse_unexpected_parentheses_in_for_head)]
1459pub(crate) struct ParenthesesInForHead {
1460    #[primary_span]
1461    pub span: Vec<Span>,
1462    #[subdiagnostic]
1463    pub sugg: ParenthesesInForHeadSugg,
1464}
1465
1466#[derive(Subdiagnostic)]
1467#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1468pub(crate) struct ParenthesesInForHeadSugg {
1469    #[suggestion_part(code = " ")]
1470    pub left: Span,
1471    #[suggestion_part(code = " ")]
1472    pub right: Span,
1473}
1474
1475#[derive(Diagnostic)]
1476#[diag(parse_unexpected_parentheses_in_match_arm_pattern)]
1477pub(crate) struct ParenthesesInMatchPat {
1478    #[primary_span]
1479    pub span: Vec<Span>,
1480    #[subdiagnostic]
1481    pub sugg: ParenthesesInMatchPatSugg,
1482}
1483
1484#[derive(Subdiagnostic)]
1485#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1486pub(crate) struct ParenthesesInMatchPatSugg {
1487    #[suggestion_part(code = "")]
1488    pub left: Span,
1489    #[suggestion_part(code = "")]
1490    pub right: Span,
1491}
1492
1493#[derive(Diagnostic)]
1494#[diag(parse_doc_comment_on_param_type)]
1495pub(crate) struct DocCommentOnParamType {
1496    #[primary_span]
1497    #[label]
1498    pub span: Span,
1499}
1500
1501#[derive(Diagnostic)]
1502#[diag(parse_attribute_on_param_type)]
1503pub(crate) struct AttributeOnParamType {
1504    #[primary_span]
1505    #[label]
1506    pub span: Span,
1507}
1508
1509#[derive(Diagnostic)]
1510#[diag(parse_attribute_on_type)]
1511pub(crate) struct AttributeOnType {
1512    #[primary_span]
1513    #[label]
1514    pub span: Span,
1515    #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
1516    pub fix_span: Span,
1517}
1518
1519#[derive(Diagnostic)]
1520#[diag(parse_attribute_on_generic_arg)]
1521pub(crate) struct AttributeOnGenericArg {
1522    #[primary_span]
1523    #[label]
1524    pub span: Span,
1525    #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
1526    pub fix_span: Span,
1527}
1528
1529#[derive(Diagnostic)]
1530#[diag(parse_attribute_on_empty_type)]
1531pub(crate) struct AttributeOnEmptyType {
1532    #[primary_span]
1533    #[label]
1534    pub span: Span,
1535}
1536
1537#[derive(Diagnostic)]
1538#[diag(parse_pattern_method_param_without_body, code = E0642)]
1539pub(crate) struct PatternMethodParamWithoutBody {
1540    #[primary_span]
1541    #[suggestion(code = "_", applicability = "machine-applicable", style = "verbose")]
1542    pub span: Span,
1543}
1544
1545#[derive(Diagnostic)]
1546#[diag(parse_self_param_not_first)]
1547pub(crate) struct SelfParamNotFirst {
1548    #[primary_span]
1549    #[label]
1550    pub span: Span,
1551}
1552
1553#[derive(Diagnostic)]
1554#[diag(parse_const_generic_without_braces)]
1555pub(crate) struct ConstGenericWithoutBraces {
1556    #[primary_span]
1557    pub span: Span,
1558    #[subdiagnostic]
1559    pub sugg: ConstGenericWithoutBracesSugg,
1560}
1561
1562#[derive(Subdiagnostic)]
1563#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1564pub(crate) struct ConstGenericWithoutBracesSugg {
1565    #[suggestion_part(code = "{{ ")]
1566    pub left: Span,
1567    #[suggestion_part(code = " }}")]
1568    pub right: Span,
1569}
1570
1571#[derive(Diagnostic)]
1572#[diag(parse_unexpected_const_param_declaration)]
1573pub(crate) struct UnexpectedConstParamDeclaration {
1574    #[primary_span]
1575    #[label]
1576    pub span: Span,
1577    #[subdiagnostic]
1578    pub sugg: Option<UnexpectedConstParamDeclarationSugg>,
1579}
1580
1581#[derive(Subdiagnostic)]
1582pub(crate) enum UnexpectedConstParamDeclarationSugg {
1583    #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1584    AddParam {
1585        #[suggestion_part(code = "<{snippet}>")]
1586        impl_generics: Span,
1587        #[suggestion_part(code = "{ident}")]
1588        incorrect_decl: Span,
1589        snippet: String,
1590        ident: String,
1591    },
1592    #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1593    AppendParam {
1594        #[suggestion_part(code = ", {snippet}")]
1595        impl_generics_end: Span,
1596        #[suggestion_part(code = "{ident}")]
1597        incorrect_decl: Span,
1598        snippet: String,
1599        ident: String,
1600    },
1601}
1602
1603#[derive(Diagnostic)]
1604#[diag(parse_unexpected_const_in_generic_param)]
1605pub(crate) struct UnexpectedConstInGenericParam {
1606    #[primary_span]
1607    pub span: Span,
1608    #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")]
1609    pub to_remove: Option<Span>,
1610}
1611
1612#[derive(Diagnostic)]
1613#[diag(parse_async_move_order_incorrect)]
1614pub(crate) struct AsyncMoveOrderIncorrect {
1615    #[primary_span]
1616    #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")]
1617    pub span: Span,
1618}
1619
1620#[derive(Diagnostic)]
1621#[diag(parse_async_use_order_incorrect)]
1622pub(crate) struct AsyncUseOrderIncorrect {
1623    #[primary_span]
1624    #[suggestion(style = "verbose", code = "async use", applicability = "maybe-incorrect")]
1625    pub span: Span,
1626}
1627
1628#[derive(Diagnostic)]
1629#[diag(parse_double_colon_in_bound)]
1630pub(crate) struct DoubleColonInBound {
1631    #[primary_span]
1632    pub span: Span,
1633    #[suggestion(code = ": ", applicability = "machine-applicable", style = "verbose")]
1634    pub between: Span,
1635}
1636
1637#[derive(Diagnostic)]
1638#[diag(parse_fn_ptr_with_generics)]
1639pub(crate) struct FnPtrWithGenerics {
1640    #[primary_span]
1641    pub span: Span,
1642    #[subdiagnostic]
1643    pub sugg: Option<FnPtrWithGenericsSugg>,
1644}
1645
1646#[derive(Subdiagnostic)]
1647#[multipart_suggestion(
1648    parse_misplaced_return_type,
1649    style = "verbose",
1650    applicability = "maybe-incorrect"
1651)]
1652pub(crate) struct MisplacedReturnType {
1653    #[suggestion_part(code = " {snippet}")]
1654    pub fn_params_end: Span,
1655    pub snippet: String,
1656    #[suggestion_part(code = "")]
1657    pub ret_ty_span: Span,
1658}
1659
1660#[derive(Subdiagnostic)]
1661#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")]
1662pub(crate) struct FnPtrWithGenericsSugg {
1663    #[suggestion_part(code = "{snippet}")]
1664    pub left: Span,
1665    pub snippet: String,
1666    #[suggestion_part(code = "")]
1667    pub right: Span,
1668    pub arity: usize,
1669    pub for_param_list_exists: bool,
1670}
1671
1672pub(crate) struct FnTraitMissingParen {
1673    pub span: Span,
1674}
1675
1676impl Subdiagnostic for FnTraitMissingParen {
1677    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1678        diag.span_label(self.span, crate::fluent_generated::parse_fn_trait_missing_paren);
1679        diag.span_suggestion_short(
1680            self.span.shrink_to_hi(),
1681            crate::fluent_generated::parse_add_paren,
1682            "()",
1683            Applicability::MachineApplicable,
1684        );
1685    }
1686}
1687
1688#[derive(Diagnostic)]
1689#[diag(parse_unexpected_if_with_if)]
1690pub(crate) struct UnexpectedIfWithIf(
1691    #[primary_span]
1692    #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
1693    pub Span,
1694);
1695
1696#[derive(Diagnostic)]
1697#[diag(parse_maybe_fn_typo_with_impl)]
1698pub(crate) struct FnTypoWithImpl {
1699    #[primary_span]
1700    #[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
1701    pub fn_span: Span,
1702}
1703
1704#[derive(Diagnostic)]
1705#[diag(parse_expected_fn_path_found_fn_keyword)]
1706pub(crate) struct ExpectedFnPathFoundFnKeyword {
1707    #[primary_span]
1708    #[suggestion(applicability = "machine-applicable", code = "Fn", style = "verbose")]
1709    pub fn_token_span: Span,
1710}
1711
1712#[derive(Diagnostic)]
1713#[diag(parse_path_found_named_params)]
1714pub(crate) struct FnPathFoundNamedParams {
1715    #[primary_span]
1716    #[suggestion(applicability = "machine-applicable", code = "")]
1717    pub named_param_span: Span,
1718}
1719
1720#[derive(Diagnostic)]
1721#[diag(parse_path_found_c_variadic_params)]
1722pub(crate) struct PathFoundCVariadicParams {
1723    #[primary_span]
1724    #[suggestion(applicability = "machine-applicable", code = "")]
1725    pub span: Span,
1726}
1727
1728#[derive(Diagnostic)]
1729#[diag(parse_path_found_attribute_in_params)]
1730pub(crate) struct PathFoundAttributeInParams {
1731    #[primary_span]
1732    #[suggestion(applicability = "machine-applicable", code = "")]
1733    pub span: Span,
1734}
1735
1736#[derive(Diagnostic)]
1737#[diag(parse_path_double_colon)]
1738pub(crate) struct PathSingleColon {
1739    #[primary_span]
1740    pub span: Span,
1741
1742    #[suggestion(applicability = "machine-applicable", code = ":", style = "verbose")]
1743    pub suggestion: Span,
1744}
1745
1746#[derive(Diagnostic)]
1747#[diag(parse_path_double_colon)]
1748pub(crate) struct PathTripleColon {
1749    #[primary_span]
1750    #[suggestion(applicability = "maybe-incorrect", code = "", style = "verbose")]
1751    pub span: Span,
1752}
1753
1754#[derive(Diagnostic)]
1755#[diag(parse_colon_as_semi)]
1756pub(crate) struct ColonAsSemi {
1757    #[primary_span]
1758    #[suggestion(applicability = "machine-applicable", code = ";", style = "verbose")]
1759    pub span: Span,
1760}
1761
1762#[derive(Diagnostic)]
1763#[diag(parse_where_clause_before_tuple_struct_body)]
1764pub(crate) struct WhereClauseBeforeTupleStructBody {
1765    #[primary_span]
1766    #[label]
1767    pub span: Span,
1768    #[label(parse_name_label)]
1769    pub name: Span,
1770    #[label(parse_body_label)]
1771    pub body: Span,
1772    #[subdiagnostic]
1773    pub sugg: Option<WhereClauseBeforeTupleStructBodySugg>,
1774}
1775
1776#[derive(Subdiagnostic)]
1777#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1778pub(crate) struct WhereClauseBeforeTupleStructBodySugg {
1779    #[suggestion_part(code = "{snippet}")]
1780    pub left: Span,
1781    pub snippet: String,
1782    #[suggestion_part(code = "")]
1783    pub right: Span,
1784}
1785
1786#[derive(Diagnostic)]
1787#[diag(parse_async_fn_in_2015, code = E0670)]
1788pub(crate) struct AsyncFnIn2015 {
1789    #[primary_span]
1790    #[label]
1791    pub span: Span,
1792    #[subdiagnostic]
1793    pub help: HelpUseLatestEdition,
1794}
1795
1796#[derive(Subdiagnostic)]
1797#[label(parse_async_block_in_2015)]
1798pub(crate) struct AsyncBlockIn2015 {
1799    #[primary_span]
1800    pub span: Span,
1801}
1802
1803#[derive(Diagnostic)]
1804#[diag(parse_async_move_block_in_2015)]
1805pub(crate) struct AsyncMoveBlockIn2015 {
1806    #[primary_span]
1807    pub span: Span,
1808}
1809
1810#[derive(Diagnostic)]
1811#[diag(parse_async_use_block_in_2015)]
1812pub(crate) struct AsyncUseBlockIn2015 {
1813    #[primary_span]
1814    pub span: Span,
1815}
1816
1817#[derive(Diagnostic)]
1818#[diag(parse_async_bound_modifier_in_2015)]
1819pub(crate) struct AsyncBoundModifierIn2015 {
1820    #[primary_span]
1821    pub span: Span,
1822    #[subdiagnostic]
1823    pub help: HelpUseLatestEdition,
1824}
1825
1826#[derive(Diagnostic)]
1827#[diag(parse_let_chain_pre_2024)]
1828pub(crate) struct LetChainPre2024 {
1829    #[primary_span]
1830    pub span: Span,
1831}
1832
1833#[derive(Diagnostic)]
1834#[diag(parse_self_argument_pointer)]
1835pub(crate) struct SelfArgumentPointer {
1836    #[primary_span]
1837    #[label]
1838    pub span: Span,
1839}
1840
1841#[derive(Diagnostic)]
1842#[diag(parse_unexpected_token_after_dot)]
1843pub(crate) struct UnexpectedTokenAfterDot {
1844    #[primary_span]
1845    pub span: Span,
1846    pub actual: String,
1847}
1848
1849#[derive(Diagnostic)]
1850#[diag(parse_visibility_not_followed_by_item)]
1851#[help]
1852pub(crate) struct VisibilityNotFollowedByItem {
1853    #[primary_span]
1854    #[label]
1855    pub span: Span,
1856    pub vis: Visibility,
1857}
1858
1859#[derive(Diagnostic)]
1860#[diag(parse_default_not_followed_by_item)]
1861#[note]
1862pub(crate) struct DefaultNotFollowedByItem {
1863    #[primary_span]
1864    #[label]
1865    pub span: Span,
1866}
1867
1868#[derive(Diagnostic)]
1869pub(crate) enum MissingKeywordForItemDefinition {
1870    #[diag(parse_missing_enum_for_enum_definition)]
1871    Enum {
1872        #[primary_span]
1873        span: Span,
1874        #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "enum ")]
1875        insert_span: Span,
1876        ident: Ident,
1877    },
1878    #[diag(parse_missing_enum_or_struct_for_item_definition)]
1879    EnumOrStruct {
1880        #[primary_span]
1881        span: Span,
1882    },
1883    #[diag(parse_missing_struct_for_struct_definition)]
1884    Struct {
1885        #[primary_span]
1886        span: Span,
1887        #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "struct ")]
1888        insert_span: Span,
1889        ident: Ident,
1890    },
1891    #[diag(parse_missing_fn_for_function_definition)]
1892    Function {
1893        #[primary_span]
1894        span: Span,
1895        #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "fn ")]
1896        insert_span: Span,
1897        ident: Ident,
1898    },
1899    #[diag(parse_missing_fn_for_method_definition)]
1900    Method {
1901        #[primary_span]
1902        span: Span,
1903        #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "fn ")]
1904        insert_span: Span,
1905        ident: Ident,
1906    },
1907    #[diag(parse_missing_fn_or_struct_for_item_definition)]
1908    Ambiguous {
1909        #[primary_span]
1910        span: Span,
1911        #[subdiagnostic]
1912        subdiag: Option<AmbiguousMissingKwForItemSub>,
1913    },
1914}
1915
1916#[derive(Subdiagnostic)]
1917pub(crate) enum AmbiguousMissingKwForItemSub {
1918    #[suggestion(
1919        parse_suggestion,
1920        applicability = "maybe-incorrect",
1921        code = "{snippet}!",
1922        style = "verbose"
1923    )]
1924    SuggestMacro {
1925        #[primary_span]
1926        span: Span,
1927        snippet: String,
1928    },
1929    #[help(parse_help)]
1930    HelpMacro,
1931}
1932
1933#[derive(Diagnostic)]
1934#[diag(parse_missing_fn_params)]
1935pub(crate) struct MissingFnParams {
1936    #[primary_span]
1937    #[suggestion(code = "()", applicability = "machine-applicable", style = "verbose")]
1938    pub span: Span,
1939}
1940
1941#[derive(Diagnostic)]
1942#[diag(parse_invalid_path_sep_in_fn_definition)]
1943pub(crate) struct InvalidPathSepInFnDefinition {
1944    #[primary_span]
1945    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
1946    pub span: Span,
1947}
1948
1949#[derive(Diagnostic)]
1950#[diag(parse_missing_trait_in_trait_impl)]
1951pub(crate) struct MissingTraitInTraitImpl {
1952    #[primary_span]
1953    #[suggestion(
1954        parse_suggestion_add_trait,
1955        code = " Trait ",
1956        applicability = "has-placeholders",
1957        style = "verbose"
1958    )]
1959    pub span: Span,
1960    #[suggestion(
1961        parse_suggestion_remove_for,
1962        code = "",
1963        applicability = "maybe-incorrect",
1964        style = "verbose"
1965    )]
1966    pub for_span: Span,
1967}
1968
1969#[derive(Diagnostic)]
1970#[diag(parse_missing_for_in_trait_impl)]
1971pub(crate) struct MissingForInTraitImpl {
1972    #[primary_span]
1973    #[suggestion(style = "verbose", code = " for ", applicability = "machine-applicable")]
1974    pub span: Span,
1975}
1976
1977#[derive(Diagnostic)]
1978#[diag(parse_expected_trait_in_trait_impl_found_type)]
1979pub(crate) struct ExpectedTraitInTraitImplFoundType {
1980    #[primary_span]
1981    pub span: Span,
1982}
1983
1984#[derive(Diagnostic)]
1985#[diag(parse_extra_impl_keyword_in_trait_impl)]
1986pub(crate) struct ExtraImplKeywordInTraitImpl {
1987    #[primary_span]
1988    #[suggestion(code = "", applicability = "maybe-incorrect", style = "short")]
1989    pub extra_impl_kw: Span,
1990    #[note]
1991    pub impl_trait_span: Span,
1992}
1993
1994#[derive(Diagnostic)]
1995#[diag(parse_bounds_not_allowed_on_trait_aliases)]
1996pub(crate) struct BoundsNotAllowedOnTraitAliases {
1997    #[primary_span]
1998    pub span: Span,
1999}
2000
2001#[derive(Diagnostic)]
2002#[diag(parse_trait_alias_cannot_be_auto)]
2003pub(crate) struct TraitAliasCannotBeAuto {
2004    #[primary_span]
2005    #[label(parse_trait_alias_cannot_be_auto)]
2006    pub span: Span,
2007}
2008
2009#[derive(Diagnostic)]
2010#[diag(parse_trait_alias_cannot_be_unsafe)]
2011pub(crate) struct TraitAliasCannotBeUnsafe {
2012    #[primary_span]
2013    #[label(parse_trait_alias_cannot_be_unsafe)]
2014    pub span: Span,
2015}
2016
2017#[derive(Diagnostic)]
2018#[diag(parse_associated_static_item_not_allowed)]
2019pub(crate) struct AssociatedStaticItemNotAllowed {
2020    #[primary_span]
2021    pub span: Span,
2022}
2023
2024#[derive(Diagnostic)]
2025#[diag(parse_extern_crate_name_with_dashes)]
2026pub(crate) struct ExternCrateNameWithDashes {
2027    #[primary_span]
2028    #[label]
2029    pub span: Span,
2030    #[subdiagnostic]
2031    pub sugg: ExternCrateNameWithDashesSugg,
2032}
2033
2034#[derive(Subdiagnostic)]
2035#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
2036pub(crate) struct ExternCrateNameWithDashesSugg {
2037    #[suggestion_part(code = "_")]
2038    pub dashes: Vec<Span>,
2039}
2040
2041#[derive(Diagnostic)]
2042#[diag(parse_extern_item_cannot_be_const)]
2043#[note]
2044pub(crate) struct ExternItemCannotBeConst {
2045    #[primary_span]
2046    pub ident_span: Span,
2047    #[suggestion(code = "static ", applicability = "machine-applicable", style = "verbose")]
2048    pub const_span: Option<Span>,
2049}
2050
2051#[derive(Diagnostic)]
2052#[diag(parse_const_global_cannot_be_mutable)]
2053pub(crate) struct ConstGlobalCannotBeMutable {
2054    #[primary_span]
2055    #[label]
2056    pub ident_span: Span,
2057    #[suggestion(code = "static", style = "verbose", applicability = "maybe-incorrect")]
2058    pub const_span: Span,
2059}
2060
2061#[derive(Diagnostic)]
2062#[diag(parse_missing_const_type)]
2063pub(crate) struct MissingConstType {
2064    #[primary_span]
2065    #[suggestion(code = "{colon} <type>", style = "verbose", applicability = "has-placeholders")]
2066    pub span: Span,
2067
2068    pub kind: &'static str,
2069    pub colon: &'static str,
2070}
2071
2072#[derive(Diagnostic)]
2073#[diag(parse_enum_struct_mutually_exclusive)]
2074pub(crate) struct EnumStructMutuallyExclusive {
2075    #[primary_span]
2076    #[suggestion(code = "enum", style = "verbose", applicability = "machine-applicable")]
2077    pub span: Span,
2078}
2079
2080#[derive(Diagnostic)]
2081pub(crate) enum UnexpectedTokenAfterStructName {
2082    #[diag(parse_unexpected_token_after_struct_name_found_reserved_identifier)]
2083    ReservedIdentifier {
2084        #[primary_span]
2085        #[label(parse_unexpected_token_after_struct_name)]
2086        span: Span,
2087        token: Token,
2088    },
2089    #[diag(parse_unexpected_token_after_struct_name_found_keyword)]
2090    Keyword {
2091        #[primary_span]
2092        #[label(parse_unexpected_token_after_struct_name)]
2093        span: Span,
2094        token: Token,
2095    },
2096    #[diag(parse_unexpected_token_after_struct_name_found_reserved_keyword)]
2097    ReservedKeyword {
2098        #[primary_span]
2099        #[label(parse_unexpected_token_after_struct_name)]
2100        span: Span,
2101        token: Token,
2102    },
2103    #[diag(parse_unexpected_token_after_struct_name_found_doc_comment)]
2104    DocComment {
2105        #[primary_span]
2106        #[label(parse_unexpected_token_after_struct_name)]
2107        span: Span,
2108        token: Token,
2109    },
2110    #[diag(parse_unexpected_token_after_struct_name_found_metavar)]
2111    MetaVar {
2112        #[primary_span]
2113        #[label(parse_unexpected_token_after_struct_name)]
2114        span: Span,
2115    },
2116    #[diag(parse_unexpected_token_after_struct_name_found_other)]
2117    Other {
2118        #[primary_span]
2119        #[label(parse_unexpected_token_after_struct_name)]
2120        span: Span,
2121        token: Token,
2122    },
2123}
2124
2125impl UnexpectedTokenAfterStructName {
2126    pub(crate) fn new(span: Span, token: Token) -> Self {
2127        match TokenDescription::from_token(&token) {
2128            Some(TokenDescription::ReservedIdentifier) => Self::ReservedIdentifier { span, token },
2129            Some(TokenDescription::Keyword) => Self::Keyword { span, token },
2130            Some(TokenDescription::ReservedKeyword) => Self::ReservedKeyword { span, token },
2131            Some(TokenDescription::DocComment) => Self::DocComment { span, token },
2132            Some(TokenDescription::MetaVar(_)) => Self::MetaVar { span },
2133            None => Self::Other { span, token },
2134        }
2135    }
2136}
2137
2138#[derive(Diagnostic)]
2139#[diag(parse_unexpected_self_in_generic_parameters)]
2140#[note]
2141pub(crate) struct UnexpectedSelfInGenericParameters {
2142    #[primary_span]
2143    pub span: Span,
2144}
2145
2146#[derive(Diagnostic)]
2147#[diag(parse_unexpected_default_value_for_lifetime_in_generic_parameters)]
2148pub(crate) struct UnexpectedDefaultValueForLifetimeInGenericParameters {
2149    #[primary_span]
2150    #[label]
2151    pub span: Span,
2152}
2153
2154#[derive(Diagnostic)]
2155#[diag(parse_multiple_where_clauses)]
2156pub(crate) struct MultipleWhereClauses {
2157    #[primary_span]
2158    pub span: Span,
2159    #[label]
2160    pub previous: Span,
2161    #[suggestion(style = "verbose", code = ",", applicability = "maybe-incorrect")]
2162    pub between: Span,
2163}
2164
2165#[derive(Diagnostic)]
2166pub(crate) enum UnexpectedNonterminal {
2167    #[diag(parse_nonterminal_expected_item_keyword)]
2168    Item(#[primary_span] Span),
2169    #[diag(parse_nonterminal_expected_statement)]
2170    Statement(#[primary_span] Span),
2171    #[diag(parse_nonterminal_expected_ident)]
2172    Ident {
2173        #[primary_span]
2174        span: Span,
2175        token: Token,
2176    },
2177    #[diag(parse_nonterminal_expected_lifetime)]
2178    Lifetime {
2179        #[primary_span]
2180        span: Span,
2181        token: Token,
2182    },
2183}
2184
2185#[derive(Diagnostic)]
2186pub(crate) enum TopLevelOrPatternNotAllowed {
2187    #[diag(parse_or_pattern_not_allowed_in_let_binding)]
2188    LetBinding {
2189        #[primary_span]
2190        span: Span,
2191        #[subdiagnostic]
2192        sub: Option<TopLevelOrPatternNotAllowedSugg>,
2193    },
2194    #[diag(parse_or_pattern_not_allowed_in_fn_parameters)]
2195    FunctionParameter {
2196        #[primary_span]
2197        span: Span,
2198        #[subdiagnostic]
2199        sub: Option<TopLevelOrPatternNotAllowedSugg>,
2200    },
2201}
2202
2203#[derive(Diagnostic)]
2204#[diag(parse_cannot_be_raw_ident)]
2205pub(crate) struct CannotBeRawIdent {
2206    #[primary_span]
2207    pub span: Span,
2208    pub ident: Symbol,
2209}
2210
2211#[derive(Diagnostic)]
2212#[diag(parse_cannot_be_raw_lifetime)]
2213pub(crate) struct CannotBeRawLifetime {
2214    #[primary_span]
2215    pub span: Span,
2216    pub ident: Symbol,
2217}
2218
2219#[derive(Diagnostic)]
2220#[diag(parse_keyword_lifetime)]
2221pub(crate) struct KeywordLifetime {
2222    #[primary_span]
2223    pub span: Span,
2224}
2225
2226#[derive(Diagnostic)]
2227#[diag(parse_keyword_label)]
2228pub(crate) struct KeywordLabel {
2229    #[primary_span]
2230    pub span: Span,
2231}
2232
2233#[derive(Diagnostic)]
2234#[diag(parse_cr_doc_comment)]
2235pub(crate) struct CrDocComment {
2236    #[primary_span]
2237    pub span: Span,
2238    pub block: bool,
2239}
2240
2241#[derive(Diagnostic)]
2242#[diag(parse_no_digits_literal, code = E0768)]
2243pub(crate) struct NoDigitsLiteral {
2244    #[primary_span]
2245    pub span: Span,
2246}
2247
2248#[derive(Diagnostic)]
2249#[diag(parse_invalid_digit_literal)]
2250pub(crate) struct InvalidDigitLiteral {
2251    #[primary_span]
2252    pub span: Span,
2253    pub base: u32,
2254}
2255
2256#[derive(Diagnostic)]
2257#[diag(parse_empty_exponent_float)]
2258pub(crate) struct EmptyExponentFloat {
2259    #[primary_span]
2260    pub span: Span,
2261}
2262
2263#[derive(Diagnostic)]
2264#[diag(parse_float_literal_unsupported_base)]
2265pub(crate) struct FloatLiteralUnsupportedBase {
2266    #[primary_span]
2267    pub span: Span,
2268    pub base: &'static str,
2269}
2270
2271#[derive(Diagnostic)]
2272#[diag(parse_unknown_prefix)]
2273#[note]
2274pub(crate) struct UnknownPrefix<'a> {
2275    #[primary_span]
2276    #[label]
2277    pub span: Span,
2278    pub prefix: &'a str,
2279    #[subdiagnostic]
2280    pub sugg: Option<UnknownPrefixSugg>,
2281}
2282
2283#[derive(Subdiagnostic)]
2284#[note(parse_macro_expands_to_adt_field)]
2285pub(crate) struct MacroExpandsToAdtField<'a> {
2286    pub adt_ty: &'a str,
2287}
2288
2289#[derive(Subdiagnostic)]
2290pub(crate) enum UnknownPrefixSugg {
2291    #[suggestion(
2292        parse_suggestion_br,
2293        code = "br",
2294        applicability = "maybe-incorrect",
2295        style = "verbose"
2296    )]
2297    UseBr(#[primary_span] Span),
2298    #[suggestion(
2299        parse_suggestion_cr,
2300        code = "cr",
2301        applicability = "maybe-incorrect",
2302        style = "verbose"
2303    )]
2304    UseCr(#[primary_span] Span),
2305    #[suggestion(
2306        parse_suggestion_whitespace,
2307        code = " ",
2308        applicability = "maybe-incorrect",
2309        style = "verbose"
2310    )]
2311    Whitespace(#[primary_span] Span),
2312    #[multipart_suggestion(
2313        parse_suggestion_str,
2314        applicability = "maybe-incorrect",
2315        style = "verbose"
2316    )]
2317    MeantStr {
2318        #[suggestion_part(code = "\"")]
2319        start: Span,
2320        #[suggestion_part(code = "\"")]
2321        end: Span,
2322    },
2323}
2324
2325#[derive(Diagnostic)]
2326#[diag(parse_reserved_multihash)]
2327#[note]
2328pub(crate) struct ReservedMultihash {
2329    #[primary_span]
2330    pub span: Span,
2331    #[subdiagnostic]
2332    pub sugg: Option<GuardedStringSugg>,
2333}
2334#[derive(Diagnostic)]
2335#[diag(parse_reserved_string)]
2336#[note]
2337pub(crate) struct ReservedString {
2338    #[primary_span]
2339    pub span: Span,
2340    #[subdiagnostic]
2341    pub sugg: Option<GuardedStringSugg>,
2342}
2343#[derive(Subdiagnostic)]
2344#[suggestion(
2345    parse_suggestion_whitespace,
2346    code = " ",
2347    applicability = "maybe-incorrect",
2348    style = "verbose"
2349)]
2350pub(crate) struct GuardedStringSugg(#[primary_span] pub Span);
2351
2352#[derive(Diagnostic)]
2353#[diag(parse_too_many_hashes)]
2354pub(crate) struct TooManyHashes {
2355    #[primary_span]
2356    pub span: Span,
2357    pub num: u32,
2358}
2359
2360#[derive(Diagnostic)]
2361#[diag(parse_unknown_start_of_token)]
2362pub(crate) struct UnknownTokenStart {
2363    #[primary_span]
2364    pub span: Span,
2365    pub escaped: String,
2366    #[subdiagnostic]
2367    pub sugg: Option<TokenSubstitution>,
2368    #[subdiagnostic]
2369    pub null: Option<UnknownTokenNull>,
2370    #[subdiagnostic]
2371    pub repeat: Option<UnknownTokenRepeat>,
2372}
2373
2374#[derive(Subdiagnostic)]
2375pub(crate) enum TokenSubstitution {
2376    #[suggestion(
2377        parse_sugg_quotes,
2378        code = "{suggestion}",
2379        applicability = "maybe-incorrect",
2380        style = "verbose"
2381    )]
2382    DirectedQuotes {
2383        #[primary_span]
2384        span: Span,
2385        suggestion: String,
2386        ascii_str: &'static str,
2387        ascii_name: &'static str,
2388    },
2389    #[suggestion(
2390        parse_sugg_other,
2391        code = "{suggestion}",
2392        applicability = "maybe-incorrect",
2393        style = "verbose"
2394    )]
2395    Other {
2396        #[primary_span]
2397        span: Span,
2398        suggestion: String,
2399        ch: String,
2400        u_name: &'static str,
2401        ascii_str: &'static str,
2402        ascii_name: &'static str,
2403    },
2404}
2405
2406#[derive(Subdiagnostic)]
2407#[note(parse_note_repeats)]
2408pub(crate) struct UnknownTokenRepeat {
2409    pub repeats: usize,
2410}
2411
2412#[derive(Subdiagnostic)]
2413#[help(parse_help_null)]
2414pub(crate) struct UnknownTokenNull;
2415
2416#[derive(Diagnostic)]
2417pub(crate) enum UnescapeError {
2418    #[diag(parse_invalid_unicode_escape)]
2419    #[help]
2420    InvalidUnicodeEscape {
2421        #[primary_span]
2422        #[label]
2423        span: Span,
2424        surrogate: bool,
2425    },
2426    #[diag(parse_escape_only_char)]
2427    EscapeOnlyChar {
2428        #[primary_span]
2429        span: Span,
2430        #[suggestion(
2431            parse_escape,
2432            applicability = "machine-applicable",
2433            code = "{escaped_sugg}",
2434            style = "verbose"
2435        )]
2436        char_span: Span,
2437        escaped_sugg: String,
2438        escaped_msg: String,
2439        byte: bool,
2440    },
2441    #[diag(parse_bare_cr)]
2442    BareCr {
2443        #[primary_span]
2444        #[suggestion(
2445            parse_escape,
2446            applicability = "machine-applicable",
2447            code = "\\r",
2448            style = "verbose"
2449        )]
2450        span: Span,
2451        double_quotes: bool,
2452    },
2453    #[diag(parse_bare_cr_in_raw_string)]
2454    BareCrRawString(#[primary_span] Span),
2455    #[diag(parse_too_short_hex_escape)]
2456    TooShortHexEscape(#[primary_span] Span),
2457    #[diag(parse_invalid_char_in_escape)]
2458    InvalidCharInEscape {
2459        #[primary_span]
2460        #[label]
2461        span: Span,
2462        is_hex: bool,
2463        ch: String,
2464    },
2465    #[diag(parse_leading_underscore_unicode_escape)]
2466    LeadingUnderscoreUnicodeEscape {
2467        #[primary_span]
2468        #[label(parse_leading_underscore_unicode_escape_label)]
2469        span: Span,
2470        ch: String,
2471    },
2472    #[diag(parse_overlong_unicode_escape)]
2473    OverlongUnicodeEscape(
2474        #[primary_span]
2475        #[label]
2476        Span,
2477    ),
2478    #[diag(parse_unclosed_unicode_escape)]
2479    UnclosedUnicodeEscape(
2480        #[primary_span]
2481        #[label]
2482        Span,
2483        #[suggestion(
2484            parse_terminate,
2485            code = "}}",
2486            applicability = "maybe-incorrect",
2487            style = "verbose"
2488        )]
2489        Span,
2490    ),
2491    #[diag(parse_no_brace_unicode_escape)]
2492    NoBraceInUnicodeEscape {
2493        #[primary_span]
2494        span: Span,
2495        #[label]
2496        label: Option<Span>,
2497        #[subdiagnostic]
2498        sub: NoBraceUnicodeSub,
2499    },
2500    #[diag(parse_unicode_escape_in_byte)]
2501    #[help]
2502    UnicodeEscapeInByte(
2503        #[primary_span]
2504        #[label]
2505        Span,
2506    ),
2507    #[diag(parse_empty_unicode_escape)]
2508    EmptyUnicodeEscape(
2509        #[primary_span]
2510        #[label]
2511        Span,
2512    ),
2513    #[diag(parse_zero_chars)]
2514    ZeroChars(
2515        #[primary_span]
2516        #[label]
2517        Span,
2518    ),
2519    #[diag(parse_lone_slash)]
2520    LoneSlash(
2521        #[primary_span]
2522        #[label]
2523        Span,
2524    ),
2525    #[diag(parse_unskipped_whitespace)]
2526    UnskippedWhitespace {
2527        #[primary_span]
2528        span: Span,
2529        #[label]
2530        char_span: Span,
2531        ch: String,
2532    },
2533    #[diag(parse_multiple_skipped_lines)]
2534    MultipleSkippedLinesWarning(
2535        #[primary_span]
2536        #[label]
2537        Span,
2538    ),
2539    #[diag(parse_more_than_one_char)]
2540    MoreThanOneChar {
2541        #[primary_span]
2542        span: Span,
2543        #[subdiagnostic]
2544        note: Option<MoreThanOneCharNote>,
2545        #[subdiagnostic]
2546        suggestion: MoreThanOneCharSugg,
2547    },
2548    #[diag(parse_nul_in_c_str)]
2549    NulInCStr {
2550        #[primary_span]
2551        span: Span,
2552    },
2553}
2554
2555#[derive(Subdiagnostic)]
2556pub(crate) enum MoreThanOneCharSugg {
2557    #[suggestion(
2558        parse_consider_normalized,
2559        code = "{normalized}",
2560        applicability = "machine-applicable",
2561        style = "verbose"
2562    )]
2563    NormalizedForm {
2564        #[primary_span]
2565        span: Span,
2566        ch: String,
2567        normalized: String,
2568    },
2569    #[suggestion(
2570        parse_remove_non,
2571        code = "{ch}",
2572        applicability = "maybe-incorrect",
2573        style = "verbose"
2574    )]
2575    RemoveNonPrinting {
2576        #[primary_span]
2577        span: Span,
2578        ch: String,
2579    },
2580    #[suggestion(
2581        parse_use_double_quotes,
2582        code = "{sugg}",
2583        applicability = "machine-applicable",
2584        style = "verbose"
2585    )]
2586    QuotesFull {
2587        #[primary_span]
2588        span: Span,
2589        is_byte: bool,
2590        sugg: String,
2591    },
2592    #[multipart_suggestion(parse_use_double_quotes, applicability = "machine-applicable")]
2593    Quotes {
2594        #[suggestion_part(code = "{prefix}\"")]
2595        start: Span,
2596        #[suggestion_part(code = "\"")]
2597        end: Span,
2598        is_byte: bool,
2599        prefix: &'static str,
2600    },
2601}
2602
2603#[derive(Subdiagnostic)]
2604pub(crate) enum MoreThanOneCharNote {
2605    #[note(parse_followed_by)]
2606    AllCombining {
2607        #[primary_span]
2608        span: Span,
2609        chr: String,
2610        len: usize,
2611        escaped_marks: String,
2612    },
2613    #[note(parse_non_printing)]
2614    NonPrinting {
2615        #[primary_span]
2616        span: Span,
2617        escaped: String,
2618    },
2619}
2620
2621#[derive(Subdiagnostic)]
2622pub(crate) enum NoBraceUnicodeSub {
2623    #[suggestion(
2624        parse_use_braces,
2625        code = "{suggestion}",
2626        applicability = "maybe-incorrect",
2627        style = "verbose"
2628    )]
2629    Suggestion {
2630        #[primary_span]
2631        span: Span,
2632        suggestion: String,
2633    },
2634    #[help(parse_format_of_unicode)]
2635    Help,
2636}
2637
2638#[derive(Subdiagnostic)]
2639#[multipart_suggestion(parse_sugg_wrap_pattern_in_parens, applicability = "machine-applicable")]
2640pub(crate) struct WrapInParens {
2641    #[suggestion_part(code = "(")]
2642    pub(crate) lo: Span,
2643    #[suggestion_part(code = ")")]
2644    pub(crate) hi: Span,
2645}
2646
2647#[derive(Subdiagnostic)]
2648pub(crate) enum TopLevelOrPatternNotAllowedSugg {
2649    #[suggestion(
2650        parse_sugg_remove_leading_vert_in_pattern,
2651        code = "",
2652        applicability = "machine-applicable",
2653        style = "tool-only"
2654    )]
2655    RemoveLeadingVert {
2656        #[primary_span]
2657        span: Span,
2658    },
2659    WrapInParens {
2660        #[primary_span]
2661        span: Span,
2662        #[subdiagnostic]
2663        suggestion: WrapInParens,
2664    },
2665}
2666
2667#[derive(Diagnostic)]
2668#[diag(parse_unexpected_vert_vert_before_function_parameter)]
2669#[note(parse_note_pattern_alternatives_use_single_vert)]
2670pub(crate) struct UnexpectedVertVertBeforeFunctionParam {
2671    #[primary_span]
2672    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2673    pub span: Span,
2674}
2675
2676#[derive(Diagnostic)]
2677#[diag(parse_unexpected_vert_vert_in_pattern)]
2678pub(crate) struct UnexpectedVertVertInPattern {
2679    #[primary_span]
2680    #[suggestion(code = "|", applicability = "machine-applicable", style = "verbose")]
2681    pub span: Span,
2682    #[label(parse_label_while_parsing_or_pattern_here)]
2683    pub start: Option<Span>,
2684}
2685
2686#[derive(Subdiagnostic)]
2687#[suggestion(
2688    parse_trailing_vert_not_allowed,
2689    code = "",
2690    applicability = "machine-applicable",
2691    style = "tool-only"
2692)]
2693pub(crate) struct TrailingVertSuggestion {
2694    #[primary_span]
2695    pub span: Span,
2696}
2697
2698#[derive(Diagnostic)]
2699#[diag(parse_trailing_vert_not_allowed)]
2700pub(crate) struct TrailingVertNotAllowed {
2701    #[primary_span]
2702    pub span: Span,
2703    #[subdiagnostic]
2704    pub suggestion: TrailingVertSuggestion,
2705    #[label(parse_label_while_parsing_or_pattern_here)]
2706    pub start: Option<Span>,
2707    pub token: Token,
2708    #[note(parse_note_pattern_alternatives_use_single_vert)]
2709    pub note_double_vert: bool,
2710}
2711
2712#[derive(Diagnostic)]
2713#[diag(parse_dotdotdot_rest_pattern)]
2714pub(crate) struct DotDotDotRestPattern {
2715    #[primary_span]
2716    #[label]
2717    pub span: Span,
2718    #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
2719    pub suggestion: Option<Span>,
2720    #[note]
2721    pub var_args: Option<()>,
2722}
2723
2724#[derive(Diagnostic)]
2725#[diag(parse_pattern_on_wrong_side_of_at)]
2726pub(crate) struct PatternOnWrongSideOfAt {
2727    #[primary_span]
2728    #[suggestion(code = "{whole_pat}", applicability = "machine-applicable", style = "verbose")]
2729    pub whole_span: Span,
2730    pub whole_pat: String,
2731    #[label(parse_label_pattern)]
2732    pub pattern: Span,
2733    #[label(parse_label_binding)]
2734    pub binding: Span,
2735}
2736
2737#[derive(Diagnostic)]
2738#[diag(parse_expected_binding_left_of_at)]
2739#[note]
2740pub(crate) struct ExpectedBindingLeftOfAt {
2741    #[primary_span]
2742    pub whole_span: Span,
2743    #[label(parse_label_lhs)]
2744    pub lhs: Span,
2745    #[label(parse_label_rhs)]
2746    pub rhs: Span,
2747}
2748
2749#[derive(Subdiagnostic)]
2750#[multipart_suggestion(
2751    parse_ambiguous_range_pattern_suggestion,
2752    applicability = "machine-applicable"
2753)]
2754pub(crate) struct ParenRangeSuggestion {
2755    #[suggestion_part(code = "(")]
2756    pub lo: Span,
2757    #[suggestion_part(code = ")")]
2758    pub hi: Span,
2759}
2760
2761#[derive(Diagnostic)]
2762#[diag(parse_ambiguous_range_pattern)]
2763pub(crate) struct AmbiguousRangePattern {
2764    #[primary_span]
2765    pub span: Span,
2766    #[subdiagnostic]
2767    pub suggestion: ParenRangeSuggestion,
2768}
2769
2770#[derive(Diagnostic)]
2771#[diag(parse_unexpected_lifetime_in_pattern)]
2772pub(crate) struct UnexpectedLifetimeInPattern {
2773    #[primary_span]
2774    pub span: Span,
2775    pub symbol: Symbol,
2776    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2777    pub suggestion: Span,
2778}
2779
2780#[derive(Diagnostic)]
2781pub(crate) enum InvalidMutInPattern {
2782    #[diag(parse_mut_on_nested_ident_pattern)]
2783    #[note(parse_note_mut_pattern_usage)]
2784    NestedIdent {
2785        #[primary_span]
2786        #[suggestion(code = "{pat}", applicability = "machine-applicable", style = "verbose")]
2787        span: Span,
2788        pat: String,
2789    },
2790    #[diag(parse_mut_on_non_ident_pattern)]
2791    #[note(parse_note_mut_pattern_usage)]
2792    NonIdent {
2793        #[primary_span]
2794        #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2795        span: Span,
2796    },
2797}
2798
2799#[derive(Diagnostic)]
2800#[diag(parse_repeated_mut_in_pattern)]
2801pub(crate) struct RepeatedMutInPattern {
2802    #[primary_span]
2803    pub span: Span,
2804    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2805    pub suggestion: Span,
2806}
2807
2808#[derive(Diagnostic)]
2809#[diag(parse_dot_dot_dot_range_to_pattern_not_allowed)]
2810pub(crate) struct DotDotDotRangeToPatternNotAllowed {
2811    #[primary_span]
2812    #[suggestion(style = "verbose", code = "..=", applicability = "machine-applicable")]
2813    pub span: Span,
2814}
2815
2816#[derive(Diagnostic)]
2817#[diag(parse_enum_pattern_instead_of_identifier)]
2818pub(crate) struct EnumPatternInsteadOfIdentifier {
2819    #[primary_span]
2820    pub span: Span,
2821}
2822
2823#[derive(Diagnostic)]
2824#[diag(parse_at_dot_dot_in_struct_pattern)]
2825pub(crate) struct AtDotDotInStructPattern {
2826    #[primary_span]
2827    pub span: Span,
2828    #[suggestion(code = "", style = "verbose", applicability = "machine-applicable")]
2829    pub remove: Span,
2830    pub ident: Ident,
2831}
2832
2833#[derive(Diagnostic)]
2834#[diag(parse_at_in_struct_pattern)]
2835#[note]
2836#[help]
2837pub(crate) struct AtInStructPattern {
2838    #[primary_span]
2839    pub span: Span,
2840}
2841
2842#[derive(Diagnostic)]
2843#[diag(parse_dot_dot_dot_for_remaining_fields)]
2844pub(crate) struct DotDotDotForRemainingFields {
2845    #[primary_span]
2846    #[suggestion(code = "..", style = "verbose", applicability = "machine-applicable")]
2847    pub span: Span,
2848    pub token_str: Cow<'static, str>,
2849}
2850
2851#[derive(Diagnostic)]
2852#[diag(parse_expected_comma_after_pattern_field)]
2853pub(crate) struct ExpectedCommaAfterPatternField {
2854    #[primary_span]
2855    pub span: Span,
2856}
2857
2858#[derive(Diagnostic)]
2859#[diag(parse_unexpected_expr_in_pat)]
2860#[note]
2861pub(crate) struct UnexpectedExpressionInPattern {
2862    /// The unexpected expr's span.
2863    #[primary_span]
2864    #[label]
2865    pub span: Span,
2866    /// Was a `RangePatternBound` expected?
2867    pub is_bound: bool,
2868    /// The unexpected expr's precedence (used in match arm guard suggestions).
2869    pub expr_precedence: ExprPrecedence,
2870}
2871
2872#[derive(Subdiagnostic)]
2873pub(crate) enum UnexpectedExpressionInPatternSugg {
2874    #[multipart_suggestion(
2875        parse_unexpected_expr_in_pat_create_guard_sugg,
2876        applicability = "maybe-incorrect"
2877    )]
2878    CreateGuard {
2879        /// Where to put the suggested identifier.
2880        #[suggestion_part(code = "{ident}")]
2881        ident_span: Span,
2882        /// Where to put the match arm.
2883        #[suggestion_part(code = " if {ident} == {expr}")]
2884        pat_hi: Span,
2885        /// The suggested identifier.
2886        ident: String,
2887        /// The unexpected expression.
2888        expr: String,
2889    },
2890
2891    #[multipart_suggestion(
2892        parse_unexpected_expr_in_pat_update_guard_sugg,
2893        applicability = "maybe-incorrect"
2894    )]
2895    UpdateGuard {
2896        /// Where to put the suggested identifier.
2897        #[suggestion_part(code = "{ident}")]
2898        ident_span: Span,
2899        /// The beginning of the match arm guard's expression (insert a `(` if `Some`).
2900        #[suggestion_part(code = "(")]
2901        guard_lo: Option<Span>,
2902        /// The end of the match arm guard's expression.
2903        #[suggestion_part(code = "{guard_hi_paren} && {ident} == {expr}")]
2904        guard_hi: Span,
2905        /// Either `")"` or `""`.
2906        guard_hi_paren: &'static str,
2907        /// The suggested identifier.
2908        ident: String,
2909        /// The unexpected expression.
2910        expr: String,
2911    },
2912
2913    #[multipart_suggestion(
2914        parse_unexpected_expr_in_pat_const_sugg,
2915        applicability = "has-placeholders"
2916    )]
2917    Const {
2918        /// Where to put the extracted constant declaration.
2919        #[suggestion_part(code = "{indentation}const {ident}: /* Type */ = {expr};\n")]
2920        stmt_lo: Span,
2921        /// Where to put the suggested identifier.
2922        #[suggestion_part(code = "{ident}")]
2923        ident_span: Span,
2924        /// The suggested identifier.
2925        ident: String,
2926        /// The unexpected expression.
2927        expr: String,
2928        /// The statement's block's indentation.
2929        indentation: String,
2930    },
2931}
2932
2933#[derive(Diagnostic)]
2934#[diag(parse_unexpected_paren_in_range_pat)]
2935pub(crate) struct UnexpectedParenInRangePat {
2936    #[primary_span]
2937    pub span: Vec<Span>,
2938    #[subdiagnostic]
2939    pub sugg: UnexpectedParenInRangePatSugg,
2940}
2941
2942#[derive(Subdiagnostic)]
2943#[multipart_suggestion(
2944    parse_unexpected_paren_in_range_pat_sugg,
2945    applicability = "machine-applicable"
2946)]
2947pub(crate) struct UnexpectedParenInRangePatSugg {
2948    #[suggestion_part(code = "")]
2949    pub start_span: Span,
2950    #[suggestion_part(code = "")]
2951    pub end_span: Span,
2952}
2953
2954#[derive(Diagnostic)]
2955#[diag(parse_return_types_use_thin_arrow)]
2956pub(crate) struct ReturnTypesUseThinArrow {
2957    #[primary_span]
2958    pub span: Span,
2959    #[suggestion(style = "verbose", code = " -> ", applicability = "machine-applicable")]
2960    pub suggestion: Span,
2961}
2962
2963#[derive(Diagnostic)]
2964#[diag(parse_need_plus_after_trait_object_lifetime)]
2965pub(crate) struct NeedPlusAfterTraitObjectLifetime {
2966    #[primary_span]
2967    pub span: Span,
2968    #[suggestion(code = " + /* Trait */", applicability = "has-placeholders")]
2969    pub suggestion: Span,
2970}
2971
2972#[derive(Diagnostic)]
2973#[diag(parse_expected_mut_or_const_in_raw_pointer_type)]
2974pub(crate) struct ExpectedMutOrConstInRawPointerType {
2975    #[primary_span]
2976    pub span: Span,
2977    #[suggestion(code("mut ", "const "), applicability = "has-placeholders", style = "verbose")]
2978    pub after_asterisk: Span,
2979}
2980
2981#[derive(Diagnostic)]
2982#[diag(parse_lifetime_after_mut)]
2983pub(crate) struct LifetimeAfterMut {
2984    #[primary_span]
2985    pub span: Span,
2986    #[suggestion(code = "&{snippet} mut", applicability = "maybe-incorrect", style = "verbose")]
2987    pub suggest_lifetime: Option<Span>,
2988    pub snippet: String,
2989}
2990
2991#[derive(Diagnostic)]
2992#[diag(parse_dyn_after_mut)]
2993pub(crate) struct DynAfterMut {
2994    #[primary_span]
2995    #[suggestion(code = "&mut dyn", applicability = "machine-applicable", style = "verbose")]
2996    pub span: Span,
2997}
2998
2999#[derive(Diagnostic)]
3000#[diag(parse_fn_pointer_cannot_be_const)]
3001#[note]
3002pub(crate) struct FnPointerCannotBeConst {
3003    #[primary_span]
3004    #[label]
3005    pub span: Span,
3006    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3007    pub suggestion: Span,
3008}
3009
3010#[derive(Diagnostic)]
3011#[diag(parse_fn_pointer_cannot_be_async)]
3012#[note]
3013pub(crate) struct FnPointerCannotBeAsync {
3014    #[primary_span]
3015    #[label]
3016    pub span: Span,
3017    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3018    pub suggestion: Span,
3019}
3020
3021#[derive(Diagnostic)]
3022#[diag(parse_nested_c_variadic_type, code = E0743)]
3023pub(crate) struct NestedCVariadicType {
3024    #[primary_span]
3025    pub span: Span,
3026}
3027
3028#[derive(Diagnostic)]
3029#[diag(parse_dotdotdot_rest_type)]
3030#[note]
3031pub(crate) struct InvalidCVariadicType {
3032    #[primary_span]
3033    pub span: Span,
3034}
3035
3036#[derive(Diagnostic)]
3037#[diag(parse_invalid_dyn_keyword)]
3038#[help]
3039pub(crate) struct InvalidDynKeyword {
3040    #[primary_span]
3041    pub span: Span,
3042    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
3043    pub suggestion: Span,
3044}
3045
3046#[derive(Subdiagnostic)]
3047pub(crate) enum HelpUseLatestEdition {
3048    #[help(parse_help_set_edition_cargo)]
3049    #[note(parse_note_edition_guide)]
3050    Cargo { edition: Edition },
3051    #[help(parse_help_set_edition_standalone)]
3052    #[note(parse_note_edition_guide)]
3053    Standalone { edition: Edition },
3054}
3055
3056impl HelpUseLatestEdition {
3057    pub(crate) fn new() -> Self {
3058        let edition = LATEST_STABLE_EDITION;
3059        if rustc_session::utils::was_invoked_from_cargo() {
3060            Self::Cargo { edition }
3061        } else {
3062            Self::Standalone { edition }
3063        }
3064    }
3065}
3066
3067#[derive(Diagnostic)]
3068#[diag(parse_box_syntax_removed)]
3069pub(crate) struct BoxSyntaxRemoved {
3070    #[primary_span]
3071    pub span: Span,
3072    #[subdiagnostic]
3073    pub sugg: AddBoxNew,
3074}
3075
3076#[derive(Subdiagnostic)]
3077#[multipart_suggestion(
3078    parse_box_syntax_removed_suggestion,
3079    applicability = "machine-applicable",
3080    style = "verbose"
3081)]
3082pub(crate) struct AddBoxNew {
3083    #[suggestion_part(code = "Box::new(")]
3084    pub box_kw_and_lo: Span,
3085    #[suggestion_part(code = ")")]
3086    pub hi: Span,
3087}
3088
3089#[derive(Diagnostic)]
3090#[diag(parse_bad_return_type_notation_output)]
3091pub(crate) struct BadReturnTypeNotationOutput {
3092    #[primary_span]
3093    pub span: Span,
3094    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3095    pub suggestion: Span,
3096}
3097
3098#[derive(Diagnostic)]
3099#[diag(parse_bad_assoc_type_bounds)]
3100pub(crate) struct BadAssocTypeBounds {
3101    #[primary_span]
3102    #[label]
3103    pub span: Span,
3104}
3105
3106#[derive(Diagnostic)]
3107#[diag(parse_attr_after_generic)]
3108pub(crate) struct AttrAfterGeneric {
3109    #[primary_span]
3110    #[label]
3111    pub span: Span,
3112}
3113
3114#[derive(Diagnostic)]
3115#[diag(parse_attr_without_generics)]
3116pub(crate) struct AttrWithoutGenerics {
3117    #[primary_span]
3118    #[label]
3119    pub span: Span,
3120}
3121
3122#[derive(Diagnostic)]
3123#[diag(parse_where_generics)]
3124pub(crate) struct WhereOnGenerics {
3125    #[primary_span]
3126    #[label]
3127    pub span: Span,
3128}
3129
3130#[derive(Diagnostic)]
3131#[diag(parse_generics_in_path)]
3132pub(crate) struct GenericsInPath {
3133    #[primary_span]
3134    pub span: Vec<Span>,
3135}
3136
3137#[derive(Diagnostic)]
3138#[diag(parse_lifetime_in_eq_constraint)]
3139#[help]
3140pub(crate) struct LifetimeInEqConstraint {
3141    #[primary_span]
3142    #[label]
3143    pub span: Span,
3144    pub lifetime: Ident,
3145    #[label(parse_context_label)]
3146    pub binding_label: Span,
3147    #[suggestion(
3148        parse_colon_sugg,
3149        style = "verbose",
3150        applicability = "maybe-incorrect",
3151        code = ": "
3152    )]
3153    pub colon_sugg: Span,
3154}
3155
3156#[derive(Diagnostic)]
3157#[diag(parse_modifier_lifetime)]
3158pub(crate) struct ModifierLifetime {
3159    #[primary_span]
3160    #[suggestion(style = "tool-only", applicability = "maybe-incorrect", code = "")]
3161    pub span: Span,
3162    pub modifier: &'static str,
3163}
3164
3165#[derive(Diagnostic)]
3166#[diag(parse_underscore_literal_suffix)]
3167pub(crate) struct UnderscoreLiteralSuffix {
3168    #[primary_span]
3169    pub span: Span,
3170}
3171
3172#[derive(Diagnostic)]
3173#[diag(parse_expect_label_found_ident)]
3174pub(crate) struct ExpectedLabelFoundIdent {
3175    #[primary_span]
3176    pub span: Span,
3177    #[suggestion(code = "'", applicability = "machine-applicable", style = "verbose")]
3178    pub start: Span,
3179}
3180
3181#[derive(Diagnostic)]
3182#[diag(parse_inappropriate_default)]
3183#[note]
3184pub(crate) struct InappropriateDefault {
3185    #[primary_span]
3186    #[label]
3187    pub span: Span,
3188    pub article: &'static str,
3189    pub descr: &'static str,
3190}
3191
3192#[derive(Diagnostic)]
3193#[diag(parse_recover_import_as_use)]
3194pub(crate) struct RecoverImportAsUse {
3195    #[primary_span]
3196    #[suggestion(code = "use", applicability = "machine-applicable", style = "verbose")]
3197    pub span: Span,
3198    pub token_name: String,
3199}
3200
3201#[derive(Diagnostic)]
3202#[diag(parse_single_colon_import_path)]
3203#[note]
3204pub(crate) struct SingleColonImportPath {
3205    #[primary_span]
3206    #[suggestion(code = "::", applicability = "machine-applicable", style = "verbose")]
3207    pub span: Span,
3208}
3209
3210#[derive(Diagnostic)]
3211#[diag(parse_bad_item_kind)]
3212pub(crate) struct BadItemKind {
3213    #[primary_span]
3214    pub span: Span,
3215    pub descr: &'static str,
3216    pub ctx: &'static str,
3217    #[help]
3218    pub help: bool,
3219}
3220
3221#[derive(Diagnostic)]
3222#[diag(parse_macro_rules_missing_bang)]
3223pub(crate) struct MacroRulesMissingBang {
3224    #[primary_span]
3225    pub span: Span,
3226    #[suggestion(code = "!", applicability = "machine-applicable", style = "verbose")]
3227    pub hi: Span,
3228}
3229
3230#[derive(Diagnostic)]
3231#[diag(parse_macro_name_remove_bang)]
3232pub(crate) struct MacroNameRemoveBang {
3233    #[primary_span]
3234    #[suggestion(code = "", applicability = "machine-applicable", style = "short")]
3235    pub span: Span,
3236}
3237
3238#[derive(Diagnostic)]
3239#[diag(parse_macro_rules_visibility)]
3240pub(crate) struct MacroRulesVisibility<'a> {
3241    #[primary_span]
3242    #[suggestion(code = "#[macro_export]", applicability = "maybe-incorrect", style = "verbose")]
3243    pub span: Span,
3244    pub vis: &'a str,
3245}
3246
3247#[derive(Diagnostic)]
3248#[diag(parse_macro_invocation_visibility)]
3249#[help]
3250pub(crate) struct MacroInvocationVisibility<'a> {
3251    #[primary_span]
3252    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
3253    pub span: Span,
3254    pub vis: &'a str,
3255}
3256
3257#[derive(Diagnostic)]
3258#[diag(parse_nested_adt)]
3259pub(crate) struct NestedAdt<'a> {
3260    #[primary_span]
3261    pub span: Span,
3262    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3263    pub item: Span,
3264    pub keyword: &'a str,
3265    pub kw_str: Cow<'a, str>,
3266}
3267
3268#[derive(Diagnostic)]
3269#[diag(parse_function_body_equals_expr)]
3270pub(crate) struct FunctionBodyEqualsExpr {
3271    #[primary_span]
3272    pub span: Span,
3273    #[subdiagnostic]
3274    pub sugg: FunctionBodyEqualsExprSugg,
3275}
3276
3277#[derive(Subdiagnostic)]
3278#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3279pub(crate) struct FunctionBodyEqualsExprSugg {
3280    #[suggestion_part(code = "{{")]
3281    pub eq: Span,
3282    #[suggestion_part(code = " }}")]
3283    pub semi: Span,
3284}
3285
3286#[derive(Diagnostic)]
3287#[diag(parse_box_not_pat)]
3288pub(crate) struct BoxNotPat {
3289    #[primary_span]
3290    pub span: Span,
3291    #[note]
3292    pub kw: Span,
3293    #[suggestion(code = "r#", applicability = "maybe-incorrect", style = "verbose")]
3294    pub lo: Span,
3295    pub descr: String,
3296}
3297
3298#[derive(Diagnostic)]
3299#[diag(parse_unmatched_angle)]
3300pub(crate) struct UnmatchedAngle {
3301    #[primary_span]
3302    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
3303    pub span: Span,
3304    pub plural: bool,
3305}
3306
3307#[derive(Diagnostic)]
3308#[diag(parse_missing_plus_in_bounds)]
3309pub(crate) struct MissingPlusBounds {
3310    #[primary_span]
3311    pub span: Span,
3312    #[suggestion(code = " +", applicability = "maybe-incorrect", style = "verbose")]
3313    pub hi: Span,
3314    pub sym: Symbol,
3315}
3316
3317#[derive(Diagnostic)]
3318#[diag(parse_incorrect_parens_trait_bounds)]
3319pub(crate) struct IncorrectParensTraitBounds {
3320    #[primary_span]
3321    pub span: Vec<Span>,
3322    #[subdiagnostic]
3323    pub sugg: IncorrectParensTraitBoundsSugg,
3324}
3325
3326#[derive(Subdiagnostic)]
3327#[multipart_suggestion(
3328    parse_incorrect_parens_trait_bounds_sugg,
3329    applicability = "machine-applicable"
3330)]
3331pub(crate) struct IncorrectParensTraitBoundsSugg {
3332    #[suggestion_part(code = " ")]
3333    pub wrong_span: Span,
3334    #[suggestion_part(code = "(")]
3335    pub new_span: Span,
3336}
3337
3338#[derive(Diagnostic)]
3339#[diag(parse_kw_bad_case)]
3340pub(crate) struct KwBadCase<'a> {
3341    #[primary_span]
3342    #[suggestion(code = "{kw}", style = "verbose", applicability = "machine-applicable")]
3343    pub span: Span,
3344    pub kw: &'a str,
3345    pub case: Case,
3346}
3347
3348pub(crate) enum Case {
3349    Upper,
3350    Lower,
3351    Mixed,
3352}
3353
3354impl IntoDiagArg for Case {
3355    fn into_diag_arg(self, path: &mut Option<PathBuf>) -> DiagArgValue {
3356        match self {
3357            Case::Upper => "uppercase",
3358            Case::Lower => "lowercase",
3359            Case::Mixed => "the correct case",
3360        }
3361        .into_diag_arg(path)
3362    }
3363}
3364
3365#[derive(Diagnostic)]
3366#[diag(parse_unknown_builtin_construct)]
3367pub(crate) struct UnknownBuiltinConstruct {
3368    #[primary_span]
3369    pub span: Span,
3370    pub name: Ident,
3371}
3372
3373#[derive(Diagnostic)]
3374#[diag(parse_expected_builtin_ident)]
3375pub(crate) struct ExpectedBuiltinIdent {
3376    #[primary_span]
3377    pub span: Span,
3378}
3379
3380#[derive(Diagnostic)]
3381#[diag(parse_static_with_generics)]
3382pub(crate) struct StaticWithGenerics {
3383    #[primary_span]
3384    pub span: Span,
3385}
3386
3387#[derive(Diagnostic)]
3388#[diag(parse_where_clause_before_const_body)]
3389pub(crate) struct WhereClauseBeforeConstBody {
3390    #[primary_span]
3391    #[label]
3392    pub span: Span,
3393    #[label(parse_name_label)]
3394    pub name: Span,
3395    #[label(parse_body_label)]
3396    pub body: Span,
3397    #[subdiagnostic]
3398    pub sugg: Option<WhereClauseBeforeConstBodySugg>,
3399}
3400
3401#[derive(Subdiagnostic)]
3402#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3403pub(crate) struct WhereClauseBeforeConstBodySugg {
3404    #[suggestion_part(code = "= {snippet} ")]
3405    pub left: Span,
3406    pub snippet: String,
3407    #[suggestion_part(code = "")]
3408    pub right: Span,
3409}
3410
3411#[derive(Diagnostic)]
3412#[diag(parse_generic_args_in_pat_require_turbofish_syntax)]
3413pub(crate) struct GenericArgsInPatRequireTurbofishSyntax {
3414    #[primary_span]
3415    pub span: Span,
3416    #[suggestion(
3417        parse_sugg_turbofish_syntax,
3418        style = "verbose",
3419        code = "::",
3420        applicability = "maybe-incorrect"
3421    )]
3422    pub suggest_turbofish: Span,
3423}
3424
3425#[derive(Diagnostic)]
3426#[diag(parse_transpose_dyn_or_impl)]
3427pub(crate) struct TransposeDynOrImpl<'a> {
3428    #[primary_span]
3429    pub span: Span,
3430    pub kw: &'a str,
3431    #[subdiagnostic]
3432    pub sugg: TransposeDynOrImplSugg<'a>,
3433}
3434
3435#[derive(Subdiagnostic)]
3436#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3437pub(crate) struct TransposeDynOrImplSugg<'a> {
3438    #[suggestion_part(code = "")]
3439    pub removal_span: Span,
3440    #[suggestion_part(code = "{kw} ")]
3441    pub insertion_span: Span,
3442    pub kw: &'a str,
3443}
3444
3445#[derive(Diagnostic)]
3446#[diag(parse_array_index_offset_of)]
3447pub(crate) struct ArrayIndexInOffsetOf(#[primary_span] pub Span);
3448
3449#[derive(Diagnostic)]
3450#[diag(parse_invalid_offset_of)]
3451pub(crate) struct InvalidOffsetOf(#[primary_span] pub Span);
3452
3453#[derive(Diagnostic)]
3454#[diag(parse_async_impl)]
3455pub(crate) struct AsyncImpl {
3456    #[primary_span]
3457    pub span: Span,
3458}
3459
3460#[derive(Diagnostic)]
3461#[diag(parse_expr_rarrow_call)]
3462#[help]
3463pub(crate) struct ExprRArrowCall {
3464    #[primary_span]
3465    #[suggestion(style = "verbose", applicability = "machine-applicable", code = ".")]
3466    pub span: Span,
3467}
3468
3469#[derive(Diagnostic)]
3470#[diag(parse_dot_dot_range_attribute)]
3471pub(crate) struct DotDotRangeAttribute {
3472    #[primary_span]
3473    pub span: Span,
3474}
3475
3476#[derive(Diagnostic)]
3477#[diag(parse_binder_before_modifiers)]
3478pub(crate) struct BinderBeforeModifiers {
3479    #[primary_span]
3480    pub binder_span: Span,
3481    #[label]
3482    pub modifiers_span: Span,
3483}
3484
3485#[derive(Diagnostic)]
3486#[diag(parse_binder_and_polarity)]
3487pub(crate) struct BinderAndPolarity {
3488    #[primary_span]
3489    pub polarity_span: Span,
3490    #[label]
3491    pub binder_span: Span,
3492    pub polarity: &'static str,
3493}
3494
3495#[derive(Diagnostic)]
3496#[diag(parse_modifiers_and_polarity)]
3497pub(crate) struct PolarityAndModifiers {
3498    #[primary_span]
3499    pub polarity_span: Span,
3500    #[label]
3501    pub modifiers_span: Span,
3502    pub polarity: &'static str,
3503    pub modifiers_concatenated: String,
3504}
3505
3506#[derive(Diagnostic)]
3507#[diag(parse_incorrect_type_on_self)]
3508pub(crate) struct IncorrectTypeOnSelf {
3509    #[primary_span]
3510    pub span: Span,
3511    #[subdiagnostic]
3512    pub move_self_modifier: MoveSelfModifier,
3513}
3514
3515#[derive(Subdiagnostic)]
3516#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3517pub(crate) struct MoveSelfModifier {
3518    #[suggestion_part(code = "")]
3519    pub removal_span: Span,
3520    #[suggestion_part(code = "{modifier}")]
3521    pub insertion_span: Span,
3522    pub modifier: String,
3523}
3524
3525#[derive(Diagnostic)]
3526#[diag(parse_asm_unsupported_operand)]
3527pub(crate) struct AsmUnsupportedOperand<'a> {
3528    #[primary_span]
3529    #[label]
3530    pub(crate) span: Span,
3531    pub(crate) symbol: &'a str,
3532    pub(crate) macro_name: &'static str,
3533}
3534
3535#[derive(Diagnostic)]
3536#[diag(parse_asm_underscore_input)]
3537pub(crate) struct AsmUnderscoreInput {
3538    #[primary_span]
3539    pub(crate) span: Span,
3540}
3541
3542#[derive(Diagnostic)]
3543#[diag(parse_asm_sym_no_path)]
3544pub(crate) struct AsmSymNoPath {
3545    #[primary_span]
3546    pub(crate) span: Span,
3547}
3548
3549#[derive(Diagnostic)]
3550#[diag(parse_asm_requires_template)]
3551pub(crate) struct AsmRequiresTemplate {
3552    #[primary_span]
3553    pub(crate) span: Span,
3554}
3555
3556#[derive(Diagnostic)]
3557#[diag(parse_asm_expected_comma)]
3558pub(crate) struct AsmExpectedComma {
3559    #[primary_span]
3560    #[label]
3561    pub(crate) span: Span,
3562}
3563
3564#[derive(Diagnostic)]
3565#[diag(parse_asm_expected_other)]
3566pub(crate) struct AsmExpectedOther {
3567    #[primary_span]
3568    #[label(parse_asm_expected_other)]
3569    pub(crate) span: Span,
3570    pub(crate) is_inline_asm: bool,
3571}
3572
3573#[derive(Diagnostic)]
3574#[diag(parse_asm_non_abi)]
3575pub(crate) struct NonABI {
3576    #[primary_span]
3577    pub(crate) span: Span,
3578}
3579
3580#[derive(Diagnostic)]
3581#[diag(parse_asm_expected_string_literal)]
3582pub(crate) struct AsmExpectedStringLiteral {
3583    #[primary_span]
3584    #[label]
3585    pub(crate) span: Span,
3586}
3587
3588#[derive(Diagnostic)]
3589#[diag(parse_asm_expected_register_class_or_explicit_register)]
3590pub(crate) struct ExpectedRegisterClassOrExplicitRegister {
3591    #[primary_span]
3592    pub(crate) span: Span,
3593}
3594
3595#[derive(LintDiagnostic)]
3596#[diag(parse_hidden_unicode_codepoints)]
3597#[note]
3598pub(crate) struct HiddenUnicodeCodepointsDiag {
3599    pub label: String,
3600    pub count: usize,
3601    #[label]
3602    pub span_label: Span,
3603    #[subdiagnostic]
3604    pub labels: Option<HiddenUnicodeCodepointsDiagLabels>,
3605    #[subdiagnostic]
3606    pub sub: HiddenUnicodeCodepointsDiagSub,
3607}
3608
3609pub(crate) struct HiddenUnicodeCodepointsDiagLabels {
3610    pub spans: Vec<(char, Span)>,
3611}
3612
3613impl Subdiagnostic for HiddenUnicodeCodepointsDiagLabels {
3614    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
3615        for (c, span) in self.spans {
3616            diag.span_label(span, format!("{c:?}"));
3617        }
3618    }
3619}
3620
3621pub(crate) enum HiddenUnicodeCodepointsDiagSub {
3622    Escape { spans: Vec<(char, Span)> },
3623    NoEscape { spans: Vec<(char, Span)> },
3624}
3625
3626// Used because of multiple multipart_suggestion and note
3627impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub {
3628    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
3629        match self {
3630            HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
3631                diag.multipart_suggestion_with_style(
3632                    fluent::parse_suggestion_remove,
3633                    spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
3634                    Applicability::MachineApplicable,
3635                    SuggestionStyle::HideCodeAlways,
3636                );
3637                diag.multipart_suggestion(
3638                    fluent::parse_suggestion_escape,
3639                    spans
3640                        .into_iter()
3641                        .map(|(c, span)| {
3642                            let c = format!("{c:?}");
3643                            (span, c[1..c.len() - 1].to_string())
3644                        })
3645                        .collect(),
3646                    Applicability::MachineApplicable,
3647                );
3648            }
3649            HiddenUnicodeCodepointsDiagSub::NoEscape { spans } => {
3650                // FIXME: in other suggestions we've reversed the inner spans of doc comments. We
3651                // should do the same here to provide the same good suggestions as we do for
3652                // literals above.
3653                diag.arg(
3654                    "escaped",
3655                    spans
3656                        .into_iter()
3657                        .map(|(c, _)| format!("{c:?}"))
3658                        .collect::<Vec<String>>()
3659                        .join(", "),
3660                );
3661                diag.note(fluent::parse_suggestion_remove);
3662                diag.note(fluent::parse_no_suggestion_note_escape);
3663            }
3664        }
3665    }
3666}
3667
3668#[derive(LintDiagnostic)]
3669#[diag(parse_varargs_without_pattern)]
3670pub(crate) struct VarargsWithoutPattern {
3671    #[suggestion(code = "_: ...", applicability = "machine-applicable")]
3672    pub span: Span,
3673}