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    #[help(parse_tuple_exception_line_1)]
1021    #[help(parse_tuple_exception_line_2)]
1022    #[help(parse_tuple_exception_line_3)]
1023    pub exception: bool,
1024}
1025
1026#[derive(Diagnostic)]
1027#[diag(parse_non_string_abi_literal)]
1028pub(crate) struct NonStringAbiLiteral {
1029    #[primary_span]
1030    #[suggestion(code = "\"C\"", applicability = "maybe-incorrect", style = "verbose")]
1031    pub span: Span,
1032}
1033
1034#[derive(Diagnostic)]
1035#[diag(parse_mismatched_closing_delimiter)]
1036pub(crate) struct MismatchedClosingDelimiter {
1037    #[primary_span]
1038    pub spans: Vec<Span>,
1039    pub delimiter: String,
1040    #[label(parse_label_unmatched)]
1041    pub unmatched: Span,
1042    #[label(parse_label_opening_candidate)]
1043    pub opening_candidate: Option<Span>,
1044    #[label(parse_label_unclosed)]
1045    pub unclosed: Option<Span>,
1046}
1047
1048#[derive(Diagnostic)]
1049#[diag(parse_incorrect_visibility_restriction, code = E0704)]
1050#[help]
1051pub(crate) struct IncorrectVisibilityRestriction {
1052    #[primary_span]
1053    #[suggestion(code = "in {inner_str}", applicability = "machine-applicable", style = "verbose")]
1054    pub span: Span,
1055    pub inner_str: String,
1056}
1057
1058#[derive(Diagnostic)]
1059#[diag(parse_assignment_else_not_allowed)]
1060pub(crate) struct AssignmentElseNotAllowed {
1061    #[primary_span]
1062    pub span: Span,
1063}
1064
1065#[derive(Diagnostic)]
1066#[diag(parse_expected_statement_after_outer_attr)]
1067pub(crate) struct ExpectedStatementAfterOuterAttr {
1068    #[primary_span]
1069    pub span: Span,
1070}
1071
1072#[derive(Diagnostic)]
1073#[diag(parse_doc_comment_does_not_document_anything, code = E0585)]
1074#[help]
1075pub(crate) struct DocCommentDoesNotDocumentAnything {
1076    #[primary_span]
1077    pub span: Span,
1078    #[suggestion(code = ",", applicability = "machine-applicable", style = "verbose")]
1079    pub missing_comma: Option<Span>,
1080}
1081
1082#[derive(Diagnostic)]
1083#[diag(parse_const_let_mutually_exclusive)]
1084pub(crate) struct ConstLetMutuallyExclusive {
1085    #[primary_span]
1086    #[suggestion(code = "const", applicability = "maybe-incorrect", style = "verbose")]
1087    pub span: Span,
1088}
1089
1090#[derive(Diagnostic)]
1091#[diag(parse_invalid_expression_in_let_else)]
1092pub(crate) struct InvalidExpressionInLetElse {
1093    #[primary_span]
1094    pub span: Span,
1095    pub operator: &'static str,
1096    #[subdiagnostic]
1097    pub sugg: WrapInParentheses,
1098}
1099
1100#[derive(Diagnostic)]
1101#[diag(parse_invalid_curly_in_let_else)]
1102pub(crate) struct InvalidCurlyInLetElse {
1103    #[primary_span]
1104    pub span: Span,
1105    #[subdiagnostic]
1106    pub sugg: WrapInParentheses,
1107}
1108
1109#[derive(Diagnostic)]
1110#[diag(parse_compound_assignment_expression_in_let)]
1111#[help]
1112pub(crate) struct CompoundAssignmentExpressionInLet {
1113    #[primary_span]
1114    pub span: Span,
1115    #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")]
1116    pub suggestion: Span,
1117}
1118
1119#[derive(Diagnostic)]
1120#[diag(parse_suffixed_literal_in_attribute)]
1121#[help]
1122pub(crate) struct SuffixedLiteralInAttribute {
1123    #[primary_span]
1124    pub span: Span,
1125}
1126
1127#[derive(Diagnostic)]
1128#[diag(parse_invalid_meta_item)]
1129pub(crate) struct InvalidMetaItem {
1130    #[primary_span]
1131    pub span: Span,
1132    pub descr: String,
1133    #[subdiagnostic]
1134    pub quote_ident_sugg: Option<InvalidMetaItemQuoteIdentSugg>,
1135}
1136
1137#[derive(Subdiagnostic)]
1138#[multipart_suggestion(parse_quote_ident_sugg, applicability = "machine-applicable")]
1139pub(crate) struct InvalidMetaItemQuoteIdentSugg {
1140    #[suggestion_part(code = "\"")]
1141    pub before: Span,
1142    #[suggestion_part(code = "\"")]
1143    pub after: Span,
1144}
1145
1146#[derive(Subdiagnostic)]
1147#[suggestion(
1148    parse_sugg_escape_identifier,
1149    style = "verbose",
1150    applicability = "maybe-incorrect",
1151    code = "r#"
1152)]
1153pub(crate) struct SuggEscapeIdentifier {
1154    #[primary_span]
1155    pub span: Span,
1156    pub ident_name: String,
1157}
1158
1159#[derive(Subdiagnostic)]
1160#[suggestion(
1161    parse_sugg_remove_comma,
1162    applicability = "machine-applicable",
1163    code = "",
1164    style = "verbose"
1165)]
1166pub(crate) struct SuggRemoveComma {
1167    #[primary_span]
1168    pub span: Span,
1169}
1170
1171#[derive(Subdiagnostic)]
1172#[suggestion(
1173    parse_sugg_add_let_for_stmt,
1174    style = "verbose",
1175    applicability = "maybe-incorrect",
1176    code = "let "
1177)]
1178pub(crate) struct SuggAddMissingLetStmt {
1179    #[primary_span]
1180    pub span: Span,
1181}
1182
1183#[derive(Subdiagnostic)]
1184pub(crate) enum ExpectedIdentifierFound {
1185    #[label(parse_expected_identifier_found_reserved_identifier)]
1186    ReservedIdentifier(#[primary_span] Span),
1187    #[label(parse_expected_identifier_found_keyword)]
1188    Keyword(#[primary_span] Span),
1189    #[label(parse_expected_identifier_found_reserved_keyword)]
1190    ReservedKeyword(#[primary_span] Span),
1191    #[label(parse_expected_identifier_found_doc_comment)]
1192    DocComment(#[primary_span] Span),
1193    #[label(parse_expected_identifier_found_metavar)]
1194    MetaVar(#[primary_span] Span),
1195    #[label(parse_expected_identifier)]
1196    Other(#[primary_span] Span),
1197}
1198
1199impl ExpectedIdentifierFound {
1200    pub(crate) fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
1201        (match token_descr {
1202            Some(TokenDescription::ReservedIdentifier) => {
1203                ExpectedIdentifierFound::ReservedIdentifier
1204            }
1205            Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword,
1206            Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
1207            Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment,
1208            Some(TokenDescription::MetaVar(_)) => ExpectedIdentifierFound::MetaVar,
1209            None => ExpectedIdentifierFound::Other,
1210        })(span)
1211    }
1212}
1213
1214pub(crate) struct ExpectedIdentifier {
1215    pub span: Span,
1216    pub token: Token,
1217    pub suggest_raw: Option<SuggEscapeIdentifier>,
1218    pub suggest_remove_comma: Option<SuggRemoveComma>,
1219    pub help_cannot_start_number: Option<HelpIdentifierStartsWithNumber>,
1220}
1221
1222impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedIdentifier {
1223    #[track_caller]
1224    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
1225        let token_descr = TokenDescription::from_token(&self.token);
1226
1227        let mut add_token = true;
1228        let mut diag = Diag::new(
1229            dcx,
1230            level,
1231            match token_descr {
1232                Some(TokenDescription::ReservedIdentifier) => {
1233                    fluent::parse_expected_identifier_found_reserved_identifier_str
1234                }
1235                Some(TokenDescription::Keyword) => {
1236                    fluent::parse_expected_identifier_found_keyword_str
1237                }
1238                Some(TokenDescription::ReservedKeyword) => {
1239                    fluent::parse_expected_identifier_found_reserved_keyword_str
1240                }
1241                Some(TokenDescription::DocComment) => {
1242                    fluent::parse_expected_identifier_found_doc_comment_str
1243                }
1244                Some(TokenDescription::MetaVar(_)) => {
1245                    add_token = false;
1246                    fluent::parse_expected_identifier_found_metavar_str
1247                }
1248                None => fluent::parse_expected_identifier_found_str,
1249            },
1250        );
1251        diag.span(self.span);
1252        if add_token {
1253            diag.arg("token", self.token);
1254        }
1255
1256        if let Some(sugg) = self.suggest_raw {
1257            sugg.add_to_diag(&mut diag);
1258        }
1259
1260        ExpectedIdentifierFound::new(token_descr, self.span).add_to_diag(&mut diag);
1261
1262        if let Some(sugg) = self.suggest_remove_comma {
1263            sugg.add_to_diag(&mut diag);
1264        }
1265
1266        if let Some(help) = self.help_cannot_start_number {
1267            help.add_to_diag(&mut diag);
1268        }
1269
1270        diag
1271    }
1272}
1273
1274#[derive(Subdiagnostic)]
1275#[help(parse_invalid_identifier_with_leading_number)]
1276pub(crate) struct HelpIdentifierStartsWithNumber {
1277    #[primary_span]
1278    pub num_span: Span,
1279}
1280
1281pub(crate) struct ExpectedSemi {
1282    pub span: Span,
1283    pub token: Token,
1284
1285    pub unexpected_token_label: Option<Span>,
1286    pub sugg: ExpectedSemiSugg,
1287}
1288
1289impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for ExpectedSemi {
1290    #[track_caller]
1291    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
1292        let token_descr = TokenDescription::from_token(&self.token);
1293
1294        let mut add_token = true;
1295        let mut diag = Diag::new(
1296            dcx,
1297            level,
1298            match token_descr {
1299                Some(TokenDescription::ReservedIdentifier) => {
1300                    fluent::parse_expected_semi_found_reserved_identifier_str
1301                }
1302                Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str,
1303                Some(TokenDescription::ReservedKeyword) => {
1304                    fluent::parse_expected_semi_found_reserved_keyword_str
1305                }
1306                Some(TokenDescription::DocComment) => {
1307                    fluent::parse_expected_semi_found_doc_comment_str
1308                }
1309                Some(TokenDescription::MetaVar(_)) => {
1310                    add_token = false;
1311                    fluent::parse_expected_semi_found_metavar_str
1312                }
1313                None => fluent::parse_expected_semi_found_str,
1314            },
1315        );
1316        diag.span(self.span);
1317        if add_token {
1318            diag.arg("token", self.token);
1319        }
1320
1321        if let Some(unexpected_token_label) = self.unexpected_token_label {
1322            diag.span_label(unexpected_token_label, fluent::parse_label_unexpected_token);
1323        }
1324
1325        self.sugg.add_to_diag(&mut diag);
1326
1327        diag
1328    }
1329}
1330
1331#[derive(Subdiagnostic)]
1332pub(crate) enum ExpectedSemiSugg {
1333    #[suggestion(
1334        parse_sugg_change_this_to_semi,
1335        code = ";",
1336        applicability = "machine-applicable",
1337        style = "short"
1338    )]
1339    ChangeToSemi(#[primary_span] Span),
1340    #[suggestion(
1341        parse_sugg_add_semi,
1342        code = ";",
1343        applicability = "machine-applicable",
1344        style = "short"
1345    )]
1346    AddSemi(#[primary_span] Span),
1347}
1348
1349#[derive(Diagnostic)]
1350#[diag(parse_struct_literal_body_without_path)]
1351pub(crate) struct StructLiteralBodyWithoutPath {
1352    #[primary_span]
1353    pub span: Span,
1354    #[subdiagnostic]
1355    pub sugg: StructLiteralBodyWithoutPathSugg,
1356}
1357
1358#[derive(Subdiagnostic)]
1359#[multipart_suggestion(parse_suggestion, applicability = "has-placeholders")]
1360pub(crate) struct StructLiteralBodyWithoutPathSugg {
1361    #[suggestion_part(code = "{{ SomeStruct ")]
1362    pub before: Span,
1363    #[suggestion_part(code = " }}")]
1364    pub after: Span,
1365}
1366
1367#[derive(Diagnostic)]
1368#[diag(parse_unmatched_angle_brackets)]
1369pub(crate) struct UnmatchedAngleBrackets {
1370    #[primary_span]
1371    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
1372    pub span: Span,
1373    pub num_extra_brackets: usize,
1374}
1375
1376#[derive(Diagnostic)]
1377#[diag(parse_generic_parameters_without_angle_brackets)]
1378pub(crate) struct GenericParamsWithoutAngleBrackets {
1379    #[primary_span]
1380    pub span: Span,
1381    #[subdiagnostic]
1382    pub sugg: GenericParamsWithoutAngleBracketsSugg,
1383}
1384
1385#[derive(Subdiagnostic)]
1386#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1387pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
1388    #[suggestion_part(code = "<")]
1389    pub left: Span,
1390    #[suggestion_part(code = ">")]
1391    pub right: Span,
1392}
1393
1394#[derive(Diagnostic)]
1395#[diag(parse_comparison_operators_cannot_be_chained)]
1396pub(crate) struct ComparisonOperatorsCannotBeChained {
1397    #[primary_span]
1398    pub span: Vec<Span>,
1399    #[suggestion(
1400        parse_sugg_turbofish_syntax,
1401        style = "verbose",
1402        code = "::",
1403        applicability = "maybe-incorrect"
1404    )]
1405    pub suggest_turbofish: Option<Span>,
1406    #[help(parse_sugg_turbofish_syntax)]
1407    #[help(parse_sugg_parentheses_for_function_args)]
1408    pub help_turbofish: bool,
1409    #[subdiagnostic]
1410    pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
1411}
1412
1413#[derive(Subdiagnostic)]
1414pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
1415    #[suggestion(
1416        parse_sugg_split_comparison,
1417        style = "verbose",
1418        code = " && {middle_term}",
1419        applicability = "maybe-incorrect"
1420    )]
1421    SplitComparison {
1422        #[primary_span]
1423        span: Span,
1424        middle_term: String,
1425    },
1426    #[multipart_suggestion(parse_sugg_parenthesize, applicability = "maybe-incorrect")]
1427    Parenthesize {
1428        #[suggestion_part(code = "(")]
1429        left: Span,
1430        #[suggestion_part(code = ")")]
1431        right: Span,
1432    },
1433}
1434
1435#[derive(Diagnostic)]
1436#[diag(parse_question_mark_in_type)]
1437pub(crate) struct QuestionMarkInType {
1438    #[primary_span]
1439    #[label]
1440    pub span: Span,
1441    #[subdiagnostic]
1442    pub sugg: QuestionMarkInTypeSugg,
1443}
1444
1445#[derive(Subdiagnostic)]
1446#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1447pub(crate) struct QuestionMarkInTypeSugg {
1448    #[suggestion_part(code = "Option<")]
1449    pub left: Span,
1450    #[suggestion_part(code = ">")]
1451    pub right: Span,
1452}
1453
1454#[derive(Diagnostic)]
1455#[diag(parse_unexpected_parentheses_in_for_head)]
1456pub(crate) struct ParenthesesInForHead {
1457    #[primary_span]
1458    pub span: Vec<Span>,
1459    #[subdiagnostic]
1460    pub sugg: ParenthesesInForHeadSugg,
1461}
1462
1463#[derive(Subdiagnostic)]
1464#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1465pub(crate) struct ParenthesesInForHeadSugg {
1466    #[suggestion_part(code = " ")]
1467    pub left: Span,
1468    #[suggestion_part(code = " ")]
1469    pub right: Span,
1470}
1471
1472#[derive(Diagnostic)]
1473#[diag(parse_unexpected_parentheses_in_match_arm_pattern)]
1474pub(crate) struct ParenthesesInMatchPat {
1475    #[primary_span]
1476    pub span: Vec<Span>,
1477    #[subdiagnostic]
1478    pub sugg: ParenthesesInMatchPatSugg,
1479}
1480
1481#[derive(Subdiagnostic)]
1482#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1483pub(crate) struct ParenthesesInMatchPatSugg {
1484    #[suggestion_part(code = "")]
1485    pub left: Span,
1486    #[suggestion_part(code = "")]
1487    pub right: Span,
1488}
1489
1490#[derive(Diagnostic)]
1491#[diag(parse_doc_comment_on_param_type)]
1492pub(crate) struct DocCommentOnParamType {
1493    #[primary_span]
1494    #[label]
1495    pub span: Span,
1496}
1497
1498#[derive(Diagnostic)]
1499#[diag(parse_attribute_on_param_type)]
1500pub(crate) struct AttributeOnParamType {
1501    #[primary_span]
1502    #[label]
1503    pub span: Span,
1504}
1505
1506#[derive(Diagnostic)]
1507#[diag(parse_attribute_on_type)]
1508pub(crate) struct AttributeOnType {
1509    #[primary_span]
1510    #[label]
1511    pub span: Span,
1512    #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
1513    pub fix_span: Span,
1514}
1515
1516#[derive(Diagnostic)]
1517#[diag(parse_attribute_on_generic_arg)]
1518pub(crate) struct AttributeOnGenericArg {
1519    #[primary_span]
1520    #[label]
1521    pub span: Span,
1522    #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
1523    pub fix_span: Span,
1524}
1525
1526#[derive(Diagnostic)]
1527#[diag(parse_attribute_on_empty_type)]
1528pub(crate) struct AttributeOnEmptyType {
1529    #[primary_span]
1530    #[label]
1531    pub span: Span,
1532}
1533
1534#[derive(Diagnostic)]
1535#[diag(parse_pattern_method_param_without_body, code = E0642)]
1536pub(crate) struct PatternMethodParamWithoutBody {
1537    #[primary_span]
1538    #[suggestion(code = "_", applicability = "machine-applicable", style = "verbose")]
1539    pub span: Span,
1540}
1541
1542#[derive(Diagnostic)]
1543#[diag(parse_self_param_not_first)]
1544pub(crate) struct SelfParamNotFirst {
1545    #[primary_span]
1546    #[label]
1547    pub span: Span,
1548}
1549
1550#[derive(Diagnostic)]
1551#[diag(parse_const_generic_without_braces)]
1552pub(crate) struct ConstGenericWithoutBraces {
1553    #[primary_span]
1554    pub span: Span,
1555    #[subdiagnostic]
1556    pub sugg: ConstGenericWithoutBracesSugg,
1557}
1558
1559#[derive(Subdiagnostic)]
1560#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1561pub(crate) struct ConstGenericWithoutBracesSugg {
1562    #[suggestion_part(code = "{{ ")]
1563    pub left: Span,
1564    #[suggestion_part(code = " }}")]
1565    pub right: Span,
1566}
1567
1568#[derive(Diagnostic)]
1569#[diag(parse_unexpected_const_param_declaration)]
1570pub(crate) struct UnexpectedConstParamDeclaration {
1571    #[primary_span]
1572    #[label]
1573    pub span: Span,
1574    #[subdiagnostic]
1575    pub sugg: Option<UnexpectedConstParamDeclarationSugg>,
1576}
1577
1578#[derive(Subdiagnostic)]
1579pub(crate) enum UnexpectedConstParamDeclarationSugg {
1580    #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1581    AddParam {
1582        #[suggestion_part(code = "<{snippet}>")]
1583        impl_generics: Span,
1584        #[suggestion_part(code = "{ident}")]
1585        incorrect_decl: Span,
1586        snippet: String,
1587        ident: String,
1588    },
1589    #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1590    AppendParam {
1591        #[suggestion_part(code = ", {snippet}")]
1592        impl_generics_end: Span,
1593        #[suggestion_part(code = "{ident}")]
1594        incorrect_decl: Span,
1595        snippet: String,
1596        ident: String,
1597    },
1598}
1599
1600#[derive(Diagnostic)]
1601#[diag(parse_unexpected_const_in_generic_param)]
1602pub(crate) struct UnexpectedConstInGenericParam {
1603    #[primary_span]
1604    pub span: Span,
1605    #[suggestion(style = "verbose", code = "", applicability = "maybe-incorrect")]
1606    pub to_remove: Option<Span>,
1607}
1608
1609#[derive(Diagnostic)]
1610#[diag(parse_async_move_order_incorrect)]
1611pub(crate) struct AsyncMoveOrderIncorrect {
1612    #[primary_span]
1613    #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")]
1614    pub span: Span,
1615}
1616
1617#[derive(Diagnostic)]
1618#[diag(parse_async_use_order_incorrect)]
1619pub(crate) struct AsyncUseOrderIncorrect {
1620    #[primary_span]
1621    #[suggestion(style = "verbose", code = "async use", applicability = "maybe-incorrect")]
1622    pub span: Span,
1623}
1624
1625#[derive(Diagnostic)]
1626#[diag(parse_double_colon_in_bound)]
1627pub(crate) struct DoubleColonInBound {
1628    #[primary_span]
1629    pub span: Span,
1630    #[suggestion(code = ": ", applicability = "machine-applicable", style = "verbose")]
1631    pub between: Span,
1632}
1633
1634#[derive(Diagnostic)]
1635#[diag(parse_fn_ptr_with_generics)]
1636pub(crate) struct FnPtrWithGenerics {
1637    #[primary_span]
1638    pub span: Span,
1639    #[subdiagnostic]
1640    pub sugg: Option<FnPtrWithGenericsSugg>,
1641}
1642
1643#[derive(Subdiagnostic)]
1644#[multipart_suggestion(
1645    parse_misplaced_return_type,
1646    style = "verbose",
1647    applicability = "maybe-incorrect"
1648)]
1649pub(crate) struct MisplacedReturnType {
1650    #[suggestion_part(code = " {snippet}")]
1651    pub fn_params_end: Span,
1652    pub snippet: String,
1653    #[suggestion_part(code = "")]
1654    pub ret_ty_span: Span,
1655}
1656
1657#[derive(Subdiagnostic)]
1658#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")]
1659pub(crate) struct FnPtrWithGenericsSugg {
1660    #[suggestion_part(code = "{snippet}")]
1661    pub left: Span,
1662    pub snippet: String,
1663    #[suggestion_part(code = "")]
1664    pub right: Span,
1665    pub arity: usize,
1666    pub for_param_list_exists: bool,
1667}
1668
1669pub(crate) struct FnTraitMissingParen {
1670    pub span: Span,
1671}
1672
1673impl Subdiagnostic for FnTraitMissingParen {
1674    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1675        diag.span_label(self.span, crate::fluent_generated::parse_fn_trait_missing_paren);
1676        diag.span_suggestion_short(
1677            self.span.shrink_to_hi(),
1678            crate::fluent_generated::parse_add_paren,
1679            "()",
1680            Applicability::MachineApplicable,
1681        );
1682    }
1683}
1684
1685#[derive(Diagnostic)]
1686#[diag(parse_unexpected_if_with_if)]
1687pub(crate) struct UnexpectedIfWithIf(
1688    #[primary_span]
1689    #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")]
1690    pub Span,
1691);
1692
1693#[derive(Diagnostic)]
1694#[diag(parse_maybe_fn_typo_with_impl)]
1695pub(crate) struct FnTypoWithImpl {
1696    #[primary_span]
1697    #[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
1698    pub fn_span: Span,
1699}
1700
1701#[derive(Diagnostic)]
1702#[diag(parse_expected_fn_path_found_fn_keyword)]
1703pub(crate) struct ExpectedFnPathFoundFnKeyword {
1704    #[primary_span]
1705    #[suggestion(applicability = "machine-applicable", code = "Fn", style = "verbose")]
1706    pub fn_token_span: Span,
1707}
1708
1709#[derive(Diagnostic)]
1710#[diag(parse_path_found_named_params)]
1711pub(crate) struct FnPathFoundNamedParams {
1712    #[primary_span]
1713    #[suggestion(applicability = "machine-applicable", code = "")]
1714    pub named_param_span: Span,
1715}
1716
1717#[derive(Diagnostic)]
1718#[diag(parse_path_found_c_variadic_params)]
1719pub(crate) struct PathFoundCVariadicParams {
1720    #[primary_span]
1721    #[suggestion(applicability = "machine-applicable", code = "")]
1722    pub span: Span,
1723}
1724
1725#[derive(Diagnostic)]
1726#[diag(parse_path_found_attribute_in_params)]
1727pub(crate) struct PathFoundAttributeInParams {
1728    #[primary_span]
1729    #[suggestion(applicability = "machine-applicable", code = "")]
1730    pub span: Span,
1731}
1732
1733#[derive(Diagnostic)]
1734#[diag(parse_path_double_colon)]
1735pub(crate) struct PathSingleColon {
1736    #[primary_span]
1737    pub span: Span,
1738
1739    #[suggestion(applicability = "machine-applicable", code = ":", style = "verbose")]
1740    pub suggestion: Span,
1741}
1742
1743#[derive(Diagnostic)]
1744#[diag(parse_path_double_colon)]
1745pub(crate) struct PathTripleColon {
1746    #[primary_span]
1747    #[suggestion(applicability = "maybe-incorrect", code = "", style = "verbose")]
1748    pub span: Span,
1749}
1750
1751#[derive(Diagnostic)]
1752#[diag(parse_colon_as_semi)]
1753pub(crate) struct ColonAsSemi {
1754    #[primary_span]
1755    #[suggestion(applicability = "machine-applicable", code = ";", style = "verbose")]
1756    pub span: Span,
1757}
1758
1759#[derive(Diagnostic)]
1760#[diag(parse_where_clause_before_tuple_struct_body)]
1761pub(crate) struct WhereClauseBeforeTupleStructBody {
1762    #[primary_span]
1763    #[label]
1764    pub span: Span,
1765    #[label(parse_name_label)]
1766    pub name: Span,
1767    #[label(parse_body_label)]
1768    pub body: Span,
1769    #[subdiagnostic]
1770    pub sugg: Option<WhereClauseBeforeTupleStructBodySugg>,
1771}
1772
1773#[derive(Subdiagnostic)]
1774#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
1775pub(crate) struct WhereClauseBeforeTupleStructBodySugg {
1776    #[suggestion_part(code = "{snippet}")]
1777    pub left: Span,
1778    pub snippet: String,
1779    #[suggestion_part(code = "")]
1780    pub right: Span,
1781}
1782
1783#[derive(Diagnostic)]
1784#[diag(parse_async_fn_in_2015, code = E0670)]
1785pub(crate) struct AsyncFnIn2015 {
1786    #[primary_span]
1787    #[label]
1788    pub span: Span,
1789    #[subdiagnostic]
1790    pub help: HelpUseLatestEdition,
1791}
1792
1793#[derive(Subdiagnostic)]
1794#[label(parse_async_block_in_2015)]
1795pub(crate) struct AsyncBlockIn2015 {
1796    #[primary_span]
1797    pub span: Span,
1798}
1799
1800#[derive(Diagnostic)]
1801#[diag(parse_async_move_block_in_2015)]
1802pub(crate) struct AsyncMoveBlockIn2015 {
1803    #[primary_span]
1804    pub span: Span,
1805}
1806
1807#[derive(Diagnostic)]
1808#[diag(parse_async_use_block_in_2015)]
1809pub(crate) struct AsyncUseBlockIn2015 {
1810    #[primary_span]
1811    pub span: Span,
1812}
1813
1814#[derive(Diagnostic)]
1815#[diag(parse_async_bound_modifier_in_2015)]
1816pub(crate) struct AsyncBoundModifierIn2015 {
1817    #[primary_span]
1818    pub span: Span,
1819    #[subdiagnostic]
1820    pub help: HelpUseLatestEdition,
1821}
1822
1823#[derive(Diagnostic)]
1824#[diag(parse_let_chain_pre_2024)]
1825pub(crate) struct LetChainPre2024 {
1826    #[primary_span]
1827    pub span: Span,
1828}
1829
1830#[derive(Diagnostic)]
1831#[diag(parse_self_argument_pointer)]
1832pub(crate) struct SelfArgumentPointer {
1833    #[primary_span]
1834    #[label]
1835    pub span: Span,
1836}
1837
1838#[derive(Diagnostic)]
1839#[diag(parse_unexpected_token_after_dot)]
1840pub(crate) struct UnexpectedTokenAfterDot {
1841    #[primary_span]
1842    pub span: Span,
1843    pub actual: String,
1844}
1845
1846#[derive(Diagnostic)]
1847#[diag(parse_visibility_not_followed_by_item)]
1848#[help]
1849pub(crate) struct VisibilityNotFollowedByItem {
1850    #[primary_span]
1851    #[label]
1852    pub span: Span,
1853    pub vis: Visibility,
1854}
1855
1856#[derive(Diagnostic)]
1857#[diag(parse_default_not_followed_by_item)]
1858#[note]
1859pub(crate) struct DefaultNotFollowedByItem {
1860    #[primary_span]
1861    #[label]
1862    pub span: Span,
1863}
1864
1865#[derive(Diagnostic)]
1866pub(crate) enum MissingKeywordForItemDefinition {
1867    #[diag(parse_missing_enum_for_enum_definition)]
1868    Enum {
1869        #[primary_span]
1870        span: Span,
1871        #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "enum ")]
1872        insert_span: Span,
1873        ident: Ident,
1874    },
1875    #[diag(parse_missing_enum_or_struct_for_item_definition)]
1876    EnumOrStruct {
1877        #[primary_span]
1878        span: Span,
1879    },
1880    #[diag(parse_missing_struct_for_struct_definition)]
1881    Struct {
1882        #[primary_span]
1883        span: Span,
1884        #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "struct ")]
1885        insert_span: Span,
1886        ident: Ident,
1887    },
1888    #[diag(parse_missing_fn_for_function_definition)]
1889    Function {
1890        #[primary_span]
1891        span: Span,
1892        #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "fn ")]
1893        insert_span: Span,
1894        ident: Ident,
1895    },
1896    #[diag(parse_missing_fn_for_method_definition)]
1897    Method {
1898        #[primary_span]
1899        span: Span,
1900        #[suggestion(style = "verbose", applicability = "maybe-incorrect", code = "fn ")]
1901        insert_span: Span,
1902        ident: Ident,
1903    },
1904    #[diag(parse_missing_fn_or_struct_for_item_definition)]
1905    Ambiguous {
1906        #[primary_span]
1907        span: Span,
1908        #[subdiagnostic]
1909        subdiag: Option<AmbiguousMissingKwForItemSub>,
1910    },
1911}
1912
1913#[derive(Subdiagnostic)]
1914pub(crate) enum AmbiguousMissingKwForItemSub {
1915    #[suggestion(
1916        parse_suggestion,
1917        applicability = "maybe-incorrect",
1918        code = "{snippet}!",
1919        style = "verbose"
1920    )]
1921    SuggestMacro {
1922        #[primary_span]
1923        span: Span,
1924        snippet: String,
1925    },
1926    #[help(parse_help)]
1927    HelpMacro,
1928}
1929
1930#[derive(Diagnostic)]
1931#[diag(parse_missing_fn_params)]
1932pub(crate) struct MissingFnParams {
1933    #[primary_span]
1934    #[suggestion(code = "()", applicability = "machine-applicable", style = "verbose")]
1935    pub span: Span,
1936}
1937
1938#[derive(Diagnostic)]
1939#[diag(parse_invalid_path_sep_in_fn_definition)]
1940pub(crate) struct InvalidPathSepInFnDefinition {
1941    #[primary_span]
1942    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
1943    pub span: Span,
1944}
1945
1946#[derive(Diagnostic)]
1947#[diag(parse_missing_trait_in_trait_impl)]
1948pub(crate) struct MissingTraitInTraitImpl {
1949    #[primary_span]
1950    #[suggestion(
1951        parse_suggestion_add_trait,
1952        code = " Trait ",
1953        applicability = "has-placeholders",
1954        style = "verbose"
1955    )]
1956    pub span: Span,
1957    #[suggestion(
1958        parse_suggestion_remove_for,
1959        code = "",
1960        applicability = "maybe-incorrect",
1961        style = "verbose"
1962    )]
1963    pub for_span: Span,
1964}
1965
1966#[derive(Diagnostic)]
1967#[diag(parse_missing_for_in_trait_impl)]
1968pub(crate) struct MissingForInTraitImpl {
1969    #[primary_span]
1970    #[suggestion(style = "verbose", code = " for ", applicability = "machine-applicable")]
1971    pub span: Span,
1972}
1973
1974#[derive(Diagnostic)]
1975#[diag(parse_expected_trait_in_trait_impl_found_type)]
1976pub(crate) struct ExpectedTraitInTraitImplFoundType {
1977    #[primary_span]
1978    pub span: Span,
1979}
1980
1981#[derive(Diagnostic)]
1982#[diag(parse_extra_impl_keyword_in_trait_impl)]
1983pub(crate) struct ExtraImplKeywordInTraitImpl {
1984    #[primary_span]
1985    #[suggestion(code = "", applicability = "maybe-incorrect", style = "short")]
1986    pub extra_impl_kw: Span,
1987    #[note]
1988    pub impl_trait_span: Span,
1989}
1990
1991#[derive(Diagnostic)]
1992#[diag(parse_bounds_not_allowed_on_trait_aliases)]
1993pub(crate) struct BoundsNotAllowedOnTraitAliases {
1994    #[primary_span]
1995    pub span: Span,
1996}
1997
1998#[derive(Diagnostic)]
1999#[diag(parse_trait_alias_cannot_be_auto)]
2000pub(crate) struct TraitAliasCannotBeAuto {
2001    #[primary_span]
2002    #[label(parse_trait_alias_cannot_be_auto)]
2003    pub span: Span,
2004}
2005
2006#[derive(Diagnostic)]
2007#[diag(parse_trait_alias_cannot_be_const)]
2008pub(crate) struct TraitAliasCannotBeConst {
2009    #[primary_span]
2010    #[label(parse_trait_alias_cannot_be_const)]
2011    pub span: Span,
2012}
2013
2014#[derive(Diagnostic)]
2015#[diag(parse_trait_alias_cannot_be_unsafe)]
2016pub(crate) struct TraitAliasCannotBeUnsafe {
2017    #[primary_span]
2018    #[label(parse_trait_alias_cannot_be_unsafe)]
2019    pub span: Span,
2020}
2021
2022#[derive(Diagnostic)]
2023#[diag(parse_associated_static_item_not_allowed)]
2024pub(crate) struct AssociatedStaticItemNotAllowed {
2025    #[primary_span]
2026    pub span: Span,
2027}
2028
2029#[derive(Diagnostic)]
2030#[diag(parse_extern_crate_name_with_dashes)]
2031pub(crate) struct ExternCrateNameWithDashes {
2032    #[primary_span]
2033    #[label]
2034    pub span: Span,
2035    #[subdiagnostic]
2036    pub sugg: ExternCrateNameWithDashesSugg,
2037}
2038
2039#[derive(Subdiagnostic)]
2040#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
2041pub(crate) struct ExternCrateNameWithDashesSugg {
2042    #[suggestion_part(code = "_")]
2043    pub dashes: Vec<Span>,
2044}
2045
2046#[derive(Diagnostic)]
2047#[diag(parse_extern_item_cannot_be_const)]
2048#[note]
2049pub(crate) struct ExternItemCannotBeConst {
2050    #[primary_span]
2051    pub ident_span: Span,
2052    #[suggestion(code = "static ", applicability = "machine-applicable", style = "verbose")]
2053    pub const_span: Option<Span>,
2054}
2055
2056#[derive(Diagnostic)]
2057#[diag(parse_const_global_cannot_be_mutable)]
2058pub(crate) struct ConstGlobalCannotBeMutable {
2059    #[primary_span]
2060    #[label]
2061    pub ident_span: Span,
2062    #[suggestion(code = "static", style = "verbose", applicability = "maybe-incorrect")]
2063    pub const_span: Span,
2064}
2065
2066#[derive(Diagnostic)]
2067#[diag(parse_missing_const_type)]
2068pub(crate) struct MissingConstType {
2069    #[primary_span]
2070    #[suggestion(code = "{colon} <type>", style = "verbose", applicability = "has-placeholders")]
2071    pub span: Span,
2072
2073    pub kind: &'static str,
2074    pub colon: &'static str,
2075}
2076
2077#[derive(Diagnostic)]
2078#[diag(parse_enum_struct_mutually_exclusive)]
2079pub(crate) struct EnumStructMutuallyExclusive {
2080    #[primary_span]
2081    #[suggestion(code = "enum", style = "verbose", applicability = "machine-applicable")]
2082    pub span: Span,
2083}
2084
2085#[derive(Diagnostic)]
2086pub(crate) enum UnexpectedTokenAfterStructName {
2087    #[diag(parse_unexpected_token_after_struct_name_found_reserved_identifier)]
2088    ReservedIdentifier {
2089        #[primary_span]
2090        #[label(parse_unexpected_token_after_struct_name)]
2091        span: Span,
2092        token: Token,
2093    },
2094    #[diag(parse_unexpected_token_after_struct_name_found_keyword)]
2095    Keyword {
2096        #[primary_span]
2097        #[label(parse_unexpected_token_after_struct_name)]
2098        span: Span,
2099        token: Token,
2100    },
2101    #[diag(parse_unexpected_token_after_struct_name_found_reserved_keyword)]
2102    ReservedKeyword {
2103        #[primary_span]
2104        #[label(parse_unexpected_token_after_struct_name)]
2105        span: Span,
2106        token: Token,
2107    },
2108    #[diag(parse_unexpected_token_after_struct_name_found_doc_comment)]
2109    DocComment {
2110        #[primary_span]
2111        #[label(parse_unexpected_token_after_struct_name)]
2112        span: Span,
2113        token: Token,
2114    },
2115    #[diag(parse_unexpected_token_after_struct_name_found_metavar)]
2116    MetaVar {
2117        #[primary_span]
2118        #[label(parse_unexpected_token_after_struct_name)]
2119        span: Span,
2120    },
2121    #[diag(parse_unexpected_token_after_struct_name_found_other)]
2122    Other {
2123        #[primary_span]
2124        #[label(parse_unexpected_token_after_struct_name)]
2125        span: Span,
2126        token: Token,
2127    },
2128}
2129
2130impl UnexpectedTokenAfterStructName {
2131    pub(crate) fn new(span: Span, token: Token) -> Self {
2132        match TokenDescription::from_token(&token) {
2133            Some(TokenDescription::ReservedIdentifier) => Self::ReservedIdentifier { span, token },
2134            Some(TokenDescription::Keyword) => Self::Keyword { span, token },
2135            Some(TokenDescription::ReservedKeyword) => Self::ReservedKeyword { span, token },
2136            Some(TokenDescription::DocComment) => Self::DocComment { span, token },
2137            Some(TokenDescription::MetaVar(_)) => Self::MetaVar { span },
2138            None => Self::Other { span, token },
2139        }
2140    }
2141}
2142
2143#[derive(Diagnostic)]
2144#[diag(parse_unexpected_self_in_generic_parameters)]
2145#[note]
2146pub(crate) struct UnexpectedSelfInGenericParameters {
2147    #[primary_span]
2148    pub span: Span,
2149}
2150
2151#[derive(Diagnostic)]
2152#[diag(parse_unexpected_default_value_for_lifetime_in_generic_parameters)]
2153pub(crate) struct UnexpectedDefaultValueForLifetimeInGenericParameters {
2154    #[primary_span]
2155    #[label]
2156    pub span: Span,
2157}
2158
2159#[derive(Diagnostic)]
2160#[diag(parse_multiple_where_clauses)]
2161pub(crate) struct MultipleWhereClauses {
2162    #[primary_span]
2163    pub span: Span,
2164    #[label]
2165    pub previous: Span,
2166    #[suggestion(style = "verbose", code = ",", applicability = "maybe-incorrect")]
2167    pub between: Span,
2168}
2169
2170#[derive(Diagnostic)]
2171pub(crate) enum UnexpectedNonterminal {
2172    #[diag(parse_nonterminal_expected_item_keyword)]
2173    Item(#[primary_span] Span),
2174    #[diag(parse_nonterminal_expected_statement)]
2175    Statement(#[primary_span] Span),
2176    #[diag(parse_nonterminal_expected_ident)]
2177    Ident {
2178        #[primary_span]
2179        span: Span,
2180        token: Token,
2181    },
2182    #[diag(parse_nonterminal_expected_lifetime)]
2183    Lifetime {
2184        #[primary_span]
2185        span: Span,
2186        token: Token,
2187    },
2188}
2189
2190#[derive(Diagnostic)]
2191pub(crate) enum TopLevelOrPatternNotAllowed {
2192    #[diag(parse_or_pattern_not_allowed_in_let_binding)]
2193    LetBinding {
2194        #[primary_span]
2195        span: Span,
2196        #[subdiagnostic]
2197        sub: Option<TopLevelOrPatternNotAllowedSugg>,
2198    },
2199    #[diag(parse_or_pattern_not_allowed_in_fn_parameters)]
2200    FunctionParameter {
2201        #[primary_span]
2202        span: Span,
2203        #[subdiagnostic]
2204        sub: Option<TopLevelOrPatternNotAllowedSugg>,
2205    },
2206}
2207
2208#[derive(Diagnostic)]
2209#[diag(parse_cannot_be_raw_ident)]
2210pub(crate) struct CannotBeRawIdent {
2211    #[primary_span]
2212    pub span: Span,
2213    pub ident: Symbol,
2214}
2215
2216#[derive(Diagnostic)]
2217#[diag(parse_cannot_be_raw_lifetime)]
2218pub(crate) struct CannotBeRawLifetime {
2219    #[primary_span]
2220    pub span: Span,
2221    pub ident: Symbol,
2222}
2223
2224#[derive(Diagnostic)]
2225#[diag(parse_keyword_lifetime)]
2226pub(crate) struct KeywordLifetime {
2227    #[primary_span]
2228    pub span: Span,
2229}
2230
2231#[derive(Diagnostic)]
2232#[diag(parse_keyword_label)]
2233pub(crate) struct KeywordLabel {
2234    #[primary_span]
2235    pub span: Span,
2236}
2237
2238#[derive(Diagnostic)]
2239#[diag(parse_cr_doc_comment)]
2240pub(crate) struct CrDocComment {
2241    #[primary_span]
2242    pub span: Span,
2243    pub block: bool,
2244}
2245
2246#[derive(Diagnostic)]
2247#[diag(parse_no_digits_literal, code = E0768)]
2248pub(crate) struct NoDigitsLiteral {
2249    #[primary_span]
2250    pub span: Span,
2251}
2252
2253#[derive(Diagnostic)]
2254#[diag(parse_invalid_digit_literal)]
2255pub(crate) struct InvalidDigitLiteral {
2256    #[primary_span]
2257    pub span: Span,
2258    pub base: u32,
2259}
2260
2261#[derive(Diagnostic)]
2262#[diag(parse_empty_exponent_float)]
2263pub(crate) struct EmptyExponentFloat {
2264    #[primary_span]
2265    pub span: Span,
2266}
2267
2268#[derive(Diagnostic)]
2269#[diag(parse_float_literal_unsupported_base)]
2270pub(crate) struct FloatLiteralUnsupportedBase {
2271    #[primary_span]
2272    pub span: Span,
2273    pub base: &'static str,
2274}
2275
2276#[derive(Diagnostic)]
2277#[diag(parse_unknown_prefix)]
2278#[note]
2279pub(crate) struct UnknownPrefix<'a> {
2280    #[primary_span]
2281    #[label]
2282    pub span: Span,
2283    pub prefix: &'a str,
2284    #[subdiagnostic]
2285    pub sugg: Option<UnknownPrefixSugg>,
2286}
2287
2288#[derive(Subdiagnostic)]
2289#[note(parse_macro_expands_to_adt_field)]
2290pub(crate) struct MacroExpandsToAdtField<'a> {
2291    pub adt_ty: &'a str,
2292}
2293
2294#[derive(Subdiagnostic)]
2295pub(crate) enum UnknownPrefixSugg {
2296    #[suggestion(
2297        parse_suggestion_br,
2298        code = "br",
2299        applicability = "maybe-incorrect",
2300        style = "verbose"
2301    )]
2302    UseBr(#[primary_span] Span),
2303    #[suggestion(
2304        parse_suggestion_cr,
2305        code = "cr",
2306        applicability = "maybe-incorrect",
2307        style = "verbose"
2308    )]
2309    UseCr(#[primary_span] Span),
2310    #[suggestion(
2311        parse_suggestion_whitespace,
2312        code = " ",
2313        applicability = "maybe-incorrect",
2314        style = "verbose"
2315    )]
2316    Whitespace(#[primary_span] Span),
2317    #[multipart_suggestion(
2318        parse_suggestion_str,
2319        applicability = "maybe-incorrect",
2320        style = "verbose"
2321    )]
2322    MeantStr {
2323        #[suggestion_part(code = "\"")]
2324        start: Span,
2325        #[suggestion_part(code = "\"")]
2326        end: Span,
2327    },
2328}
2329
2330#[derive(Diagnostic)]
2331#[diag(parse_reserved_multihash)]
2332#[note]
2333pub(crate) struct ReservedMultihash {
2334    #[primary_span]
2335    pub span: Span,
2336    #[subdiagnostic]
2337    pub sugg: Option<GuardedStringSugg>,
2338}
2339#[derive(Diagnostic)]
2340#[diag(parse_reserved_string)]
2341#[note]
2342pub(crate) struct ReservedString {
2343    #[primary_span]
2344    pub span: Span,
2345    #[subdiagnostic]
2346    pub sugg: Option<GuardedStringSugg>,
2347}
2348#[derive(Subdiagnostic)]
2349#[suggestion(
2350    parse_suggestion_whitespace,
2351    code = " ",
2352    applicability = "maybe-incorrect",
2353    style = "verbose"
2354)]
2355pub(crate) struct GuardedStringSugg(#[primary_span] pub Span);
2356
2357#[derive(Diagnostic)]
2358#[diag(parse_too_many_hashes)]
2359pub(crate) struct TooManyHashes {
2360    #[primary_span]
2361    pub span: Span,
2362    pub num: u32,
2363}
2364
2365#[derive(Diagnostic)]
2366#[diag(parse_unknown_start_of_token)]
2367pub(crate) struct UnknownTokenStart {
2368    #[primary_span]
2369    pub span: Span,
2370    pub escaped: String,
2371    #[subdiagnostic]
2372    pub sugg: Option<TokenSubstitution>,
2373    #[subdiagnostic]
2374    pub null: Option<UnknownTokenNull>,
2375    #[subdiagnostic]
2376    pub repeat: Option<UnknownTokenRepeat>,
2377}
2378
2379#[derive(Subdiagnostic)]
2380pub(crate) enum TokenSubstitution {
2381    #[suggestion(
2382        parse_sugg_quotes,
2383        code = "{suggestion}",
2384        applicability = "maybe-incorrect",
2385        style = "verbose"
2386    )]
2387    DirectedQuotes {
2388        #[primary_span]
2389        span: Span,
2390        suggestion: String,
2391        ascii_str: &'static str,
2392        ascii_name: &'static str,
2393    },
2394    #[suggestion(
2395        parse_sugg_other,
2396        code = "{suggestion}",
2397        applicability = "maybe-incorrect",
2398        style = "verbose"
2399    )]
2400    Other {
2401        #[primary_span]
2402        span: Span,
2403        suggestion: String,
2404        ch: String,
2405        u_name: &'static str,
2406        ascii_str: &'static str,
2407        ascii_name: &'static str,
2408    },
2409}
2410
2411#[derive(Subdiagnostic)]
2412#[note(parse_note_repeats)]
2413pub(crate) struct UnknownTokenRepeat {
2414    pub repeats: usize,
2415}
2416
2417#[derive(Subdiagnostic)]
2418#[help(parse_help_null)]
2419pub(crate) struct UnknownTokenNull;
2420
2421#[derive(Diagnostic)]
2422pub(crate) enum UnescapeError {
2423    #[diag(parse_invalid_unicode_escape)]
2424    #[help]
2425    InvalidUnicodeEscape {
2426        #[primary_span]
2427        #[label]
2428        span: Span,
2429        surrogate: bool,
2430    },
2431    #[diag(parse_escape_only_char)]
2432    EscapeOnlyChar {
2433        #[primary_span]
2434        span: Span,
2435        #[suggestion(
2436            parse_escape,
2437            applicability = "machine-applicable",
2438            code = "{escaped_sugg}",
2439            style = "verbose"
2440        )]
2441        char_span: Span,
2442        escaped_sugg: String,
2443        escaped_msg: String,
2444        byte: bool,
2445    },
2446    #[diag(parse_bare_cr)]
2447    BareCr {
2448        #[primary_span]
2449        #[suggestion(
2450            parse_escape,
2451            applicability = "machine-applicable",
2452            code = "\\r",
2453            style = "verbose"
2454        )]
2455        span: Span,
2456        double_quotes: bool,
2457    },
2458    #[diag(parse_bare_cr_in_raw_string)]
2459    BareCrRawString(#[primary_span] Span),
2460    #[diag(parse_too_short_hex_escape)]
2461    TooShortHexEscape(#[primary_span] Span),
2462    #[diag(parse_invalid_char_in_escape)]
2463    InvalidCharInEscape {
2464        #[primary_span]
2465        #[label]
2466        span: Span,
2467        is_hex: bool,
2468        ch: String,
2469    },
2470    #[diag(parse_out_of_range_hex_escape)]
2471    OutOfRangeHexEscape(
2472        #[primary_span]
2473        #[label]
2474        Span,
2475    ),
2476    #[diag(parse_leading_underscore_unicode_escape)]
2477    LeadingUnderscoreUnicodeEscape {
2478        #[primary_span]
2479        #[label(parse_leading_underscore_unicode_escape_label)]
2480        span: Span,
2481        ch: String,
2482    },
2483    #[diag(parse_overlong_unicode_escape)]
2484    OverlongUnicodeEscape(
2485        #[primary_span]
2486        #[label]
2487        Span,
2488    ),
2489    #[diag(parse_unclosed_unicode_escape)]
2490    UnclosedUnicodeEscape(
2491        #[primary_span]
2492        #[label]
2493        Span,
2494        #[suggestion(
2495            parse_terminate,
2496            code = "}}",
2497            applicability = "maybe-incorrect",
2498            style = "verbose"
2499        )]
2500        Span,
2501    ),
2502    #[diag(parse_no_brace_unicode_escape)]
2503    NoBraceInUnicodeEscape {
2504        #[primary_span]
2505        span: Span,
2506        #[label]
2507        label: Option<Span>,
2508        #[subdiagnostic]
2509        sub: NoBraceUnicodeSub,
2510    },
2511    #[diag(parse_unicode_escape_in_byte)]
2512    #[help]
2513    UnicodeEscapeInByte(
2514        #[primary_span]
2515        #[label]
2516        Span,
2517    ),
2518    #[diag(parse_empty_unicode_escape)]
2519    EmptyUnicodeEscape(
2520        #[primary_span]
2521        #[label]
2522        Span,
2523    ),
2524    #[diag(parse_zero_chars)]
2525    ZeroChars(
2526        #[primary_span]
2527        #[label]
2528        Span,
2529    ),
2530    #[diag(parse_lone_slash)]
2531    LoneSlash(
2532        #[primary_span]
2533        #[label]
2534        Span,
2535    ),
2536    #[diag(parse_unskipped_whitespace)]
2537    UnskippedWhitespace {
2538        #[primary_span]
2539        span: Span,
2540        #[label]
2541        char_span: Span,
2542        ch: String,
2543    },
2544    #[diag(parse_multiple_skipped_lines)]
2545    MultipleSkippedLinesWarning(
2546        #[primary_span]
2547        #[label]
2548        Span,
2549    ),
2550    #[diag(parse_more_than_one_char)]
2551    MoreThanOneChar {
2552        #[primary_span]
2553        span: Span,
2554        #[subdiagnostic]
2555        note: Option<MoreThanOneCharNote>,
2556        #[subdiagnostic]
2557        suggestion: MoreThanOneCharSugg,
2558    },
2559    #[diag(parse_nul_in_c_str)]
2560    NulInCStr {
2561        #[primary_span]
2562        span: Span,
2563    },
2564}
2565
2566#[derive(Subdiagnostic)]
2567pub(crate) enum MoreThanOneCharSugg {
2568    #[suggestion(
2569        parse_consider_normalized,
2570        code = "{normalized}",
2571        applicability = "machine-applicable",
2572        style = "verbose"
2573    )]
2574    NormalizedForm {
2575        #[primary_span]
2576        span: Span,
2577        ch: String,
2578        normalized: String,
2579    },
2580    #[suggestion(
2581        parse_remove_non,
2582        code = "{ch}",
2583        applicability = "maybe-incorrect",
2584        style = "verbose"
2585    )]
2586    RemoveNonPrinting {
2587        #[primary_span]
2588        span: Span,
2589        ch: String,
2590    },
2591    #[suggestion(
2592        parse_use_double_quotes,
2593        code = "{sugg}",
2594        applicability = "machine-applicable",
2595        style = "verbose"
2596    )]
2597    QuotesFull {
2598        #[primary_span]
2599        span: Span,
2600        is_byte: bool,
2601        sugg: String,
2602    },
2603    #[multipart_suggestion(parse_use_double_quotes, applicability = "machine-applicable")]
2604    Quotes {
2605        #[suggestion_part(code = "{prefix}\"")]
2606        start: Span,
2607        #[suggestion_part(code = "\"")]
2608        end: Span,
2609        is_byte: bool,
2610        prefix: &'static str,
2611    },
2612}
2613
2614#[derive(Subdiagnostic)]
2615pub(crate) enum MoreThanOneCharNote {
2616    #[note(parse_followed_by)]
2617    AllCombining {
2618        #[primary_span]
2619        span: Span,
2620        chr: String,
2621        len: usize,
2622        escaped_marks: String,
2623    },
2624    #[note(parse_non_printing)]
2625    NonPrinting {
2626        #[primary_span]
2627        span: Span,
2628        escaped: String,
2629    },
2630}
2631
2632#[derive(Subdiagnostic)]
2633pub(crate) enum NoBraceUnicodeSub {
2634    #[suggestion(
2635        parse_use_braces,
2636        code = "{suggestion}",
2637        applicability = "maybe-incorrect",
2638        style = "verbose"
2639    )]
2640    Suggestion {
2641        #[primary_span]
2642        span: Span,
2643        suggestion: String,
2644    },
2645    #[help(parse_format_of_unicode)]
2646    Help,
2647}
2648
2649#[derive(Subdiagnostic)]
2650#[multipart_suggestion(parse_sugg_wrap_pattern_in_parens, applicability = "machine-applicable")]
2651pub(crate) struct WrapInParens {
2652    #[suggestion_part(code = "(")]
2653    pub(crate) lo: Span,
2654    #[suggestion_part(code = ")")]
2655    pub(crate) hi: Span,
2656}
2657
2658#[derive(Subdiagnostic)]
2659pub(crate) enum TopLevelOrPatternNotAllowedSugg {
2660    #[suggestion(
2661        parse_sugg_remove_leading_vert_in_pattern,
2662        code = "",
2663        applicability = "machine-applicable",
2664        style = "tool-only"
2665    )]
2666    RemoveLeadingVert {
2667        #[primary_span]
2668        span: Span,
2669    },
2670    WrapInParens {
2671        #[primary_span]
2672        span: Span,
2673        #[subdiagnostic]
2674        suggestion: WrapInParens,
2675    },
2676}
2677
2678#[derive(Diagnostic)]
2679#[diag(parse_unexpected_vert_vert_before_function_parameter)]
2680#[note(parse_note_pattern_alternatives_use_single_vert)]
2681pub(crate) struct UnexpectedVertVertBeforeFunctionParam {
2682    #[primary_span]
2683    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2684    pub span: Span,
2685}
2686
2687#[derive(Diagnostic)]
2688#[diag(parse_unexpected_vert_vert_in_pattern)]
2689pub(crate) struct UnexpectedVertVertInPattern {
2690    #[primary_span]
2691    #[suggestion(code = "|", applicability = "machine-applicable", style = "verbose")]
2692    pub span: Span,
2693    #[label(parse_label_while_parsing_or_pattern_here)]
2694    pub start: Option<Span>,
2695}
2696
2697#[derive(Subdiagnostic)]
2698#[suggestion(
2699    parse_trailing_vert_not_allowed,
2700    code = "",
2701    applicability = "machine-applicable",
2702    style = "tool-only"
2703)]
2704pub(crate) struct TrailingVertSuggestion {
2705    #[primary_span]
2706    pub span: Span,
2707}
2708
2709#[derive(Diagnostic)]
2710#[diag(parse_trailing_vert_not_allowed)]
2711pub(crate) struct TrailingVertNotAllowed {
2712    #[primary_span]
2713    pub span: Span,
2714    #[subdiagnostic]
2715    pub suggestion: TrailingVertSuggestion,
2716    #[label(parse_label_while_parsing_or_pattern_here)]
2717    pub start: Option<Span>,
2718    pub token: Token,
2719    #[note(parse_note_pattern_alternatives_use_single_vert)]
2720    pub note_double_vert: bool,
2721}
2722
2723#[derive(Diagnostic)]
2724#[diag(parse_dotdotdot_rest_pattern)]
2725pub(crate) struct DotDotDotRestPattern {
2726    #[primary_span]
2727    #[label]
2728    pub span: Span,
2729    #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
2730    pub suggestion: Span,
2731}
2732
2733#[derive(Diagnostic)]
2734#[diag(parse_pattern_on_wrong_side_of_at)]
2735pub(crate) struct PatternOnWrongSideOfAt {
2736    #[primary_span]
2737    #[suggestion(code = "{whole_pat}", applicability = "machine-applicable", style = "verbose")]
2738    pub whole_span: Span,
2739    pub whole_pat: String,
2740    #[label(parse_label_pattern)]
2741    pub pattern: Span,
2742    #[label(parse_label_binding)]
2743    pub binding: Span,
2744}
2745
2746#[derive(Diagnostic)]
2747#[diag(parse_expected_binding_left_of_at)]
2748#[note]
2749pub(crate) struct ExpectedBindingLeftOfAt {
2750    #[primary_span]
2751    pub whole_span: Span,
2752    #[label(parse_label_lhs)]
2753    pub lhs: Span,
2754    #[label(parse_label_rhs)]
2755    pub rhs: Span,
2756}
2757
2758#[derive(Subdiagnostic)]
2759#[multipart_suggestion(
2760    parse_ambiguous_range_pattern_suggestion,
2761    applicability = "machine-applicable"
2762)]
2763pub(crate) struct ParenRangeSuggestion {
2764    #[suggestion_part(code = "(")]
2765    pub lo: Span,
2766    #[suggestion_part(code = ")")]
2767    pub hi: Span,
2768}
2769
2770#[derive(Diagnostic)]
2771#[diag(parse_ambiguous_range_pattern)]
2772pub(crate) struct AmbiguousRangePattern {
2773    #[primary_span]
2774    pub span: Span,
2775    #[subdiagnostic]
2776    pub suggestion: ParenRangeSuggestion,
2777}
2778
2779#[derive(Diagnostic)]
2780#[diag(parse_unexpected_lifetime_in_pattern)]
2781pub(crate) struct UnexpectedLifetimeInPattern {
2782    #[primary_span]
2783    pub span: Span,
2784    pub symbol: Symbol,
2785    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2786    pub suggestion: Span,
2787}
2788
2789#[derive(Diagnostic)]
2790pub(crate) enum InvalidMutInPattern {
2791    #[diag(parse_mut_on_nested_ident_pattern)]
2792    #[note(parse_note_mut_pattern_usage)]
2793    NestedIdent {
2794        #[primary_span]
2795        #[suggestion(code = "{pat}", applicability = "machine-applicable", style = "verbose")]
2796        span: Span,
2797        pat: String,
2798    },
2799    #[diag(parse_mut_on_non_ident_pattern)]
2800    #[note(parse_note_mut_pattern_usage)]
2801    NonIdent {
2802        #[primary_span]
2803        #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2804        span: Span,
2805    },
2806}
2807
2808#[derive(Diagnostic)]
2809#[diag(parse_repeated_mut_in_pattern)]
2810pub(crate) struct RepeatedMutInPattern {
2811    #[primary_span]
2812    pub span: Span,
2813    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
2814    pub suggestion: Span,
2815}
2816
2817#[derive(Diagnostic)]
2818#[diag(parse_dot_dot_dot_range_to_pattern_not_allowed)]
2819pub(crate) struct DotDotDotRangeToPatternNotAllowed {
2820    #[primary_span]
2821    #[suggestion(style = "verbose", code = "..=", applicability = "machine-applicable")]
2822    pub span: Span,
2823}
2824
2825#[derive(Diagnostic)]
2826#[diag(parse_enum_pattern_instead_of_identifier)]
2827pub(crate) struct EnumPatternInsteadOfIdentifier {
2828    #[primary_span]
2829    pub span: Span,
2830}
2831
2832#[derive(Diagnostic)]
2833#[diag(parse_at_dot_dot_in_struct_pattern)]
2834pub(crate) struct AtDotDotInStructPattern {
2835    #[primary_span]
2836    pub span: Span,
2837    #[suggestion(code = "", style = "verbose", applicability = "machine-applicable")]
2838    pub remove: Span,
2839    pub ident: Ident,
2840}
2841
2842#[derive(Diagnostic)]
2843#[diag(parse_at_in_struct_pattern)]
2844#[note]
2845#[help]
2846pub(crate) struct AtInStructPattern {
2847    #[primary_span]
2848    pub span: Span,
2849}
2850
2851#[derive(Diagnostic)]
2852#[diag(parse_dot_dot_dot_for_remaining_fields)]
2853pub(crate) struct DotDotDotForRemainingFields {
2854    #[primary_span]
2855    #[suggestion(code = "..", style = "verbose", applicability = "machine-applicable")]
2856    pub span: Span,
2857    pub token_str: Cow<'static, str>,
2858}
2859
2860#[derive(Diagnostic)]
2861#[diag(parse_expected_comma_after_pattern_field)]
2862pub(crate) struct ExpectedCommaAfterPatternField {
2863    #[primary_span]
2864    pub span: Span,
2865}
2866
2867#[derive(Diagnostic)]
2868#[diag(parse_unexpected_expr_in_pat)]
2869#[note]
2870pub(crate) struct UnexpectedExpressionInPattern {
2871    /// The unexpected expr's span.
2872    #[primary_span]
2873    #[label]
2874    pub span: Span,
2875    /// Was a `RangePatternBound` expected?
2876    pub is_bound: bool,
2877    /// The unexpected expr's precedence (used in match arm guard suggestions).
2878    pub expr_precedence: ExprPrecedence,
2879}
2880
2881#[derive(Subdiagnostic)]
2882pub(crate) enum UnexpectedExpressionInPatternSugg {
2883    #[multipart_suggestion(
2884        parse_unexpected_expr_in_pat_create_guard_sugg,
2885        applicability = "maybe-incorrect"
2886    )]
2887    CreateGuard {
2888        /// Where to put the suggested identifier.
2889        #[suggestion_part(code = "{ident}")]
2890        ident_span: Span,
2891        /// Where to put the match arm.
2892        #[suggestion_part(code = " if {ident} == {expr}")]
2893        pat_hi: Span,
2894        /// The suggested identifier.
2895        ident: String,
2896        /// The unexpected expression.
2897        expr: String,
2898    },
2899
2900    #[multipart_suggestion(
2901        parse_unexpected_expr_in_pat_update_guard_sugg,
2902        applicability = "maybe-incorrect"
2903    )]
2904    UpdateGuard {
2905        /// Where to put the suggested identifier.
2906        #[suggestion_part(code = "{ident}")]
2907        ident_span: Span,
2908        /// The beginning of the match arm guard's expression (insert a `(` if `Some`).
2909        #[suggestion_part(code = "(")]
2910        guard_lo: Option<Span>,
2911        /// The end of the match arm guard's expression.
2912        #[suggestion_part(code = "{guard_hi_paren} && {ident} == {expr}")]
2913        guard_hi: Span,
2914        /// Either `")"` or `""`.
2915        guard_hi_paren: &'static str,
2916        /// The suggested identifier.
2917        ident: String,
2918        /// The unexpected expression.
2919        expr: String,
2920    },
2921
2922    #[multipart_suggestion(
2923        parse_unexpected_expr_in_pat_const_sugg,
2924        applicability = "has-placeholders"
2925    )]
2926    Const {
2927        /// Where to put the extracted constant declaration.
2928        #[suggestion_part(code = "{indentation}const {ident}: /* Type */ = {expr};\n")]
2929        stmt_lo: Span,
2930        /// Where to put the suggested identifier.
2931        #[suggestion_part(code = "{ident}")]
2932        ident_span: Span,
2933        /// The suggested identifier.
2934        ident: String,
2935        /// The unexpected expression.
2936        expr: String,
2937        /// The statement's block's indentation.
2938        indentation: String,
2939    },
2940}
2941
2942#[derive(Diagnostic)]
2943#[diag(parse_unexpected_paren_in_range_pat)]
2944pub(crate) struct UnexpectedParenInRangePat {
2945    #[primary_span]
2946    pub span: Vec<Span>,
2947    #[subdiagnostic]
2948    pub sugg: UnexpectedParenInRangePatSugg,
2949}
2950
2951#[derive(Subdiagnostic)]
2952#[multipart_suggestion(
2953    parse_unexpected_paren_in_range_pat_sugg,
2954    applicability = "machine-applicable"
2955)]
2956pub(crate) struct UnexpectedParenInRangePatSugg {
2957    #[suggestion_part(code = "")]
2958    pub start_span: Span,
2959    #[suggestion_part(code = "")]
2960    pub end_span: Span,
2961}
2962
2963#[derive(Diagnostic)]
2964#[diag(parse_return_types_use_thin_arrow)]
2965pub(crate) struct ReturnTypesUseThinArrow {
2966    #[primary_span]
2967    pub span: Span,
2968    #[suggestion(style = "verbose", code = " -> ", applicability = "machine-applicable")]
2969    pub suggestion: Span,
2970}
2971
2972#[derive(Diagnostic)]
2973#[diag(parse_need_plus_after_trait_object_lifetime)]
2974pub(crate) struct NeedPlusAfterTraitObjectLifetime {
2975    #[primary_span]
2976    pub span: Span,
2977    #[suggestion(code = " + /* Trait */", applicability = "has-placeholders")]
2978    pub suggestion: Span,
2979}
2980
2981#[derive(Diagnostic)]
2982#[diag(parse_expected_mut_or_const_in_raw_pointer_type)]
2983pub(crate) struct ExpectedMutOrConstInRawPointerType {
2984    #[primary_span]
2985    pub span: Span,
2986    #[suggestion(code("mut ", "const "), applicability = "has-placeholders", style = "verbose")]
2987    pub after_asterisk: Span,
2988}
2989
2990#[derive(Diagnostic)]
2991#[diag(parse_lifetime_after_mut)]
2992pub(crate) struct LifetimeAfterMut {
2993    #[primary_span]
2994    pub span: Span,
2995    #[suggestion(code = "&{snippet} mut", applicability = "maybe-incorrect", style = "verbose")]
2996    pub suggest_lifetime: Option<Span>,
2997    pub snippet: String,
2998}
2999
3000#[derive(Diagnostic)]
3001#[diag(parse_dyn_after_mut)]
3002pub(crate) struct DynAfterMut {
3003    #[primary_span]
3004    #[suggestion(code = "&mut dyn", applicability = "machine-applicable", style = "verbose")]
3005    pub span: Span,
3006}
3007
3008#[derive(Diagnostic)]
3009#[diag(parse_fn_pointer_cannot_be_const)]
3010#[note]
3011pub(crate) struct FnPointerCannotBeConst {
3012    #[primary_span]
3013    #[label]
3014    pub span: Span,
3015    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3016    pub suggestion: Span,
3017}
3018
3019#[derive(Diagnostic)]
3020#[diag(parse_fn_pointer_cannot_be_async)]
3021#[note]
3022pub(crate) struct FnPointerCannotBeAsync {
3023    #[primary_span]
3024    #[label]
3025    pub span: Span,
3026    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3027    pub suggestion: Span,
3028}
3029
3030#[derive(Diagnostic)]
3031#[diag(parse_nested_c_variadic_type, code = E0743)]
3032pub(crate) struct NestedCVariadicType {
3033    #[primary_span]
3034    pub span: Span,
3035}
3036
3037#[derive(Diagnostic)]
3038#[diag(parse_invalid_dyn_keyword)]
3039#[help]
3040pub(crate) struct InvalidDynKeyword {
3041    #[primary_span]
3042    pub span: Span,
3043    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
3044    pub suggestion: Span,
3045}
3046
3047#[derive(Subdiagnostic)]
3048pub(crate) enum HelpUseLatestEdition {
3049    #[help(parse_help_set_edition_cargo)]
3050    #[note(parse_note_edition_guide)]
3051    Cargo { edition: Edition },
3052    #[help(parse_help_set_edition_standalone)]
3053    #[note(parse_note_edition_guide)]
3054    Standalone { edition: Edition },
3055}
3056
3057impl HelpUseLatestEdition {
3058    pub(crate) fn new() -> Self {
3059        let edition = LATEST_STABLE_EDITION;
3060        if rustc_session::utils::was_invoked_from_cargo() {
3061            Self::Cargo { edition }
3062        } else {
3063            Self::Standalone { edition }
3064        }
3065    }
3066}
3067
3068#[derive(Diagnostic)]
3069#[diag(parse_box_syntax_removed)]
3070pub(crate) struct BoxSyntaxRemoved {
3071    #[primary_span]
3072    pub span: Span,
3073    #[subdiagnostic]
3074    pub sugg: AddBoxNew,
3075}
3076
3077#[derive(Subdiagnostic)]
3078#[multipart_suggestion(
3079    parse_box_syntax_removed_suggestion,
3080    applicability = "machine-applicable",
3081    style = "verbose"
3082)]
3083pub(crate) struct AddBoxNew {
3084    #[suggestion_part(code = "Box::new(")]
3085    pub box_kw_and_lo: Span,
3086    #[suggestion_part(code = ")")]
3087    pub hi: Span,
3088}
3089
3090#[derive(Diagnostic)]
3091#[diag(parse_bad_return_type_notation_output)]
3092pub(crate) struct BadReturnTypeNotationOutput {
3093    #[primary_span]
3094    pub span: Span,
3095    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3096    pub suggestion: Span,
3097}
3098
3099#[derive(Diagnostic)]
3100#[diag(parse_bad_assoc_type_bounds)]
3101pub(crate) struct BadAssocTypeBounds {
3102    #[primary_span]
3103    #[label]
3104    pub span: Span,
3105}
3106
3107#[derive(Diagnostic)]
3108#[diag(parse_attr_after_generic)]
3109pub(crate) struct AttrAfterGeneric {
3110    #[primary_span]
3111    #[label]
3112    pub span: Span,
3113}
3114
3115#[derive(Diagnostic)]
3116#[diag(parse_attr_without_generics)]
3117pub(crate) struct AttrWithoutGenerics {
3118    #[primary_span]
3119    #[label]
3120    pub span: Span,
3121}
3122
3123#[derive(Diagnostic)]
3124#[diag(parse_where_generics)]
3125pub(crate) struct WhereOnGenerics {
3126    #[primary_span]
3127    #[label]
3128    pub span: Span,
3129}
3130
3131#[derive(Diagnostic)]
3132#[diag(parse_generics_in_path)]
3133pub(crate) struct GenericsInPath {
3134    #[primary_span]
3135    pub span: Vec<Span>,
3136}
3137
3138#[derive(Diagnostic)]
3139#[diag(parse_lifetime_in_eq_constraint)]
3140#[help]
3141pub(crate) struct LifetimeInEqConstraint {
3142    #[primary_span]
3143    #[label]
3144    pub span: Span,
3145    pub lifetime: Ident,
3146    #[label(parse_context_label)]
3147    pub binding_label: Span,
3148    #[suggestion(
3149        parse_colon_sugg,
3150        style = "verbose",
3151        applicability = "maybe-incorrect",
3152        code = ": "
3153    )]
3154    pub colon_sugg: Span,
3155}
3156
3157#[derive(Diagnostic)]
3158#[diag(parse_modifier_lifetime)]
3159pub(crate) struct ModifierLifetime {
3160    #[primary_span]
3161    #[suggestion(style = "tool-only", applicability = "maybe-incorrect", code = "")]
3162    pub span: Span,
3163    pub modifier: &'static str,
3164}
3165
3166#[derive(Diagnostic)]
3167#[diag(parse_underscore_literal_suffix)]
3168pub(crate) struct UnderscoreLiteralSuffix {
3169    #[primary_span]
3170    pub span: Span,
3171}
3172
3173#[derive(Diagnostic)]
3174#[diag(parse_expect_label_found_ident)]
3175pub(crate) struct ExpectedLabelFoundIdent {
3176    #[primary_span]
3177    pub span: Span,
3178    #[suggestion(code = "'", applicability = "machine-applicable", style = "verbose")]
3179    pub start: Span,
3180}
3181
3182#[derive(Diagnostic)]
3183#[diag(parse_inappropriate_default)]
3184#[note]
3185pub(crate) struct InappropriateDefault {
3186    #[primary_span]
3187    #[label]
3188    pub span: Span,
3189    pub article: &'static str,
3190    pub descr: &'static str,
3191}
3192
3193#[derive(Diagnostic)]
3194#[diag(parse_recover_import_as_use)]
3195pub(crate) struct RecoverImportAsUse {
3196    #[primary_span]
3197    #[suggestion(code = "use", applicability = "machine-applicable", style = "verbose")]
3198    pub span: Span,
3199    pub token_name: String,
3200}
3201
3202#[derive(Diagnostic)]
3203#[diag(parse_single_colon_import_path)]
3204#[note]
3205pub(crate) struct SingleColonImportPath {
3206    #[primary_span]
3207    #[suggestion(code = "::", applicability = "machine-applicable", style = "verbose")]
3208    pub span: Span,
3209}
3210
3211#[derive(Diagnostic)]
3212#[diag(parse_bad_item_kind)]
3213pub(crate) struct BadItemKind {
3214    #[primary_span]
3215    pub span: Span,
3216    pub descr: &'static str,
3217    pub ctx: &'static str,
3218    #[help]
3219    pub help: bool,
3220}
3221
3222#[derive(Diagnostic)]
3223#[diag(parse_macro_rules_missing_bang)]
3224pub(crate) struct MacroRulesMissingBang {
3225    #[primary_span]
3226    pub span: Span,
3227    #[suggestion(code = "!", applicability = "machine-applicable", style = "verbose")]
3228    pub hi: Span,
3229}
3230
3231#[derive(Diagnostic)]
3232#[diag(parse_macro_name_remove_bang)]
3233pub(crate) struct MacroNameRemoveBang {
3234    #[primary_span]
3235    #[suggestion(code = "", applicability = "machine-applicable", style = "short")]
3236    pub span: Span,
3237}
3238
3239#[derive(Diagnostic)]
3240#[diag(parse_macro_rules_visibility)]
3241pub(crate) struct MacroRulesVisibility<'a> {
3242    #[primary_span]
3243    #[suggestion(code = "#[macro_export]", applicability = "maybe-incorrect", style = "verbose")]
3244    pub span: Span,
3245    pub vis: &'a str,
3246}
3247
3248#[derive(Diagnostic)]
3249#[diag(parse_macro_invocation_visibility)]
3250#[help]
3251pub(crate) struct MacroInvocationVisibility<'a> {
3252    #[primary_span]
3253    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
3254    pub span: Span,
3255    pub vis: &'a str,
3256}
3257
3258#[derive(Diagnostic)]
3259#[diag(parse_nested_adt)]
3260pub(crate) struct NestedAdt<'a> {
3261    #[primary_span]
3262    pub span: Span,
3263    #[suggestion(code = "", applicability = "maybe-incorrect", style = "verbose")]
3264    pub item: Span,
3265    pub keyword: &'a str,
3266    pub kw_str: Cow<'a, str>,
3267}
3268
3269#[derive(Diagnostic)]
3270#[diag(parse_function_body_equals_expr)]
3271pub(crate) struct FunctionBodyEqualsExpr {
3272    #[primary_span]
3273    pub span: Span,
3274    #[subdiagnostic]
3275    pub sugg: FunctionBodyEqualsExprSugg,
3276}
3277
3278#[derive(Subdiagnostic)]
3279#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3280pub(crate) struct FunctionBodyEqualsExprSugg {
3281    #[suggestion_part(code = "{{")]
3282    pub eq: Span,
3283    #[suggestion_part(code = " }}")]
3284    pub semi: Span,
3285}
3286
3287#[derive(Diagnostic)]
3288#[diag(parse_box_not_pat)]
3289pub(crate) struct BoxNotPat {
3290    #[primary_span]
3291    pub span: Span,
3292    #[note]
3293    pub kw: Span,
3294    #[suggestion(code = "r#", applicability = "maybe-incorrect", style = "verbose")]
3295    pub lo: Span,
3296    pub descr: String,
3297}
3298
3299#[derive(Diagnostic)]
3300#[diag(parse_unmatched_angle)]
3301pub(crate) struct UnmatchedAngle {
3302    #[primary_span]
3303    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
3304    pub span: Span,
3305    pub plural: bool,
3306}
3307
3308#[derive(Diagnostic)]
3309#[diag(parse_missing_plus_in_bounds)]
3310pub(crate) struct MissingPlusBounds {
3311    #[primary_span]
3312    pub span: Span,
3313    #[suggestion(code = " +", applicability = "maybe-incorrect", style = "verbose")]
3314    pub hi: Span,
3315    pub sym: Symbol,
3316}
3317
3318#[derive(Diagnostic)]
3319#[diag(parse_incorrect_parens_trait_bounds)]
3320pub(crate) struct IncorrectParensTraitBounds {
3321    #[primary_span]
3322    pub span: Vec<Span>,
3323    #[subdiagnostic]
3324    pub sugg: IncorrectParensTraitBoundsSugg,
3325}
3326
3327#[derive(Subdiagnostic)]
3328#[multipart_suggestion(
3329    parse_incorrect_parens_trait_bounds_sugg,
3330    applicability = "machine-applicable"
3331)]
3332pub(crate) struct IncorrectParensTraitBoundsSugg {
3333    #[suggestion_part(code = " ")]
3334    pub wrong_span: Span,
3335    #[suggestion_part(code = "(")]
3336    pub new_span: Span,
3337}
3338
3339#[derive(Diagnostic)]
3340#[diag(parse_kw_bad_case)]
3341pub(crate) struct KwBadCase<'a> {
3342    #[primary_span]
3343    #[suggestion(code = "{kw}", style = "verbose", applicability = "machine-applicable")]
3344    pub span: Span,
3345    pub kw: &'a str,
3346}
3347
3348#[derive(Diagnostic)]
3349#[diag(parse_cfg_attr_bad_delim)]
3350pub(crate) struct CfgAttrBadDelim {
3351    #[primary_span]
3352    pub span: Span,
3353    #[subdiagnostic]
3354    pub sugg: MetaBadDelimSugg,
3355}
3356
3357#[derive(Subdiagnostic)]
3358#[multipart_suggestion(parse_meta_bad_delim_suggestion, applicability = "machine-applicable")]
3359pub(crate) struct MetaBadDelimSugg {
3360    #[suggestion_part(code = "(")]
3361    pub open: Span,
3362    #[suggestion_part(code = ")")]
3363    pub close: Span,
3364}
3365
3366#[derive(Diagnostic)]
3367#[diag(parse_malformed_cfg_attr)]
3368#[note]
3369pub(crate) struct MalformedCfgAttr {
3370    #[primary_span]
3371    #[suggestion(style = "verbose", code = "{sugg}")]
3372    pub span: Span,
3373    pub sugg: &'static str,
3374}
3375
3376#[derive(Diagnostic)]
3377#[diag(parse_unknown_builtin_construct)]
3378pub(crate) struct UnknownBuiltinConstruct {
3379    #[primary_span]
3380    pub span: Span,
3381    pub name: Ident,
3382}
3383
3384#[derive(Diagnostic)]
3385#[diag(parse_expected_builtin_ident)]
3386pub(crate) struct ExpectedBuiltinIdent {
3387    #[primary_span]
3388    pub span: Span,
3389}
3390
3391#[derive(Diagnostic)]
3392#[diag(parse_static_with_generics)]
3393pub(crate) struct StaticWithGenerics {
3394    #[primary_span]
3395    pub span: Span,
3396}
3397
3398#[derive(Diagnostic)]
3399#[diag(parse_where_clause_before_const_body)]
3400pub(crate) struct WhereClauseBeforeConstBody {
3401    #[primary_span]
3402    #[label]
3403    pub span: Span,
3404    #[label(parse_name_label)]
3405    pub name: Span,
3406    #[label(parse_body_label)]
3407    pub body: Span,
3408    #[subdiagnostic]
3409    pub sugg: Option<WhereClauseBeforeConstBodySugg>,
3410}
3411
3412#[derive(Subdiagnostic)]
3413#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3414pub(crate) struct WhereClauseBeforeConstBodySugg {
3415    #[suggestion_part(code = "= {snippet} ")]
3416    pub left: Span,
3417    pub snippet: String,
3418    #[suggestion_part(code = "")]
3419    pub right: Span,
3420}
3421
3422#[derive(Diagnostic)]
3423#[diag(parse_generic_args_in_pat_require_turbofish_syntax)]
3424pub(crate) struct GenericArgsInPatRequireTurbofishSyntax {
3425    #[primary_span]
3426    pub span: Span,
3427    #[suggestion(
3428        parse_sugg_turbofish_syntax,
3429        style = "verbose",
3430        code = "::",
3431        applicability = "maybe-incorrect"
3432    )]
3433    pub suggest_turbofish: Span,
3434}
3435
3436#[derive(Diagnostic)]
3437#[diag(parse_transpose_dyn_or_impl)]
3438pub(crate) struct TransposeDynOrImpl<'a> {
3439    #[primary_span]
3440    pub span: Span,
3441    pub kw: &'a str,
3442    #[subdiagnostic]
3443    pub sugg: TransposeDynOrImplSugg<'a>,
3444}
3445
3446#[derive(Subdiagnostic)]
3447#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3448pub(crate) struct TransposeDynOrImplSugg<'a> {
3449    #[suggestion_part(code = "")]
3450    pub removal_span: Span,
3451    #[suggestion_part(code = "{kw} ")]
3452    pub insertion_span: Span,
3453    pub kw: &'a str,
3454}
3455
3456#[derive(Diagnostic)]
3457#[diag(parse_array_index_offset_of)]
3458pub(crate) struct ArrayIndexInOffsetOf(#[primary_span] pub Span);
3459
3460#[derive(Diagnostic)]
3461#[diag(parse_invalid_offset_of)]
3462pub(crate) struct InvalidOffsetOf(#[primary_span] pub Span);
3463
3464#[derive(Diagnostic)]
3465#[diag(parse_async_impl)]
3466pub(crate) struct AsyncImpl {
3467    #[primary_span]
3468    pub span: Span,
3469}
3470
3471#[derive(Diagnostic)]
3472#[diag(parse_expr_rarrow_call)]
3473#[help]
3474pub(crate) struct ExprRArrowCall {
3475    #[primary_span]
3476    #[suggestion(style = "verbose", applicability = "machine-applicable", code = ".")]
3477    pub span: Span,
3478}
3479
3480#[derive(Diagnostic)]
3481#[diag(parse_dot_dot_range_attribute)]
3482pub(crate) struct DotDotRangeAttribute {
3483    #[primary_span]
3484    pub span: Span,
3485}
3486
3487#[derive(Diagnostic)]
3488#[diag(parse_binder_before_modifiers)]
3489pub(crate) struct BinderBeforeModifiers {
3490    #[primary_span]
3491    pub binder_span: Span,
3492    #[label]
3493    pub modifiers_span: Span,
3494}
3495
3496#[derive(Diagnostic)]
3497#[diag(parse_binder_and_polarity)]
3498pub(crate) struct BinderAndPolarity {
3499    #[primary_span]
3500    pub polarity_span: Span,
3501    #[label]
3502    pub binder_span: Span,
3503    pub polarity: &'static str,
3504}
3505
3506#[derive(Diagnostic)]
3507#[diag(parse_modifiers_and_polarity)]
3508pub(crate) struct PolarityAndModifiers {
3509    #[primary_span]
3510    pub polarity_span: Span,
3511    #[label]
3512    pub modifiers_span: Span,
3513    pub polarity: &'static str,
3514    pub modifiers_concatenated: String,
3515}
3516
3517#[derive(Diagnostic)]
3518#[diag(parse_incorrect_type_on_self)]
3519pub(crate) struct IncorrectTypeOnSelf {
3520    #[primary_span]
3521    pub span: Span,
3522    #[subdiagnostic]
3523    pub move_self_modifier: MoveSelfModifier,
3524}
3525
3526#[derive(Subdiagnostic)]
3527#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
3528pub(crate) struct MoveSelfModifier {
3529    #[suggestion_part(code = "")]
3530    pub removal_span: Span,
3531    #[suggestion_part(code = "{modifier}")]
3532    pub insertion_span: Span,
3533    pub modifier: String,
3534}
3535
3536#[derive(Diagnostic)]
3537#[diag(parse_asm_unsupported_operand)]
3538pub(crate) struct AsmUnsupportedOperand<'a> {
3539    #[primary_span]
3540    #[label]
3541    pub(crate) span: Span,
3542    pub(crate) symbol: &'a str,
3543    pub(crate) macro_name: &'static str,
3544}
3545
3546#[derive(Diagnostic)]
3547#[diag(parse_asm_underscore_input)]
3548pub(crate) struct AsmUnderscoreInput {
3549    #[primary_span]
3550    pub(crate) span: Span,
3551}
3552
3553#[derive(Diagnostic)]
3554#[diag(parse_asm_sym_no_path)]
3555pub(crate) struct AsmSymNoPath {
3556    #[primary_span]
3557    pub(crate) span: Span,
3558}
3559
3560#[derive(Diagnostic)]
3561#[diag(parse_asm_requires_template)]
3562pub(crate) struct AsmRequiresTemplate {
3563    #[primary_span]
3564    pub(crate) span: Span,
3565}
3566
3567#[derive(Diagnostic)]
3568#[diag(parse_asm_expected_comma)]
3569pub(crate) struct AsmExpectedComma {
3570    #[primary_span]
3571    #[label]
3572    pub(crate) span: Span,
3573}
3574
3575#[derive(Diagnostic)]
3576#[diag(parse_asm_expected_other)]
3577pub(crate) struct AsmExpectedOther {
3578    #[primary_span]
3579    #[label(parse_asm_expected_other)]
3580    pub(crate) span: Span,
3581    pub(crate) is_inline_asm: bool,
3582}
3583
3584#[derive(Diagnostic)]
3585#[diag(parse_asm_non_abi)]
3586pub(crate) struct NonABI {
3587    #[primary_span]
3588    pub(crate) span: Span,
3589}
3590
3591#[derive(Diagnostic)]
3592#[diag(parse_asm_expected_string_literal)]
3593pub(crate) struct AsmExpectedStringLiteral {
3594    #[primary_span]
3595    #[label]
3596    pub(crate) span: Span,
3597}
3598
3599#[derive(Diagnostic)]
3600#[diag(parse_asm_expected_register_class_or_explicit_register)]
3601pub(crate) struct ExpectedRegisterClassOrExplicitRegister {
3602    #[primary_span]
3603    pub(crate) span: Span,
3604}
3605
3606#[derive(LintDiagnostic)]
3607#[diag(parse_hidden_unicode_codepoints)]
3608#[note]
3609pub(crate) struct HiddenUnicodeCodepointsDiag {
3610    pub label: String,
3611    pub count: usize,
3612    #[label]
3613    pub span_label: Span,
3614    #[subdiagnostic]
3615    pub labels: Option<HiddenUnicodeCodepointsDiagLabels>,
3616    #[subdiagnostic]
3617    pub sub: HiddenUnicodeCodepointsDiagSub,
3618}
3619
3620pub(crate) struct HiddenUnicodeCodepointsDiagLabels {
3621    pub spans: Vec<(char, Span)>,
3622}
3623
3624impl Subdiagnostic for HiddenUnicodeCodepointsDiagLabels {
3625    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
3626        for (c, span) in self.spans {
3627            diag.span_label(span, format!("{c:?}"));
3628        }
3629    }
3630}
3631
3632pub(crate) enum HiddenUnicodeCodepointsDiagSub {
3633    Escape { spans: Vec<(char, Span)> },
3634    NoEscape { spans: Vec<(char, Span)> },
3635}
3636
3637// Used because of multiple multipart_suggestion and note
3638impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub {
3639    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
3640        match self {
3641            HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
3642                diag.multipart_suggestion_with_style(
3643                    fluent::parse_suggestion_remove,
3644                    spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
3645                    Applicability::MachineApplicable,
3646                    SuggestionStyle::HideCodeAlways,
3647                );
3648                diag.multipart_suggestion(
3649                    fluent::parse_suggestion_escape,
3650                    spans
3651                        .into_iter()
3652                        .map(|(c, span)| {
3653                            let c = format!("{c:?}");
3654                            (span, c[1..c.len() - 1].to_string())
3655                        })
3656                        .collect(),
3657                    Applicability::MachineApplicable,
3658                );
3659            }
3660            HiddenUnicodeCodepointsDiagSub::NoEscape { spans } => {
3661                // FIXME: in other suggestions we've reversed the inner spans of doc comments. We
3662                // should do the same here to provide the same good suggestions as we do for
3663                // literals above.
3664                diag.arg(
3665                    "escaped",
3666                    spans
3667                        .into_iter()
3668                        .map(|(c, _)| format!("{c:?}"))
3669                        .collect::<Vec<String>>()
3670                        .join(", "),
3671                );
3672                diag.note(fluent::parse_suggestion_remove);
3673                diag.note(fluent::parse_no_suggestion_note_escape);
3674            }
3675        }
3676    }
3677}