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    #[subdiagnostic]
2373    pub invisible: Option<InvisibleCharacter>,
2374}
2375
2376#[derive(Subdiagnostic)]
2377pub(crate) enum TokenSubstitution {
2378    #[suggestion(
2379        parse_sugg_quotes,
2380        code = "{suggestion}",
2381        applicability = "maybe-incorrect",
2382        style = "verbose"
2383    )]
2384    DirectedQuotes {
2385        #[primary_span]
2386        span: Span,
2387        suggestion: String,
2388        ascii_str: &'static str,
2389        ascii_name: &'static str,
2390    },
2391    #[suggestion(
2392        parse_sugg_other,
2393        code = "{suggestion}",
2394        applicability = "maybe-incorrect",
2395        style = "verbose"
2396    )]
2397    Other {
2398        #[primary_span]
2399        span: Span,
2400        suggestion: String,
2401        ch: String,
2402        u_name: &'static str,
2403        ascii_str: &'static str,
2404        ascii_name: &'static str,
2405    },
2406}
2407
2408#[derive(Subdiagnostic)]
2409#[note(parse_note_repeats)]
2410pub(crate) struct UnknownTokenRepeat {
2411    pub repeats: usize,
2412}
2413
2414#[derive(Subdiagnostic)]
2415#[help(parse_help_invisible_char)]
2416pub(crate) struct InvisibleCharacter;
2417
2418#[derive(Subdiagnostic)]
2419#[help(parse_help_null)]
2420pub(crate) struct UnknownTokenNull;
2421
2422#[derive(Diagnostic)]
2423pub(crate) enum UnescapeError {
2424    #[diag(parse_invalid_unicode_escape)]
2425    #[help]
2426    InvalidUnicodeEscape {
2427        #[primary_span]
2428        #[label]
2429        span: Span,
2430        surrogate: bool,
2431    },
2432    #[diag(parse_escape_only_char)]
2433    EscapeOnlyChar {
2434        #[primary_span]
2435        span: Span,
2436        #[suggestion(
2437            parse_escape,
2438            applicability = "machine-applicable",
2439            code = "{escaped_sugg}",
2440            style = "verbose"
2441        )]
2442        char_span: Span,
2443        escaped_sugg: String,
2444        escaped_msg: String,
2445        byte: bool,
2446    },
2447    #[diag(parse_bare_cr)]
2448    BareCr {
2449        #[primary_span]
2450        #[suggestion(
2451            parse_escape,
2452            applicability = "machine-applicable",
2453            code = "\\r",
2454            style = "verbose"
2455        )]
2456        span: Span,
2457        double_quotes: bool,
2458    },
2459    #[diag(parse_bare_cr_in_raw_string)]
2460    BareCrRawString(#[primary_span] Span),
2461    #[diag(parse_too_short_hex_escape)]
2462    TooShortHexEscape(#[primary_span] Span),
2463    #[diag(parse_invalid_char_in_escape)]
2464    InvalidCharInEscape {
2465        #[primary_span]
2466        #[label]
2467        span: Span,
2468        is_hex: bool,
2469        ch: String,
2470    },
2471    #[diag(parse_leading_underscore_unicode_escape)]
2472    LeadingUnderscoreUnicodeEscape {
2473        #[primary_span]
2474        #[label(parse_leading_underscore_unicode_escape_label)]
2475        span: Span,
2476        ch: String,
2477    },
2478    #[diag(parse_overlong_unicode_escape)]
2479    OverlongUnicodeEscape(
2480        #[primary_span]
2481        #[label]
2482        Span,
2483    ),
2484    #[diag(parse_unclosed_unicode_escape)]
2485    UnclosedUnicodeEscape(
2486        #[primary_span]
2487        #[label]
2488        Span,
2489        #[suggestion(
2490            parse_terminate,
2491            code = "}}",
2492            applicability = "maybe-incorrect",
2493            style = "verbose"
2494        )]
2495        Span,
2496    ),
2497    #[diag(parse_no_brace_unicode_escape)]
2498    NoBraceInUnicodeEscape {
2499        #[primary_span]
2500        span: Span,
2501        #[label]
2502        label: Option<Span>,
2503        #[subdiagnostic]
2504        sub: NoBraceUnicodeSub,
2505    },
2506    #[diag(parse_unicode_escape_in_byte)]
2507    #[help]
2508    UnicodeEscapeInByte(
2509        #[primary_span]
2510        #[label]
2511        Span,
2512    ),
2513    #[diag(parse_empty_unicode_escape)]
2514    EmptyUnicodeEscape(
2515        #[primary_span]
2516        #[label]
2517        Span,
2518    ),
2519    #[diag(parse_zero_chars)]
2520    ZeroChars(
2521        #[primary_span]
2522        #[label]
2523        Span,
2524    ),
2525    #[diag(parse_lone_slash)]
2526    LoneSlash(
2527        #[primary_span]
2528        #[label]
2529        Span,
2530    ),
2531    #[diag(parse_unskipped_whitespace)]
2532    UnskippedWhitespace {
2533        #[primary_span]
2534        span: Span,
2535        #[label]
2536        char_span: Span,
2537        ch: String,
2538    },
2539    #[diag(parse_multiple_skipped_lines)]
2540    MultipleSkippedLinesWarning(
2541        #[primary_span]
2542        #[label]
2543        Span,
2544    ),
2545    #[diag(parse_more_than_one_char)]
2546    MoreThanOneChar {
2547        #[primary_span]
2548        span: Span,
2549        #[subdiagnostic]
2550        note: Option<MoreThanOneCharNote>,
2551        #[subdiagnostic]
2552        suggestion: MoreThanOneCharSugg,
2553    },
2554    #[diag(parse_nul_in_c_str)]
2555    NulInCStr {
2556        #[primary_span]
2557        span: Span,
2558    },
2559}
2560
2561#[derive(Subdiagnostic)]
2562pub(crate) enum MoreThanOneCharSugg {
2563    #[suggestion(
2564        parse_consider_normalized,
2565        code = "{normalized}",
2566        applicability = "machine-applicable",
2567        style = "verbose"
2568    )]
2569    NormalizedForm {
2570        #[primary_span]
2571        span: Span,
2572        ch: String,
2573        normalized: String,
2574    },
2575    #[suggestion(
2576        parse_remove_non,
2577        code = "{ch}",
2578        applicability = "maybe-incorrect",
2579        style = "verbose"
2580    )]
2581    RemoveNonPrinting {
2582        #[primary_span]
2583        span: Span,
2584        ch: String,
2585    },
2586    #[suggestion(
2587        parse_use_double_quotes,
2588        code = "{sugg}",
2589        applicability = "machine-applicable",
2590        style = "verbose"
2591    )]
2592    QuotesFull {
2593        #[primary_span]
2594        span: Span,
2595        is_byte: bool,
2596        sugg: String,
2597    },
2598    #[multipart_suggestion(parse_use_double_quotes, applicability = "machine-applicable")]
2599    Quotes {
2600        #[suggestion_part(code = "{prefix}\"")]
2601        start: Span,
2602        #[suggestion_part(code = "\"")]
2603        end: Span,
2604        is_byte: bool,
2605        prefix: &'static str,
2606    },
2607}
2608
2609#[derive(Subdiagnostic)]
2610pub(crate) enum MoreThanOneCharNote {
2611    #[note(parse_followed_by)]
2612    AllCombining {
2613        #[primary_span]
2614        span: Span,
2615        chr: String,
2616        len: usize,
2617        escaped_marks: String,
2618    },
2619    #[note(parse_non_printing)]
2620    NonPrinting {
2621        #[primary_span]
2622        span: Span,
2623        escaped: String,
2624    },
2625}
2626
2627#[derive(Subdiagnostic)]
2628pub(crate) enum NoBraceUnicodeSub {
2629    #[suggestion(
2630        parse_use_braces,
2631        code = "{suggestion}",
2632        applicability = "maybe-incorrect",
2633        style = "verbose"
2634    )]
2635    Suggestion {
2636        #[primary_span]
2637        span: Span,
2638        suggestion: String,
2639    },
2640    #[help(parse_format_of_unicode)]
2641    Help,
2642}
2643
2644#[derive(Subdiagnostic)]
2645#[multipart_suggestion(parse_sugg_wrap_pattern_in_parens, applicability = "machine-applicable")]
2646pub(crate) struct WrapInParens {
2647    #[suggestion_part(code = "(")]
2648    pub(crate) lo: Span,
2649    #[suggestion_part(code = ")")]
2650    pub(crate) hi: Span,
2651}
2652
2653#[derive(Subdiagnostic)]
2654pub(crate) enum TopLevelOrPatternNotAllowedSugg {
2655    #[suggestion(
2656        parse_sugg_remove_leading_vert_in_pattern,
2657        code = "",
2658        applicability = "machine-applicable",
2659        style = "tool-only"
2660    )]
2661    RemoveLeadingVert {
2662        #[primary_span]
2663        span: Span,
2664    },
2665    WrapInParens {
2666        #[primary_span]
2667        span: Span,
2668        #[subdiagnostic]
2669        suggestion: WrapInParens,
2670    },
2671}
2672
2673#[derive(Diagnostic)]
2674#[diag(parse_unexpected_vert_vert_before_function_parameter)]
2675#[note(parse_note_pattern_alternatives_use_single_vert)]
2676pub(crate) struct UnexpectedVertVertBeforeFunctionParam {
2677    #[primary_span]
2678    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2679    pub span: Span,
2680}
2681
2682#[derive(Diagnostic)]
2683#[diag(parse_unexpected_vert_vert_in_pattern)]
2684pub(crate) struct UnexpectedVertVertInPattern {
2685    #[primary_span]
2686    #[suggestion(code = "|", applicability = "machine-applicable", style = "verbose")]
2687    pub span: Span,
2688    #[label(parse_label_while_parsing_or_pattern_here)]
2689    pub start: Option<Span>,
2690}
2691
2692#[derive(Subdiagnostic)]
2693#[suggestion(
2694    parse_trailing_vert_not_allowed,
2695    code = "",
2696    applicability = "machine-applicable",
2697    style = "tool-only"
2698)]
2699pub(crate) struct TrailingVertSuggestion {
2700    #[primary_span]
2701    pub span: Span,
2702}
2703
2704#[derive(Diagnostic)]
2705#[diag(parse_trailing_vert_not_allowed)]
2706pub(crate) struct TrailingVertNotAllowed {
2707    #[primary_span]
2708    pub span: Span,
2709    #[subdiagnostic]
2710    pub suggestion: TrailingVertSuggestion,
2711    #[label(parse_label_while_parsing_or_pattern_here)]
2712    pub start: Option<Span>,
2713    pub token: Token,
2714    #[note(parse_note_pattern_alternatives_use_single_vert)]
2715    pub note_double_vert: bool,
2716}
2717
2718#[derive(Diagnostic)]
2719#[diag(parse_dotdotdot_rest_pattern)]
2720pub(crate) struct DotDotDotRestPattern {
2721    #[primary_span]
2722    #[label]
2723    pub span: Span,
2724    #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
2725    pub suggestion: Option<Span>,
2726    #[note]
2727    pub var_args: Option<()>,
2728}
2729
2730#[derive(Diagnostic)]
2731#[diag(parse_pattern_on_wrong_side_of_at)]
2732pub(crate) struct PatternOnWrongSideOfAt {
2733    #[primary_span]
2734    #[suggestion(code = "{whole_pat}", applicability = "machine-applicable", style = "verbose")]
2735    pub whole_span: Span,
2736    pub whole_pat: String,
2737    #[label(parse_label_pattern)]
2738    pub pattern: Span,
2739    #[label(parse_label_binding)]
2740    pub binding: Span,
2741}
2742
2743#[derive(Diagnostic)]
2744#[diag(parse_expected_binding_left_of_at)]
2745#[note]
2746pub(crate) struct ExpectedBindingLeftOfAt {
2747    #[primary_span]
2748    pub whole_span: Span,
2749    #[label(parse_label_lhs)]
2750    pub lhs: Span,
2751    #[label(parse_label_rhs)]
2752    pub rhs: Span,
2753}
2754
2755#[derive(Subdiagnostic)]
2756#[multipart_suggestion(
2757    parse_ambiguous_range_pattern_suggestion,
2758    applicability = "machine-applicable"
2759)]
2760pub(crate) struct ParenRangeSuggestion {
2761    #[suggestion_part(code = "(")]
2762    pub lo: Span,
2763    #[suggestion_part(code = ")")]
2764    pub hi: Span,
2765}
2766
2767#[derive(Diagnostic)]
2768#[diag(parse_ambiguous_range_pattern)]
2769pub(crate) struct AmbiguousRangePattern {
2770    #[primary_span]
2771    pub span: Span,
2772    #[subdiagnostic]
2773    pub suggestion: ParenRangeSuggestion,
2774}
2775
2776#[derive(Diagnostic)]
2777#[diag(parse_unexpected_lifetime_in_pattern)]
2778pub(crate) struct UnexpectedLifetimeInPattern {
2779    #[primary_span]
2780    pub span: Span,
2781    pub symbol: Symbol,
2782    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2783    pub suggestion: Span,
2784}
2785
2786#[derive(Diagnostic)]
2787pub(crate) enum InvalidMutInPattern {
2788    #[diag(parse_mut_on_nested_ident_pattern)]
2789    #[note(parse_note_mut_pattern_usage)]
2790    NestedIdent {
2791        #[primary_span]
2792        #[suggestion(code = "{pat}", applicability = "machine-applicable", style = "verbose")]
2793        span: Span,
2794        pat: String,
2795    },
2796    #[diag(parse_mut_on_non_ident_pattern)]
2797    #[note(parse_note_mut_pattern_usage)]
2798    NonIdent {
2799        #[primary_span]
2800        #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2801        span: Span,
2802    },
2803}
2804
2805#[derive(Diagnostic)]
2806#[diag(parse_repeated_mut_in_pattern)]
2807pub(crate) struct RepeatedMutInPattern {
2808    #[primary_span]
2809    pub span: Span,
2810    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2811    pub suggestion: Span,
2812}
2813
2814#[derive(Diagnostic)]
2815#[diag(parse_dot_dot_dot_range_to_pattern_not_allowed)]
2816pub(crate) struct DotDotDotRangeToPatternNotAllowed {
2817    #[primary_span]
2818    #[suggestion(style = "verbose", code = "..=", applicability = "machine-applicable")]
2819    pub span: Span,
2820}
2821
2822#[derive(Diagnostic)]
2823#[diag(parse_enum_pattern_instead_of_identifier)]
2824pub(crate) struct EnumPatternInsteadOfIdentifier {
2825    #[primary_span]
2826    pub span: Span,
2827}
2828
2829#[derive(Diagnostic)]
2830#[diag(parse_at_dot_dot_in_struct_pattern)]
2831pub(crate) struct AtDotDotInStructPattern {
2832    #[primary_span]
2833    pub span: Span,
2834    #[suggestion(code = "", style = "verbose", applicability = "machine-applicable")]
2835    pub remove: Span,
2836    pub ident: Ident,
2837}
2838
2839#[derive(Diagnostic)]
2840#[diag(parse_at_in_struct_pattern)]
2841#[note]
2842#[help]
2843pub(crate) struct AtInStructPattern {
2844    #[primary_span]
2845    pub span: Span,
2846}
2847
2848#[derive(Diagnostic)]
2849#[diag(parse_dot_dot_dot_for_remaining_fields)]
2850pub(crate) struct DotDotDotForRemainingFields {
2851    #[primary_span]
2852    #[suggestion(code = "..", style = "verbose", applicability = "machine-applicable")]
2853    pub span: Span,
2854    pub token_str: Cow<'static, str>,
2855}
2856
2857#[derive(Diagnostic)]
2858#[diag(parse_expected_comma_after_pattern_field)]
2859pub(crate) struct ExpectedCommaAfterPatternField {
2860    #[primary_span]
2861    pub span: Span,
2862}
2863
2864#[derive(Diagnostic)]
2865#[diag(parse_unexpected_expr_in_pat)]
2866#[note]
2867pub(crate) struct UnexpectedExpressionInPattern {
2868    /// The unexpected expr's span.
2869    #[primary_span]
2870    #[label]
2871    pub span: Span,
2872    /// Was a `RangePatternBound` expected?
2873    pub is_bound: bool,
2874    /// The unexpected expr's precedence (used in match arm guard suggestions).
2875    pub expr_precedence: ExprPrecedence,
2876}
2877
2878#[derive(Subdiagnostic)]
2879pub(crate) enum UnexpectedExpressionInPatternSugg {
2880    #[multipart_suggestion(
2881        parse_unexpected_expr_in_pat_create_guard_sugg,
2882        applicability = "maybe-incorrect"
2883    )]
2884    CreateGuard {
2885        /// Where to put the suggested identifier.
2886        #[suggestion_part(code = "{ident}")]
2887        ident_span: Span,
2888        /// Where to put the match arm.
2889        #[suggestion_part(code = " if {ident} == {expr}")]
2890        pat_hi: Span,
2891        /// The suggested identifier.
2892        ident: String,
2893        /// The unexpected expression.
2894        expr: String,
2895    },
2896
2897    #[multipart_suggestion(
2898        parse_unexpected_expr_in_pat_update_guard_sugg,
2899        applicability = "maybe-incorrect"
2900    )]
2901    UpdateGuard {
2902        /// Where to put the suggested identifier.
2903        #[suggestion_part(code = "{ident}")]
2904        ident_span: Span,
2905        /// The beginning of the match arm guard's expression (insert a `(` if `Some`).
2906        #[suggestion_part(code = "(")]
2907        guard_lo: Option<Span>,
2908        /// The end of the match arm guard's expression.
2909        #[suggestion_part(code = "{guard_hi_paren} && {ident} == {expr}")]
2910        guard_hi: Span,
2911        /// Either `")"` or `""`.
2912        guard_hi_paren: &'static str,
2913        /// The suggested identifier.
2914        ident: String,
2915        /// The unexpected expression.
2916        expr: String,
2917    },
2918
2919    #[multipart_suggestion(
2920        parse_unexpected_expr_in_pat_const_sugg,
2921        applicability = "has-placeholders"
2922    )]
2923    Const {
2924        /// Where to put the extracted constant declaration.
2925        #[suggestion_part(code = "{indentation}const {ident}: /* Type */ = {expr};\n")]
2926        stmt_lo: Span,
2927        /// Where to put the suggested identifier.
2928        #[suggestion_part(code = "{ident}")]
2929        ident_span: Span,
2930        /// The suggested identifier.
2931        ident: String,
2932        /// The unexpected expression.
2933        expr: String,
2934        /// The statement's block's indentation.
2935        indentation: String,
2936    },
2937}
2938
2939#[derive(Diagnostic)]
2940#[diag(parse_unexpected_paren_in_range_pat)]
2941pub(crate) struct UnexpectedParenInRangePat {
2942    #[primary_span]
2943    pub span: Vec<Span>,
2944    #[subdiagnostic]
2945    pub sugg: UnexpectedParenInRangePatSugg,
2946}
2947
2948#[derive(Subdiagnostic)]
2949#[multipart_suggestion(
2950    parse_unexpected_paren_in_range_pat_sugg,
2951    applicability = "machine-applicable"
2952)]
2953pub(crate) struct UnexpectedParenInRangePatSugg {
2954    #[suggestion_part(code = "")]
2955    pub start_span: Span,
2956    #[suggestion_part(code = "")]
2957    pub end_span: Span,
2958}
2959
2960#[derive(Diagnostic)]
2961#[diag(parse_return_types_use_thin_arrow)]
2962pub(crate) struct ReturnTypesUseThinArrow {
2963    #[primary_span]
2964    pub span: Span,
2965    #[suggestion(style = "verbose", code = " -> ", applicability = "machine-applicable")]
2966    pub suggestion: Span,
2967}
2968
2969#[derive(Diagnostic)]
2970#[diag(parse_need_plus_after_trait_object_lifetime)]
2971pub(crate) struct NeedPlusAfterTraitObjectLifetime {
2972    #[primary_span]
2973    pub span: Span,
2974    #[suggestion(code = " + /* Trait */", applicability = "has-placeholders")]
2975    pub suggestion: Span,
2976}
2977
2978#[derive(Diagnostic)]
2979#[diag(parse_expected_mut_or_const_in_raw_pointer_type)]
2980pub(crate) struct ExpectedMutOrConstInRawPointerType {
2981    #[primary_span]
2982    pub span: Span,
2983    #[suggestion(code("mut ", "const "), applicability = "has-placeholders", style = "verbose")]
2984    pub after_asterisk: Span,
2985}
2986
2987#[derive(Diagnostic)]
2988#[diag(parse_lifetime_after_mut)]
2989pub(crate) struct LifetimeAfterMut {
2990    #[primary_span]
2991    pub span: Span,
2992    #[suggestion(code = "&{snippet} mut", applicability = "maybe-incorrect", style = "verbose")]
2993    pub suggest_lifetime: Option<Span>,
2994    pub snippet: String,
2995}
2996
2997#[derive(Diagnostic)]
2998#[diag(parse_dyn_after_mut)]
2999pub(crate) struct DynAfterMut {
3000    #[primary_span]
3001    #[suggestion(code = "&mut dyn", applicability = "machine-applicable", style = "verbose")]
3002    pub span: Span,
3003}
3004
3005#[derive(Diagnostic)]
3006#[diag(parse_fn_pointer_cannot_be_const)]
3007#[note]
3008pub(crate) struct FnPointerCannotBeConst {
3009    #[primary_span]
3010    #[label]
3011    pub span: Span,
3012    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3013    pub suggestion: Span,
3014}
3015
3016#[derive(Diagnostic)]
3017#[diag(parse_fn_pointer_cannot_be_async)]
3018#[note]
3019pub(crate) struct FnPointerCannotBeAsync {
3020    #[primary_span]
3021    #[label]
3022    pub span: Span,
3023    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3024    pub suggestion: Span,
3025}
3026
3027#[derive(Diagnostic)]
3028#[diag(parse_nested_c_variadic_type, code = E0743)]
3029pub(crate) struct NestedCVariadicType {
3030    #[primary_span]
3031    pub span: Span,
3032}
3033
3034#[derive(Diagnostic)]
3035#[diag(parse_dotdotdot_rest_type)]
3036#[note]
3037pub(crate) struct InvalidCVariadicType {
3038    #[primary_span]
3039    pub span: Span,
3040}
3041
3042#[derive(Diagnostic)]
3043#[diag(parse_invalid_dyn_keyword)]
3044#[help]
3045pub(crate) struct InvalidDynKeyword {
3046    #[primary_span]
3047    pub span: Span,
3048    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
3049    pub suggestion: Span,
3050}
3051
3052#[derive(Subdiagnostic)]
3053pub(crate) enum HelpUseLatestEdition {
3054    #[help(parse_help_set_edition_cargo)]
3055    #[note(parse_note_edition_guide)]
3056    Cargo { edition: Edition },
3057    #[help(parse_help_set_edition_standalone)]
3058    #[note(parse_note_edition_guide)]
3059    Standalone { edition: Edition },
3060}
3061
3062impl HelpUseLatestEdition {
3063    pub(crate) fn new() -> Self {
3064        let edition = LATEST_STABLE_EDITION;
3065        if rustc_session::utils::was_invoked_from_cargo() {
3066            Self::Cargo { edition }
3067        } else {
3068            Self::Standalone { edition }
3069        }
3070    }
3071}
3072
3073#[derive(Diagnostic)]
3074#[diag(parse_box_syntax_removed)]
3075pub(crate) struct BoxSyntaxRemoved {
3076    #[primary_span]
3077    pub span: Span,
3078    #[subdiagnostic]
3079    pub sugg: AddBoxNew,
3080}
3081
3082#[derive(Subdiagnostic)]
3083#[multipart_suggestion(
3084    parse_box_syntax_removed_suggestion,
3085    applicability = "machine-applicable",
3086    style = "verbose"
3087)]
3088pub(crate) struct AddBoxNew {
3089    #[suggestion_part(code = "Box::new(")]
3090    pub box_kw_and_lo: Span,
3091    #[suggestion_part(code = ")")]
3092    pub hi: Span,
3093}
3094
3095#[derive(Diagnostic)]
3096#[diag(parse_bad_return_type_notation_output)]
3097pub(crate) struct BadReturnTypeNotationOutput {
3098    #[primary_span]
3099    pub span: Span,
3100    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3101    pub suggestion: Span,
3102}
3103
3104#[derive(Diagnostic)]
3105#[diag(parse_bad_assoc_type_bounds)]
3106pub(crate) struct BadAssocTypeBounds {
3107    #[primary_span]
3108    #[label]
3109    pub span: Span,
3110}
3111
3112#[derive(Diagnostic)]
3113#[diag(parse_attr_after_generic)]
3114pub(crate) struct AttrAfterGeneric {
3115    #[primary_span]
3116    #[label]
3117    pub span: Span,
3118}
3119
3120#[derive(Diagnostic)]
3121#[diag(parse_attr_without_generics)]
3122pub(crate) struct AttrWithoutGenerics {
3123    #[primary_span]
3124    #[label]
3125    pub span: Span,
3126}
3127
3128#[derive(Diagnostic)]
3129#[diag(parse_where_generics)]
3130pub(crate) struct WhereOnGenerics {
3131    #[primary_span]
3132    #[label]
3133    pub span: Span,
3134}
3135
3136#[derive(Diagnostic)]
3137#[diag(parse_generics_in_path)]
3138pub(crate) struct GenericsInPath {
3139    #[primary_span]
3140    pub span: Vec<Span>,
3141}
3142
3143#[derive(Diagnostic)]
3144#[diag(parse_lifetime_in_eq_constraint)]
3145#[help]
3146pub(crate) struct LifetimeInEqConstraint {
3147    #[primary_span]
3148    #[label]
3149    pub span: Span,
3150    pub lifetime: Ident,
3151    #[label(parse_context_label)]
3152    pub binding_label: Span,
3153    #[suggestion(
3154        parse_colon_sugg,
3155        style = "verbose",
3156        applicability = "maybe-incorrect",
3157        code = ": "
3158    )]
3159    pub colon_sugg: Span,
3160}
3161
3162#[derive(Diagnostic)]
3163#[diag(parse_modifier_lifetime)]
3164pub(crate) struct ModifierLifetime {
3165    #[primary_span]
3166    #[suggestion(style = "tool-only", applicability = "maybe-incorrect", code = "")]
3167    pub span: Span,
3168    pub modifier: &'static str,
3169}
3170
3171#[derive(Diagnostic)]
3172#[diag(parse_underscore_literal_suffix)]
3173pub(crate) struct UnderscoreLiteralSuffix {
3174    #[primary_span]
3175    pub span: Span,
3176}
3177
3178#[derive(Diagnostic)]
3179#[diag(parse_expect_label_found_ident)]
3180pub(crate) struct ExpectedLabelFoundIdent {
3181    #[primary_span]
3182    pub span: Span,
3183    #[suggestion(code = "'", applicability = "machine-applicable", style = "verbose")]
3184    pub start: Span,
3185}
3186
3187#[derive(Diagnostic)]
3188#[diag(parse_inappropriate_default)]
3189#[note]
3190pub(crate) struct InappropriateDefault {
3191    #[primary_span]
3192    #[label]
3193    pub span: Span,
3194    pub article: &'static str,
3195    pub descr: &'static str,
3196}
3197
3198#[derive(Diagnostic)]
3199#[diag(parse_recover_import_as_use)]
3200pub(crate) struct RecoverImportAsUse {
3201    #[primary_span]
3202    #[suggestion(code = "use", applicability = "machine-applicable", style = "verbose")]
3203    pub span: Span,
3204    pub token_name: String,
3205}
3206
3207#[derive(Diagnostic)]
3208#[diag(parse_single_colon_import_path)]
3209#[note]
3210pub(crate) struct SingleColonImportPath {
3211    #[primary_span]
3212    #[suggestion(code = "::", applicability = "machine-applicable", style = "verbose")]
3213    pub span: Span,
3214}
3215
3216#[derive(Diagnostic)]
3217#[diag(parse_bad_item_kind)]
3218pub(crate) struct BadItemKind {
3219    #[primary_span]
3220    pub span: Span,
3221    pub descr: &'static str,
3222    pub ctx: &'static str,
3223    #[help]
3224    pub help: bool,
3225}
3226
3227#[derive(Diagnostic)]
3228#[diag(parse_macro_rules_missing_bang)]
3229pub(crate) struct MacroRulesMissingBang {
3230    #[primary_span]
3231    pub span: Span,
3232    #[suggestion(code = "!", applicability = "machine-applicable", style = "verbose")]
3233    pub hi: Span,
3234}
3235
3236#[derive(Diagnostic)]
3237#[diag(parse_macro_name_remove_bang)]
3238pub(crate) struct MacroNameRemoveBang {
3239    #[primary_span]
3240    #[suggestion(code = "", applicability = "machine-applicable", style = "short")]
3241    pub span: Span,
3242}
3243
3244#[derive(Diagnostic)]
3245#[diag(parse_macro_rules_visibility)]
3246pub(crate) struct MacroRulesVisibility<'a> {
3247    #[primary_span]
3248    #[suggestion(code = "#[macro_export]", applicability = "maybe-incorrect", style = "verbose")]
3249    pub span: Span,
3250    pub vis: &'a str,
3251}
3252
3253#[derive(Diagnostic)]
3254#[diag(parse_macro_invocation_visibility)]
3255#[help]
3256pub(crate) struct MacroInvocationVisibility<'a> {
3257    #[primary_span]
3258    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
3259    pub span: Span,
3260    pub vis: &'a str,
3261}
3262
3263#[derive(Diagnostic)]
3264#[diag(parse_nested_adt)]
3265pub(crate) struct NestedAdt<'a> {
3266    #[primary_span]
3267    pub span: Span,
3268    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3269    pub item: Span,
3270    pub keyword: &'a str,
3271    pub kw_str: Cow<'a, str>,
3272}
3273
3274#[derive(Diagnostic)]
3275#[diag(parse_function_body_equals_expr)]
3276pub(crate) struct FunctionBodyEqualsExpr {
3277    #[primary_span]
3278    pub span: Span,
3279    #[subdiagnostic]
3280    pub sugg: FunctionBodyEqualsExprSugg,
3281}
3282
3283#[derive(Subdiagnostic)]
3284#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3285pub(crate) struct FunctionBodyEqualsExprSugg {
3286    #[suggestion_part(code = "{{")]
3287    pub eq: Span,
3288    #[suggestion_part(code = " }}")]
3289    pub semi: Span,
3290}
3291
3292#[derive(Diagnostic)]
3293#[diag(parse_box_not_pat)]
3294pub(crate) struct BoxNotPat {
3295    #[primary_span]
3296    pub span: Span,
3297    #[note]
3298    pub kw: Span,
3299    #[suggestion(code = "r#", applicability = "maybe-incorrect", style = "verbose")]
3300    pub lo: Span,
3301    pub descr: String,
3302}
3303
3304#[derive(Diagnostic)]
3305#[diag(parse_unmatched_angle)]
3306pub(crate) struct UnmatchedAngle {
3307    #[primary_span]
3308    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
3309    pub span: Span,
3310    pub plural: bool,
3311}
3312
3313#[derive(Diagnostic)]
3314#[diag(parse_missing_plus_in_bounds)]
3315pub(crate) struct MissingPlusBounds {
3316    #[primary_span]
3317    pub span: Span,
3318    #[suggestion(code = " +", applicability = "maybe-incorrect", style = "verbose")]
3319    pub hi: Span,
3320    pub sym: Symbol,
3321}
3322
3323#[derive(Diagnostic)]
3324#[diag(parse_incorrect_parens_trait_bounds)]
3325pub(crate) struct IncorrectParensTraitBounds {
3326    #[primary_span]
3327    pub span: Vec<Span>,
3328    #[subdiagnostic]
3329    pub sugg: IncorrectParensTraitBoundsSugg,
3330}
3331
3332#[derive(Subdiagnostic)]
3333#[multipart_suggestion(
3334    parse_incorrect_parens_trait_bounds_sugg,
3335    applicability = "machine-applicable"
3336)]
3337pub(crate) struct IncorrectParensTraitBoundsSugg {
3338    #[suggestion_part(code = " ")]
3339    pub wrong_span: Span,
3340    #[suggestion_part(code = "(")]
3341    pub new_span: Span,
3342}
3343
3344#[derive(Diagnostic)]
3345#[diag(parse_kw_bad_case)]
3346pub(crate) struct KwBadCase<'a> {
3347    #[primary_span]
3348    #[suggestion(code = "{kw}", style = "verbose", applicability = "machine-applicable")]
3349    pub span: Span,
3350    pub kw: &'a str,
3351    pub case: Case,
3352}
3353
3354pub(crate) enum Case {
3355    Upper,
3356    Lower,
3357    Mixed,
3358}
3359
3360impl IntoDiagArg for Case {
3361    fn into_diag_arg(self, path: &mut Option<PathBuf>) -> DiagArgValue {
3362        match self {
3363            Case::Upper => "uppercase",
3364            Case::Lower => "lowercase",
3365            Case::Mixed => "the correct case",
3366        }
3367        .into_diag_arg(path)
3368    }
3369}
3370
3371#[derive(Diagnostic)]
3372#[diag(parse_unknown_builtin_construct)]
3373pub(crate) struct UnknownBuiltinConstruct {
3374    #[primary_span]
3375    pub span: Span,
3376    pub name: Ident,
3377}
3378
3379#[derive(Diagnostic)]
3380#[diag(parse_expected_builtin_ident)]
3381pub(crate) struct ExpectedBuiltinIdent {
3382    #[primary_span]
3383    pub span: Span,
3384}
3385
3386#[derive(Diagnostic)]
3387#[diag(parse_static_with_generics)]
3388pub(crate) struct StaticWithGenerics {
3389    #[primary_span]
3390    pub span: Span,
3391}
3392
3393#[derive(Diagnostic)]
3394#[diag(parse_where_clause_before_const_body)]
3395pub(crate) struct WhereClauseBeforeConstBody {
3396    #[primary_span]
3397    #[label]
3398    pub span: Span,
3399    #[label(parse_name_label)]
3400    pub name: Span,
3401    #[label(parse_body_label)]
3402    pub body: Span,
3403    #[subdiagnostic]
3404    pub sugg: Option<WhereClauseBeforeConstBodySugg>,
3405}
3406
3407#[derive(Subdiagnostic)]
3408#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3409pub(crate) struct WhereClauseBeforeConstBodySugg {
3410    #[suggestion_part(code = "= {snippet} ")]
3411    pub left: Span,
3412    pub snippet: String,
3413    #[suggestion_part(code = "")]
3414    pub right: Span,
3415}
3416
3417#[derive(Diagnostic)]
3418#[diag(parse_generic_args_in_pat_require_turbofish_syntax)]
3419pub(crate) struct GenericArgsInPatRequireTurbofishSyntax {
3420    #[primary_span]
3421    pub span: Span,
3422    #[suggestion(
3423        parse_sugg_turbofish_syntax,
3424        style = "verbose",
3425        code = "::",
3426        applicability = "maybe-incorrect"
3427    )]
3428    pub suggest_turbofish: Span,
3429}
3430
3431#[derive(Diagnostic)]
3432#[diag(parse_transpose_dyn_or_impl)]
3433pub(crate) struct TransposeDynOrImpl<'a> {
3434    #[primary_span]
3435    pub span: Span,
3436    pub kw: &'a str,
3437    #[subdiagnostic]
3438    pub sugg: TransposeDynOrImplSugg<'a>,
3439}
3440
3441#[derive(Subdiagnostic)]
3442#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3443pub(crate) struct TransposeDynOrImplSugg<'a> {
3444    #[suggestion_part(code = "")]
3445    pub removal_span: Span,
3446    #[suggestion_part(code = "{kw} ")]
3447    pub insertion_span: Span,
3448    pub kw: &'a str,
3449}
3450
3451#[derive(Diagnostic)]
3452#[diag(parse_array_index_offset_of)]
3453pub(crate) struct ArrayIndexInOffsetOf(#[primary_span] pub Span);
3454
3455#[derive(Diagnostic)]
3456#[diag(parse_invalid_offset_of)]
3457pub(crate) struct InvalidOffsetOf(#[primary_span] pub Span);
3458
3459#[derive(Diagnostic)]
3460#[diag(parse_async_impl)]
3461pub(crate) struct AsyncImpl {
3462    #[primary_span]
3463    pub span: Span,
3464}
3465
3466#[derive(Diagnostic)]
3467#[diag(parse_expr_rarrow_call)]
3468#[help]
3469pub(crate) struct ExprRArrowCall {
3470    #[primary_span]
3471    #[suggestion(style = "verbose", applicability = "machine-applicable", code = ".")]
3472    pub span: Span,
3473}
3474
3475#[derive(Diagnostic)]
3476#[diag(parse_dot_dot_range_attribute)]
3477pub(crate) struct DotDotRangeAttribute {
3478    #[primary_span]
3479    pub span: Span,
3480}
3481
3482#[derive(Diagnostic)]
3483#[diag(parse_binder_before_modifiers)]
3484pub(crate) struct BinderBeforeModifiers {
3485    #[primary_span]
3486    pub binder_span: Span,
3487    #[label]
3488    pub modifiers_span: Span,
3489}
3490
3491#[derive(Diagnostic)]
3492#[diag(parse_binder_and_polarity)]
3493pub(crate) struct BinderAndPolarity {
3494    #[primary_span]
3495    pub polarity_span: Span,
3496    #[label]
3497    pub binder_span: Span,
3498    pub polarity: &'static str,
3499}
3500
3501#[derive(Diagnostic)]
3502#[diag(parse_modifiers_and_polarity)]
3503pub(crate) struct PolarityAndModifiers {
3504    #[primary_span]
3505    pub polarity_span: Span,
3506    #[label]
3507    pub modifiers_span: Span,
3508    pub polarity: &'static str,
3509    pub modifiers_concatenated: String,
3510}
3511
3512#[derive(Diagnostic)]
3513#[diag(parse_incorrect_type_on_self)]
3514pub(crate) struct IncorrectTypeOnSelf {
3515    #[primary_span]
3516    pub span: Span,
3517    #[subdiagnostic]
3518    pub move_self_modifier: MoveSelfModifier,
3519}
3520
3521#[derive(Subdiagnostic)]
3522#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3523pub(crate) struct MoveSelfModifier {
3524    #[suggestion_part(code = "")]
3525    pub removal_span: Span,
3526    #[suggestion_part(code = "{modifier}")]
3527    pub insertion_span: Span,
3528    pub modifier: String,
3529}
3530
3531#[derive(Diagnostic)]
3532#[diag(parse_asm_unsupported_operand)]
3533pub(crate) struct AsmUnsupportedOperand<'a> {
3534    #[primary_span]
3535    #[label]
3536    pub(crate) span: Span,
3537    pub(crate) symbol: &'a str,
3538    pub(crate) macro_name: &'static str,
3539}
3540
3541#[derive(Diagnostic)]
3542#[diag(parse_asm_underscore_input)]
3543pub(crate) struct AsmUnderscoreInput {
3544    #[primary_span]
3545    pub(crate) span: Span,
3546}
3547
3548#[derive(Diagnostic)]
3549#[diag(parse_asm_sym_no_path)]
3550pub(crate) struct AsmSymNoPath {
3551    #[primary_span]
3552    pub(crate) span: Span,
3553}
3554
3555#[derive(Diagnostic)]
3556#[diag(parse_asm_requires_template)]
3557pub(crate) struct AsmRequiresTemplate {
3558    #[primary_span]
3559    pub(crate) span: Span,
3560}
3561
3562#[derive(Diagnostic)]
3563#[diag(parse_asm_expected_comma)]
3564pub(crate) struct AsmExpectedComma {
3565    #[primary_span]
3566    #[label]
3567    pub(crate) span: Span,
3568}
3569
3570#[derive(Diagnostic)]
3571#[diag(parse_asm_expected_other)]
3572pub(crate) struct AsmExpectedOther {
3573    #[primary_span]
3574    #[label(parse_asm_expected_other)]
3575    pub(crate) span: Span,
3576    pub(crate) is_inline_asm: bool,
3577}
3578
3579#[derive(Diagnostic)]
3580#[diag(parse_asm_non_abi)]
3581pub(crate) struct NonABI {
3582    #[primary_span]
3583    pub(crate) span: Span,
3584}
3585
3586#[derive(Diagnostic)]
3587#[diag(parse_asm_expected_string_literal)]
3588pub(crate) struct AsmExpectedStringLiteral {
3589    #[primary_span]
3590    #[label]
3591    pub(crate) span: Span,
3592}
3593
3594#[derive(Diagnostic)]
3595#[diag(parse_asm_expected_register_class_or_explicit_register)]
3596pub(crate) struct ExpectedRegisterClassOrExplicitRegister {
3597    #[primary_span]
3598    pub(crate) span: Span,
3599}
3600
3601#[derive(LintDiagnostic)]
3602#[diag(parse_hidden_unicode_codepoints)]
3603#[note]
3604pub(crate) struct HiddenUnicodeCodepointsDiag {
3605    pub label: String,
3606    pub count: usize,
3607    #[label]
3608    pub span_label: Span,
3609    #[subdiagnostic]
3610    pub labels: Option<HiddenUnicodeCodepointsDiagLabels>,
3611    #[subdiagnostic]
3612    pub sub: HiddenUnicodeCodepointsDiagSub,
3613}
3614
3615pub(crate) struct HiddenUnicodeCodepointsDiagLabels {
3616    pub spans: Vec<(char, Span)>,
3617}
3618
3619impl Subdiagnostic for HiddenUnicodeCodepointsDiagLabels {
3620    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
3621        for (c, span) in self.spans {
3622            diag.span_label(span, format!("{c:?}"));
3623        }
3624    }
3625}
3626
3627pub(crate) enum HiddenUnicodeCodepointsDiagSub {
3628    Escape { spans: Vec<(char, Span)> },
3629    NoEscape { spans: Vec<(char, Span)> },
3630}
3631
3632// Used because of multiple multipart_suggestion and note
3633impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub {
3634    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
3635        match self {
3636            HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
3637                diag.multipart_suggestion_with_style(
3638                    fluent::parse_suggestion_remove,
3639                    spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
3640                    Applicability::MachineApplicable,
3641                    SuggestionStyle::HideCodeAlways,
3642                );
3643                diag.multipart_suggestion(
3644                    fluent::parse_suggestion_escape,
3645                    spans
3646                        .into_iter()
3647                        .map(|(c, span)| {
3648                            let c = format!("{c:?}");
3649                            (span, c[1..c.len() - 1].to_string())
3650                        })
3651                        .collect(),
3652                    Applicability::MachineApplicable,
3653                );
3654            }
3655            HiddenUnicodeCodepointsDiagSub::NoEscape { spans } => {
3656                // FIXME: in other suggestions we've reversed the inner spans of doc comments. We
3657                // should do the same here to provide the same good suggestions as we do for
3658                // literals above.
3659                diag.arg(
3660                    "escaped",
3661                    spans
3662                        .into_iter()
3663                        .map(|(c, _)| format!("{c:?}"))
3664                        .collect::<Vec<String>>()
3665                        .join(", "),
3666                );
3667                diag.note(fluent::parse_suggestion_remove);
3668                diag.note(fluent::parse_no_suggestion_note_escape);
3669            }
3670        }
3671    }
3672}
3673
3674#[derive(LintDiagnostic)]
3675#[diag(parse_varargs_without_pattern)]
3676pub(crate) struct VarargsWithoutPattern {
3677    #[suggestion(code = "_: ...", applicability = "machine-applicable")]
3678    pub span: Span,
3679}
3680
3681#[derive(Diagnostic)]
3682#[diag(parse_delegation_non_trait_impl_reuse)]
3683pub(crate) struct ImplReuseInherentImpl {
3684    #[primary_span]
3685    pub span: Span,
3686}