Skip to content

Commit e1b1d7b

Browse files
committed
Migrate more rustc_parse diagnostics to diagnostic structs
1 parent e56d6a6 commit e1b1d7b

File tree

9 files changed

+192
-160
lines changed

9 files changed

+192
-160
lines changed

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

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ parser_parentheses_with_struct_fields = invalid `struct` delimiters or `fn` call
188188
.suggestion_no_fields_for_fn = if `{$name}` is a function, use the arguments directly
189189
190190
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
191+
192+
parser_sugg_wrap_expression_in_parentheses = wrap the expression in parentheses
192193
193194
parser_array_brackets_instead_of_braces = this is a block expression, not an array
194195
.suggestion = to make an array, use square brackets instead of curly braces
@@ -231,3 +232,33 @@ parser_mismatched_closing_delimiter = mismatched closing delimiter: `{$delimiter
231232
.label_unmatched = mismatched closing delimiter
232233
.label_opening_candidate = closing delimiter possibly meant for this
233234
.label_unclosed = unclosed delimiter
235+
236+
parser_incorrect_visibility_restriction = incorrect visibility restriction
237+
.help = some possible visibility restrictions are:
238+
`pub(crate)`: visible only on the current crate
239+
`pub(super)`: visible only in the current module's parent
240+
`pub(in path::to::module)`: visible only on the specified path
241+
.suggestion = make this visible only to module `{$inner_str}` with `in`
242+
243+
parser_assignment_else_not_allowed = <assignment> ... else {"{"} ... {"}"} is not allowed
244+
245+
parser_expected_statement_after_outer_attr = expected statement after outer attribute
246+
247+
parser_doc_comment_does_not_document_anything = found a documentation comment that doesn't document anything
248+
.help = doc comments must come before what they document, maybe a comment was intended with `//`?
249+
.suggestion = missing comma here
250+
251+
parser_const_let_mutually_exclusive = `const` and `let` are mutually exclusive
252+
.suggestion = remove `let`
253+
254+
parser_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else`
255+
parser_invalid_curly_in_let_else = right curly brace `{"}"}` before `else` in a `let...else` statement not allowed
256+
257+
parser_compound_assignment_expression_in_let = can't reassign to an uninitialized variable
258+
.suggestion = initialize the variable
259+
.help = if you meant to overwrite, remove the `let` binding
260+
261+
parser_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes
262+
.help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
263+
264+
parser_invalid_meta_item = expected unsuffixed literal or identifier, found `{$token}`

compiler/rustc_parse/src/errors.rs

Lines changed: 94 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -624,16 +624,19 @@ pub(crate) struct LabeledLoopInBreak {
624624
#[primary_span]
625625
pub span: Span,
626626
#[subdiagnostic]
627-
pub sub: LabeledLoopInBreakSub,
627+
pub sub: WrapExpressionInParentheses,
628628
}
629629

630630
#[derive(Subdiagnostic)]
631-
#[multipart_suggestion(parser::suggestion, applicability = "machine-applicable")]
632-
pub(crate) struct LabeledLoopInBreakSub {
631+
#[multipart_suggestion(
632+
parser::sugg_wrap_expression_in_parentheses,
633+
applicability = "machine-applicable"
634+
)]
635+
pub(crate) struct WrapExpressionInParentheses {
633636
#[suggestion_part(code = "(")]
634-
pub first: Span,
637+
pub left: Span,
635638
#[suggestion_part(code = ")")]
636-
pub second: Span,
639+
pub right: Span,
637640
}
638641

639642
#[derive(Diagnostic)]
@@ -781,3 +784,89 @@ pub(crate) struct MismatchedClosingDelimiter {
781784
#[label(parser::label_unclosed)]
782785
pub unclosed: Option<Span>,
783786
}
787+
788+
#[derive(Diagnostic)]
789+
#[diag(parser::incorrect_visibility_restriction, code = "E0704")]
790+
#[help]
791+
pub(crate) struct IncorrectVisibilityRestriction {
792+
#[primary_span]
793+
#[suggestion(code = "in {inner_str}", applicability = "machine-applicable")]
794+
pub span: Span,
795+
pub inner_str: String,
796+
}
797+
798+
#[derive(Diagnostic)]
799+
#[diag(parser::assignment_else_not_allowed)]
800+
pub(crate) struct AssignmentElseNotAllowed {
801+
#[primary_span]
802+
pub span: Span,
803+
}
804+
805+
#[derive(Diagnostic)]
806+
#[diag(parser::expected_statement_after_outer_attr)]
807+
pub(crate) struct ExpectedStatementAfterOuterAttr {
808+
#[primary_span]
809+
pub span: Span,
810+
}
811+
812+
#[derive(Diagnostic)]
813+
#[diag(parser::doc_comment_does_not_document_anything, code = "E0585")]
814+
#[help]
815+
pub(crate) struct DocCommentDoesNotDocumentAnything {
816+
#[primary_span]
817+
pub span: Span,
818+
#[suggestion(code = ",", applicability = "machine-applicable")]
819+
pub missing_comma: Option<Span>,
820+
}
821+
822+
#[derive(Diagnostic)]
823+
#[diag(parser::const_let_mutually_exclusive)]
824+
pub(crate) struct ConstLetMutuallyExclusive {
825+
#[primary_span]
826+
#[suggestion(code = "const", applicability = "maybe-incorrect")]
827+
pub span: Span,
828+
}
829+
830+
#[derive(Diagnostic)]
831+
#[diag(parser::invalid_expression_in_let_else)]
832+
pub(crate) struct InvalidExpressionInLetElse {
833+
#[primary_span]
834+
pub span: Span,
835+
pub operator: &'static str,
836+
#[subdiagnostic]
837+
pub sugg: WrapExpressionInParentheses,
838+
}
839+
840+
#[derive(Diagnostic)]
841+
#[diag(parser::invalid_curly_in_let_else)]
842+
pub(crate) struct InvalidCurlyInLetElse {
843+
#[primary_span]
844+
pub span: Span,
845+
#[subdiagnostic]
846+
pub sugg: WrapExpressionInParentheses,
847+
}
848+
849+
#[derive(Diagnostic)]
850+
#[diag(parser::compound_assignment_expression_in_let)]
851+
#[help]
852+
pub(crate) struct CompoundAssignmentExpressionInLet {
853+
#[primary_span]
854+
#[suggestion_short(code = "=", applicability = "maybe-incorrect")]
855+
pub span: Span,
856+
}
857+
858+
#[derive(Diagnostic)]
859+
#[diag(parser::suffixed_literal_in_attribute)]
860+
#[help]
861+
pub(crate) struct SuffixedLiteralInAttribute {
862+
#[primary_span]
863+
pub span: Span,
864+
}
865+
866+
#[derive(Diagnostic)]
867+
#[diag(parser::invalid_meta_item)]
868+
pub(crate) struct InvalidMetaItem {
869+
#[primary_span]
870+
pub span: Span,
871+
pub token: String,
872+
}

compiler/rustc_parse/src/parser/attr.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
use crate::errors::{InvalidMetaItem, SuffixedLiteralInAttribute};
2+
13
use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle};
24
use rustc_ast as ast;
35
use rustc_ast::attr;
46
use rustc_ast::token::{self, Delimiter, Nonterminal};
57
use rustc_ast_pretty::pprust;
6-
use rustc_errors::{error_code, Diagnostic, PResult};
8+
use rustc_errors::{error_code, Diagnostic, IntoDiagnostic, PResult};
79
use rustc_span::{sym, BytePos, Span};
810
use std::convert::TryInto;
911

@@ -337,12 +339,7 @@ impl<'a> Parser<'a> {
337339
debug!("checking if {:?} is unusuffixed", lit);
338340

339341
if !lit.kind.is_unsuffixed() {
340-
self.struct_span_err(lit.span, "suffixed literals are not allowed in attributes")
341-
.help(
342-
"instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), \
343-
use an unsuffixed version (`1`, `1.0`, etc.)",
344-
)
345-
.emit();
342+
self.sess.emit_err(SuffixedLiteralInAttribute { span: lit.span });
346343
}
347344

348345
Ok(lit)
@@ -435,9 +432,9 @@ impl<'a> Parser<'a> {
435432
Err(err) => err.cancel(),
436433
}
437434

438-
let found = pprust::token_to_string(&self.token);
439-
let msg = format!("expected unsuffixed literal or identifier, found `{found}`");
440-
Err(self.struct_span_err(self.token.span, &msg))
435+
let token = pprust::token_to_string(&self.token).to_string();
436+
Err(InvalidMetaItem { span: self.token.span, token }
437+
.into_diagnostic(&self.sess.span_diagnostic))
441438
}
442439
}
443440

compiler/rustc_parse/src/parser/diagnostics.rs

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -55,34 +55,6 @@ pub(super) fn dummy_arg(ident: Ident) -> Param {
5555
}
5656
}
5757

58-
pub enum Error {
59-
UselessDocComment,
60-
}
61-
62-
impl Error {
63-
fn span_err(
64-
self,
65-
sp: impl Into<MultiSpan>,
66-
handler: &Handler,
67-
) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
68-
match self {
69-
Error::UselessDocComment => {
70-
let mut err = struct_span_err!(
71-
handler,
72-
sp,
73-
E0585,
74-
"found a documentation comment that doesn't document anything",
75-
);
76-
err.help(
77-
"doc comments must come before what they document, maybe a comment was \
78-
intended with `//`?",
79-
);
80-
err
81-
}
82-
}
83-
}
84-
}
85-
8658
pub(super) trait RecoverQPath: Sized + 'static {
8759
const PATH_STYLE: PathStyle = PathStyle::Expr;
8860
fn to_ty(&self) -> Option<P<Ty>>;
@@ -268,15 +240,6 @@ impl<'a> DerefMut for SnapshotParser<'a> {
268240
}
269241

270242
impl<'a> Parser<'a> {
271-
#[rustc_lint_diagnostics]
272-
pub(super) fn span_err<S: Into<MultiSpan>>(
273-
&self,
274-
sp: S,
275-
err: Error,
276-
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
277-
err.span_err(sp, self.diagnostic())
278-
}
279-
280243
#[rustc_lint_diagnostics]
281244
pub fn struct_span_err<S: Into<MultiSpan>>(
282245
&self,

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ use crate::errors::{
1717
InvalidIntLiteralWidth, InvalidInterpolatedExpression, InvalidLiteralSuffix,
1818
InvalidLiteralSuffixOnTupleIndex, InvalidLogicalOperator, InvalidLogicalOperatorSub,
1919
InvalidNumLiteralBasePrefix, InvalidNumLiteralSuffix, LabeledLoopInBreak,
20-
LabeledLoopInBreakSub, LeadingPlusNotSupported, LeftArrowOperator, LifetimeInBorrowExpression,
20+
LeadingPlusNotSupported, LeftArrowOperator, LifetimeInBorrowExpression,
2121
MacroInvocationWithQualifiedPath, MalformedLoopLabel, MatchArmBodyWithoutBraces,
2222
MatchArmBodyWithoutBracesSugg, MissingCommaAfterMatchArm, MissingInInForLoop,
2323
MissingInInForLoopSub, MissingSemicolonBeforeArray, NoFieldsForFnCall, NotAsNegationOperator,
2424
NotAsNegationOperatorSub, OctalFloatLiteralNotSupported, OuterAttributeNotAllowedOnIfElse,
2525
ParenthesesWithStructFields, RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric,
2626
StructLiteralNotAllowedHere, StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator,
27-
UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg,
27+
UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses,
2828
};
2929
use crate::maybe_recover_from_interpolated_ty_qpath;
3030

@@ -1661,9 +1661,9 @@ impl<'a> Parser<'a> {
16611661
let lexpr = self.parse_labeled_expr(label.take().unwrap(), true)?;
16621662
self.sess.emit_err(LabeledLoopInBreak {
16631663
span: lexpr.span,
1664-
sub: LabeledLoopInBreakSub {
1665-
first: lexpr.span.shrink_to_lo(),
1666-
second: lexpr.span.shrink_to_hi(),
1664+
sub: WrapExpressionInParentheses {
1665+
left: lexpr.span.shrink_to_lo(),
1666+
right: lexpr.span.shrink_to_hi(),
16671667
},
16681668
});
16691669
Some(lexpr)

compiler/rustc_parse/src/parser/item.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use crate::errors::UseEmptyBlockNotSemi;
1+
use crate::errors::{DocCommentDoesNotDocumentAnything, UseEmptyBlockNotSemi};
22

3-
use super::diagnostics::{dummy_arg, ConsumeClosingDelim, Error};
3+
use super::diagnostics::{dummy_arg, ConsumeClosingDelim};
44
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
55
use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
66

@@ -15,7 +15,7 @@ use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, Vari
1515
use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind};
1616
use rustc_ast::{MacArgs, MacCall, MacDelimiter};
1717
use rustc_ast_pretty::pprust;
18-
use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
18+
use rustc_errors::{struct_span_err, Applicability, IntoDiagnostic, PResult, StashKey};
1919
use rustc_span::edition::Edition;
2020
use rustc_span::lev_distance::lev_distance;
2121
use rustc_span::source_map::{self, Span};
@@ -1586,7 +1586,10 @@ impl<'a> Parser<'a> {
15861586
token::CloseDelim(Delimiter::Brace) => {}
15871587
token::DocComment(..) => {
15881588
let previous_span = self.prev_token.span;
1589-
let mut err = self.span_err(self.token.span, Error::UselessDocComment);
1589+
let mut err = DocCommentDoesNotDocumentAnything {
1590+
span: self.token.span,
1591+
missing_comma: None,
1592+
};
15901593
self.bump(); // consume the doc comment
15911594
let comma_after_doc_seen = self.eat(&token::Comma);
15921595
// `seen_comma` is always false, because we are inside doc block
@@ -1595,18 +1598,13 @@ impl<'a> Parser<'a> {
15951598
seen_comma = true;
15961599
}
15971600
if comma_after_doc_seen || self.token == token::CloseDelim(Delimiter::Brace) {
1598-
err.emit();
1601+
self.sess.emit_err(err);
15991602
} else {
16001603
if !seen_comma {
16011604
let sp = self.sess.source_map().next_point(previous_span);
1602-
err.span_suggestion(
1603-
sp,
1604-
"missing comma here",
1605-
",",
1606-
Applicability::MachineApplicable,
1607-
);
1605+
err.missing_comma = Some(sp);
16081606
}
1609-
return Err(err);
1607+
return Err(err.into_diagnostic(&self.sess.span_diagnostic));
16101608
}
16111609
}
16121610
_ => {

0 commit comments

Comments
 (0)