about summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/errors.rs783
-rw-r--r--compiler/rustc_parse/src/lib.rs2
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs786
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs46
-rw-r--r--compiler/rustc_parse/src/parser/item.rs4
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs2
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs5
8 files changed, 819 insertions, 811 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
new file mode 100644
index 00000000000..dc7a39457a0
--- /dev/null
+++ b/compiler/rustc_parse/src/errors.rs
@@ -0,0 +1,783 @@
+use rustc_errors::Applicability;
+use rustc_macros::{Diagnostic, Subdiagnostic};
+use rustc_session::errors::ExprParenthesesNeeded;
+use rustc_span::symbol::Ident;
+use rustc_span::{Span, Symbol};
+
+#[derive(Diagnostic)]
+#[diag(parser::maybe_report_ambiguous_plus)]
+pub(crate) struct AmbiguousPlus {
+    pub sum_ty: String,
+    #[primary_span]
+    #[suggestion(code = "({sum_ty})")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::maybe_recover_from_bad_type_plus, code = "E0178")]
+pub(crate) struct BadTypePlus {
+    pub ty: String,
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub sub: BadTypePlusSub,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum BadTypePlusSub {
+    #[suggestion(
+        parser::add_paren,
+        code = "{sum_with_parens}",
+        applicability = "machine-applicable"
+    )]
+    AddParen {
+        sum_with_parens: String,
+        #[primary_span]
+        span: Span,
+    },
+    #[label(parser::forgot_paren)]
+    ForgotParen {
+        #[primary_span]
+        span: Span,
+    },
+    #[label(parser::expect_path)]
+    ExpectPath {
+        #[primary_span]
+        span: Span,
+    },
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::maybe_recover_from_bad_qpath_stage_2)]
+pub(crate) struct BadQPathStage2 {
+    #[primary_span]
+    #[suggestion(code = "", applicability = "maybe-incorrect")]
+    pub span: Span,
+    pub ty: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::incorrect_semicolon)]
+pub(crate) struct IncorrectSemicolon<'a> {
+    #[primary_span]
+    #[suggestion_short(code = "", applicability = "machine-applicable")]
+    pub span: Span,
+    #[help]
+    pub opt_help: Option<()>,
+    pub name: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::incorrect_use_of_await)]
+pub(crate) struct IncorrectUseOfAwait {
+    #[primary_span]
+    #[suggestion(parser::parentheses_suggestion, code = "", applicability = "machine-applicable")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::incorrect_use_of_await)]
+pub(crate) struct IncorrectAwait {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(parser::postfix_suggestion, code = "{expr}.await{question_mark}")]
+    pub sugg_span: (Span, Applicability),
+    pub expr: String,
+    pub question_mark: &'static str,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::in_in_typo)]
+pub(crate) struct InInTypo {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(code = "", applicability = "machine-applicable")]
+    pub sugg_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_variable_declaration)]
+pub(crate) struct InvalidVariableDeclaration {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub sub: InvalidVariableDeclarationSub,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum InvalidVariableDeclarationSub {
+    #[suggestion(
+        parser::switch_mut_let_order,
+        applicability = "maybe-incorrect",
+        code = "let mut"
+    )]
+    SwitchMutLetOrder(#[primary_span] Span),
+    #[suggestion(
+        parser::missing_let_before_mut,
+        applicability = "machine-applicable",
+        code = "let mut"
+    )]
+    MissingLet(#[primary_span] Span),
+    #[suggestion(parser::use_let_not_auto, applicability = "machine-applicable", code = "let")]
+    UseLetNotAuto(#[primary_span] Span),
+    #[suggestion(parser::use_let_not_var, applicability = "machine-applicable", code = "let")]
+    UseLetNotVar(#[primary_span] Span),
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_comparison_operator)]
+pub(crate) struct InvalidComparisonOperator {
+    #[primary_span]
+    pub span: Span,
+    pub invalid: String,
+    #[subdiagnostic]
+    pub sub: InvalidComparisonOperatorSub,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum InvalidComparisonOperatorSub {
+    #[suggestion_short(
+        parser::use_instead,
+        applicability = "machine-applicable",
+        code = "{correct}"
+    )]
+    Correctable {
+        #[primary_span]
+        span: Span,
+        invalid: String,
+        correct: String,
+    },
+    #[label(parser::spaceship_operator_invalid)]
+    Spaceship(#[primary_span] Span),
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_logical_operator)]
+#[note]
+pub(crate) struct InvalidLogicalOperator {
+    #[primary_span]
+    pub span: Span,
+    pub incorrect: String,
+    #[subdiagnostic]
+    pub sub: InvalidLogicalOperatorSub,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum InvalidLogicalOperatorSub {
+    #[suggestion_short(
+        parser::use_amp_amp_for_conjunction,
+        applicability = "machine-applicable",
+        code = "&&"
+    )]
+    Conjunction(#[primary_span] Span),
+    #[suggestion_short(
+        parser::use_pipe_pipe_for_disjunction,
+        applicability = "machine-applicable",
+        code = "||"
+    )]
+    Disjunction(#[primary_span] Span),
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::tilde_is_not_unary_operator)]
+pub(crate) struct TildeAsUnaryOperator(
+    #[primary_span]
+    #[suggestion_short(applicability = "machine-applicable", code = "!")]
+    pub Span,
+);
+
+#[derive(Diagnostic)]
+#[diag(parser::unexpected_token_after_not)]
+pub(crate) struct NotAsNegationOperator {
+    #[primary_span]
+    pub negated: Span,
+    pub negated_desc: String,
+    #[subdiagnostic]
+    pub sub: NotAsNegationOperatorSub,
+}
+
+#[derive(Subdiagnostic)]
+pub enum NotAsNegationOperatorSub {
+    #[suggestion_short(
+        parser::unexpected_token_after_not_default,
+        applicability = "machine-applicable",
+        code = "!"
+    )]
+    SuggestNotDefault(#[primary_span] Span),
+
+    #[suggestion_short(
+        parser::unexpected_token_after_not_bitwise,
+        applicability = "machine-applicable",
+        code = "!"
+    )]
+    SuggestNotBitwise(#[primary_span] Span),
+
+    #[suggestion_short(
+        parser::unexpected_token_after_not_logical,
+        applicability = "machine-applicable",
+        code = "!"
+    )]
+    SuggestNotLogical(#[primary_span] Span),
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::malformed_loop_label)]
+pub(crate) struct MalformedLoopLabel {
+    #[primary_span]
+    #[suggestion(applicability = "machine-applicable", code = "{correct_label}")]
+    pub span: Span,
+    pub correct_label: Ident,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::lifetime_in_borrow_expression)]
+pub(crate) struct LifetimeInBorrowExpression {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(applicability = "machine-applicable", code = "")]
+    #[label]
+    pub lifetime_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::field_expression_with_generic)]
+pub(crate) struct FieldExpressionWithGeneric(#[primary_span] pub Span);
+
+#[derive(Diagnostic)]
+#[diag(parser::macro_invocation_with_qualified_path)]
+pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span);
+
+#[derive(Diagnostic)]
+#[diag(parser::unexpected_token_after_label)]
+pub(crate) struct UnexpectedTokenAfterLabel {
+    #[primary_span]
+    #[label(parser::unexpected_token_after_label)]
+    pub span: Span,
+    #[suggestion_verbose(parser::suggestion_remove_label, code = "")]
+    pub remove_label: Option<Span>,
+    #[subdiagnostic]
+    pub enclose_in_block: Option<UnexpectedTokenAfterLabelSugg>,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parser::suggestion_enclose_in_block, applicability = "machine-applicable")]
+pub(crate) struct UnexpectedTokenAfterLabelSugg {
+    #[suggestion_part(code = "{{ ")]
+    pub left: Span,
+    #[suggestion_part(code = " }}")]
+    pub right: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::require_colon_after_labeled_expression)]
+#[note]
+pub(crate) struct RequireColonAfterLabeledExpression {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub label: Span,
+    #[suggestion_short(applicability = "machine-applicable", code = ": ")]
+    pub label_end: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::do_catch_syntax_removed)]
+#[note]
+pub(crate) struct DoCatchSyntaxRemoved {
+    #[primary_span]
+    #[suggestion(applicability = "machine-applicable", code = "try")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::float_literal_requires_integer_part)]
+pub(crate) struct FloatLiteralRequiresIntegerPart {
+    #[primary_span]
+    #[suggestion(applicability = "machine-applicable", code = "{correct}")]
+    pub span: Span,
+    pub correct: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_int_literal_width)]
+#[help]
+pub(crate) struct InvalidIntLiteralWidth {
+    #[primary_span]
+    pub span: Span,
+    pub width: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_num_literal_base_prefix)]
+#[note]
+pub(crate) struct InvalidNumLiteralBasePrefix {
+    #[primary_span]
+    #[suggestion(applicability = "maybe-incorrect", code = "{fixed}")]
+    pub span: Span,
+    pub fixed: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_num_literal_suffix)]
+#[help]
+pub(crate) struct InvalidNumLiteralSuffix {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub suffix: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_float_literal_width)]
+#[help]
+pub(crate) struct InvalidFloatLiteralWidth {
+    #[primary_span]
+    pub span: Span,
+    pub width: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_float_literal_suffix)]
+#[help]
+pub(crate) struct InvalidFloatLiteralSuffix {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub suffix: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::int_literal_too_large)]
+pub(crate) struct IntLiteralTooLarge {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::missing_semicolon_before_array)]
+pub(crate) struct MissingSemicolonBeforeArray {
+    #[primary_span]
+    pub open_delim: Span,
+    #[suggestion_verbose(applicability = "maybe-incorrect", code = ";")]
+    pub semicolon: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_block_macro_segment)]
+pub(crate) struct InvalidBlockMacroSegment {
+    #[primary_span]
+    pub span: Span,
+    #[label]
+    pub context: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::if_expression_missing_then_block)]
+pub(crate) struct IfExpressionMissingThenBlock {
+    #[primary_span]
+    pub if_span: Span,
+    #[subdiagnostic]
+    pub sub: IfExpressionMissingThenBlockSub,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum IfExpressionMissingThenBlockSub {
+    #[help(parser::condition_possibly_unfinished)]
+    UnfinishedCondition(#[primary_span] Span),
+    #[help(parser::add_then_block)]
+    AddThenBlock(#[primary_span] Span),
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::if_expression_missing_condition)]
+pub(crate) struct IfExpressionMissingCondition {
+    #[primary_span]
+    #[label(parser::condition_label)]
+    pub if_span: Span,
+    #[label(parser::block_label)]
+    pub block_span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::expected_expression_found_let)]
+pub(crate) struct ExpectedExpressionFoundLet {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::expected_else_block)]
+pub(crate) struct ExpectedElseBlock {
+    #[primary_span]
+    pub first_tok_span: Span,
+    pub first_tok: String,
+    #[label]
+    pub else_span: Span,
+    #[suggestion(applicability = "maybe-incorrect", code = "if ")]
+    pub condition_start: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::outer_attribute_not_allowed_on_if_else)]
+pub(crate) struct OuterAttributeNotAllowedOnIfElse {
+    #[primary_span]
+    pub last: Span,
+
+    #[label(parser::branch_label)]
+    pub branch_span: Span,
+
+    #[label(parser::ctx_label)]
+    pub ctx_span: Span,
+    pub ctx: String,
+
+    #[suggestion(applicability = "machine-applicable", code = "")]
+    pub attributes: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::missing_in_in_for_loop)]
+pub(crate) struct MissingInInForLoop {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub sub: MissingInInForLoopSub,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum MissingInInForLoopSub {
+    // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect
+    #[suggestion_short(parser::use_in_not_of, applicability = "maybe-incorrect", code = "in")]
+    InNotOf(#[primary_span] Span),
+    #[suggestion_short(parser::add_in, applicability = "maybe-incorrect", code = " in ")]
+    AddIn(#[primary_span] Span),
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::missing_comma_after_match_arm)]
+pub(crate) struct MissingCommaAfterMatchArm {
+    #[primary_span]
+    #[suggestion(applicability = "machine-applicable", code = ",")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::catch_after_try)]
+#[help]
+pub(crate) struct CatchAfterTry {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::comma_after_base_struct)]
+#[note]
+pub(crate) struct CommaAfterBaseStruct {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion_short(applicability = "machine-applicable", code = "")]
+    pub comma: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::eq_field_init)]
+pub(crate) struct EqFieldInit {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(applicability = "machine-applicable", code = ":")]
+    pub eq: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::dotdotdot)]
+pub(crate) struct DotDotDot {
+    #[primary_span]
+    #[suggestion(parser::suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
+    #[suggestion(parser::suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::left_arrow_operator)]
+pub(crate) struct LeftArrowOperator {
+    #[primary_span]
+    #[suggestion(applicability = "maybe-incorrect", code = "< -")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::remove_let)]
+pub(crate) struct RemoveLet {
+    #[primary_span]
+    #[suggestion(applicability = "machine-applicable", code = "")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::use_eq_instead)]
+pub(crate) struct UseEqInstead {
+    #[primary_span]
+    #[suggestion_short(applicability = "machine-applicable", code = "=")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::use_empty_block_not_semi)]
+pub(crate) struct UseEmptyBlockNotSemi {
+    #[primary_span]
+    #[suggestion_hidden(applicability = "machine-applicable", code = "{{}}")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::comparison_interpreted_as_generic)]
+pub(crate) struct ComparisonInterpretedAsGeneric {
+    #[primary_span]
+    #[label(parser::label_comparison)]
+    pub comparison: Span,
+    pub typename: String,
+    #[label(parser::label_args)]
+    pub args: Span,
+    #[subdiagnostic]
+    pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::shift_interpreted_as_generic)]
+pub(crate) struct ShiftInterpretedAsGeneric {
+    #[primary_span]
+    #[label(parser::label_comparison)]
+    pub shift: Span,
+    pub typename: String,
+    #[label(parser::label_args)]
+    pub args: Span,
+    #[subdiagnostic]
+    pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
+pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
+    #[suggestion_part(code = "(")]
+    pub left: Span,
+    #[suggestion_part(code = ")")]
+    pub right: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::found_expr_would_be_stmt)]
+pub(crate) struct FoundExprWouldBeStmt {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub token: String,
+    #[subdiagnostic]
+    pub suggestion: ExprParenthesesNeeded,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::leading_plus_not_supported)]
+pub(crate) struct LeadingPlusNotSupported {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    #[suggestion_verbose(
+        parser::suggestion_remove_plus,
+        code = "",
+        applicability = "machine-applicable"
+    )]
+    pub remove_plus: Option<Span>,
+    #[subdiagnostic]
+    pub add_parentheses: Option<ExprParenthesesNeeded>,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::parentheses_with_struct_fields)]
+pub(crate) struct ParenthesesWithStructFields {
+    #[primary_span]
+    pub span: Span,
+    pub name: String,
+    #[subdiagnostic]
+    pub braces_for_struct: BracesForStructLiteral,
+    #[subdiagnostic]
+    pub no_fields_for_fn: NoFieldsForFnCall,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parser::suggestion_braces_for_struct, applicability = "maybe-incorrect")]
+pub(crate) struct BracesForStructLiteral {
+    #[suggestion_part(code = " {{ ")]
+    pub first: Span,
+    #[suggestion_part(code = " }}")]
+    pub second: Span,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parser::suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
+pub(crate) struct NoFieldsForFnCall {
+    #[suggestion_part(code = "")]
+    pub fields: Vec<Span>,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::labeled_loop_in_break)]
+pub(crate) struct LabeledLoopInBreak {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub sub: LabeledLoopInBreakSub,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
+pub(crate) struct LabeledLoopInBreakSub {
+    #[suggestion_part(code = "(")]
+    pub first: Span,
+    #[suggestion_part(code = ")")]
+    pub second: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::array_brackets_instead_of_braces)]
+pub(crate) struct ArrayBracketsInsteadOfSpaces {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub sub: ArrayBracketsInsteadOfSpacesSugg,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parser::suggestion, applicability = "maybe-incorrect")]
+pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
+    #[suggestion_part(code = "[")]
+    pub left: Span,
+    #[suggestion_part(code = "]")]
+    pub right: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::match_arm_body_without_braces)]
+pub(crate) struct MatchArmBodyWithoutBraces {
+    #[primary_span]
+    #[label(parser::label_statements)]
+    pub statements: Span,
+    #[label(parser::label_arrow)]
+    pub arrow: Span,
+    pub num_statements: usize,
+    #[subdiagnostic]
+    pub sub: MatchArmBodyWithoutBracesSugg,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum MatchArmBodyWithoutBracesSugg {
+    #[multipart_suggestion(parser::suggestion_add_braces, applicability = "machine-applicable")]
+    AddBraces {
+        #[suggestion_part(code = "{{ ")]
+        left: Span,
+        #[suggestion_part(code = " }}")]
+        right: Span,
+    },
+    #[suggestion(
+        parser::suggestion_use_comma_not_semicolon,
+        code = ",",
+        applicability = "machine-applicable"
+    )]
+    UseComma {
+        #[primary_span]
+        semicolon: Span,
+    },
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::struct_literal_not_allowed_here)]
+pub(crate) struct StructLiteralNotAllowedHere {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub sub: StructLiteralNotAllowedHereSugg,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
+pub(crate) struct StructLiteralNotAllowedHereSugg {
+    #[suggestion_part(code = "(")]
+    pub left: Span,
+    #[suggestion_part(code = ")")]
+    pub right: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_interpolated_expression)]
+pub(crate) struct InvalidInterpolatedExpression {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::hexadecimal_float_literal_not_supported)]
+pub(crate) struct HexadecimalFloatLiteralNotSupported {
+    #[primary_span]
+    #[label(parser::not_supported)]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::octal_float_literal_not_supported)]
+pub(crate) struct OctalFloatLiteralNotSupported {
+    #[primary_span]
+    #[label(parser::not_supported)]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::binary_float_literal_not_supported)]
+pub(crate) struct BinaryFloatLiteralNotSupported {
+    #[primary_span]
+    #[label(parser::not_supported)]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_literal_suffix)]
+pub(crate) struct InvalidLiteralSuffix {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    // FIXME(#100717)
+    pub kind: String,
+    pub suffix: Symbol,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::invalid_literal_suffix_on_tuple_index)]
+pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    pub suffix: Symbol,
+    #[help(parser::tuple_exception_line_1)]
+    #[help(parser::tuple_exception_line_2)]
+    #[help(parser::tuple_exception_line_3)]
+    pub exception: Option<()>,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::non_string_abi_literal)]
+pub(crate) struct NonStringAbiLiteral {
+    #[primary_span]
+    #[suggestion(code = "\"C\"", applicability = "maybe-incorrect")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
+#[diag(parser::mismatched_closing_delimiter)]
+pub(crate) struct MismatchedClosingDelimiter {
+    #[primary_span]
+    pub spans: Vec<Span>,
+    pub delimiter: String,
+    #[label(parser::label_unmatched)]
+    pub unmatched: Span,
+    #[label(parser::label_opening_candidate)]
+    pub opening_candidate: Option<Span>,
+    #[label(parser::label_unclosed)]
+    pub unclosed: Option<Span>,
+}
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 06245380927..0bdfe10359c 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -32,6 +32,8 @@ use parser::{emit_unclosed_delims, make_unclosed_delims_error, Parser};
 pub mod lexer;
 pub mod validate_attr;
 
+mod errors;
+
 // A bunch of utility functions of the form `parse_<thing>_from_<source>`
 // where <thing> includes crate, expr, item, stmt, tts, and one that
 // uses a HOF to parse anything, and <source> includes file and
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index c50ca9a2933..0fdde291757 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -3,6 +3,10 @@ use super::{
     BlockMode, CommaRecoveryMode, Parser, PathStyle, Restrictions, SemiColonMode, SeqSep,
     TokenExpectType, TokenType,
 };
+use crate::errors::{
+    AmbiguousPlus, BadQPathStage2, BadTypePlus, BadTypePlusSub, InInTypo, IncorrectAwait,
+    IncorrectSemicolon, IncorrectUseOfAwait, UseEqInstead,
+};
 
 use crate::lexer::UnmatchedBrace;
 use rustc_ast as ast;
@@ -20,11 +24,9 @@ use rustc_errors::{
     fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, Handler, MultiSpan, PResult,
 };
 use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
-use rustc_macros::{Diagnostic, Subdiagnostic};
-use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident};
-use rustc_span::{Span, SpanSnippetError, Symbol, DUMMY_SP};
+use rustc_span::{Span, SpanSnippetError, DUMMY_SP};
 use std::ops::{Deref, DerefMut};
 
 use std::mem::take;
@@ -243,784 +245,6 @@ impl MultiSugg {
     }
 }
 
-#[derive(Diagnostic)]
-#[diag(parser::maybe_report_ambiguous_plus)]
-struct AmbiguousPlus {
-    pub sum_ty: String,
-    #[primary_span]
-    #[suggestion(code = "({sum_ty})")]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::maybe_recover_from_bad_type_plus, code = "E0178")]
-struct BadTypePlus {
-    pub ty: String,
-    #[primary_span]
-    pub span: Span,
-    #[subdiagnostic]
-    pub sub: BadTypePlusSub,
-}
-
-#[derive(Subdiagnostic)]
-pub enum BadTypePlusSub {
-    #[suggestion(
-        parser::add_paren,
-        code = "{sum_with_parens}",
-        applicability = "machine-applicable"
-    )]
-    AddParen {
-        sum_with_parens: String,
-        #[primary_span]
-        span: Span,
-    },
-    #[label(parser::forgot_paren)]
-    ForgotParen {
-        #[primary_span]
-        span: Span,
-    },
-    #[label(parser::expect_path)]
-    ExpectPath {
-        #[primary_span]
-        span: Span,
-    },
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::maybe_recover_from_bad_qpath_stage_2)]
-struct BadQPathStage2 {
-    #[primary_span]
-    #[suggestion(code = "", applicability = "maybe-incorrect")]
-    span: Span,
-    ty: String,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::incorrect_semicolon)]
-struct IncorrectSemicolon<'a> {
-    #[primary_span]
-    #[suggestion_short(code = "", applicability = "machine-applicable")]
-    span: Span,
-    #[help]
-    opt_help: Option<()>,
-    name: &'a str,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::incorrect_use_of_await)]
-struct IncorrectUseOfAwait {
-    #[primary_span]
-    #[suggestion(parser::parentheses_suggestion, code = "", applicability = "machine-applicable")]
-    span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::incorrect_use_of_await)]
-struct IncorrectAwait {
-    #[primary_span]
-    span: Span,
-    #[suggestion(parser::postfix_suggestion, code = "{expr}.await{question_mark}")]
-    sugg_span: (Span, Applicability),
-    expr: String,
-    question_mark: &'static str,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::in_in_typo)]
-struct InInTypo {
-    #[primary_span]
-    span: Span,
-    #[suggestion(code = "", applicability = "machine-applicable")]
-    sugg_span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_variable_declaration)]
-pub struct InvalidVariableDeclaration {
-    #[primary_span]
-    pub span: Span,
-    #[subdiagnostic]
-    pub sub: InvalidVariableDeclarationSub,
-}
-
-#[derive(Subdiagnostic)]
-pub enum InvalidVariableDeclarationSub {
-    #[suggestion(
-        parser::switch_mut_let_order,
-        applicability = "maybe-incorrect",
-        code = "let mut"
-    )]
-    SwitchMutLetOrder(#[primary_span] Span),
-    #[suggestion(
-        parser::missing_let_before_mut,
-        applicability = "machine-applicable",
-        code = "let mut"
-    )]
-    MissingLet(#[primary_span] Span),
-    #[suggestion(parser::use_let_not_auto, applicability = "machine-applicable", code = "let")]
-    UseLetNotAuto(#[primary_span] Span),
-    #[suggestion(parser::use_let_not_var, applicability = "machine-applicable", code = "let")]
-    UseLetNotVar(#[primary_span] Span),
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_comparison_operator)]
-pub(crate) struct InvalidComparisonOperator {
-    #[primary_span]
-    pub span: Span,
-    pub invalid: String,
-    #[subdiagnostic]
-    pub sub: InvalidComparisonOperatorSub,
-}
-
-#[derive(Subdiagnostic)]
-pub(crate) enum InvalidComparisonOperatorSub {
-    #[suggestion_short(
-        parser::use_instead,
-        applicability = "machine-applicable",
-        code = "{correct}"
-    )]
-    Correctable {
-        #[primary_span]
-        span: Span,
-        invalid: String,
-        correct: String,
-    },
-    #[label(parser::spaceship_operator_invalid)]
-    Spaceship(#[primary_span] Span),
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_logical_operator)]
-#[note]
-pub(crate) struct InvalidLogicalOperator {
-    #[primary_span]
-    pub span: Span,
-    pub incorrect: String,
-    #[subdiagnostic]
-    pub sub: InvalidLogicalOperatorSub,
-}
-
-#[derive(Subdiagnostic)]
-pub(crate) enum InvalidLogicalOperatorSub {
-    #[suggestion_short(
-        parser::use_amp_amp_for_conjunction,
-        applicability = "machine-applicable",
-        code = "&&"
-    )]
-    Conjunction(#[primary_span] Span),
-    #[suggestion_short(
-        parser::use_pipe_pipe_for_disjunction,
-        applicability = "machine-applicable",
-        code = "||"
-    )]
-    Disjunction(#[primary_span] Span),
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::tilde_is_not_unary_operator)]
-pub(crate) struct TildeAsUnaryOperator(
-    #[primary_span]
-    #[suggestion_short(applicability = "machine-applicable", code = "!")]
-    pub Span,
-);
-
-#[derive(Diagnostic)]
-#[diag(parser::unexpected_token_after_not)]
-pub(crate) struct NotAsNegationOperator {
-    #[primary_span]
-    pub negated: Span,
-    pub negated_desc: String,
-    #[subdiagnostic]
-    pub sub: NotAsNegationOperatorSub,
-}
-
-#[derive(Subdiagnostic)]
-pub enum NotAsNegationOperatorSub {
-    #[suggestion_short(
-        parser::unexpected_token_after_not_default,
-        applicability = "machine-applicable",
-        code = "!"
-    )]
-    SuggestNotDefault(#[primary_span] Span),
-
-    #[suggestion_short(
-        parser::unexpected_token_after_not_bitwise,
-        applicability = "machine-applicable",
-        code = "!"
-    )]
-    SuggestNotBitwise(#[primary_span] Span),
-
-    #[suggestion_short(
-        parser::unexpected_token_after_not_logical,
-        applicability = "machine-applicable",
-        code = "!"
-    )]
-    SuggestNotLogical(#[primary_span] Span),
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::malformed_loop_label)]
-pub(crate) struct MalformedLoopLabel {
-    #[primary_span]
-    #[suggestion(applicability = "machine-applicable", code = "{correct_label}")]
-    pub span: Span,
-    pub correct_label: Ident,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::lifetime_in_borrow_expression)]
-pub(crate) struct LifetimeInBorrowExpression {
-    #[primary_span]
-    pub span: Span,
-    #[suggestion(applicability = "machine-applicable", code = "")]
-    #[label]
-    pub lifetime_span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::field_expression_with_generic)]
-pub(crate) struct FieldExpressionWithGeneric(#[primary_span] pub Span);
-
-#[derive(Diagnostic)]
-#[diag(parser::macro_invocation_with_qualified_path)]
-pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span);
-
-#[derive(Diagnostic)]
-#[diag(parser::unexpected_token_after_label)]
-pub(crate) struct UnexpectedTokenAfterLabel {
-    #[primary_span]
-    #[label(parser::unexpected_token_after_label)]
-    pub span: Span,
-    #[suggestion_verbose(parser::suggestion_remove_label, code = "")]
-    pub remove_label: Option<Span>,
-    #[subdiagnostic]
-    pub enclose_in_block: Option<UnexpectedTokenAfterLabelSugg>,
-}
-
-#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser::suggestion_enclose_in_block, applicability = "machine-applicable")]
-pub(crate) struct UnexpectedTokenAfterLabelSugg {
-    #[suggestion_part(code = "{{ ")]
-    pub left: Span,
-    #[suggestion_part(code = " }}")]
-    pub right: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::require_colon_after_labeled_expression)]
-#[note]
-pub(crate) struct RequireColonAfterLabeledExpression {
-    #[primary_span]
-    pub span: Span,
-    #[label]
-    pub label: Span,
-    #[suggestion_short(applicability = "machine-applicable", code = ": ")]
-    pub label_end: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::do_catch_syntax_removed)]
-#[note]
-pub(crate) struct DoCatchSyntaxRemoved {
-    #[primary_span]
-    #[suggestion(applicability = "machine-applicable", code = "try")]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::float_literal_requires_integer_part)]
-pub(crate) struct FloatLiteralRequiresIntegerPart {
-    #[primary_span]
-    #[suggestion(applicability = "machine-applicable", code = "{correct}")]
-    pub span: Span,
-    pub correct: String,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_int_literal_width)]
-#[help]
-pub(crate) struct InvalidIntLiteralWidth {
-    #[primary_span]
-    pub span: Span,
-    pub width: String,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_num_literal_base_prefix)]
-#[note]
-pub(crate) struct InvalidNumLiteralBasePrefix {
-    #[primary_span]
-    #[suggestion(applicability = "maybe-incorrect", code = "{fixed}")]
-    pub span: Span,
-    pub fixed: String,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_num_literal_suffix)]
-#[help]
-pub(crate) struct InvalidNumLiteralSuffix {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    pub suffix: String,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_float_literal_width)]
-#[help]
-pub(crate) struct InvalidFloatLiteralWidth {
-    #[primary_span]
-    pub span: Span,
-    pub width: String,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_float_literal_suffix)]
-#[help]
-pub(crate) struct InvalidFloatLiteralSuffix {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    pub suffix: String,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::int_literal_too_large)]
-pub(crate) struct IntLiteralTooLarge {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::missing_semicolon_before_array)]
-pub(crate) struct MissingSemicolonBeforeArray {
-    #[primary_span]
-    pub open_delim: Span,
-    #[suggestion_verbose(applicability = "maybe-incorrect", code = ";")]
-    pub semicolon: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_block_macro_segment)]
-pub(crate) struct InvalidBlockMacroSegment {
-    #[primary_span]
-    pub span: Span,
-    #[label]
-    pub context: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::if_expression_missing_then_block)]
-pub(crate) struct IfExpressionMissingThenBlock {
-    #[primary_span]
-    pub if_span: Span,
-    #[subdiagnostic]
-    pub sub: IfExpressionMissingThenBlockSub,
-}
-
-#[derive(Subdiagnostic)]
-pub(crate) enum IfExpressionMissingThenBlockSub {
-    #[help(parser::condition_possibly_unfinished)]
-    UnfinishedCondition(#[primary_span] Span),
-    #[help(parser::add_then_block)]
-    AddThenBlock(#[primary_span] Span),
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::if_expression_missing_condition)]
-pub(crate) struct IfExpressionMissingCondition {
-    #[primary_span]
-    #[label(parser::condition_label)]
-    pub if_span: Span,
-    #[label(parser::block_label)]
-    pub block_span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::expected_expression_found_let)]
-pub(crate) struct ExpectedExpressionFoundLet {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::expected_else_block)]
-pub(crate) struct ExpectedElseBlock {
-    #[primary_span]
-    pub first_tok_span: Span,
-    pub first_tok: String,
-    #[label]
-    pub else_span: Span,
-    #[suggestion(applicability = "maybe-incorrect", code = "if ")]
-    pub condition_start: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::outer_attribute_not_allowed_on_if_else)]
-pub(crate) struct OuterAttributeNotAllowedOnIfElse {
-    #[primary_span]
-    pub last: Span,
-
-    #[label(parser::branch_label)]
-    pub branch_span: Span,
-
-    #[label(parser::ctx_label)]
-    pub ctx_span: Span,
-    pub ctx: String,
-
-    #[suggestion(applicability = "machine-applicable", code = "")]
-    pub attributes: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::missing_in_in_for_loop)]
-pub(crate) struct MissingInInForLoop {
-    #[primary_span]
-    pub span: Span,
-    #[subdiagnostic]
-    pub sub: MissingInInForLoopSub,
-}
-
-#[derive(Subdiagnostic)]
-pub(crate) enum MissingInInForLoopSub {
-    // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect
-    #[suggestion_short(parser::use_in_not_of, applicability = "maybe-incorrect", code = "in")]
-    InNotOf(#[primary_span] Span),
-    #[suggestion_short(parser::add_in, applicability = "maybe-incorrect", code = " in ")]
-    AddIn(#[primary_span] Span),
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::missing_comma_after_match_arm)]
-pub(crate) struct MissingCommaAfterMatchArm {
-    #[primary_span]
-    #[suggestion(applicability = "machine-applicable", code = ",")]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::catch_after_try)]
-#[help]
-pub(crate) struct CatchAfterTry {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::comma_after_base_struct)]
-#[note]
-pub(crate) struct CommaAfterBaseStruct {
-    #[primary_span]
-    pub span: Span,
-    #[suggestion_short(applicability = "machine-applicable", code = "")]
-    pub comma: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::eq_field_init)]
-pub(crate) struct EqFieldInit {
-    #[primary_span]
-    pub span: Span,
-    #[suggestion(applicability = "machine-applicable", code = ":")]
-    pub eq: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::dotdotdot)]
-pub(crate) struct DotDotDot {
-    #[primary_span]
-    #[suggestion(parser::suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")]
-    #[suggestion(parser::suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::left_arrow_operator)]
-pub(crate) struct LeftArrowOperator {
-    #[primary_span]
-    #[suggestion(applicability = "maybe-incorrect", code = "< -")]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::remove_let)]
-pub(crate) struct RemoveLet {
-    #[primary_span]
-    #[suggestion(applicability = "machine-applicable", code = "")]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::use_eq_instead)]
-pub(crate) struct UseEqInstead {
-    #[primary_span]
-    #[suggestion_short(applicability = "machine-applicable", code = "=")]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::use_empty_block_not_semi)]
-pub(crate) struct UseEmptyBlockNotSemi {
-    #[primary_span]
-    #[suggestion_hidden(applicability = "machine-applicable", code = "{{}}")]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::comparison_interpreted_as_generic)]
-pub(crate) struct ComparisonInterpretedAsGeneric {
-    #[primary_span]
-    #[label(parser::label_comparison)]
-    pub comparison: Span,
-    pub typename: String,
-    #[label(parser::label_args)]
-    pub args: Span,
-    #[subdiagnostic]
-    pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::shift_interpreted_as_generic)]
-pub(crate) struct ShiftInterpretedAsGeneric {
-    #[primary_span]
-    #[label(parser::label_comparison)]
-    pub shift: Span,
-    pub typename: String,
-    #[label(parser::label_args)]
-    pub args: Span,
-    #[subdiagnostic]
-    pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
-}
-
-#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
-pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
-    #[suggestion_part(code = "(")]
-    pub left: Span,
-    #[suggestion_part(code = ")")]
-    pub right: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::found_expr_would_be_stmt)]
-pub(crate) struct FoundExprWouldBeStmt {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    pub token: String,
-    #[subdiagnostic]
-    pub suggestion: ExprParenthesesNeeded,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::leading_plus_not_supported)]
-pub(crate) struct LeadingPlusNotSupported {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    #[suggestion_verbose(
-        parser::suggestion_remove_plus,
-        code = "",
-        applicability = "machine-applicable"
-    )]
-    pub remove_plus: Option<Span>,
-    #[subdiagnostic]
-    pub add_parentheses: Option<ExprParenthesesNeeded>,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::parentheses_with_struct_fields)]
-pub(crate) struct ParenthesesWithStructFields {
-    #[primary_span]
-    pub span: Span,
-    pub name: String,
-    #[subdiagnostic]
-    pub braces_for_struct: BracesForStructLiteral,
-    #[subdiagnostic]
-    pub no_fields_for_fn: NoFieldsForFnCall,
-}
-
-#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser::suggestion_braces_for_struct, applicability = "maybe-incorrect")]
-pub(crate) struct BracesForStructLiteral {
-    #[suggestion_part(code = " {{ ")]
-    pub first: Span,
-    #[suggestion_part(code = " }}")]
-    pub second: Span,
-}
-
-#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser::suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
-pub(crate) struct NoFieldsForFnCall {
-    #[suggestion_part(code = "")]
-    pub fields: Vec<Span>,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::labeled_loop_in_break)]
-pub(crate) struct LabeledLoopInBreak {
-    #[primary_span]
-    pub span: Span,
-    #[subdiagnostic]
-    pub sub: LabeledLoopInBreakSub,
-}
-
-#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
-pub(crate) struct LabeledLoopInBreakSub {
-    #[suggestion_part(code = "(")]
-    pub first: Span,
-    #[suggestion_part(code = ")")]
-    pub second: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::array_brackets_instead_of_braces)]
-pub(crate) struct ArrayBracketsInsteadOfSpaces {
-    #[primary_span]
-    pub span: Span,
-    #[subdiagnostic]
-    pub sub: ArrayBracketsInsteadOfSpacesSugg,
-}
-
-#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser::suggestion, applicability = "maybe-incorrect")]
-pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
-    #[suggestion_part(code = "[")]
-    pub left: Span,
-    #[suggestion_part(code = "]")]
-    pub right: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::match_arm_body_without_braces)]
-pub(crate) struct MatchArmBodyWithoutBraces {
-    #[primary_span]
-    #[label(parser::label_statements)]
-    pub statements: Span,
-    #[label(parser::label_arrow)]
-    pub arrow: Span,
-    pub num_statements: usize,
-    #[subdiagnostic]
-    pub sub: MatchArmBodyWithoutBracesSugg,
-}
-
-#[derive(Subdiagnostic)]
-pub(crate) enum MatchArmBodyWithoutBracesSugg {
-    #[multipart_suggestion(parser::suggestion_add_braces, applicability = "machine-applicable")]
-    AddBraces {
-        #[suggestion_part(code = "{{ ")]
-        left: Span,
-        #[suggestion_part(code = " }}")]
-        right: Span,
-    },
-    #[suggestion(
-        parser::suggestion_use_comma_not_semicolon,
-        code = ",",
-        applicability = "machine-applicable"
-    )]
-    UseComma {
-        #[primary_span]
-        semicolon: Span,
-    },
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::struct_literal_not_allowed_here)]
-pub(crate) struct StructLiteralNotAllowedHere {
-    #[primary_span]
-    pub span: Span,
-    #[subdiagnostic]
-    pub sub: StructLiteralNotAllowedHereSugg,
-}
-
-#[derive(Subdiagnostic)]
-#[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
-pub(crate) struct StructLiteralNotAllowedHereSugg {
-    #[suggestion_part(code = "(")]
-    pub left: Span,
-    #[suggestion_part(code = ")")]
-    pub right: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_interpolated_expression)]
-pub(crate) struct InvalidInterpolatedExpression {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::hexadecimal_float_literal_not_supported)]
-pub(crate) struct HexadecimalFloatLiteralNotSupported {
-    #[primary_span]
-    #[label(parser::not_supported)]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::octal_float_literal_not_supported)]
-pub(crate) struct OctalFloatLiteralNotSupported {
-    #[primary_span]
-    #[label(parser::not_supported)]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::binary_float_literal_not_supported)]
-pub(crate) struct BinaryFloatLiteralNotSupported {
-    #[primary_span]
-    #[label(parser::not_supported)]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_literal_suffix)]
-pub(crate) struct InvalidLiteralSuffix {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    // FIXME(#100717)
-    pub kind: String,
-    pub suffix: Symbol,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::invalid_literal_suffix_on_tuple_index)]
-pub(crate) struct InvalidLiteralSuffixOnTupleIndex {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    pub suffix: Symbol,
-    #[help(parser::tuple_exception_line_1)]
-    #[help(parser::tuple_exception_line_2)]
-    #[help(parser::tuple_exception_line_3)]
-    pub exception: Option<()>,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::non_string_abi_literal)]
-pub(crate) struct NonStringAbiLiteral {
-    #[primary_span]
-    #[suggestion(code = "\"C\"", applicability = "maybe-incorrect")]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(parser::mismatched_closing_delimiter)]
-pub(crate) struct MismatchedClosingDelimiter {
-    #[primary_span]
-    pub spans: Vec<Span>,
-    pub delimiter: String,
-    #[label(parser::label_unmatched)]
-    pub unmatched: Span,
-    #[label(parser::label_opening_candidate)]
-    pub opening_candidate: Option<Span>,
-    #[label(parser::label_unclosed)]
-    pub unclosed: Option<Span>,
-}
-
 // SnapshotParser is used to create a snapshot of the parser
 // without causing duplicate errors being emitted when the `Parser`
 // is dropped.
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index f954dff9394..784a8ae4c2e 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1,34 +1,32 @@
-use super::diagnostics::{
-    ArrayBracketsInsteadOfSpaces, ArrayBracketsInsteadOfSpacesSugg, BracesForStructLiteral,
-    CatchAfterTry, CommaAfterBaseStruct, ComparisonInterpretedAsGeneric,
-    ComparisonOrShiftInterpretedAsGenericSugg, DoCatchSyntaxRemoved, DotDotDot, EqFieldInit,
-    ExpectedElseBlock, ExpectedExpressionFoundLet, FieldExpressionWithGeneric,
-    FloatLiteralRequiresIntegerPart, FoundExprWouldBeStmt, IfExpressionMissingCondition,
-    IfExpressionMissingThenBlock, IfExpressionMissingThenBlockSub, InvalidBlockMacroSegment,
-    InvalidComparisonOperator, InvalidComparisonOperatorSub, InvalidInterpolatedExpression,
-    InvalidLiteralSuffix, InvalidLiteralSuffixOnTupleIndex, InvalidLogicalOperator,
-    InvalidLogicalOperatorSub, LabeledLoopInBreak, LeftArrowOperator, LifetimeInBorrowExpression,
-    MacroInvocationWithQualifiedPath, MalformedLoopLabel, MatchArmBodyWithoutBraces,
-    MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray, NoFieldsForFnCall,
-    NotAsNegationOperator, NotAsNegationOperatorSub, OuterAttributeNotAllowedOnIfElse,
-    ParenthesesWithStructFields, RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric,
-    SnapshotParser, StructLiteralNotAllowedHere, TildeAsUnaryOperator, UnexpectedTokenAfterLabel,
-    UnexpectedTokenAfterLabelSugg,
-};
+use super::diagnostics::SnapshotParser;
 use super::pat::{CommaRecoveryMode, RecoverColon, RecoverComma, PARAM_EXPECTED};
 use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
 use super::{
     AttrWrapper, BlockMode, ClosureSpans, ForceCollect, Parser, PathStyle, Restrictions,
     SemiColonMode, SeqSep, TokenExpectType, TokenType, TrailingToken,
 };
-use crate::maybe_recover_from_interpolated_ty_qpath;
-use crate::parser::diagnostics::{
-    BinaryFloatLiteralNotSupported, HexadecimalFloatLiteralNotSupported, IntLiteralTooLarge,
-    InvalidFloatLiteralSuffix, InvalidFloatLiteralWidth, InvalidIntLiteralWidth,
-    InvalidNumLiteralBasePrefix, InvalidNumLiteralSuffix, LabeledLoopInBreakSub,
-    LeadingPlusNotSupported, MatchArmBodyWithoutBracesSugg, MissingCommaAfterMatchArm,
-    OctalFloatLiteralNotSupported, StructLiteralNotAllowedHereSugg,
+use crate::errors::{
+    ArrayBracketsInsteadOfSpaces, ArrayBracketsInsteadOfSpacesSugg, BinaryFloatLiteralNotSupported,
+    BracesForStructLiteral, CatchAfterTry, CommaAfterBaseStruct, ComparisonInterpretedAsGeneric,
+    ComparisonOrShiftInterpretedAsGenericSugg, DoCatchSyntaxRemoved, DotDotDot, EqFieldInit,
+    ExpectedElseBlock, ExpectedExpressionFoundLet, FieldExpressionWithGeneric,
+    FloatLiteralRequiresIntegerPart, FoundExprWouldBeStmt, HexadecimalFloatLiteralNotSupported,
+    IfExpressionMissingCondition, IfExpressionMissingThenBlock, IfExpressionMissingThenBlockSub,
+    IntLiteralTooLarge, InvalidBlockMacroSegment, InvalidComparisonOperator,
+    InvalidComparisonOperatorSub, InvalidFloatLiteralSuffix, InvalidFloatLiteralWidth,
+    InvalidIntLiteralWidth, InvalidInterpolatedExpression, InvalidLiteralSuffix,
+    InvalidLiteralSuffixOnTupleIndex, InvalidLogicalOperator, InvalidLogicalOperatorSub,
+    InvalidNumLiteralBasePrefix, InvalidNumLiteralSuffix, LabeledLoopInBreak,
+    LabeledLoopInBreakSub, LeadingPlusNotSupported, LeftArrowOperator, LifetimeInBorrowExpression,
+    MacroInvocationWithQualifiedPath, MalformedLoopLabel, MatchArmBodyWithoutBraces,
+    MatchArmBodyWithoutBracesSugg, MissingCommaAfterMatchArm, MissingInInForLoop,
+    MissingInInForLoopSub, MissingSemicolonBeforeArray, NoFieldsForFnCall, NotAsNegationOperator,
+    NotAsNegationOperatorSub, OctalFloatLiteralNotSupported, OuterAttributeNotAllowedOnIfElse,
+    ParenthesesWithStructFields, RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric,
+    StructLiteralNotAllowedHere, StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator,
+    UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg,
 };
+use crate::maybe_recover_from_interpolated_ty_qpath;
 
 use core::mem;
 use rustc_ast::ptr::P;
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 6c4cfcf6ddf..37d12f78397 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1,4 +1,6 @@
-use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error, UseEmptyBlockNotSemi};
+use crate::errors::UseEmptyBlockNotSemi;
+
+use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error};
 use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
 use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
 
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 123e6ce7ab5..af6c0e34e2f 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -42,7 +42,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use std::ops::Range;
 use std::{cmp, mem, slice};
 
-use self::diagnostics::{MismatchedClosingDelimiter, NonStringAbiLiteral};
+use crate::errors::{MismatchedClosingDelimiter, NonStringAbiLiteral};
 
 bitflags::bitflags! {
     struct Restrictions: u8 {
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 120a3c267f1..542a1ac5dc6 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -1,5 +1,5 @@
 use super::{ForceCollect, Parser, PathStyle, TrailingToken};
-use crate::parser::diagnostics::RemoveLet;
+use crate::errors::RemoveLet;
 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
 use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
 use rustc_ast::ptr::P;
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 3d957406b19..03ced75d763 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -1,7 +1,5 @@
 use super::attr::DEFAULT_INNER_ATTR_FORBIDDEN;
-use super::diagnostics::{
-    AttemptLocalParseRecovery, Error, InvalidVariableDeclaration, InvalidVariableDeclarationSub,
-};
+use super::diagnostics::{AttemptLocalParseRecovery, Error};
 use super::expr::LhsExpr;
 use super::pat::RecoverComma;
 use super::path::PathStyle;
@@ -9,6 +7,7 @@ use super::TrailingToken;
 use super::{
     AttrWrapper, BlockMode, FnParseMode, ForceCollect, Parser, Restrictions, SemiColonMode,
 };
+use crate::errors::{InvalidVariableDeclaration, InvalidVariableDeclarationSub};
 use crate::maybe_whole;
 
 use rustc_ast as ast;