rustc_parse/
errors.rs

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