Skip to content

Commit ab7c7dc

Browse files
committed
Migrate more diagnostics in rustc_parse to diagnostic structs
1 parent 4d02892 commit ab7c7dc

File tree

6 files changed

+465
-220
lines changed

6 files changed

+465
-220
lines changed

compiler/rustc_error_messages/locales/en-US/parser.ftl

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ parser_field_expression_with_generic = field expressions cannot have generic arg
7171
parser_macro_invocation_with_qualified_path = macros cannot use qualified paths
7272
7373
parser_unexpected_token_after_label = expected `while`, `for`, `loop` or `{"{"}` after a label
74+
.suggestion_remove_label = consider removing the label
75+
.suggestion_enclose_in_block = consider enclosing expression in a block
7476
7577
parser_require_colon_after_labeled_expression = labeled expression must be followed by `:`
7678
.note = labels are used before loops and blocks, allowing e.g., `break 'label` to them
@@ -161,3 +163,62 @@ parser_use_eq_instead = unexpected `==`
161163
162164
parser_use_empty_block_not_semi = expected { "`{}`" }, found `;`
163165
.suggestion = try using { "`{}`" } instead
166+
167+
parser_comparison_interpreted_as_generic =
168+
`<` is interpreted as a start of generic arguments for `{$typename}`, not a comparison
169+
.label_args = interpreted as generic arguments
170+
.label_comparison = not interpreted as comparison
171+
.suggestion = try comparing the cast value
172+
173+
parser_shift_interpreted_as_generic =
174+
`<<` is interpreted as a start of generic arguments for `{$typename}`, not a shift
175+
.label_args = interpreted as generic arguments
176+
.label_comparison = not interpreted as shift
177+
.suggestion = try shifting the cast value
178+
179+
parser_found_expr_would_be_stmt = expected expression, found `{$token}`
180+
.label = expected expression
181+
182+
parser_leading_plus_not_supported = leading `+` is not supported
183+
.label = unexpected `+`
184+
.suggestion_remove_plus = try removing the `+`
185+
186+
parser_parentheses_with_struct_fields = invalid `struct` delimiters or `fn` call arguments
187+
.suggestion_braces_for_struct = if `{$name}` is a struct, use braces as delimiters
188+
.suggestion_no_fields_for_fn = if `{$name}` is a function, use the arguments directly
189+
190+
parser_labeled_loop_in_break = parentheses are required around this expression to avoid confusion with a labeled break expression
191+
.suggestion = wrap the expression in parentheses
192+
193+
parser_array_brackets_instead_of_braces = this is a block expression, not an array
194+
.suggestion = to make an array, use square brackets instead of curly braces
195+
196+
parser_match_arm_body_without_braces = `match` arm body without braces
197+
.label_statements = {$num_statements ->
198+
[one] this statement is not surrounded by a body
199+
*[other] these statements are not surrounded by a body
200+
}
201+
.label_arrow = while parsing the `match` arm starting here
202+
.suggestion_add_braces = surround the {$num_statements ->
203+
[one] statement
204+
*[other] statements
205+
} with a body
206+
.suggestion_use_comma_not_semicolon = use a comma to end a `match` arm expression
207+
208+
parser_struct_literal_not_allowed_here = struct literals are not allowed here
209+
.suggestion = surround the struct literal with parentheses
210+
211+
parser_invalid_interpolated_expression = invalid interpolated expression
212+
213+
parser_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported
214+
parser_octal_float_literal_not_supported = octal float literal is not supported
215+
parser_binary_float_literal_not_supported = binary float literal is not supported
216+
parser_not_supported = not supported
217+
218+
parser_non_string_abi_literal = non-string ABI literal
219+
.suggestion = specify the ABI with a string literal
220+
221+
parser_mismatched_closing_delimiter = mismatched closing delimiter: `{$delimiter}`
222+
.label_unmatched = mismatched closing delimiter
223+
.label_opening_candidate = closing delimiter possibly meant for this
224+
.label_unclosed = unclosed delimiter

compiler/rustc_parse/src/parser/diagnostics.rs

Lines changed: 247 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_errors::{
2121
};
2222
use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
2323
use rustc_macros::{Diagnostic, Subdiagnostic};
24+
use rustc_session::errors::ExprParenthesesNeeded;
2425
use rustc_span::source_map::Spanned;
2526
use rustc_span::symbol::{kw, sym, Ident};
2627
use rustc_span::{Span, SpanSnippetError, DUMMY_SP};
@@ -487,11 +488,24 @@ pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span);
487488

488489
#[derive(Diagnostic)]
489490
#[diag(parser::unexpected_token_after_label)]
490-
pub(crate) struct UnexpectedTokenAfterLabel(
491+
pub(crate) struct UnexpectedTokenAfterLabel {
491492
#[primary_span]
492493
#[label(parser::unexpected_token_after_label)]
493-
pub Span,
494-
);
494+
pub span: Span,
495+
#[suggestion_verbose(parser::suggestion_remove_label, code = "")]
496+
pub remove_label: Option<Span>,
497+
#[subdiagnostic]
498+
pub enclose_in_block: Option<UnexpectedTokenAfterLabelSugg>,
499+
}
500+
501+
#[derive(Subdiagnostic)]
502+
#[multipart_suggestion(parser::suggestion_enclose_in_block, applicability = "machine-applicable")]
503+
pub(crate) struct UnexpectedTokenAfterLabelSugg {
504+
#[suggestion_part(code = "{{ ")]
505+
pub left: Span,
506+
#[suggestion_part(code = " }}")]
507+
pub right: Span,
508+
}
495509

496510
#[derive(Diagnostic)]
497511
#[diag(parser::require_colon_after_labeled_expression)]
@@ -753,6 +767,236 @@ pub(crate) struct UseEmptyBlockNotSemi {
753767
pub span: Span,
754768
}
755769

770+
#[derive(Diagnostic)]
771+
#[diag(parser::comparison_interpreted_as_generic)]
772+
pub(crate) struct ComparisonInterpretedAsGeneric {
773+
#[primary_span]
774+
#[label(parser::label_comparison)]
775+
pub comparison: Span,
776+
pub typename: String,
777+
#[label(parser::label_args)]
778+
pub args: Span,
779+
#[subdiagnostic]
780+
pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
781+
}
782+
783+
#[derive(Diagnostic)]
784+
#[diag(parser::shift_interpreted_as_generic)]
785+
pub(crate) struct ShiftInterpretedAsGeneric {
786+
#[primary_span]
787+
#[label(parser::label_comparison)]
788+
pub shift: Span,
789+
pub typename: String,
790+
#[label(parser::label_args)]
791+
pub args: Span,
792+
#[subdiagnostic]
793+
pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg,
794+
}
795+
796+
#[derive(Subdiagnostic)]
797+
#[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
798+
pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg {
799+
#[suggestion_part(code = "(")]
800+
pub left: Span,
801+
#[suggestion_part(code = ")")]
802+
pub right: Span,
803+
}
804+
805+
#[derive(Diagnostic)]
806+
#[diag(parser::found_expr_would_be_stmt)]
807+
pub(crate) struct FoundExprWouldBeStmt {
808+
#[primary_span]
809+
#[label]
810+
pub span: Span,
811+
pub token: String,
812+
#[subdiagnostic]
813+
pub suggestion: ExprParenthesesNeeded,
814+
}
815+
816+
#[derive(Diagnostic)]
817+
#[diag(parser::leading_plus_not_supported)]
818+
pub(crate) struct LeadingPlusNotSupported {
819+
#[primary_span]
820+
#[label]
821+
pub span: Span,
822+
#[suggestion_verbose(
823+
parser::suggestion_remove_plus,
824+
code = "",
825+
applicability = "machine-applicable"
826+
)]
827+
pub remove_plus: Option<Span>,
828+
#[subdiagnostic]
829+
pub add_parentheses: Option<ExprParenthesesNeeded>,
830+
}
831+
832+
#[derive(Diagnostic)]
833+
#[diag(parser::parentheses_with_struct_fields)]
834+
pub(crate) struct ParenthesesWithStructFields {
835+
#[primary_span]
836+
pub span: Span,
837+
pub name: String,
838+
#[subdiagnostic]
839+
pub braces_for_struct: BracesForStructLiteral,
840+
#[subdiagnostic]
841+
pub no_fields_for_fn: NoFieldsForFnCall,
842+
}
843+
844+
#[derive(Subdiagnostic)]
845+
#[multipart_suggestion(parser::suggestion_braces_for_struct, applicability = "maybe-incorrect")]
846+
pub(crate) struct BracesForStructLiteral {
847+
#[suggestion_part(code = " {{ ")]
848+
pub first: Span,
849+
#[suggestion_part(code = " }}")]
850+
pub second: Span,
851+
}
852+
853+
#[derive(Subdiagnostic)]
854+
#[multipart_suggestion(parser::suggestion_no_fields_for_fn, applicability = "maybe-incorrect")]
855+
pub(crate) struct NoFieldsForFnCall {
856+
#[suggestion_part(code = "")]
857+
pub fields: Vec<Span>,
858+
}
859+
860+
#[derive(Diagnostic)]
861+
#[diag(parser::labeled_loop_in_break)]
862+
pub(crate) struct LabeledLoopInBreak {
863+
#[primary_span]
864+
pub span: Span,
865+
#[subdiagnostic]
866+
pub sub: LabeledLoopInBreakSub,
867+
}
868+
869+
#[derive(Subdiagnostic)]
870+
#[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
871+
pub(crate) struct LabeledLoopInBreakSub {
872+
#[suggestion_part(code = "(")]
873+
pub first: Span,
874+
#[suggestion_part(code = ")")]
875+
pub second: Span,
876+
}
877+
878+
#[derive(Diagnostic)]
879+
#[diag(parser::array_brackets_instead_of_braces)]
880+
pub(crate) struct ArrayBracketsInsteadOfSpaces {
881+
#[primary_span]
882+
pub span: Span,
883+
#[subdiagnostic]
884+
pub sub: ArrayBracketsInsteadOfSpacesSugg,
885+
}
886+
887+
#[derive(Subdiagnostic)]
888+
#[multipart_suggestion(parser::suggestion, applicability = "maybe-incorrect")]
889+
pub(crate) struct ArrayBracketsInsteadOfSpacesSugg {
890+
#[suggestion_part(code = "[")]
891+
pub left: Span,
892+
#[suggestion_part(code = "]")]
893+
pub right: Span,
894+
}
895+
896+
#[derive(Diagnostic)]
897+
#[diag(parser::match_arm_body_without_braces)]
898+
pub(crate) struct MatchArmBodyWithoutBraces {
899+
#[primary_span]
900+
#[label(parser::label_statements)]
901+
pub statements: Span,
902+
#[label(parser::label_arrow)]
903+
pub arrow: Span,
904+
pub num_statements: usize,
905+
#[subdiagnostic]
906+
pub sub: MatchArmBodyWithoutBracesSugg,
907+
}
908+
909+
#[derive(Subdiagnostic)]
910+
pub(crate) enum MatchArmBodyWithoutBracesSugg {
911+
#[multipart_suggestion(parser::suggestion_add_braces, applicability = "machine-applicable")]
912+
AddBraces {
913+
#[suggestion_part(code = "{{ ")]
914+
left: Span,
915+
#[suggestion_part(code = " }}")]
916+
right: Span,
917+
},
918+
#[suggestion(
919+
parser::suggestion_use_comma_not_semicolon,
920+
code = ",",
921+
applicability = "machine-applicable"
922+
)]
923+
UseComma {
924+
#[primary_span]
925+
semicolon: Span,
926+
},
927+
}
928+
929+
#[derive(Diagnostic)]
930+
#[diag(parser::struct_literal_not_allowed_here)]
931+
pub(crate) struct StructLiteralNotAllowedHere {
932+
#[primary_span]
933+
pub span: Span,
934+
#[subdiagnostic]
935+
pub sub: StructLiteralNotAllowedHereSugg,
936+
}
937+
938+
#[derive(Subdiagnostic)]
939+
#[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
940+
pub(crate) struct StructLiteralNotAllowedHereSugg {
941+
#[suggestion_part(code = "(")]
942+
pub left: Span,
943+
#[suggestion_part(code = ")")]
944+
pub right: Span,
945+
}
946+
947+
#[derive(Diagnostic)]
948+
#[diag(parser::invalid_interpolated_expression)]
949+
pub(crate) struct InvalidInterpolatedExpression {
950+
#[primary_span]
951+
pub span: Span,
952+
}
953+
954+
#[derive(Diagnostic)]
955+
#[diag(parser::hexadecimal_float_literal_not_supported)]
956+
pub(crate) struct HexadecimalFloatLiteralNotSupported {
957+
#[primary_span]
958+
#[label(parser::not_supported)]
959+
pub span: Span,
960+
}
961+
962+
#[derive(Diagnostic)]
963+
#[diag(parser::octal_float_literal_not_supported)]
964+
pub(crate) struct OctalFloatLiteralNotSupported {
965+
#[primary_span]
966+
#[label(parser::not_supported)]
967+
pub span: Span,
968+
}
969+
970+
#[derive(Diagnostic)]
971+
#[diag(parser::binary_float_literal_not_supported)]
972+
pub(crate) struct BinaryFloatLiteralNotSupported {
973+
#[primary_span]
974+
#[label(parser::not_supported)]
975+
pub span: Span,
976+
}
977+
978+
#[derive(Diagnostic)]
979+
#[diag(parser::non_string_abi_literal)]
980+
pub(crate) struct NonStringAbiLiteral {
981+
#[primary_span]
982+
#[suggestion(code = "\"C\"", applicability = "maybe-incorrect")]
983+
pub span: Span,
984+
}
985+
986+
#[derive(Diagnostic)]
987+
#[diag(parser::mismatched_closing_delimiter)]
988+
pub(crate) struct MismatchedClosingDelimiter {
989+
#[primary_span]
990+
pub spans: Vec<Span>,
991+
pub delimiter: String,
992+
#[label(parser::label_unmatched)]
993+
pub unmatched: Span,
994+
#[label(parser::label_opening_candidate)]
995+
pub opening_candidate: Option<Span>,
996+
#[label(parser::label_unclosed)]
997+
pub unclosed: Option<Span>,
998+
}
999+
7561000
// SnapshotParser is used to create a snapshot of the parser
7571001
// without causing duplicate errors being emitted when the `Parser`
7581002
// is dropped.

0 commit comments

Comments
 (0)