]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_parse/src/errors.rs
Fix the bug of next_point in span
[rust.git] / compiler / rustc_parse / src / errors.rs
1 use rustc_ast::token::Token;
2 use rustc_ast::Path;
3 use rustc_errors::{fluent, AddToDiagnostic, Applicability, EmissionGuarantee, IntoDiagnostic};
4 use rustc_macros::{Diagnostic, Subdiagnostic};
5 use rustc_session::errors::ExprParenthesesNeeded;
6 use rustc_span::symbol::Ident;
7 use rustc_span::{Span, Symbol};
8
9 use crate::parser::TokenDescription;
10
11 #[derive(Diagnostic)]
12 #[diag(parser::maybe_report_ambiguous_plus)]
13 pub(crate) struct AmbiguousPlus {
14     pub sum_ty: String,
15     #[primary_span]
16     #[suggestion(code = "({sum_ty})")]
17     pub span: Span,
18 }
19
20 #[derive(Diagnostic)]
21 #[diag(parser::maybe_recover_from_bad_type_plus, code = "E0178")]
22 pub(crate) struct BadTypePlus {
23     pub ty: String,
24     #[primary_span]
25     pub span: Span,
26     #[subdiagnostic]
27     pub sub: BadTypePlusSub,
28 }
29
30 #[derive(Subdiagnostic)]
31 pub(crate) enum BadTypePlusSub {
32     #[suggestion(
33         parser::add_paren,
34         code = "{sum_with_parens}",
35         applicability = "machine-applicable"
36     )]
37     AddParen {
38         sum_with_parens: String,
39         #[primary_span]
40         span: Span,
41     },
42     #[label(parser::forgot_paren)]
43     ForgotParen {
44         #[primary_span]
45         span: Span,
46     },
47     #[label(parser::expect_path)]
48     ExpectPath {
49         #[primary_span]
50         span: Span,
51     },
52 }
53
54 #[derive(Diagnostic)]
55 #[diag(parser::maybe_recover_from_bad_qpath_stage_2)]
56 pub(crate) struct BadQPathStage2 {
57     #[primary_span]
58     #[suggestion(code = "", applicability = "maybe-incorrect")]
59     pub span: Span,
60     pub ty: String,
61 }
62
63 #[derive(Diagnostic)]
64 #[diag(parser::incorrect_semicolon)]
65 pub(crate) struct IncorrectSemicolon<'a> {
66     #[primary_span]
67     #[suggestion_short(code = "", applicability = "machine-applicable")]
68     pub span: Span,
69     #[help]
70     pub opt_help: Option<()>,
71     pub name: &'a str,
72 }
73
74 #[derive(Diagnostic)]
75 #[diag(parser::incorrect_use_of_await)]
76 pub(crate) struct IncorrectUseOfAwait {
77     #[primary_span]
78     #[suggestion(parser::parentheses_suggestion, code = "", applicability = "machine-applicable")]
79     pub span: Span,
80 }
81
82 #[derive(Diagnostic)]
83 #[diag(parser::incorrect_use_of_await)]
84 pub(crate) struct IncorrectAwait {
85     #[primary_span]
86     pub span: Span,
87     #[suggestion(parser::postfix_suggestion, code = "{expr}.await{question_mark}")]
88     pub sugg_span: (Span, Applicability),
89     pub expr: String,
90     pub question_mark: &'static str,
91 }
92
93 #[derive(Diagnostic)]
94 #[diag(parser::in_in_typo)]
95 pub(crate) struct InInTypo {
96     #[primary_span]
97     pub span: Span,
98     #[suggestion(code = "", applicability = "machine-applicable")]
99     pub sugg_span: Span,
100 }
101
102 #[derive(Diagnostic)]
103 #[diag(parser::invalid_variable_declaration)]
104 pub(crate) struct InvalidVariableDeclaration {
105     #[primary_span]
106     pub span: Span,
107     #[subdiagnostic]
108     pub sub: InvalidVariableDeclarationSub,
109 }
110
111 #[derive(Subdiagnostic)]
112 pub(crate) enum InvalidVariableDeclarationSub {
113     #[suggestion(
114         parser::switch_mut_let_order,
115         applicability = "maybe-incorrect",
116         code = "let mut"
117     )]
118     SwitchMutLetOrder(#[primary_span] Span),
119     #[suggestion(
120         parser::missing_let_before_mut,
121         applicability = "machine-applicable",
122         code = "let mut"
123     )]
124     MissingLet(#[primary_span] Span),
125     #[suggestion(parser::use_let_not_auto, applicability = "machine-applicable", code = "let")]
126     UseLetNotAuto(#[primary_span] Span),
127     #[suggestion(parser::use_let_not_var, applicability = "machine-applicable", code = "let")]
128     UseLetNotVar(#[primary_span] Span),
129 }
130
131 #[derive(Diagnostic)]
132 #[diag(parser::invalid_comparison_operator)]
133 pub(crate) struct InvalidComparisonOperator {
134     #[primary_span]
135     pub span: Span,
136     pub invalid: String,
137     #[subdiagnostic]
138     pub sub: InvalidComparisonOperatorSub,
139 }
140
141 #[derive(Subdiagnostic)]
142 pub(crate) enum InvalidComparisonOperatorSub {
143     #[suggestion_short(
144         parser::use_instead,
145         applicability = "machine-applicable",
146         code = "{correct}"
147     )]
148     Correctable {
149         #[primary_span]
150         span: Span,
151         invalid: String,
152         correct: String,
153     },
154     #[label(parser::spaceship_operator_invalid)]
155     Spaceship(#[primary_span] Span),
156 }
157
158 #[derive(Diagnostic)]
159 #[diag(parser::invalid_logical_operator)]
160 #[note]
161 pub(crate) struct InvalidLogicalOperator {
162     #[primary_span]
163     pub span: Span,
164     pub incorrect: String,
165     #[subdiagnostic]
166     pub sub: InvalidLogicalOperatorSub,
167 }
168
169 #[derive(Subdiagnostic)]
170 pub(crate) enum InvalidLogicalOperatorSub {
171     #[suggestion_short(
172         parser::use_amp_amp_for_conjunction,
173         applicability = "machine-applicable",
174         code = "&&"
175     )]
176     Conjunction(#[primary_span] Span),
177     #[suggestion_short(
178         parser::use_pipe_pipe_for_disjunction,
179         applicability = "machine-applicable",
180         code = "||"
181     )]
182     Disjunction(#[primary_span] Span),
183 }
184
185 #[derive(Diagnostic)]
186 #[diag(parser::tilde_is_not_unary_operator)]
187 pub(crate) struct TildeAsUnaryOperator(
188     #[primary_span]
189     #[suggestion_short(applicability = "machine-applicable", code = "!")]
190     pub Span,
191 );
192
193 #[derive(Diagnostic)]
194 #[diag(parser::unexpected_token_after_not)]
195 pub(crate) struct NotAsNegationOperator {
196     #[primary_span]
197     pub negated: Span,
198     pub negated_desc: String,
199     #[subdiagnostic]
200     pub sub: NotAsNegationOperatorSub,
201 }
202
203 #[derive(Subdiagnostic)]
204 pub enum NotAsNegationOperatorSub {
205     #[suggestion_short(
206         parser::unexpected_token_after_not_default,
207         applicability = "machine-applicable",
208         code = "!"
209     )]
210     SuggestNotDefault(#[primary_span] Span),
211
212     #[suggestion_short(
213         parser::unexpected_token_after_not_bitwise,
214         applicability = "machine-applicable",
215         code = "!"
216     )]
217     SuggestNotBitwise(#[primary_span] Span),
218
219     #[suggestion_short(
220         parser::unexpected_token_after_not_logical,
221         applicability = "machine-applicable",
222         code = "!"
223     )]
224     SuggestNotLogical(#[primary_span] Span),
225 }
226
227 #[derive(Diagnostic)]
228 #[diag(parser::malformed_loop_label)]
229 pub(crate) struct MalformedLoopLabel {
230     #[primary_span]
231     #[suggestion(applicability = "machine-applicable", code = "{correct_label}")]
232     pub span: Span,
233     pub correct_label: Ident,
234 }
235
236 #[derive(Diagnostic)]
237 #[diag(parser::lifetime_in_borrow_expression)]
238 pub(crate) struct LifetimeInBorrowExpression {
239     #[primary_span]
240     pub span: Span,
241     #[suggestion(applicability = "machine-applicable", code = "")]
242     #[label]
243     pub lifetime_span: Span,
244 }
245
246 #[derive(Diagnostic)]
247 #[diag(parser::field_expression_with_generic)]
248 pub(crate) struct FieldExpressionWithGeneric(#[primary_span] pub Span);
249
250 #[derive(Diagnostic)]
251 #[diag(parser::macro_invocation_with_qualified_path)]
252 pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span);
253
254 #[derive(Diagnostic)]
255 #[diag(parser::unexpected_token_after_label)]
256 pub(crate) struct UnexpectedTokenAfterLabel {
257     #[primary_span]
258     #[label(parser::unexpected_token_after_label)]
259     pub span: Span,
260     #[suggestion_verbose(parser::suggestion_remove_label, code = "")]
261     pub remove_label: Option<Span>,
262     #[subdiagnostic]
263     pub enclose_in_block: Option<UnexpectedTokenAfterLabelSugg>,
264 }
265
266 #[derive(Subdiagnostic)]
267 #[multipart_suggestion(parser::suggestion_enclose_in_block, applicability = "machine-applicable")]
268 pub(crate) struct UnexpectedTokenAfterLabelSugg {
269     #[suggestion_part(code = "{{ ")]
270     pub left: Span,
271     #[suggestion_part(code = " }}")]
272     pub right: Span,
273 }
274
275 #[derive(Diagnostic)]
276 #[diag(parser::require_colon_after_labeled_expression)]
277 #[note]
278 pub(crate) struct RequireColonAfterLabeledExpression {
279     #[primary_span]
280     pub span: Span,
281     #[label]
282     pub label: Span,
283     #[suggestion_short(applicability = "machine-applicable", code = ": ")]
284     pub label_end: Span,
285 }
286
287 #[derive(Diagnostic)]
288 #[diag(parser::do_catch_syntax_removed)]
289 #[note]
290 pub(crate) struct DoCatchSyntaxRemoved {
291     #[primary_span]
292     #[suggestion(applicability = "machine-applicable", code = "try")]
293     pub span: Span,
294 }
295
296 #[derive(Diagnostic)]
297 #[diag(parser::float_literal_requires_integer_part)]
298 pub(crate) struct FloatLiteralRequiresIntegerPart {
299     #[primary_span]
300     #[suggestion(applicability = "machine-applicable", code = "{correct}")]
301     pub span: Span,
302     pub correct: String,
303 }
304
305 #[derive(Diagnostic)]
306 #[diag(parser::invalid_int_literal_width)]
307 #[help]
308 pub(crate) struct InvalidIntLiteralWidth {
309     #[primary_span]
310     pub span: Span,
311     pub width: String,
312 }
313
314 #[derive(Diagnostic)]
315 #[diag(parser::invalid_num_literal_base_prefix)]
316 #[note]
317 pub(crate) struct InvalidNumLiteralBasePrefix {
318     #[primary_span]
319     #[suggestion(applicability = "maybe-incorrect", code = "{fixed}")]
320     pub span: Span,
321     pub fixed: String,
322 }
323
324 #[derive(Diagnostic)]
325 #[diag(parser::invalid_num_literal_suffix)]
326 #[help]
327 pub(crate) struct InvalidNumLiteralSuffix {
328     #[primary_span]
329     #[label]
330     pub span: Span,
331     pub suffix: String,
332 }
333
334 #[derive(Diagnostic)]
335 #[diag(parser::invalid_float_literal_width)]
336 #[help]
337 pub(crate) struct InvalidFloatLiteralWidth {
338     #[primary_span]
339     pub span: Span,
340     pub width: String,
341 }
342
343 #[derive(Diagnostic)]
344 #[diag(parser::invalid_float_literal_suffix)]
345 #[help]
346 pub(crate) struct InvalidFloatLiteralSuffix {
347     #[primary_span]
348     #[label]
349     pub span: Span,
350     pub suffix: String,
351 }
352
353 #[derive(Diagnostic)]
354 #[diag(parser::int_literal_too_large)]
355 pub(crate) struct IntLiteralTooLarge {
356     #[primary_span]
357     pub span: Span,
358 }
359
360 #[derive(Diagnostic)]
361 #[diag(parser::missing_semicolon_before_array)]
362 pub(crate) struct MissingSemicolonBeforeArray {
363     #[primary_span]
364     pub open_delim: Span,
365     #[suggestion_verbose(applicability = "maybe-incorrect", code = ";")]
366     pub semicolon: Span,
367 }
368
369 #[derive(Diagnostic)]
370 #[diag(parser::invalid_block_macro_segment)]
371 pub(crate) struct InvalidBlockMacroSegment {
372     #[primary_span]
373     pub span: Span,
374     #[label]
375     pub context: Span,
376 }
377
378 #[derive(Diagnostic)]
379 #[diag(parser::if_expression_missing_then_block)]
380 pub(crate) struct IfExpressionMissingThenBlock {
381     #[primary_span]
382     pub if_span: Span,
383     #[subdiagnostic]
384     pub sub: IfExpressionMissingThenBlockSub,
385 }
386
387 #[derive(Subdiagnostic)]
388 pub(crate) enum IfExpressionMissingThenBlockSub {
389     #[help(parser::condition_possibly_unfinished)]
390     UnfinishedCondition(#[primary_span] Span),
391     #[help(parser::add_then_block)]
392     AddThenBlock(#[primary_span] Span),
393 }
394
395 #[derive(Diagnostic)]
396 #[diag(parser::if_expression_missing_condition)]
397 pub(crate) struct IfExpressionMissingCondition {
398     #[primary_span]
399     #[label(parser::condition_label)]
400     pub if_span: Span,
401     #[label(parser::block_label)]
402     pub block_span: Span,
403 }
404
405 #[derive(Diagnostic)]
406 #[diag(parser::expected_expression_found_let)]
407 pub(crate) struct ExpectedExpressionFoundLet {
408     #[primary_span]
409     pub span: Span,
410 }
411
412 #[derive(Diagnostic)]
413 #[diag(parser::expected_else_block)]
414 pub(crate) struct ExpectedElseBlock {
415     #[primary_span]
416     pub first_tok_span: Span,
417     pub first_tok: String,
418     #[label]
419     pub else_span: Span,
420     #[suggestion(applicability = "maybe-incorrect", code = "if ")]
421     pub condition_start: Span,
422 }
423
424 #[derive(Diagnostic)]
425 #[diag(parser::outer_attribute_not_allowed_on_if_else)]
426 pub(crate) struct OuterAttributeNotAllowedOnIfElse {
427     #[primary_span]
428     pub last: Span,
429
430     #[label(parser::branch_label)]
431     pub branch_span: Span,
432
433     #[label(parser::ctx_label)]
434     pub ctx_span: Span,
435     pub ctx: String,
436
437     #[suggestion(applicability = "machine-applicable", code = "")]
438     pub attributes: Span,
439 }
440
441 #[derive(Diagnostic)]
442 #[diag(parser::missing_in_in_for_loop)]
443 pub(crate) struct MissingInInForLoop {
444     #[primary_span]
445     pub span: Span,
446     #[subdiagnostic]
447     pub sub: MissingInInForLoopSub,
448 }
449
450 #[derive(Subdiagnostic)]
451 pub(crate) enum MissingInInForLoopSub {
452     // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect
453     #[suggestion_short(parser::use_in_not_of, applicability = "maybe-incorrect", code = "in")]
454     InNotOf(#[primary_span] Span),
455     #[suggestion_short(parser::add_in, applicability = "maybe-incorrect", code = " in ")]
456     AddIn(#[primary_span] Span),
457 }
458
459 #[derive(Diagnostic)]
460 #[diag(parser::missing_comma_after_match_arm)]
461 pub(crate) struct MissingCommaAfterMatchArm {
462     #[primary_span]
463     #[suggestion(applicability = "machine-applicable", code = ",")]
464     pub span: Span,
465 }
466
467 #[derive(Diagnostic)]
468 #[diag(parser::catch_after_try)]
469 #[help]
470 pub(crate) struct CatchAfterTry {
471     #[primary_span]
472     pub span: Span,
473 }
474
475 #[derive(Diagnostic)]
476 #[diag(parser::comma_after_base_struct)]
477 #[note]
478 pub(crate) struct CommaAfterBaseStruct {
479     #[primary_span]
480     pub span: Span,
481     #[suggestion_short(applicability = "machine-applicable", code = "")]
482     pub comma: Span,
483 }
484
485 #[derive(Diagnostic)]
486 #[diag(parser::eq_field_init)]
487 pub(crate) struct EqFieldInit {
488     #[primary_span]
489     pub span: Span,
490     #[suggestion(applicability = "machine-applicable", code = ":")]
491     pub eq: Span,
492 }
493
494 #[derive(Diagnostic)]
495 #[diag(parser::dotdotdot)]
496 pub(crate) struct DotDotDot {
497     #[primary_span]
498     #[suggestion(parser::suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
499     #[suggestion(parser::suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
500     pub span: Span,
501 }
502
503 #[derive(Diagnostic)]
504 #[diag(parser::left_arrow_operator)]
505 pub(crate) struct LeftArrowOperator {
506     #[primary_span]
507     #[suggestion(applicability = "maybe-incorrect", code = "< -")]
508     pub span: Span,
509 }
510
511 #[derive(Diagnostic)]
512 #[diag(parser::remove_let)]
513 pub(crate) struct RemoveLet {
514     #[primary_span]
515     #[suggestion(applicability = "machine-applicable", code = "")]
516     pub span: Span,
517 }
518
519 #[derive(Diagnostic)]
520 #[diag(parser::use_eq_instead)]
521 pub(crate) struct UseEqInstead {
522     #[primary_span]
523     #[suggestion_short(applicability = "machine-applicable", code = "=")]
524     pub span: Span,
525 }
526
527 #[derive(Diagnostic)]
528 #[diag(parser::use_empty_block_not_semi)]
529 pub(crate) struct UseEmptyBlockNotSemi {
530     #[primary_span]
531     #[suggestion_hidden(applicability = "machine-applicable", code = "{{}}")]
532     pub span: Span,
533 }
534
535 #[derive(Diagnostic)]
536 #[diag(parser::comparison_interpreted_as_generic)]
537 pub(crate) struct ComparisonInterpretedAsGeneric {
538     #[primary_span]
539     #[label(parser::label_comparison)]
540     pub comparison: Span,
541     pub r#type: Path,
542     #[label(parser::label_args)]
543     pub args: Span,
544     #[subdiagnostic]
545     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
546 }
547
548 #[derive(Diagnostic)]
549 #[diag(parser::shift_interpreted_as_generic)]
550 pub(crate) struct ShiftInterpretedAsGeneric {
551     #[primary_span]
552     #[label(parser::label_comparison)]
553     pub shift: Span,
554     pub r#type: Path,
555     #[label(parser::label_args)]
556     pub args: Span,
557     #[subdiagnostic]
558     pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
559 }
560
561 #[derive(Subdiagnostic)]
562 #[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
563 pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
564     #[suggestion_part(code = "(")]
565     pub left: Span,
566     #[suggestion_part(code = ")")]
567     pub right: Span,
568 }
569
570 #[derive(Diagnostic)]
571 #[diag(parser::found_expr_would_be_stmt)]
572 pub(crate) struct FoundExprWouldBeStmt {
573     #[primary_span]
574     #[label]
575     pub span: Span,
576     pub token: Token,
577     #[subdiagnostic]
578     pub suggestion: ExprParenthesesNeeded,
579 }
580
581 #[derive(Diagnostic)]
582 #[diag(parser::leading_plus_not_supported)]
583 pub(crate) struct LeadingPlusNotSupported {
584     #[primary_span]
585     #[label]
586     pub span: Span,
587     #[suggestion_verbose(
588         parser::suggestion_remove_plus,
589         code = "",
590         applicability = "machine-applicable"
591     )]
592     pub remove_plus: Option<Span>,
593     #[subdiagnostic]
594     pub add_parentheses: Option<ExprParenthesesNeeded>,
595 }
596
597 #[derive(Diagnostic)]
598 #[diag(parser::parentheses_with_struct_fields)]
599 pub(crate) struct ParenthesesWithStructFields {
600     #[primary_span]
601     pub span: Span,
602     pub r#type: Path,
603     #[subdiagnostic]
604     pub braces_for_struct: BracesForStructLiteral,
605     #[subdiagnostic]
606     pub no_fields_for_fn: NoFieldsForFnCall,
607 }
608
609 #[derive(Subdiagnostic)]
610 #[multipart_suggestion(parser::suggestion_braces_for_struct, applicability = "maybe-incorrect")]
611 pub(crate) struct BracesForStructLiteral {
612     #[suggestion_part(code = " {{ ")]
613     pub first: Span,
614     #[suggestion_part(code = " }}")]
615     pub second: Span,
616 }
617
618 #[derive(Subdiagnostic)]
619 #[multipart_suggestion(parser::suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
620 pub(crate) struct NoFieldsForFnCall {
621     #[suggestion_part(code = "")]
622     pub fields: Vec<Span>,
623 }
624
625 #[derive(Diagnostic)]
626 #[diag(parser::labeled_loop_in_break)]
627 pub(crate) struct LabeledLoopInBreak {
628     #[primary_span]
629     pub span: Span,
630     #[subdiagnostic]
631     pub sub: WrapExpressionInParentheses,
632 }
633
634 #[derive(Subdiagnostic)]
635 #[multipart_suggestion(
636     parser::sugg_wrap_expression_in_parentheses,
637     applicability = "machine-applicable"
638 )]
639 pub(crate) struct WrapExpressionInParentheses {
640     #[suggestion_part(code = "(")]
641     pub left: Span,
642     #[suggestion_part(code = ")")]
643     pub right: Span,
644 }
645
646 #[derive(Diagnostic)]
647 #[diag(parser::array_brackets_instead_of_braces)]
648 pub(crate) struct ArrayBracketsInsteadOfSpaces {
649     #[primary_span]
650     pub span: Span,
651     #[subdiagnostic]
652     pub sub: ArrayBracketsInsteadOfSpacesSugg,
653 }
654
655 #[derive(Subdiagnostic)]
656 #[multipart_suggestion(parser::suggestion, applicability = "maybe-incorrect")]
657 pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
658     #[suggestion_part(code = "[")]
659     pub left: Span,
660     #[suggestion_part(code = "]")]
661     pub right: Span,
662 }
663
664 #[derive(Diagnostic)]
665 #[diag(parser::match_arm_body_without_braces)]
666 pub(crate) struct MatchArmBodyWithoutBraces {
667     #[primary_span]
668     #[label(parser::label_statements)]
669     pub statements: Span,
670     #[label(parser::label_arrow)]
671     pub arrow: Span,
672     pub num_statements: usize,
673     #[subdiagnostic]
674     pub sub: MatchArmBodyWithoutBracesSugg,
675 }
676
677 #[derive(Subdiagnostic)]
678 pub(crate) enum MatchArmBodyWithoutBracesSugg {
679     #[multipart_suggestion(parser::suggestion_add_braces, applicability = "machine-applicable")]
680     AddBraces {
681         #[suggestion_part(code = "{{ ")]
682         left: Span,
683         #[suggestion_part(code = " }}")]
684         right: Span,
685     },
686     #[suggestion(
687         parser::suggestion_use_comma_not_semicolon,
688         code = ",",
689         applicability = "machine-applicable"
690     )]
691     UseComma {
692         #[primary_span]
693         semicolon: Span,
694     },
695 }
696
697 #[derive(Diagnostic)]
698 #[diag(parser::struct_literal_not_allowed_here)]
699 pub(crate) struct StructLiteralNotAllowedHere {
700     #[primary_span]
701     pub span: Span,
702     #[subdiagnostic]
703     pub sub: StructLiteralNotAllowedHereSugg,
704 }
705
706 #[derive(Subdiagnostic)]
707 #[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
708 pub(crate) struct StructLiteralNotAllowedHereSugg {
709     #[suggestion_part(code = "(")]
710     pub left: Span,
711     #[suggestion_part(code = ")")]
712     pub right: Span,
713 }
714
715 #[derive(Diagnostic)]
716 #[diag(parser::invalid_interpolated_expression)]
717 pub(crate) struct InvalidInterpolatedExpression {
718     #[primary_span]
719     pub span: Span,
720 }
721
722 #[derive(Diagnostic)]
723 #[diag(parser::hexadecimal_float_literal_not_supported)]
724 pub(crate) struct HexadecimalFloatLiteralNotSupported {
725     #[primary_span]
726     #[label(parser::not_supported)]
727     pub span: Span,
728 }
729
730 #[derive(Diagnostic)]
731 #[diag(parser::octal_float_literal_not_supported)]
732 pub(crate) struct OctalFloatLiteralNotSupported {
733     #[primary_span]
734     #[label(parser::not_supported)]
735     pub span: Span,
736 }
737
738 #[derive(Diagnostic)]
739 #[diag(parser::binary_float_literal_not_supported)]
740 pub(crate) struct BinaryFloatLiteralNotSupported {
741     #[primary_span]
742     #[label(parser::not_supported)]
743     pub span: Span,
744 }
745
746 #[derive(Diagnostic)]
747 #[diag(parser::invalid_literal_suffix)]
748 pub(crate) struct InvalidLiteralSuffix {
749     #[primary_span]
750     #[label]
751     pub span: Span,
752     // FIXME(#100717)
753     pub kind: String,
754     pub suffix: Symbol,
755 }
756
757 #[derive(Diagnostic)]
758 #[diag(parser::invalid_literal_suffix_on_tuple_index)]
759 pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
760     #[primary_span]
761     #[label]
762     pub span: Span,
763     pub suffix: Symbol,
764     #[help(parser::tuple_exception_line_1)]
765     #[help(parser::tuple_exception_line_2)]
766     #[help(parser::tuple_exception_line_3)]
767     pub exception: Option<()>,
768 }
769
770 #[derive(Diagnostic)]
771 #[diag(parser::non_string_abi_literal)]
772 pub(crate) struct NonStringAbiLiteral {
773     #[primary_span]
774     #[suggestion(code = "\"C\"", applicability = "maybe-incorrect")]
775     pub span: Span,
776 }
777
778 #[derive(Diagnostic)]
779 #[diag(parser::mismatched_closing_delimiter)]
780 pub(crate) struct MismatchedClosingDelimiter {
781     #[primary_span]
782     pub spans: Vec<Span>,
783     pub delimiter: String,
784     #[label(parser::label_unmatched)]
785     pub unmatched: Span,
786     #[label(parser::label_opening_candidate)]
787     pub opening_candidate: Option<Span>,
788     #[label(parser::label_unclosed)]
789     pub unclosed: Option<Span>,
790 }
791
792 #[derive(Diagnostic)]
793 #[diag(parser::incorrect_visibility_restriction, code = "E0704")]
794 #[help]
795 pub(crate) struct IncorrectVisibilityRestriction {
796     #[primary_span]
797     #[suggestion(code = "in {inner_str}", applicability = "machine-applicable")]
798     pub span: Span,
799     pub inner_str: String,
800 }
801
802 #[derive(Diagnostic)]
803 #[diag(parser::assignment_else_not_allowed)]
804 pub(crate) struct AssignmentElseNotAllowed {
805     #[primary_span]
806     pub span: Span,
807 }
808
809 #[derive(Diagnostic)]
810 #[diag(parser::expected_statement_after_outer_attr)]
811 pub(crate) struct ExpectedStatementAfterOuterAttr {
812     #[primary_span]
813     pub span: Span,
814 }
815
816 #[derive(Diagnostic)]
817 #[diag(parser::doc_comment_does_not_document_anything, code = "E0585")]
818 #[help]
819 pub(crate) struct DocCommentDoesNotDocumentAnything {
820     #[primary_span]
821     pub span: Span,
822     #[suggestion(code = ",", applicability = "machine-applicable")]
823     pub missing_comma: Option<Span>,
824 }
825
826 #[derive(Diagnostic)]
827 #[diag(parser::const_let_mutually_exclusive)]
828 pub(crate) struct ConstLetMutuallyExclusive {
829     #[primary_span]
830     #[suggestion(code = "const", applicability = "maybe-incorrect")]
831     pub span: Span,
832 }
833
834 #[derive(Diagnostic)]
835 #[diag(parser::invalid_expression_in_let_else)]
836 pub(crate) struct InvalidExpressionInLetElse {
837     #[primary_span]
838     pub span: Span,
839     pub operator: &'static str,
840     #[subdiagnostic]
841     pub sugg: WrapExpressionInParentheses,
842 }
843
844 #[derive(Diagnostic)]
845 #[diag(parser::invalid_curly_in_let_else)]
846 pub(crate) struct InvalidCurlyInLetElse {
847     #[primary_span]
848     pub span: Span,
849     #[subdiagnostic]
850     pub sugg: WrapExpressionInParentheses,
851 }
852
853 #[derive(Diagnostic)]
854 #[diag(parser::compound_assignment_expression_in_let)]
855 #[help]
856 pub(crate) struct CompoundAssignmentExpressionInLet {
857     #[primary_span]
858     #[suggestion_short(code = "=", applicability = "maybe-incorrect")]
859     pub span: Span,
860 }
861
862 #[derive(Diagnostic)]
863 #[diag(parser::suffixed_literal_in_attribute)]
864 #[help]
865 pub(crate) struct SuffixedLiteralInAttribute {
866     #[primary_span]
867     pub span: Span,
868 }
869
870 #[derive(Diagnostic)]
871 #[diag(parser::invalid_meta_item)]
872 pub(crate) struct InvalidMetaItem {
873     #[primary_span]
874     pub span: Span,
875     pub token: Token,
876 }
877
878 #[derive(Subdiagnostic)]
879 #[suggestion_verbose(
880     parser::sugg_escape_to_use_as_identifier,
881     applicability = "maybe-incorrect",
882     code = "r#"
883 )]
884 pub(crate) struct SuggEscapeToUseAsIdentifier {
885     #[primary_span]
886     pub span: Span,
887     pub ident_name: String,
888 }
889
890 #[derive(Subdiagnostic)]
891 #[suggestion(parser::sugg_remove_comma, applicability = "machine-applicable", code = "")]
892 pub(crate) struct SuggRemoveComma {
893     #[primary_span]
894     pub span: Span,
895 }
896
897 #[derive(Subdiagnostic)]
898 pub(crate) enum ExpectedIdentifierFound {
899     #[label(parser::expected_identifier_found_reserved_identifier)]
900     ReservedIdentifier(#[primary_span] Span),
901     #[label(parser::expected_identifier_found_keyword)]
902     Keyword(#[primary_span] Span),
903     #[label(parser::expected_identifier_found_reserved_keyword)]
904     ReservedKeyword(#[primary_span] Span),
905     #[label(parser::expected_identifier_found_doc_comment)]
906     DocComment(#[primary_span] Span),
907     #[label(parser::expected_identifier)]
908     Other(#[primary_span] Span),
909 }
910
911 impl ExpectedIdentifierFound {
912     pub fn new(token_descr: Option<TokenDescription>, span: Span) -> Self {
913         (match token_descr {
914             Some(TokenDescription::ReservedIdentifier) => {
915                 ExpectedIdentifierFound::ReservedIdentifier
916             }
917             Some(TokenDescription::Keyword) => ExpectedIdentifierFound::Keyword,
918             Some(TokenDescription::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
919             Some(TokenDescription::DocComment) => ExpectedIdentifierFound::DocComment,
920             None => ExpectedIdentifierFound::Other,
921         })(span)
922     }
923 }
924
925 pub(crate) struct ExpectedIdentifier {
926     pub span: Span,
927     pub token: Token,
928     pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>,
929     pub suggest_remove_comma: Option<SuggRemoveComma>,
930 }
931
932 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
933     fn into_diagnostic(
934         self,
935         handler: &'a rustc_errors::Handler,
936     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
937         let token_descr = super::parser::TokenDescription::from_token(&self.token);
938
939         let mut diag = handler.struct_diagnostic(match token_descr {
940             Some(TokenDescription::ReservedIdentifier) => {
941                 fluent::parser::expected_identifier_found_reserved_identifier_str
942             }
943             Some(TokenDescription::Keyword) => {
944                 fluent::parser::expected_identifier_found_keyword_str
945             }
946             Some(TokenDescription::ReservedKeyword) => {
947                 fluent::parser::expected_identifier_found_reserved_keyword_str
948             }
949             Some(TokenDescription::DocComment) => {
950                 fluent::parser::expected_identifier_found_doc_comment_str
951             }
952             None => fluent::parser::expected_identifier_found_str,
953         });
954         diag.set_span(self.span);
955         diag.set_arg("token", self.token);
956
957         if let Some(sugg) = self.suggest_raw {
958             sugg.add_to_diagnostic(&mut diag);
959         }
960
961         ExpectedIdentifierFound::new(token_descr, self.span).add_to_diagnostic(&mut diag);
962
963         if let Some(sugg) = self.suggest_remove_comma {
964             sugg.add_to_diagnostic(&mut diag);
965         }
966
967         diag
968     }
969 }
970
971 pub(crate) struct ExpectedSemi {
972     pub span: Span,
973     pub token: Token,
974
975     pub unexpected_token_label: Option<Span>,
976     pub sugg: ExpectedSemiSugg,
977 }
978
979 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
980     fn into_diagnostic(
981         self,
982         handler: &'a rustc_errors::Handler,
983     ) -> rustc_errors::DiagnosticBuilder<'a, G> {
984         let token_descr = super::parser::TokenDescription::from_token(&self.token);
985
986         let mut diag = handler.struct_diagnostic(match token_descr {
987             Some(TokenDescription::ReservedIdentifier) => {
988                 fluent::parser::expected_semi_found_reserved_identifier_str
989             }
990             Some(TokenDescription::Keyword) => fluent::parser::expected_semi_found_keyword_str,
991             Some(TokenDescription::ReservedKeyword) => {
992                 fluent::parser::expected_semi_found_reserved_keyword_str
993             }
994             Some(TokenDescription::DocComment) => {
995                 fluent::parser::expected_semi_found_doc_comment_str
996             }
997             None => fluent::parser::expected_semi_found_str,
998         });
999         diag.set_span(self.span);
1000         diag.set_arg("token", self.token);
1001
1002         if let Some(unexpected_token_label) = self.unexpected_token_label {
1003             diag.span_label(unexpected_token_label, fluent::parser::label_unexpected_token);
1004         }
1005
1006         self.sugg.add_to_diagnostic(&mut diag);
1007
1008         diag
1009     }
1010 }
1011
1012 #[derive(Subdiagnostic)]
1013 pub(crate) enum ExpectedSemiSugg {
1014     #[suggestion(
1015         parser::sugg_change_this_to_semi,
1016         code = ";",
1017         applicability = "machine-applicable"
1018     )]
1019     ChangeToSemi(#[primary_span] Span),
1020     #[suggestion_short(parser::sugg_add_semi, code = ";", applicability = "machine-applicable")]
1021     AddSemi(#[primary_span] Span),
1022 }
1023
1024 #[derive(Diagnostic)]
1025 #[diag(parser::struct_literal_body_without_path)]
1026 pub(crate) struct StructLiteralBodyWithoutPath {
1027     #[primary_span]
1028     pub span: Span,
1029     #[subdiagnostic]
1030     pub sugg: StructLiteralBodyWithoutPathSugg,
1031 }
1032
1033 #[derive(Subdiagnostic)]
1034 #[multipart_suggestion(parser::suggestion, applicability = "has-placeholders")]
1035 pub(crate) struct StructLiteralBodyWithoutPathSugg {
1036     #[suggestion_part(code = "{{ SomeStruct ")]
1037     pub before: Span,
1038     #[suggestion_part(code = " }}")]
1039     pub after: Span,
1040 }
1041
1042 #[derive(Diagnostic)]
1043 #[diag(parser::unmatched_angle_brackets)]
1044 pub(crate) struct UnmatchedAngleBrackets {
1045     #[primary_span]
1046     #[suggestion(code = "", applicability = "machine-applicable")]
1047     pub span: Span,
1048     pub num_extra_brackets: usize,
1049 }
1050
1051 #[derive(Diagnostic)]
1052 #[diag(parser::generic_parameters_without_angle_brackets)]
1053 pub(crate) struct GenericParamsWithoutAngleBrackets {
1054     #[primary_span]
1055     pub span: Span,
1056     #[subdiagnostic]
1057     pub sugg: GenericParamsWithoutAngleBracketsSugg,
1058 }
1059
1060 #[derive(Subdiagnostic)]
1061 #[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
1062 pub(crate) struct GenericParamsWithoutAngleBracketsSugg {
1063     #[suggestion_part(code = "<")]
1064     pub left: Span,
1065     #[suggestion_part(code = ">")]
1066     pub right: Span,
1067 }
1068
1069 #[derive(Diagnostic)]
1070 #[diag(parser::comparison_operators_cannot_be_chained)]
1071 pub(crate) struct ComparisonOperatorsCannotBeChained {
1072     #[primary_span]
1073     pub span: Vec<Span>,
1074     #[suggestion_verbose(
1075         parser::sugg_turbofish_syntax,
1076         code = "::",
1077         applicability = "maybe-incorrect"
1078     )]
1079     pub suggest_turbofish: Option<Span>,
1080     #[help(parser::sugg_turbofish_syntax)]
1081     #[help(parser::sugg_parentheses_for_function_args)]
1082     pub help_turbofish: Option<()>,
1083     #[subdiagnostic]
1084     pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>,
1085 }
1086
1087 #[derive(Subdiagnostic)]
1088 pub(crate) enum ComparisonOperatorsCannotBeChainedSugg {
1089     #[suggestion_verbose(
1090         parser::sugg_split_comparison,
1091         code = " && {middle_term}",
1092         applicability = "maybe-incorrect"
1093     )]
1094     SplitComparison {
1095         #[primary_span]
1096         span: Span,
1097         middle_term: String,
1098     },
1099     #[multipart_suggestion(parser::sugg_parenthesize, applicability = "maybe-incorrect")]
1100     Parenthesize {
1101         #[suggestion_part(code = "(")]
1102         left: Span,
1103         #[suggestion_part(code = ")")]
1104         right: Span,
1105     },
1106 }
1107
1108 #[derive(Diagnostic)]
1109 #[diag(parser::question_mark_in_type)]
1110 pub(crate) struct QuestionMarkInType {
1111     #[primary_span]
1112     #[label]
1113     pub span: Span,
1114     #[subdiagnostic]
1115     pub sugg: QuestionMarkInTypeSugg,
1116 }
1117
1118 #[derive(Subdiagnostic)]
1119 #[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
1120 pub(crate) struct QuestionMarkInTypeSugg {
1121     #[suggestion_part(code = "Option<")]
1122     pub left: Span,
1123     #[suggestion_part(code = ">")]
1124     pub right: Span,
1125 }
1126
1127 #[derive(Diagnostic)]
1128 #[diag(parser::unexpected_parentheses_in_for_head)]
1129 pub(crate) struct ParenthesesInForHead {
1130     #[primary_span]
1131     pub span: Vec<Span>,
1132     #[subdiagnostic]
1133     pub sugg: ParenthesesInForHeadSugg,
1134 }
1135
1136 #[derive(Subdiagnostic)]
1137 #[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
1138 pub(crate) struct ParenthesesInForHeadSugg {
1139     #[suggestion_part(code = "")]
1140     pub left: Span,
1141     #[suggestion_part(code = "")]
1142     pub right: Span,
1143 }
1144
1145 #[derive(Diagnostic)]
1146 #[diag(parser::doc_comment_on_param_type)]
1147 pub(crate) struct DocCommentOnParamType {
1148     #[primary_span]
1149     #[label]
1150     pub span: Span,
1151 }
1152
1153 #[derive(Diagnostic)]
1154 #[diag(parser::attribute_on_param_type)]
1155 pub(crate) struct AttributeOnParamType {
1156     #[primary_span]
1157     #[label]
1158     pub span: Span,
1159 }
1160
1161 #[derive(Diagnostic)]
1162 #[diag(parser::pattern_method_param_without_body, code = "E0642")]
1163 pub(crate) struct PatternMethodParamWithoutBody {
1164     #[primary_span]
1165     #[suggestion(code = "_", applicability = "machine-applicable")]
1166     pub span: Span,
1167 }
1168
1169 #[derive(Diagnostic)]
1170 #[diag(parser::self_param_not_first)]
1171 pub(crate) struct SelfParamNotFirst {
1172     #[primary_span]
1173     #[label]
1174     pub span: Span,
1175 }
1176
1177 #[derive(Diagnostic)]
1178 #[diag(parser::const_generic_without_braces)]
1179 pub(crate) struct ConstGenericWithoutBraces {
1180     #[primary_span]
1181     pub span: Span,
1182     #[subdiagnostic]
1183     pub sugg: ConstGenericWithoutBracesSugg,
1184 }
1185
1186 #[derive(Subdiagnostic)]
1187 #[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
1188 pub(crate) struct ConstGenericWithoutBracesSugg {
1189     #[suggestion_part(code = "{{ ")]
1190     pub left: Span,
1191     #[suggestion_part(code = " }}")]
1192     pub right: Span,
1193 }
1194
1195 #[derive(Diagnostic)]
1196 #[diag(parser::unexpected_const_param_declaration)]
1197 pub(crate) struct UnexpectedConstParamDeclaration {
1198     #[primary_span]
1199     #[label]
1200     pub span: Span,
1201     #[subdiagnostic]
1202     pub sugg: Option<UnexpectedConstParamDeclarationSugg>,
1203 }
1204
1205 #[derive(Subdiagnostic)]
1206 pub(crate) enum UnexpectedConstParamDeclarationSugg {
1207     #[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
1208     AddParam {
1209         #[suggestion_part(code = "<{snippet}>")]
1210         impl_generics: Span,
1211         #[suggestion_part(code = "{ident}")]
1212         incorrect_decl: Span,
1213         snippet: String,
1214         ident: String,
1215     },
1216     #[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
1217     AppendParam {
1218         #[suggestion_part(code = ", {snippet}")]
1219         impl_generics_end: Span,
1220         #[suggestion_part(code = "{ident}")]
1221         incorrect_decl: Span,
1222         snippet: String,
1223         ident: String,
1224     },
1225 }
1226
1227 #[derive(Diagnostic)]
1228 #[diag(parser::unexpected_const_in_generic_param)]
1229 pub(crate) struct UnexpectedConstInGenericParam {
1230     #[primary_span]
1231     pub span: Span,
1232     #[suggestion_verbose(code = "", applicability = "maybe-incorrect")]
1233     pub to_remove: Option<Span>,
1234 }
1235
1236 #[derive(Diagnostic)]
1237 #[diag(parser::async_move_order_incorrect)]
1238 pub(crate) struct AsyncMoveOrderIncorrect {
1239     #[primary_span]
1240     #[suggestion_verbose(code = "async move", applicability = "maybe-incorrect")]
1241     pub span: Span,
1242 }
1243
1244 #[derive(Diagnostic)]
1245 #[diag(parser::double_colon_in_bound)]
1246 pub(crate) struct DoubleColonInBound {
1247     #[primary_span]
1248     pub span: Span,
1249     #[suggestion(code = ": ", applicability = "machine-applicable")]
1250     pub between: Span,
1251 }